RFC 3185
Reuse of CMS Content Encryption Keys
RFC 3185: Reuse of CMS Content Encryption Keys π
okay bestie, RFC 3185 is giving Standards Track realness π . It's from October 2001, written by S. Farrell (Baltimore Technologies) and S. Turner (IECA), and it's all about reusing CMS content encryption keys π₯. The title block doesn't list anything it obsoletes or updates, so no drama there β¨.
Status of This Memo β¨
This document is an Internet standards track protocol for the Internet community, and it's literally asking for discussion and suggestions for improvements π«Ά. For the standardization state and status of this protocol, check the current edition of "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited π¦.
Copyright Notice π
Copyright (C) The Internet Society (2001). All Rights Reserved.
Abstract π§
So basically, this doc shows a way to put a key identifier inside a CMS (Cryptographic Message Syntax) enveloped data structure. That way, the content encryption key can get reused for more enveloped data packets, which is so efficient it's iconic π.
Table Of Contents π
1. Introduction................................................... 2
2. Applicability.................................................. 2
3. How to do it................................................... 3
4. Using different CEK and KEK algorithms......................... 4
5. Conformance.................................................... 5
6. Security Considerations........................................ 5
7. References..................................................... 6
Authors' Addresses................................................ 6
Appendix A: ASN.1 Module.......................................... 7
Full Copyright Statement.......................................... 10
1. Introduction π
okay so CMS [CMS] is where EnvelopedData gets specified π. EnvelopedData does data encryption with either symmetric or asymmetric key management techniques. Asymmetric key establishment is relatively expensive, so in some environments it's lowkey desirable to reuse a shared content-encryption key that was set up with asymmetric mechanisms, and use it for encryption in later messages π₯.
Here's the main idea. You reuse the content-encryption key (CEK) from a message (say MSG1) to derive the key-encryption key (KEK) for a later message (MSG2). To do that, you put a reference value for the CEK in message 1, and that same value shows up as the KEKIdentifier for message 2. The CEK from message 1 is called the "referenced CEK" π .
The key words "MUST", "REQUIRED", "SHOULD", "RECOMMENDED", and "MAY" in this document are to be interpreted as described in [RFC2119] β¨.
2. Applicability π¦
This spec is meant to give you more efficient selective field confidentiality between communicating peers. It's especially useful in these cases:
- The originator is a client that wants to send a bunch of fields to a server (the recipient) in one transaction, where the referenced CEK is used to encrypt each field separately π.
- The originator and recipient are servers that talk super often and use this spec purely for efficiency π₯.
This specification is not meant to work in every situation π. It's suited for use where:
- It's further scoped. Like, this specification doesn't define a protocol, it's more of a trick you can use in a bigger context, and each of those contexts will need additional specification π§. Specifically, to use this specification, it is REQUIRED to define the originators' and recipients' behavior where a referenced CEK has been "lost".
- This specification is not suitable for general group key management π .
- The underlying cryptographic API is suitable. It's very likely that any cryptographic API that completely "hides" the bits of cryptographic keys from the CMS layer will block reuse of a referenced CEK, because it won't have a primitive that lets MSG1.CEK get transformed into MSG2.KEK π ββοΈ.
- The algorithms for content and key encryption have compatible key values and strengths. So, for example, if MSG1.contentEncryptionAlgorithm is a 40bit cipher and MSG2.keyEncryptionAlgorithm needs 168 bits of keying material, then this specification SHOULD NOT be used π.
There are other ways you could set up the symmetric keying material you need, like using a group keying scheme or defining a content type that contains a KEK value πΈ. This scheme is much simpler than generic group key management, but if an implementation already supports group key management, then this scheme doesn't add value. It's also suitable for inclusion in CMS libraries (though adding new state might be a problem for some implementations) π. That can offer some advantages over application layer schemes, like where the content includes MSG2.KEK β¨.
3. How to do it π
To reference the content-encryption key (CEK) used in an EnvelopedData, you can include a key identifier in the unprotectedAttrs field of MSG1. That key can then be used to derive the key-encryption key (KEK) for other instances of EnvelopedData or for other purposes π. If the CEK from MSG1 is going 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 π.
MSG2.KEK is derived by reversing the bytes of MSG1.CEK π. The byte reversal exists to avoid an attack where the attacker has a known plaintext and the related ciphertext (encrypted with MSG1.CEK) that could otherwise be used directly as a MSG2.KEK π.
The application MUST ensure that the relevant algorithms are compatible. In other words, a CEKReference attribute alone can only be used where the content-encryption algorithm from MSG1 uses the same type of symmetric key as the key-encryption algorithm from MSG2 π«Ά.
Notes:
- Nothing stops you from including a CEKReference attribute in MSG2 as well as in MSG1. So an originator could "roll" the referenced CEK with every message π.
- The CEKReference attribute can show up with any of the choices for RecipientInfo: ktri, kari or kekri. Implementors MUST NOT assume that CEKReference can only occur where ktri or kari is used π.
id-aa-CEKReference OBJECT IDENTIFIER ::= { id-aa 30 }
CEKReference ::= OCTET STRING
id-aa is an object identifier defined in [CMS-MSG] π§.
So the originator of MSG1 can show the "lifetime" of the CEK, the originator MAY include a CEKMaxDecrypts attribute, also in the unprotectedAttrs field of EnvelopedData β³. This attribute has an INTEGER syntax (the value MUST be >=1 and maximally 2^31). It tells the recipient the maximum number of messages (excluding MSG1) that will use the referenced CEK π’. This Attribute MUST only be sent when a CEKReference attribute is also included π
.
The recipient SHOULD maintain the CEKReference information (minimally the key identifier and the CEK value) while fewer than maxDecrypt messages have been successfully received. Recipients SHOULD delete the CEKReference information after some locally configured period π§Ή.
When this attribute is not present, originators and recipients SHOULD behave as if a value of one had been sent πΈ.
id-aa-CEKMaxDecrypts OBJECT IDENTIFIER ::= { id-aa 31 }
CEKMaxDecrypts ::= INTEGER
If CEKMaxDecrypts is missing, or has the value one, then each CEK gets reused once as the KEK for the next message. That means MSG[n].KEK is the byte-reversal of MSG[n-1].CEK, and then MSG[n+1].KEK is the byte-reversal of MSG[n].CEK π. Note that MSG[n-1].CEK has no impact whatsoever on MSG[n+1], as long as CEKs are generated randomly (and not, say, derived from KEKs somehow) π².
4. Using different CEK and KEK algorithms π¦
When MSG1.content-encryption algorithm and MSG2.key-encryption algorithm are the same, MSG2.KEK is the byte-reverse of MSG1.CEK. In general, though, these algorithms MAY differ, like needing different key lengths π. This section specifies a generic way to derive MSG2.KEK for those cases π.
Note: In some sense, the CEK and KEK algorithms are never really the "same". For example, id-alg-CMS3DESwrap and des-ede3-cbc differ. For this specification, though, all we care about is that the algorithms use the same format and size of keying material (see also security considerations) and that they don't differ significantly in terms of the resulting cryptographic "strength." In that sense, the two algorithms in the example above are the "same" π .
Implementations MAY include this functionality π.
The basic approach uses the PBKDF2 key derivation function defined in PKCS#5 [RFC2898], but with MSG1.CEK as input instead of a password. The output of the PBKDF2 function is MSG2.KEK π. To make this work, a new attribute type is defined that lets you pass the required parameters π§.
id-aa-KEKDerivationAlg OBJECT IDENTIFIER ::= { id-aa 32 }
KEKDerivationAlgorithm ::= SEQUENCE {
kekAlg AlgorithmIdentifier,
pbkdf2Param PBKDF2-params
}
kekAlg is the algorithm identifier (and its associated parameters, if any) for the MSG2 key encryption algorithm. Note that it's not necessary to protect this field, since modification of keyAlg only represents a denial-of-service attack π.
The PBKDF2 algorithm parameters get handled as follows:
- The salt MUST use the "specified" element of the CHOICE π§.
- The message originator selects the iterationCount π’.
- The value of keyLength is determined by the kekAlg and MUST be present π.
- The prf field MUST use the default algorithm specified in [RFC2898], which is algid-hmacWithSHA1 (and so the prf field MUST be omitted) π.
5. Conformance π
This specification only applies to messages where the CEKReference attribute is present π. All attributes specified here SHOULD be ignored unless they're present in a message containing a valid, new or recognized, existing value of CEKReference π. The CEKMaxDecrypts attribute is to be treated by the recipient as a hint, but MUST be honored by the originator π«Ά.
The optional-to-implement KEKDerivationAlgorithm attribute MUST only be present when MSG1.content-encryption algorithm differs from MSG2.key-encryption algorithm, and in that case it MUST be present π. Implementations that recognize this attribute but don't support the functionality SHOULD ignore the attribute π§.
Ignoring attributes as discussed above will lead to decryption failures. CMS implementations SHOULD be able to signal the particular reason for this failure to the calling application π.
6. Security Considerations ππ
Okay bestie, this section is SO important, so let's get into it π§. First off, encryption does NOT give you authentication π. So if the encryptedContent is basically random noise, recipients MUST NOT assume that "knowing" a CEKReference value proves anything. Literally anyone could have made that EnvelopedData π. This matters for security (the recovered plaintext shouldn't be totally random, ngl) and for avoiding denial of service too. Recipients MUST NOT assume that using the right CEKReference means the message originator is genuine π.
Similarly, using the correct CEKReference does NOT mean the message wasn't replayed or inserted π¦. So recipients MUST NOT assume replay has been avoided. Not me assuming things π ββοΈ.
Now the maxDecrypts field is kind of a red flag π©. If an originator puts in a super huge value, they could get a recipient to eat up memory by storing the referenced CEKs for ages, or the originator might just never send the number of ciphertexts they said they would. So recipients SHOULD drop referenced CEKs where the maxDecrypts value is too large (according to local configuration), or where the referenced CEK has been held for too long. Protect your memory, queen π.
Heads up: if MSG1 goes to a set S1 of users, and MSG2 only goes to a subset of S1, every user in S1 can STILL decrypt MSG2 π«’. That's because MSG2.KEK is computed only from MSG1.CEK. So implementers should be aware that in cases like this, ALL members of the original set of recipients (S1) can access the plaintext of MSG2 and subsequent messages. Iconic, but also kind of scary π.
Okay, so the byte reversal is there for a reason π. Without it, an attacker who knows some of MSG1.plaintext (like a prefix in a field, for instance) could use the matching ciphertext block as the next encrypted CEK, aka MSG2.KEKRecipientInfo.encryptedKey. Then the attacker knows the next CEK π±. This attack goes after something this note is NOT claiming to protect (origin authentication), but it's super easy to avoid with the byte reversal β¨. Byte reversal was picked over bit reversal, because bit reversal would make parity bits from MSG1.CEK get used as keying bits for MSG2.KEK for DES-based algorithms π. And yeah, byte reversal would affect parity too if parity checks spanned more than one octet, but no well-known algorithms work like that, so we're good π«Ά.
Last but not least, implementations should be VERY careful with this scheme if MSG[n].KEK is used to derive MSG[n].CEK π¨. For example, if MSG[n].CEK were the byte-reversal of MSG[n].KEK, this scheme could end up with a fixed key being used unexpectedly. Yikes, bestie π.
7. References π
[CMS] Housley, R., "Cryptographic Message Syntax", RFC 2630, June 1999.
[CMS-MSG] Ramsdell, B. "S/MIME Version 3 Message Specification", RFC 2633, June 1999.
[RFC2898] Kaliski, B., "PKCS #5: Password-Based Cryptography Specification Version 2.0", RFC 2898, September 2000.
[RFC2026] Bradner, S., "The Internet Standards Process -- Revision 3", BCP 9, RFC 2026, October 1996.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
Authors' Addresses πΈ
Stephen Farrell, Baltimore Technologies, 39 Parkgate Street, Dublin 8 IRELAND
Phone: +353-1-881-6000 EMail: stephen.farrell@baltimore.ie
Sean Turner IECA, Inc. 9010 Edgepark Road Vienna, VA 22182 USA
Phone: +1.703.628.3180 EMail: turners@ieca.com
Appendix A: ASN.1 Module π§
SMIMERcek
{ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
smime(16) modules(0) rcek(13) }
-- This module contains the definitions of the attributes
-- used for re-using the content encryption key from a
-- message in further messages.
DEFINITIONS IMPLICIT TAGS ::=
BEGIN
-- EXPORTS ALL --
IMPORTS
AlgorithmIdentifier FROM
AuthenticationFramework { joint-iso-itu-t ds(5)
module(1) authenticationFramework(7) 3 } ;
-- [RFC2898] uses 1993 ASN.1 to define PBKDF2-params. Since
-- this specification only uses 1988 ASN.1, the definition is
-- repeated here for completeness.
-- The DEFAULT prf field value, MUST be used for this
-- specification
digestAlgorithm OBJECT IDENTIFIER ::=
{ iso(1) member-body(2) us(840) rsadsi(113549) 2}
id-hmacWithSHA1 OBJECT IDENTIFIER ::= {digestAlgorithm 7}
-- [RFC2898] defines PBKDF2-params using 1993 ASN.1, which
-- results in the same encoding as produced by the definition
-- below. See [RFC2898] for that definition.
PBKDF2-params ::= SEQUENCE {
salt CHOICE {
specified OCTET STRING, -- MUST BE USED
otherSource AlgorithmIdentifier -- DO NOT USE THIS FIELD
},
iterationCount INTEGER (1..MAX),
keyLength INTEGER (1..MAX) OPTIONAL
}
-- id-aa is the arc with all new authenticated and
-- unauthenticated attributes produced the by S/MIME
-- Working Group. It is also defined in [CMS-MSG]
id-aa OBJECT IDENTIFIER ::=
{iso(1) member-body(2) usa(840) rsadsi(113549)
pkcs(1) pkcs-9(9) smime(16) attributes(2)}
-- This attribute contains what will be the key identifier
-- for subsequent messages
id-aa-CEKReference OBJECT IDENTIFIER ::= { id-aa 30 }
CEKReference ::= OCTET STRING
-- This attribute contains a "hint" to the recipient
-- indicating how many times the originator will use
-- the re-used CEK
id-aa-CEKMaxDecrypts OBJECT IDENTIFIER ::= { id-aa 31 }
CEKMaxDecrypts ::= INTEGER
-- This attribute specifies the key derivation function
-- to be used when the default byte reversal operation cannot
-- be used.
id-aa-KEKDerivationAlg OBJECT IDENTIFIER ::= { id-aa 32 }
KEKDerivationAlgorithm ::= SEQUENCE {
kekAlg AlgorithmIdentifier,
pbkdf2Param PBKDF2-params }
END
Full Copyright Statement π
Copyright (C) The Internet Society (2001). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS 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.
Acknowledgement π
Funding for the RFC Editor function is currently provided by the Internet Society. β¨
π¦ where this page comes from
- ietf: rfc3185 2001-10
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms