Sessions for CAKE (v2)

Brief overview

There are two kinds of CAKE messages involved in creating and maintaining sessions. Each of these two messages may contain a myriad of sub-messages, and each of these sub-messages, while still bound for the same CAKE id, may be bound for different sub-parts of the system. A CAKE session is roughly analogous to an IPSEC security association.

A CAKE message must fit within the message size limits of any transport you are running it over. For example, for TCP there isn't a limit imposed by the transport at all. But for UDP packets, the limit is around 65000 bytes, and if you are running with high packet-loss, the practical limit is the MSS of the route between your and who you're talking to.

Sessions do include enough information to re-assemble messages that are part of the session in order, but an individual CAKE implementation may not preserve enough information to do this. It is encouraged for an implementation to store a message that has been recieved seemingly out-of-order and wait briefly until intervening message appears. But this is not guaranteed.

This means that protocols running inside of CAKE must handle these kinds of message losses intelligently.

CAKE also uses caching techniques and an 'optimistic' model for many things to minimize the number of round trips. These techniques will be described when talked about CAKE, and they will also be used and described in the design of some of the 'official' protocols that run encapsulated in CAKE.

The messages

First, a note about the MAC column:

The Yes(D) and Yes(L) in the MAC column refers to whether the MAC is of the literal (aka L) data found in the message on the wire, or the decrypted (aka D) version of that data.

New Session Message

These occur at the beginning of each session.

CAKE New Session Message (type 0 messages)
Field name Short name Basic field type Description Encrypted? MAC Signed?
See The CAKE v2 Message Layout
The type field in this header is 0 for this kind of message.
No Yes(L) Yes
Destination key destkey key name The identity of the intended recipient of the session initiation request. No Yes(L) Yes
Source key srckey key name The identity of the initiator of this session. No Yes(L) Yes
Session Serial Number sessionserial 64-bit unsigned integer with the least significant bit set to 0

The tuple (destkey, srckey, sessionserial) must be unique to each session. This field has a somewhat complex explanation and is explained after the messages are described.

No Yes(L) Yes
Encryption header enchdr variable length string For v2, this is an RSA encrypted and signed random string of at least 512 bits. It's hashed to generate the session key, the starting value for the counter for CTR mode, and the HMAC key. In the next revision it will be the RSA encrypted and signed DH parameters. With the public key of destkey Yes(L) Yes
Session Start signature sesssig variable length string A signature by srckey of all the signed fields. Yes Yes(D) This is the signature
HMAC checkpoint firsthmac 16 octets An encrypted HMAC of the following fields (hdr. inidicates that it comes from the main message header and || is the concatenation operator):
<hdr.version || hdr.type || destkey || srckey || sessionserial || enchdr || sesssig>.
This is the first in a series of rolling HMACs computed over all the repeated message sections that follow.
Yes This is the MAC. No
See CAKE Repeated Message Section. See description See description No

Session Continuation Message

These rely on session serial numbers and the associated cryptographic information being stored for some period of time. How long this will be is up to the implementation, and there are higher layer protocols that allow this to be negotiated.

CAKE Session Continuation Message (type 1 messages)
Field name Short name Basic field type Description Encrypted? MAC
See The CAKE v2 Message Layout
The type field in this header is 0 for this kind of message.
No Yes(L)
Destination key destkey key name The identity of the intended recipient of the session continuation request. No Yes(L)
Source key srckey key name The identity of the initiator of the source of this session continuation request. No Yes(L)
Session Serial Number sessionserial 64-bit integer This is the serial number used in the session creation message. The least significant bit of this serial number may be 1 for reasons explained below. Each (destkey, srckey, sessionid) triple refers to a globally unique session. No Yes(L)
Starting byte number startpos 64-bit integer If this is in the middle of a previously received message, and the HMAC is valid, the recipient should consider the session invalid and immediately discard it and abort any communications that are using it. No Yes(L)
Encrypted Header HMAC firsthmac 16 octets An Encrypted HMAC of the following fields (hdr. inidicates that it comes from the main message header and || is the concatenation operator):
<hdr.version || hdr.type || destkey || srckey || startpos>
This is the first in a series of rolling HMACs computed over all the repeated message sections that follow.
Yes This is the MAC
See CAKE Repeated Message Section. See description See description

Repeated Message Section

Lastly, the meat of a session consists of 'repeated message sections'. These are common to both session initiation and session continuation methods. This section can be repeated an arbitrary number of times as long as the limitation of 264 - 1 enrypted bytes exchanged per session is not exceeded

CAKE Repeated Message sections
Field name Short name Basic field type Description Encrypted? MAC
See either the CAKE New Session Message or the CAKE Session Continuation Message.
Note that both of these end with an HMAC followed by this section.
See description See description
Destination capability id destcap count The short name of the capability this message is addressed to. 0 and 1 are reserved short names that always refer to the same capability. 0 is the session control capability, and 1 is the chaff (i.e. discard this data) capability that can be used to make timing and length analysis attacks harder. Yes Yes(D)
Message data msgdata variable length string The raw data destined for the given capability. There is a default limit of 128k on the size of this, but it can be negotiated higher if the destination agrees. The destination may even publish public assertions that the limit is higher if it chooses. Yes Yes(D)
Rolling HMAC secthmac 16 octets This is an hmac of <everything previously hmaced || sectlen || destcap || sectdata>. It is basically a checkpoint in a rolling HMAC computed over all the data sent so far as part of the overall message (the header + all the repeated message sections). Yes This is the MAC

Explanations

So, what's this session serial number thing?

Session serial numbers need to be handled carefully in the CAKE protocol. A session serial number is a unique identifier for a session between two parties. And it's also a mechanism for preventing replay attacks in which someone re-sends an exact copy of an old message to an entity in the hopes of tricking it into acting as if it's a message the entity has never seen before.

The problem with preventing replay attacks is minimizing the amount of state that needs to be stored in order to prevent them. A session serial number allows you to prevent replay attacks by simply storing a single 64-bit number associated with a particular key. If any new session requests come in that are less than or equal to that number, they are potentially replays and should be discarded.

Of course, this has the disadvantage of discarding messages that arrive out-of-order. If an entity chooses to, it may choose to store the past few session serial numbers it has seen. If a new session request then comes in that is not equal to any of the stored numbers and is greater than the smallest of them, it can be considered valid. This allows out-of-order delivery with a window of numbers that can slide forward over time.

But sometimes, storage of even one number is too great a burden. For example, an entity representing an extremely popular website may be contacted by millions or even billions of other entities in a single day. This would require gigabytes of memory to represent the serial numbers for all the other entities it talks to. This is clearly untenable.

It is for this reason that entities are encouraged to publish signed statements declaring at what time a serial number it generates is no longer valid. This allows the information about what serial numbers are too old to be stored on the network rather than requiring individual servers.

Of course, if one entity is remembering nothing about another entity, the question of what a 'replay attack' even means is an interesting question. I can think of situations in which preventing these is still important, but the most common scenario to me seems to be a DoS attack, and this protocol provides only limited protection against these.

If an implementation wants to support limited out-of-order delivery at the price of being slightly more complex, it may elect to store the last few session serial numbers used and only reject serial numbers that are either older than the oldest one it knows, or equal to one its already seen. This allows limited out-of-order delivery.

Why this least significant bit thing in session serial numbers?

The least signficant bit is 0 in the session serial number for any newly initiated session because whenever a session is created, a reciprocal session is also created in the opposite direction. This reciprocal session has the same session number except with the least signficant bit set to 1. It also shares all the same cryptographic information with the initiating session, but all messages sent over it go in the opposite direction.

For example, if (A, B, 13479177569348982452) is the identify for a session, their is also a corresponding session with the identifier (B, A, 13479177569348982453).

The exact duration this reciprocal session is valid for is expected to be set in the first sub-message sent as part of a session.

What do you mean by 'rolling HMAC'?

Whenever an HMAC is computed for a message it includes everything that was MACed by the previous HMAC as well as any new elements. But this does not cross message boundaries, even if the two messages are part of the same session.

For example, Alice sends Bob a session initiation message:

Note that fields to which the MAC isn't applied will be in italics, though in this case that isn't any of them.

version 2
type 0
destkey 2BS2C2HOG62754DFYSMTNMNVFCZA7YQXRPRXNIOF67LNBZNZAK3A
srckey XCJQ7IFSGXJ4MEK6P4CBICW352KTWJURU4PWTZOMBLXD4YATK2ZQ
sessionserial 1289704186994818
enchdr A bunch of random bits
sessig A bunch of random bits that represent a signature

The first HMAC is the next field. The hash includes all of the preceding fields. So it's:

HMAC(key (derived from enchdr), 2 || 0 || 2BS2C2HOG62754DFYSMTNMNVFCZA7YQXRPRXNIOF67LNBZNZAK3A || XCJQ7IFSGXJ4MEK6P4CBICW352KTWJURU4PWTZOMBLXD4YATK2ZQ || 1289704186994818 || A bunch of random bits || A bunch of random bits that represent a signature).

The next HMAC is after the first block of actual message:

sectlen 129
destcap 0
secdata I will remember session 1289704186994819 for 30 seconds or until I say I've forgotten it, whichever comes first.

The next HMAC is the next field. The hash includes all of the fields the first HMAC included. So it's:

HMAC(key (derived from enchdr), 2 || 0 || 2BS2C2HOG62754DFYSMTNMNVFCZA7YQXRPRXNIOF67LNBZNZAK3A || XCJQ7IFSGXJ4MEK6P4CBICW352KTWJURU4PWTZOMBLXD4YATK2ZQ || 1289704186994818 || A bunch of random bits || A bunch of random bits that represent a signature || 129 || 0 || I will remember session 1289704186994819 for 30 seconds or until I say I've forgotten it, whichever comes first.).

And the encryption, what's going on there?

Well, there are two parts to this question, and I'm only going to explain one part here.

The part I'm not going to explain here have to do with the fields only present in a new session message, in particular the enchdr and sesssig fields. These fields hold information that's handled by public key cryptography, and CAKE has a couple of rather unique ways of handling this kind of encryption that deserve long and detailed explanations of their own.

What I will explain is how the encryption by which all the data in the session is encrypted. The public key portion is just used to encrypt the data that's then used to create the real encryption keys used by the rest of the system.

The enchdr field contains some random data from a cryptographically secure random number generator that actually uses real world entropy to generate the numbers. The source key name and this raw random data is then processed by a hash algorithm to get set 512 bits of random data. Since the source key name is used in the hash, this means different values will be generated for the reciprocal session even though the random data is the same.

This 512 bits is then split up into three pieces, key, IV, and hmac_key:

  1. 256 bits that are used as the key for the AES 256 with a 128 bit block size (aka 'key')
  2. 128 bits that are used as the starting number for a series of 128-bit numbers that are encrypted by AES-256 to be used in CTR mode (aka 'IV').
  3. 128 bits that are used as the key for the HMAC algorithm (aka 'hmac_key')

As was mentioned, the basic cipher used is AES-256 with a 128-bit block size in CTR mode. The counter starts at an IV sent in the encryption header in the new session message and counts up from there. Since a session may only transmit 264 bytes of data the counter will have an maximum interval of [IV, IV + 260. It is 260 rather than 264 because 16 (aka 24) bytes are encrypted for each value of the counter.

The system keeps a count of exactly how many encrypted bytes have been transmitted in a given message. Each and every encrypted byte counts, including the encrypted bytes of the MACs. A message need not end on a block boundary, and so a session continuation message may pick up at the beginning of a block. When storing session data, it is advisable to store the encryption key and the IV and simply add the value of the encrypted byte count divided by the block size to the IV to determine which value to encrypt for the upcoming xor block.