Reuse of CMS Content Encryption Keys
Extracted elements (26)
Byte reversal (rather than direct reuse) of MSG1.CEK to form MSG2.KEK prevents an attack where an attacker with known plaintext/ciphertext from MSG1 could directly substitute a ciphertext block as MSG2.KEKRecipientInfo.encryptedKey, thereby learning the next CEK.
Byte reversal was chosen over bit reversal because bit reversal would cause DES parity bits from MSG1.CEK to become keying bits for MSG2.KEK in DES-based algorithms, weakening the derived key.
CMS EnvelopedData asymmetric key establishment is relatively expensive, so this specification enables reuse of a content-encryption key (CEK) from one message (MSG1) as the basis for deriving the key-encryption key (KEK) for a later message (MSG2), improving efficiency in high-frequency communication scenarios.
PBKDF2 (from PKCS#5/RFC 2898) is used as the key derivation function for the cross-algorithm case, with MSG1.CEK substituted for the password input, because it provides a well-defined, parameterizable key stretching/adaptation mechanism.
All attributes defined here (CEKReference, CEKMaxDecrypts, KEKDerivationAlg) SHOULD be ignored unless present in a message containing a valid or recognized CEKReference value, to maintain backward compatibility with non-supporting implementations.
Cryptographic APIs that completely hide key bits from the CMS layer will likely prevent CEK reuse under this scheme, since they lack a primitive that transforms MSG1.CEK into MSG2.KEK; implementers should verify API support before adopting this approach.
CMS implementations SHOULD be able to signal the particular reason for decryption failures (e.g., unrecognized or ignored CEKReference) to the calling application.
If the CEK from MSG1 is to be used to derive the KEK for MSG2, then MSG1 MUST contain an unprotectedAttrs Attribute of type id-aa-CEKReference with a single value using the CEKReference syntax.
Implementors MUST NOT assume that CEKReference can only occur where ktri (key transport) or kari (key agreement) RecipientInfo is used; it can also appear with kekri.
In PBKDF2-based key derivation, the salt MUST use the 'specified' element of the CHOICE (an explicit OCTET STRING), and the prf field MUST be omitted so that the default algid-hmacWithSHA1 is used.
MSG2.KEK is derived by reversing the bytes of MSG1.CEK. The application MUST ensure that the relevant algorithms are compatible, i.e., the CEK and KEK must use the same type and size of symmetric key.
Recipients SHOULD maintain CEKReference information (at minimum the key identifier and CEK value) while fewer than maxDecrypt messages have been successfully received, and SHOULD delete it after a locally configured timeout period.
The CEKMaxDecrypts attribute MUST only be sent when a CEKReference attribute is also included in the same message.
Using this specification REQUIRES that adopting protocols define originator and recipient behavior for the case where a referenced CEK has been 'lost'.
When CEKMaxDecrypts is absent, originators and recipients SHOULD behave as if a value of one had been sent, meaning each CEK is reused once as the KEK for the next message.
When MSG1.content-encryption algorithm differs from MSG2.key-encryption algorithm, the KEKDerivationAlgorithm attribute MUST be present; implementations that recognize but do not support it SHOULD ignore the attribute.
Where CEK and KEK algorithms have incompatible key values or strengths (e.g., MSG1 uses a 40-bit cipher but MSG2 requires 168 bits), this specification SHOULD NOT be used.
The id-aa-CEKMaxDecrypts attribute (OID { id-aa 31 }, type INTEGER, value MUST be >=1 and at most 2^31) is an optional hint placed in unprotectedAttrs indicating the maximum number of subsequent messages (excluding MSG1) that will reuse the referenced CEK.
The id-aa-CEKReference attribute (OID { id-aa 30 }, type OCTET STRING) is placed in the unprotectedAttrs field of an EnvelopedData to provide a key identifier that recipients can use to locate the referenced CEK when processing subsequent messages.
The id-aa-KEKDerivationAlg attribute (OID { id-aa 32 }) carries a KEKDerivationAlgorithm SEQUENCE containing a kekAlg AlgorithmIdentifier and PBKDF2-params, used when the CEK and KEK algorithms differ and byte reversal alone is insufficient.
A large maxDecrypts value represents a potential denial-of-service vector; recipients SHOULD drop referenced CEKs where maxDecrypts exceeds a locally configured threshold or the CEK has been held beyond a maximum retention period.
Encryption does not provide authentication: recipients MUST NOT assume that possession of a valid CEKReference proves message origin, and MUST NOT assume that correct use of a CEKReference means replay or insertion attacks have been avoided.
If MSG1 is sent to recipient set S1 and MSG2 is sent to only a subset, all members of S1 can still decrypt MSG2 because MSG2.KEK is derived solely from MSG1.CEK; implementers must be aware that the effective recipient set for subsequent messages is the union of all prior recipient sets.
Implementations must take care not to create a cycle where MSG[n].CEK is the byte-reversal of MSG[n].KEK, as this could result in an unexpected fixed key being reused across messages.
CEKReference is encoded as an OCTET STRING and placed as an unprotectedAttrs Attribute of type id-aa-CEKReference with a single value; CEKMaxDecrypts is an INTEGER with the constraint 1 <= value <= 2^31.
KEKDerivationAlgorithm is a SEQUENCE { kekAlg AlgorithmIdentifier, pbkdf2Param PBKDF2-params }, where PBKDF2-params contains salt (MUST use 'specified' OCTET STRING CHOICE), iterationCount INTEGER, and optional keyLength INTEGER; the prf field MUST be omitted (defaulting to algid-hmacWithSHA1).