RFC 5297

Synthetic Initialization Vector (SIV) Authenticated Encryption Using the Advanced Encryption Standard (AES)

πŸ“… published October 2008, from ietf

RFC 5297: Synthetic Initialization Vector (SIV) Authenticated Encryption Using the Advanced Encryption Standard (AES) πŸŽ€

  • Written by: D. Harkins, Aruba Networks πŸ’œ
  • Stream: Network Working Group
  • Category: Informational 🧚
  • Date: October 2008 πŸ“
  • Obsoletes / Updates: the title block doesn't list anything this RFC obsoletes or updates ✨

Status of This Memo ✨

This memo is just providing information for the Internet community πŸ’…. It doesn't specify an Internet standard of any kind, and distribution is unlimited 🌸.

Abstract πŸ¦‹

Okay so this memo describes SIV (Synthetic Initialization Vector), which is a block cipher mode of operation πŸ’–. SIV takes a key, a plaintext, and several variable-length octet strings that get authenticated but not encrypted πŸ™ˆ. It spits out a ciphertext that's the same length as the plaintext, plus a synthetic initialization vector. Depending on how you use it, SIV gets you either deterministic authenticated encryption or nonce-based, misuse-resistant authenticated encryption. Iconic, honestly πŸ‘‘.

Table of Contents πŸ“–

   1. Introduction ....................................................3
      1.1. Background .................................................3
      1.2. Definitions ................................................4
      1.3. Motivation .................................................4
           1.3.1. Key Wrapping ........................................4
           1.3.2. Resistance to Nonce Misuse/Reuse ....................4
           1.3.3. Key Derivation ......................................5
           1.3.4. Robustness versus Performance .......................6
           1.3.5. Conservation of Cryptographic Primitives ............6
   2. Specification of SIV ............................................6
      2.1. Notation ...................................................6
      2.2. Overview ...................................................7
      2.3. Doubling ...................................................7
      2.4. S2V ........................................................8
      2.5. CTR .......................................................10
      2.6. SIV Encrypt ...............................................10
      2.7. SIV Decrypt ...............................................12
   3. Nonce-Based Authenticated Encryption with SIV ..................14
   4. Deterministic Authenticated Encryption with SIV ................15
   5. Optimizations ..................................................15
   6. IANA Considerations ............................................15
      6.1. AEAD_AES_SIV_CMAC_256 .....................................17
      6.2. AEAD_AES_SIV_CMAC_384 .....................................17
      6.3. AEAD_AES_SIV_CMAC_512 .....................................18
   7. Security Considerations ........................................18
   8. Acknowledgments ................................................19
   9. References .....................................................19
      9.1. Normative References ......................................19
      9.2. Informative References ....................................19
   Appendix A.  Test Vectors  ....................................... 22
     A.1.  Deterministic Authenticated Encryption Example ........... 22
     A.2.  Nonce-Based Authenticated Encryption Example ............. 23

1. Introduction ✨

1.1. Background 🌷

Various attacks have been described (for example, [BADESP]) when data is only privacy protected and not also authenticated or integrity protected 😭. That's why combined modes of encryption and authentication were built ([RFC5116], [RFC3610], [GCM], [JUTLA], [OCB]). When you use them with a nonce ("a number used once"), they give you conventional authenticated encryption. They usually accept extra inputs that get authenticated but not encrypted, which we call "associated data" or AD 🫢.

There's also a deterministic, nonce-less form of authenticated encryption that's been used to protect the transport of cryptographic keys (for example, [X9F1], [RFC3217], [RFC3394]). People generally call this "Key Wrapping" πŸ”.

This memo describes a brand new block cipher mode, SIV, which gives you both nonce-based authenticated encryption and deterministic, nonce-less key wrapping πŸ’…. It has a Pseudo-Random Function (PRF) construction called S2V and an encryption/decryption construction called CTR. SIV was specified by Phillip Rogaway and Thomas Shrimpton in [DAE]. The underlying block cipher for both S2V and CTR is AES, with key lengths of 128 bits, 192 bits, or 256 bits. S2V uses AES in Cipher-based Message Authentication Code ([CMAC]) mode, and CTR uses AES in counter ([MODES]) mode 🧚.

Associated data is input to an authenticated-encryption mode that gets authenticated but not encrypted πŸ¦‹. [RFC5116] says associated data can include "addresses, ports, sequence numbers, protocol version numbers, and other fields that indicate how the plaintext or ciphertext should be handled, forwarded, or processed". These are multiple, distinct inputs, and they might not be contiguous 🀯. Other authenticated-encryption modes only allow a single associated data input. So you might end up needing a scatter/gather style of data marshalling to mash the pieces into one input, or a pre-processing step that concatenates them together πŸ™„. SIV accepts multiple variable-length octet strings (we call that a "vector of strings") as associated data inputs. No marshalling or pre-processing needed to package it into a single input. Main character energy πŸ‘‘.

Because associated data can be a vector of strings, SIV also skips the need to encode the length of component fields when those fields are variable length πŸŽ€.

1.2. Definitions πŸ“–

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 [RFC2119] πŸ’œ.

1.3. Motivation 🌈

1.3.1. Key Wrapping πŸ”‘

A key distribution protocol has to protect the keys it's distributing 🫢. That hasn't always been done right πŸ’€. For example, RADIUS [RFC2865] uses Microsoft Point-to-Point Encryption (MPPE) [RFC2548] to encrypt a key before sending it from server to client, and it gives you zero integrity checking on that encrypted key 😭. [RADKEY] specifies using [RFC3394] to wrap a key inside a RADIUS request. But since there's no way to pass associated data, you need a Hashed Message Authentication Code (HMAC) [RFC2104] to authenticate the entire request. Not ideal πŸ™ˆ.

SIV can be a drop-in replacement for any specification that uses [RFC3394] or [RFC3217], including the RADIUS case we just talked about ✨. It's more of a general-purpose solution, since it lets you specify associated data too 🧚.

1.3.2. Resistance to Nonce Misuse/Reuse 🫣

The nonce-based authenticated encryption schemes above are susceptible to nonce reuse and/or misuse. Depending on the scheme, there are subtle and critical requirements on the nonce (see [SP800-38D]). [GCM] says it provides "excellent security" if its nonce is guaranteed to be distinct, but "no security" otherwise πŸ’€. Confidentiality guarantees are voided if a counter in [RFC3610] gets reused. In lots of cases, guaranteeing no nonce/counter/IV reuse is no big deal. In others, it's a huge deal 😬.

Like, a lot of applications reach cryptographic functions through an application program interface to a crypto library. These libraries are usually not stateful, so the application passes in whatever nonce, initialization vector, or counter the cipher mode needs. That puts the construction of a security-critical datum outside the encryption engine's control, which is a heavy burden on the application writer, who might not have the necessary cryptographic hygiene 😩. Maybe their random number generator isn't very good, or an application fault resets a counter. The fragility of the cipher mode can lead to accidental misuse. And if your environment is a virtual machine (knowingly or not), you might be able to roll back a virtual state machine and cause a nonce reuse, which totally gutzes the security of the authenticated encryption scheme (see [VIRT]) πŸ’€.

If the nonce is random, requiring that it never repeats limits the amount of data you can safely protect with a single key to one block. More sensibly, a random nonce is supposed to "almost always" be non-repeating, but that drastically limits how much data you can safely protect πŸ₯Ί.

SIV has a level of resistance to nonce reuse and misuse πŸ’ͺ. If the nonce is never reused, you get the usual notion of nonce-based security for an authenticated encryption mode πŸŽ‰. But if the nonce is reused, authenticity is still retained, and confidentiality is only compromised to the extent that an attacker can figure out that the same plaintext (and same associated data) was protected with the same nonce and key πŸ‘€. See Security Considerations (Section 7) πŸ”₯.

1.3.3. Key Derivation πŸ—οΈ

A PRF is often used as a key derivation function (for example, [WLAN]) by passing it a key and a single string. Usually that single string is a bunch of smaller strings glued together, like a label plus some context to bind into the derived string 🧩.

Those are usually multiple strings, but they get mashed into one string because of how PRFs are typically defined: two inputs, a key and data πŸ™ƒ. That's a crude mapping. It's inefficient, because extra data has to be included (the length of each variable-length input has to be encoded separately), and depending on the PRF, you might need memory allocation and copying too πŸ₯΄. And if only one or two inputs change when you derive a new key, you may still have to process all the other constants that came before them every single time the PRF gets invoked 😀.

When a PRF is used this way, its input is a vector of strings, not a single string, and the PRF should handle the data that way too ✨. The S2V ("string to vector") PRF construction takes a vector of inputs and maps them way more naturally. It doesn't need extra length encodings, and it skips the memory and processing overhead of marshalling inputs and their encoded lengths into one string πŸ™Œ. Constant inputs to the PRF only need to be computed once πŸ’–.

1.3.4. Robustness versus Performance 🏎️

SIV can't hit the same high throughput rates as other authenticated encryption schemes (like [GCM] or [OCB]), because it needs two passes over the data 🐒. But for situations where performance isn't the limiting factor (for example, control plane applications), it can be a robust alternative, especially considering its resistance to nonce reuse πŸ’ͺ🌸.

1.3.5. Conservation of Cryptographic Primitives 🧰

This cipher mode can do authenticated encryption, key wrapping, key derivation, and act as a generic message authentication algorithm 🀯. So you can implement all of these functions with a single tool, instead of one tool for each function. That's extremely attractive for devices that are memory and/or processor constrained and can't afford to implement multiple cryptographic primitives πŸ«ΆπŸ”‹.

2. Specification of SIV πŸ’…

2.1. Notation

okay so SIV and S2V have their own little symbol vocab πŸ’… here's what each one means, bestie:

  • len(A): returns the number of bits in A. πŸŽ€
  • pad(X): indicates padding of string X, len(X) < 128, out to 128 bits by the concatenation of a single bit of 1 followed by as many 0 bits as are necessary. πŸ¦‹
  • leftmost(A,n): the n most significant bits of A. 🌸
  • rightmost(A,n): the n least significant bits of A. 🌸
  • A || B: means concatenation of string A with string B. 🫢
  • A xor B: is the exclusive OR operation on two equal length strings, A and B. πŸ’œ
  • A xorend B: where len(A) >= len(B), means xoring a string B onto the end of string A. In other words, leftmost(A, len(A)-len(B)) || (rightmost(A, len(B)) xor B). ✨
  • A bitand B: is the logical AND operation on two equal length strings, A and B. πŸ“
  • dbl(S): is the multiplication of S and 0...010 in the finite field represented using the primitive polynomial x^128 + x^7 + x^2 + x + 1. See Doubling (Section 2.3). 🧚
  • a^b: indicates a string that is "b" bits, each having the value "a". 🌈
  • <zero>: indicates a string that is 128 zero bits. πŸ™ˆ
  • <one>: indicates a string that is 127 zero bits concatenated with a single one bit, that is 0^127 || 1^1. πŸ‘‘
  • A/B: indicates the greatest integer less than or equal to the real-valued quotient of A and B. πŸ”₯
  • E(K,X): indicates AES encryption of string X using key K. πŸ’–

2.2. Overview

so SIV-AES uses AES in CMAC mode (that's S2V) and in counter mode (that's CTR) ✨ it takes either a 256-, 384-, or 512-bit key. that key gets split into two equal-sized keys, one for S2V and one for CTR πŸŽ€ then it also takes a variable length plaintext, plus multiple variable-length strings of associated data. the output is a ciphertext made of a synthetic initialization vector concatenated with the encrypted plaintext. literally iconic πŸ‘‘

2.3. Doubling

the doubling operation on a 128-bit input string is done by left-shifting the input, and then doing a conditional xor on the result with this constant: πŸ¦‹

                00000000 00000000 00000000 00000087

the xor only happens when the bit that gets shifted off is one. πŸ’…

ngl this is the same operation used to generate the sub-keys for CMAC-AES 🫢

2.4. S2V

the S2V operation is basically doubling and xoring the outputs of a pseudo-random function, CMAC, running over each string in the input vector: S1, S2, ... , Sn. 🌸 it gets bootstrapped by running CMAC on a 128-bit string of zeros. if the final string in the vector is 128 bits or longer, the output of the double/xor chain gets xored onto the end of that final input string. then that result goes into one last CMAC operation to produce the output V. πŸ’–

if the final string is shorter than 128 bits, the double/xor chain output gets doubled one more time, and then it's xored with the final string padded using the padding function pad(X). that result also goes into a final CMAC operation to produce V. so it's a little different depending on the length, which is very main character energy πŸ‘‘

here's S2V with key K on a vector of n inputs S1, S2, ..., Sn-1, Sn, where len(Sn) >= 128:

              +----+       +----+       +------+      +----+
              | S1 |       | S2 | . . . | Sn-1 |      | Sn |
              +----+       +----+       +------+      +----+
 <zero>   K     |            |             |             |
   |      |     |            |             |             V
   V      |     V            V             V    /----> xorend
+-----+    |  +-----+      +-----+       +-----+ |        |
| AES-|<----->| AES-|  K-->| AES-|  K--->| AES-| |        |
| CMAC|       | CMAC|      | CMAC|       | CMAC| |        |
+-----+       +-----+      +-----+       +-----+ |        V
    |           |             |             |    |     +-----+
    |           |             |             |    | K-->| AES-|
    |           |             |             |    |     | CMAC|
    |           |             |             |    |     +-----+
    \-> dbl -> xor -> dbl -> xor -> dbl -> xor---/        |
                                                          V
                                                        +---+
                                                        | V |
                                                        +---+

                              Figure 2

and here's S2V with key K on a vector of n inputs S1, S2, ..., Sn-1, Sn, where len(Sn) < 128: πŸ¦‹

            +----+       +----+       +------+      +---------+
            | S1 |       | S2 | . . . | Sn-1 |      | pad(Sn) |
            +----+       +----+       +------+      +---------+
 <zero>  K     |            |             |               |
   |     |     |            |             |               V
   V     |     V            V             V     /------> xor
+-----+  |  +-----+      +-----+       +-----+  |         |
| AES-|<--->| AES-|  K-->| AES-|   K-->| AES-|  |         |
| CMAC|     | CMAC|      | CMAC|       | CMAC|  |         |
+-----+     +-----+      +-----+       +-----+  |         V
  |           |             |             |     |      +-----+
  |           |             |             |     |  K-->| AES-|
  |           |             |             |     |      | CMAC|
  |           |             |             |     |      +-----+
  \-> dbl -> xor -> dbl -> xor -> dbl -> xor-> dbl        |
                                                          V
                                                        +---+
                                                        | V |
                                                        +---+

                              Figure 3

and algorithmically, S2V looks like this 🧚

S2V(K, S1, ..., Sn) {
  if n = 0 then
    return V = AES-CMAC(K, <one>)
  fi
  D = AES-CMAC(K, <zero>)
  for i = 1 to n-1 do
    D = dbl(D) xor AES-CMAC(K, Si)
  done
  if len(Sn) >= 128 then
    T = Sn xorend D
  else
    T = dbl(D) xor pad(Sn)
  fi
  return V = AES-CMAC(K, T)
}

2.5. CTR

CTR is a counter mode of AES 🌈 it takes in a plaintext P of arbitrary length, a key K that's 128, 192, or 256 bits long, and a 128-bit counter X. then it outputs Z, which is a concatenation of a synthetic initialization vector V and the ciphertext C. the ciphertext is the same length as the plaintext ✨

the ciphertext gets made by xoring the plaintext with the first len(P) bits of this string: πŸ’–

E(K, X) || E(K, X+1) || E(K, X+2) || ...

before counter mode starts, the 31st and 63rd bits get cleared (the rightmost bit is the 0th bit) πŸ™ˆ this is so that implementations with native 32-bit (or 64-bit) addition can increment the counter modulo 2^32 (or 2^64) in a way you can't tell apart from 128-bit increments. that only holds as long as the number of increments stays under an upper bound that safely avoids a carry going out of the pre-cleared bit. πŸŽ€

more formally, for 32-bit addition, the counter goes up like this:

SALT=leftmost(X,96)

n=rightmost(X,32)

X+i = SALT || (n + i mod 2^32).

and for 64-bit addition, it goes up like this:

SALT=leftmost(X,64)

n=rightmost(X,64)

X+i = SALT || (n + i mod 2^64).
⚠️ bestie, the limit matters here: performing 32-bit or 64-bit addition on the counter limits the amount of plaintext that can be safely protected by SIV-AES to 2^39 - 128 bits or 2^71 - 128 bits, respectively. πŸ’€

2.6. SIV Encrypt

SIV-encrypt takes in a key K that's 256, 384, or 512 bits long, plaintext of arbitrary length, and a vector of associated data AD[ ]. the number of components in that vector can't be greater than 126 (see Section 7). 🫢 it spits out Z, which is a concatenation of a 128-bit synthetic initialization vector and ciphertext whose length matches the plaintext πŸ¦‹

the key gets split into equal halves: K1 = leftmost(K, len(K)/2) and K2 = rightmost(K, len(K)/2). K1 goes to S2V and K2 goes to CTR πŸ’…

in encryption mode, the associated data and plaintext make up the vector of inputs to S2V, and the plaintext is the last string in that vector. the output of S2V is a synthetic IV that acts as the starting counter for CTR πŸ”₯

here's how the SIV encryption construction works:

 +------+ +------+   +------+              +---+
 | AD 1 | | AD 2 |...| AD n |              | P |
 +------+ +------+   +------+              +---+
    |         |         |                    |
    |         |   ...   |  ------------------|
    \         |        /  /                  |
     \        |       /  / +------------+    |
      \       |      /  /  | K = K1||K2 |    |
       \      |     /  /   +------------+    V
        \     |    /  /      |     |       +-----+
         \    |   /  /   K1  |     |  K2   |     |
          \   |  /  /  ------/     \------>| CTR |
           \  | /  /  /            ------->|     |
            | | | |  |             |       +-----+
            V V V V  V             |          |
          +------------+       +--------+     V
          |    S2V     |------>|   V    |   +----+
          +------------+       +--------+   | C  |
                                   |        +----+
                                   |          |
                                   -----\     |
                                         \    |
                                          \   |
                                           V  V
                                          +-----+
                                          |  Z  |
                                          +-----+

where P is the plaintext, AD1 through ADn are the associated data, V is the synthetic IV, C is the ciphertext, and Z is the output. 🌸

Figure 8

and algorithmically, SIV Encrypt looks like this 🧚

SIV-ENCRYPT(K, P, AD1, ..., ADn) {
  K1 = leftmost(K, len(K)/2)
  K2 = rightmost(K, len(K)/2)
  V = S2V(K1, AD1, ..., ADn, P)
  Q = V bitand (1^64 || 0^1 || 1^31 || 0^1 || 1^31)
  m = (len(P) + 127)/128

  for i = 0 to m-1 do
    Xi = AES(K2, Q+i)
  done
  X = leftmost(X0 || ... || Xm-1, len(P))
  C = P xor X

  return V || C
}

where the key length used by AES in CTR and S2V is len(K)/2, and each one will be either 128 bits, 192 bits, or 256 bits. πŸ’–

the 31st and 63rd bits (the rightmost bit is the 0th) of the counter get zeroed out right before CTR uses them, purely for optimization purposes. see Section 5 for more on that πŸ¦‹

2.7. SIV Decrypt πŸ”“

okay so SIV-decrypt is the reverse move πŸ’… It takes a key K that's 256, 384, or 512 bits long, plus Z, which is a synthetic initialization vector V stuck together with a ciphertext C, plus a vector of associated data AD[ ] with no more than 126 components (see Section 7). Its output is either the original plaintext or the special symbol FAIL πŸ™ˆ

The key gets split exactly the way Section 2.6 says.

The synthetic IV acts as the starting counter for CTR, which decrypts the ciphertext. Then the associated data and the CTR output form a vector of strings that goes into S2V, with the CTR output as the very last string. Next, the S2V output gets compared against the synthetic IV that came with the original ciphertext. If they match, the CTR output is returned as the decrypted and authenticated plaintext ✨ If they don't, you get FAIL, and that's the whole drama πŸ’€

Here's the decryption construction as a picture:

+------+ +------+   +------+           +---+
| AD 1 | | AD 2 |...| AD n |           | P |
+------+ +------+   +------+           +---+
   |        |         |                  ^
   |        |    ...  /                  |
   |        |        /  /----------------|
   |        |       /  /                 |
   \        |      /  /  +------------+  |
    \       |     /  /   | K = K1||k2 |  |
     \      |    /  /    +------------+  |
      \     |   /  /       |   |      +-----+
       \    |  /  /     K1 |   |  K2  |     |
        \   | |  |   /-----/   \----->| CTR |
         \  | |  |  |         ------->|     |
          | | |  |  |         |       +-----+
          V V V  V  V         |         ^
        +-------------+   +--------+    |
        |    S2V      |   |   V    |  +---+
        +-------------+   +--------+  | C |
              |               | ^     +---+
              |               | |       ^
              |               |  \      |
              |               |   \___  |
              V               V       \ |
          +-------+      +---------+ +---+
          |   T   |----->|  if !=  | | Z |
          +-------+      +---------+ +---+
                              |
                              |
                              V
                             FAIL

                              Figure 10

Algorithmically, SIV-Decrypt looks like this 🧚

   SIV-DECRYPT(K, Z, AD1, ..., ADn) {
     V = leftmost(Z, 128)
     C = rightmost(Z, len(Z)-128)
     K1 = leftmost(K, len(K)/2)
     K2 = rightmost(K, len(K)/2)
     Q = V bitand (1^64 || 0^1 || 1^31 || 0^1 || 1^31)

     m = (len(C) + 127)/128
     for i = 0 to m-1 do
       Xi = AES(K2, Q+i)
     done
     X = leftmost(X0 || ... || Xm-1, len(C))
     P = C xor X
     T = S2V(K1, AD1, ..., ADn, P)

     if T = V then
       return P
     else
       return FAIL
     fi
   }

Here the key length used by AES in CTR and S2V is len(K)/2, and each one is going to be either 128 bits, 192 bits, or 256 bits πŸ”‘

The 31st and 63rd bits of the counter (rightmost bit is the 0th) get zeroed out right before they're used in CTR mode, for optimization purposes. More on that in Section 5 ✨


3. Nonce-Based Authenticated Encryption with SIV 🌸

SIV does nonce-based authenticated encryption whenever one piece of the associated data is a nonce. For interoperability's sake, the final component (the string sitting right before the plaintext in the vector going into S2V) is the one used for the nonce 🫢 Any other associated data is optional, and it's up to whatever application is using SIV to decide how the rest of it gets fed in.

If the nonce is random, it SHOULD be at least 128 bits long and come from a pool with at least 128 bits of entropy. A non-random source MAY also be used, like a timestamp or a counter πŸ•°οΈ A nonce is defined so that it can't be reused, but SIV is resistant to nonce reuse anyway, which is honestly iconic. Check Section 1.3.2 if you want the security side of nonce reuse spelled out πŸ¦‹

It MAY be necessary to transport this nonce along with the output that S2V generates πŸ“¦


4. Deterministic Authenticated Encryption with SIV πŸ’Ž

When the plaintext you're encrypting and authenticating has stuff in it that an attacker can't predict (a secret key, say), SIV can run in deterministic mode to do "key wrapping" πŸ” S2V takes associated data and doesn't put weird size limits on what it protects, so it's a more useful, general-purpose option than [RFC3394], no cap πŸ’œ Protocols that use SIV for deterministic authenticated encryption (so, for more than just wrapping keys) MAY define associated data inputs to SIV. In this case, you don't need to tack a nonce component onto the AD ✨


5. Optimizations πŸš€

Implementations that can't or don't want to support addition modulo 2^128 can use a neat trick: the 31st and 63rd bits (rightmost bit is the 0th) in the counter are cleared before CTR uses them. That lets implementations with native 32-bit or 64-bit addition just increment the counter normally πŸ™Œ Of course, the catch is that the amount of plaintext SIV can safely protect shrinks by a matching amount. Addition modulo 2^32 limits plaintext to (2^39 - 128) bits, and addition modulo 2^64 limits it to (2^71 - 128) bits. Choose wisely, bestie πŸ’…

It's also possible to optimize an implementation of S2V when it's being used as a key derivation function (KDF), for example in [WLAN]. This works because S2V operates on a vector of distinct strings, and the data passed to a KDF usually has constant strings in it 🧠 Depending on where the variable components of the input sit, different optimizations are possible. The CMACed output of intermediate and invariant components can be computed once and cached. Then it can be doubled and XORed with the running sum to produce the output. Or, an intermediate value that represents the doubled and XORed output of multiple components, up to the variable component, can be computed once and cached ✨


6. IANA Considerations πŸ“‹

[RFC5116] defines a uniform interface to cipher modes that provide nonce-based Authenticated Encryption with Associated Data (AEAD). It does this through a registry of AEAD algorithms πŸ—‚οΈ

The Internet Assigned Numbers Authority (IANA) assigned three entries from the AEAD Registry for AES-SIV-CMAC-256 (15), AES-SIV-CMAC-384 (16), and AES-SIV-CMAC-512 (17), based on the AEAD algorithm definitions below. [RFC5116] defines operations in octets, not bits, so the limits in this section are specified in octets πŸ“ The security analysis for each of these algorithms lives in [DAE].

Unfortunately, [RFC5116] restricts AD input to a single component, which limits how naturally SIV can handle AD made of multiple distinct components 😭 So when you need to reach SIV through the interface defined in [RFC5116], you have to marshal multiple AD inputs into a single string (see Section 1.1) before invoking SIV. This requirement isn't unique to SIV, though. All cipher modes using [RFC5116] MUST similarly marshal multiple AD inputs into a single string, and any technique used for any other AEAD mode (for example, a scatter/gather technique) can be used with SIV too 🫢

[RFC5116] requires AEAD algorithm specifications to include maximal limits on the amount of plaintext, the amount of associated data, and the size of a nonce that the AEAD algorithm can accept πŸ“

SIV uses AES in counter mode, and the security guarantees of SIV would be lost if the counter were allowed to repeat. The counter is 128 bits, so the limit on how much plaintext a single invocation of SIV can safely protect is 2^128 blocks πŸ”’

To prevent collisions, [CMAC] recommends that no more than 2^48 invocations be made to CMAC with the same key. This isn't a limit on how much data can be passed to CMAC, though. There's no practical limit on the amount of data that can go into a single CMAC invocation, and likewise, there's no practical limit on the amount of associated data or nonce material that can be passed to SIV 🌈

A collision in the output of S2V would mean the same counter gets used with different plaintext in counter mode, and that voids the security guarantees of SIV 😱 The "Birthday Paradox" (see [APPCRY]) would imply that no more than 2^64 distinct invocations of SIV be made with the same key. It's prudent to follow the example of [CMAC] though, and further limit the number of distinct invocations of SIV using the same key to 2^48. Note that [RFC5116] doesn't have a variable to describe this limit πŸ™ˆ

The counter-space for SIV is 2^128. Each invocation of SIV uses up a chunk of that counter-space, and how much it uses depends on how much plaintext goes into that one invocation. Multiple invocations of SIV with the same key can make distinct invocations overlap in the counter-space πŸ‘€ So the total amount of plaintext that can be safely protected with a single key is a function of both the number of distinct invocations and the amount of plaintext protected with each one πŸŽ€


6.1. AEAD_AES_SIV_CMAC_256 πŸ’–

The AES-SIV-CMAC-256 AEAD algorithm works as specified in Sections 2.6 and 2.7. The input and output lengths for AES-SIV-CMAC-256, as defined by [RFC5116], are:

K_LEN  is 32 octets.

P_MAX  is 2^132 octets.

A_MAX  is unlimited.

N_MIN  is 1 octet.

N_MAX  is unlimited.

C_MAX  is 2^132 + 16 octets.

The security implications of nonce reuse and/or misuse are described in Section 1.3.2 πŸ”₯


6.2. AEAD_AES_SIV_CMAC_384 🌷

The AES-SIV-CMAC-384 AEAD algorithm works as specified in Sections 2.6 and 2.7. The input and output lengths for AES-SIV-CMAC-384, as defined by [RFC5116], are:

K_LEN  is 48 octets.

P_MAX  is 2^132 octets.

A_MAX  is unlimited.

N_MIN  is 1 octet.

N_MAX  is unlimited.

C_MAX  is 2^132 + 16 octets.

The security implications of nonce reuse and/or misuse are described in Section 1.3.2 ✨


6.3. AEAD_AES_SIV_CMAC_512 πŸ‘‘

The AES-SIV-CMAC-512 AEAD algorithm works as specified in Sections 2.6 and 2.7. The input and output lengths for AES-SIV-CMAC-512, as defined by [RFC5116], are:

K_LEN  is 64 octets.

P_MAX  is 2^132 octets.

A_MAX  is unlimited.

N_MIN  is 1 octet.

N_MAX  is unlimited.

C_MAX  is 2^132 + 16 octets.

The security implications of nonce reuse and/or misuse are described in Section 1.3.2 πŸ¦‹

7. Security Considerations πŸ”

Okay bestie, this is the serious section, so let's get into it 🫢 SIV gives you confidentiality in the sense that the output of SIV-Encrypt looks totally indistinguishable from a random string of bits πŸ’… It also gives you authenticity: an attacker can't build a string of bits that returns anything other than FAIL when fed into SIV-Decrypt πŸ”₯ The proof of security for SIV, using the "all-in-one" notion of security for an authenticated encryption scheme, is in [DAE] ✨

SIV also does deterministic "key wrapping" when the plaintext contains data an adversary can't predict, like a cryptographic key πŸ—οΈ Even if that key is handed over to an attacker, the output of SIV-Encrypt still looks like random bits. Same deal on the other side: even with the key exposed, she can't craft a string of bits that SIV-Decrypt will accept with anything other than FAIL πŸ’€

Now the nonce. In the nonce-based mode of SIV-AES, if you treat the nonce with the same care you'd give a nonce or counter in other nonce-based authenticated encryption schemes (meaning you guarantee it's never used with the same key for two distinct invocations), then SIV hits the level of security we just talked about 🌈 But if the nonce gets reused, SIV still keeps the authenticity described above, just with a slightly reduced amount of privacy (see Section 1.3.2) πŸ™ˆ

If S2V is used as a key derivation function, the secret input MUST be generated uniformly at random. S2V is a pseudo-random function, so it is not suitable for use as a random oracle as defined in [RANDORCL] 🧚

The security bound from the proof of S2V in [DAE] depends on how many vector-based queries an adversary makes and on the total number of components in those queries. The security is only proven when each query has at most n-1 components, where n is the blocksize of the underlying pseudo-random function. The one used here is based on AES, whose blocksize is 128 bits. So S2V must not be passed more than 127 components. Since SIV counts the plaintext as one of the components given to S2V, that means you can safely pass at most 126 components of associated data to SIV πŸŽ€

8. Acknowledgments 🌸

Big thank yous to Phil Rogaway, who patiently answered a ton of questions about SIV and S2V and gave super useful critiques of earlier versions of this paper 🫢 Thanks also to David McGrew for loads of helpful comments and suggestions for making this paper better πŸ’œ And thanks to Jouni Malinen for reviewing this paper and writing another independent implementation of SIV, which confirmed that the test vectors are correct πŸ‘‘

9. References πŸ“š

9.1. Normative References

  • [CMAC] Dworkin, M., "Recommendation for Block Cipher Modes of Operation: The CMAC Mode for Authentication", NIST Special Pulication 800-38B, May 2005.
  • [MODES] Dworkin, M., "Recommendation for Block Cipher Modes of Operation: Methods and Techniques", NIST Special Pulication 800-38A, 2001 edition.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC5116] McGrew, D., "An Interface and Algorithms for Authenticated Encryption", RFC 5116, January 2008.

9.2. Informative References

  • [APPCRY] Menezes, A., van Oorshot, P., and S. Vanstone, "Handbook of Applied Cryptography", CRC Press Series on Discrete Mathematics and Its Applications, 1996.
  • [BADESP] Bellovin, S., "Problem Areas for the IP Security Protocols", Proceedings from the 6th Usenix UNIX Security Symposium, July 22-25 1996.
  • [RFC3610] Whiting, D., Housley, R., and N. Ferguson, "Counter with CBC-MAC (CCM)", RFC 3610, September 2003.
  • [DAE] Rogaway, P. and T. Shrimpton, "Deterministic Authenticated Encryption, A Provable-Security Treatment of the Key-Wrap Problem", Advances in Cryptology -- EUROCRYPT '06 St. Petersburg, Russia, 2006.
  • [GCM] McGrew, D. and J. Viega, "The Galois/Counter Mode of Operation (GCM)".
  • [JUTLA] Jutla, C., "Encryption Modes With Almost Free Message Integrity", Proceedings of the International Conference on the Theory and Application of Cryptographic Techniques: Advances in Cryptography.
  • [OCB] Krovetz, T. and P. Rogaway, "The OCB Authenticated Encryption Algorithm", Work in Progress, March 2005.
  • [RADKEY] Zorn, G., Zhang, T., Walker, J., and J. Salowey, "RADIUS Attributes for the Delivery of Keying Material", Work in Progress, April 2007.
  • [RANDORCL] Bellare, M. and P. Rogaway, "Random Oracles are Practical: A Paradigm for Designing Efficient Protocols", Proceeding of the First ACM Conference on Computer and Communications Security, November 1993.
  • [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997.
  • [RFC2548] Zorn, G., "Microsoft Vendor-specific RADIUS Attributes", RFC 2548, March 1999.
  • [RFC2865] Rigney, C., Willens, S., Rubens, A., and W. Simpson, "Remote Authentication Dial In User Service (RADIUS)", RFC 2865, June 2000.
  • [RFC3217] Housley, R., "Triple-DES and RC2 Key Wrapping", RFC 3217, December 2001.
  • [RFC3394] Schaad, J. and R. Housley, "Advanced Encryption Standard (AES) Key Wrap Algorithm", RFC 3394, September 2002.
  • [SP800-38D] Dworkin, M., "Recommendations for Block Cipher Modes of Operation: Galois Counter Mode (GCM) and GMAC", NIST Special Pulication 800-38D, June 2007.
  • [VIRT] Garfinkel, T. and M. Rosenblum, "When Virtual is Harder than Real: Security Challenges in Virtual Machine Based Computing Environments" In 10th Workshop on Hot Topics in Operating Systems, May 2005.
  • [WLAN] "Draft Standard for IEEE802.11: Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specification", 2007.
  • [X9F1] Dworkin, M., "Wrapping of Keys and Associated Data", Request for review of key wrap algorithms. Cryptology ePrint report 2004/340, 2004. Contents are excerpts from a draft standard of the Accredited Standards Committee, X9, entitled ANS X9.102.

Appendix A. Test Vectors πŸ§ͺ

The following test vectors are for the mode defined in Section 6.1. Let's check the math together πŸ¦‹

A.1. Deterministic Authenticated Encryption Example

Input:
-----
Key:
        fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0
        f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff

AD:
        10111213 14151617 18191a1b 1c1d1e1f
        20212223 24252627

Plaintext:
        11223344 55667788 99aabbcc ddee

S2V-CMAC-AES
------------
CMAC(zero):
        0e04dfaf c1efbf04 01405828 59bf073a

double():
        1c09bf5f 83df7e08 0280b050 b37e0e74

CMAC(ad):
        f1f922b7 f5193ce6 4ff80cb4 7d93f23b

xor:
        edf09de8 76c642ee 4d78bce4 ceedfc4f

double():
        dbe13bd0 ed8c85dc 9af179c9 9ddbf819

pad:
        11223344 55667788 99aabbcc ddee8000

xor:
        cac30894 b8eaf254 035bc205 40357819

CMAC(final):
        85632d07 c6e8f37f 950acd32 0a2ecc93

CTR-AES
-------
CTR:
        85632d07 c6e8f37f 150acd32 0a2ecc93

E(K,CTR):
        51e218d2 c5a2ab8c 4345c4a6 23b2f08f

ciphertext:
        40c02b96 90c4dc04 daef7f6a fe5c

output
------
IV || C:
        85632d07 c6e8f37f 950acd32 0a2ecc93
        40c02b96 90c4dc04 daef7f6a fe5c

A.2. Nonce-Based Authenticated Encryption Example

Input:
-----
Key:
        7f7e7d7c 7b7a7978 77767574 73727170
        40414243 44454647 48494a4b 4c4d4e4f

AD1:
        00112233 44556677 8899aabb ccddeeff
        deaddada deaddada ffeeddcc bbaa9988
        77665544 33221100

AD2:
        10203040 50607080 90a0

Nonce:
        09f91102 9d74e35b d84156c5 635688c0

Plaintext:
        74686973 20697320 736f6d65 20706c61
        696e7465 78742074 6f20656e 63727970
        74207573 696e6720 5349562d 414553

S2V-CMAC-AES
------------
CMAC(zero):
        c8b43b59 74960e7c e6a5dd85 231e591a

double():
        916876b2 e92c1cf9 cd4bbb0a 463cb2b3

CMAC(ad1)
        3c9b689a b41102e4 80954714 1dd0d15a

xor:
        adf31e28 5d3d1e1d 4ddefc1e 5bec63e9

double():
        5be63c50 ba7a3c3a 9bbdf83c b7d8c755

CMAC(ad2)
        d98c9b0b e42cb2d7 aa98478e d11eda1b

xor:
        826aa75b 5e568eed 3125bfb2 66c61d4e

double():
        04d54eb6 bcad1dda 624b7f64 cd8c3a1b

CMAC(nonce)
        128c62a1 ce3747a8 372c1c05 a538b96d

xor:
        16592c17 729a5a72 55676361 68b48376

xorend:
        74686973 20697320 736f6d65 20706c61
        696e7465 78742074 6f20656e 63727966
        2d0c6201 f3341575 342a3745 f5c625

CMAC(final)
        7bdb6e3b 432667eb 06f4d14b ff2fbd0f

CTR-AES
-------
CTR:
        7bdb6e3b 432667eb 06f4d14b 7f2fbd0f

E(K,CTR):
        bff8665c fdd73363 550f7400 e8f9d376

CTR+1:
        7bdb6e3b 432667eb 06f4d14b 7f2fbd10

E(K,CTR+1):
        b2c9088e 713b8617 d8839226 d9f88159

CTR+2
        7bdb6e3b 432667eb 06f4d14b 7f2fbd11

E(K,CTR+2):
        9e44d827 234949bc 1b12348e bc195ec7

ciphertext:
        cb900f2f ddbe4043 26601965 c889bf17
        dba77ceb 094fa663 b7a3f748 ba8af829
        ea64ad54 4a272e9c 485b62a3 fd5c0d

output
------
IV || C:
        7bdb6e3b 432667eb 06f4d14b ff2fbd0f
        cb900f2f ddbe4043 26601965 c889bf17
        dba77ceb 094fa663 b7a3f748 ba8af829
        ea64ad54 4a272e9c 485b62a3 fd5c0d

Author's Address πŸ‘©β€πŸ’»

Dan Harkins Aruba Networks

EMail: dharkins@arubanetworks.com

Copyright (C) The IETF Trust (2008).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property ✨

Okay bestie, the IETF is being super clear here πŸ’… It takes no position on whether any Intellectual Property Rights or other rights that someone might claim over the tech in this doc are valid or in scope πŸ™ˆ It also doesn't say whether any license under those rights might or might not be available. And it hasn't done its own independent digging to find any of those rights either πŸ•΅οΈβ€β™€οΈ Info on how rights work for RFC documents lives in BCP 78 and BCP 79, so go check those if you're curious πŸŽ€

Now for the fun part πŸ¦‹ Copies of IPR disclosures sent to the IETF Secretariat are a thing, and so are any assurances of licenses that might be made available. You can also find the results of an attempt to get a general license or permission for implementers or users to use those proprietary rights. All of that lives in the IETF's online IPR repository at http://www.ietf.org/ipr πŸ’œ

Quick reminder: the IETF is inviting anyone who's interested to speak up! If you spot copyrights, patents, patent applications, or other proprietary rights that may cover technology needed to implement this standard, tell them about it at ietf-ipr@ietf.org πŸ“¬

That's the whole vibe, babe, the end of the document 🌈✨

πŸ“¦ where this page comes from