RFC 8933

Update to the Cryptographic Message Syntax (CMS) for Algorithm Identifier Protection

πŸ“… published October 2020, from ietf

Abstract ✨

okay bestie, this is RFC 8933 πŸŽ€ and it's called Update to the Cryptographic Message Syntax (CMS) for Algorithm Identifier Protection. It's written by R. Housley from Vigil Security, dated October 2020, and it's a Standards Track doc (ISSN 2070-1721). It updates RFC 5652, and the header doesn't list anything it obsoletes. The whole point is protecting algorithm identifiers in the signed-data and authenticated-data content types so nobody can sneak in a swap πŸ”’

Status of This Memo 🌸

This is an Internet Standards Track document. It's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check Section 2 of RFC 7841. For the current status, errata, or a way to send feedback, go to https://www.rfc-editor.org/info/rfc8933.

Copyright (c) 2020 IETF Trust and the persons identified as the document authors. All rights reserved. This doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they're in effect on the publication date. Please read those carefully because they spell out your rights and restrictions. Any Code Components pulled out of this doc must include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes.

Table of Contents 🧚

   1.  Introduction
   2.  Terminology
   3.  Required Use of the Same Hash Algorithm
     3.1.  RFC 5652, Section 5.3
     3.2.  RFC 5652, Section 5.4
     3.3.  RFC 5652, Section 5.6
     3.4.  Backward Compatibility Considerations
     3.5.  Timestamp Compatibility Considerations
   4.  Recommended Inclusion of the CMSAlgorithmProtection Attribute
     4.1.  RFC 5652, Section 14
   5.  IANA Considerations
   6.  Security Considerations
   7.  References
     7.1.  Normative References
     7.2.  Informative References
   Acknowledgements
   Author's Address

1. Introduction ✨

So this doc updates the Cryptographic Message Syntax (CMS) from [RFC5652] so that algorithm identifiers in signed-data and authenticated-data content types are properly protected. It's giving security upgrade πŸ’…

Here's the tea πŸ«– CMS signed-data can be vulnerable to algorithm substitution attacks, which [RFC5280] X.509 certificates aren't. In one of these attacks, the attacker changes the algorithm identifier or its parameters so the recipient ends up verifying with a different process. X.509 certificates avoid this because the structure signs the algorithm identifier and its parameters too.

The attacker's move is to find a different algorithm that gives the same result as the originator's algorithm. For example, if the signer hashed the content with SHA-256 [SHS], the attacker hunts for a weaker hash that makes an output of the same length. The goal is a different message that produces the same hash value, which is called a cross-algorithm collision. Lots of hash functions make 256-bit results today, and one of them could turn out weak down the road 😭

It gets worse when a digest algorithm makes a bigger result than the signature algorithm needs. The digest gets cut down to the size the signature algorithm wants, which can happen through truncation or modulo operations (straight truncation is the simplest). Then the attacker only needs a collision with the reduced digest. For instance, if the signer uses SHA-512 [SHS] as the digest and the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve [DSS] as the signature algorithm, the attacker only needs to hit a collision in the first half of the digest πŸ™ˆ

Parameterized algorithm identifiers have the same problem. When randomized hash functions get used, like the example in [RFC6210], the algorithm identifier parameter holds a random value that an attacker can mess with while hunting for collisions. Some other identifiers have complicated parameter structures, and each value is another chance for an attacker to tamper.

This doc makes two updates to CMS to protect the algorithm identifier. First, it turns a convention that lots of implementations already follow into a requirement, so the originator has to use the same hash algorithm for the message content digest and for the digest of the signed attributes. Second, it recommends that the originator include the CMSAlgorithmProtection attribute [RFC6211].

2. Terminology πŸŽ€

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

3. Required Use of the Same Hash Algorithm πŸ”₯

This section updates [RFC5652] so the originator has to use the same hash algorithm to compute the digest of the message content and the digest of the signed attributes. Main character energy πŸ‘‘

3.1. RFC 5652, Section 5.3

Okay so you're changing the paragraph about digestAlgorithm like this:

   OLD:

   |  digestAlgorithm identifies the message digest algorithm, and any
   |  associated parameters, used by the signer.  The message digest is
   |  computed on either the content being signed or the content
   |  together with the signed attributes using the process described in
   |  Section 5.4.  The message digest algorithm SHOULD be among those
   |  listed in the digestAlgorithms field of the associated SignerData.
   |  Implementations MAY fail to validate signatures that use a digest
   |  algorithm that is not included in the SignedData digestAlgorithms
   |  set.

   NEW:

   |  digestAlgorithm identifies the message digest algorithm, and any
   |  associated parameters, used by the signer.  The message digest is
   |  computed on either the content being signed or the content
   |  together with the signedAttrs using the process described in
   |  Section 5.4.  The message digest algorithm SHOULD be among those
   |  listed in the digestAlgorithms field of the associated SignerData.
   |  If the signedAttrs field is present in the SignerInfo, then the
   |  same digest algorithm MUST be used to compute both the digest of
   |  the SignedData encapContentInfo eContent, which is carried in the
   |  message-digest attribute, and the digest of the DER-encoded
   |  signedAttrs, which is passed to the signature algorithm.
   |  Implementations MAY fail to validate signatures that use a digest
   |  algorithm that is not included in the SignedData digestAlgorithms
   |  set.

3.2. RFC 5652, Section 5.4

Add this as the second paragraph in Section 5.4:

   ADD:

   |  When the signedAttrs field is present, the same digest algorithm
   |  MUST be used to compute the digest of the encapContentInfo
   |  eContent OCTET STRING, which is carried in the message-digest
   |  attribute and the digest of the collection of attributes that are
   |  signed.

3.3. RFC 5652, Section 5.6

Next, change the paragraph about signed attributes like this:

   OLD:

   |  The recipient MUST NOT rely on any message digest values computed
   |  by the originator.  If the SignedData signerInfo includes
   |  signedAttributes, then the content message digest MUST be
   |  calculated as described in Section 5.4.  For the signature to be
   |  valid, the message digest value calculated by the recipient MUST
   |  be the same as the value of the messageDigest attribute included
   |  in the signedAttributes of the SignedData signerInfo.

   NEW:

   |  The recipient MUST NOT rely on any message digest values computed
   |  by the originator.  If the SignedData signerInfo includes the
   |  signedAttrs field, then the content message digest MUST be
   |  calculated as described in Section 5.4 using the same digest
   |  algorithm to compute the digest of the encapContentInfo eContent
   |  OCTET STRING and the message-digest attribute.  For the signature
   |  to be valid, the message digest value calculated by the recipient
   |  MUST be the same as the value of the messageDigest attribute
   |  included in the signedAttrs field of the SignedData signerInfo.

3.4. Backward Compatibility Considerations

Heads up, this new requirement could break compatibility with an implementation that let the message content digest and the signed attributes digest use different digest algorithms. Signatures from that kind of implementation, when two different digest algorithms were used, will be treated as invalid by anything following this spec πŸ’€ That said, most if not all implementations already make the originator use one digest algorithm for both operations, so it's probably fine ✨

3.5. Timestamp Compatibility Considerations

The new requirement could cause trouble for timestamping systems when the originator doesn't want to share the message content with the Time Stamping Authority (TSA) [RFC3161]. In that case, the originator sends the TSA a TimeStampReq that includes a MessageImprint, which has a digest algorithm identifier and a digest value. The TSA then uses the digest the originator gave it in the MessageImprint.

When the TSA makes the TimeStampToken, it MUST use the same digest algorithm to compute the digest of the encapContentInfo eContent (an OCTET STRING holding the TSTInfo) and the message-digest attribute inside the SignerInfo.

To keep TimeStampToken values made before this update valid, the TSA isn't required to make the TimeStampToken's digest algorithm match the digest algorithm of the MessageImprint embedded in the TSTInfo. Phew, that's a relief 🫢

This section updates [RFC5652] to recommend that the originator include the CMSAlgorithmProtection attribute [RFC6211] whenever signed attributes or authenticated attributes are present.

4.1. RFC 5652, Section 14

Add this as the eighth paragraph in Section 14:

   ADD:

   |  While there are no known algorithm substitution attacks today, the
   |  inclusion of the algorithm identifiers used by the originator as a
   |  signed attribute or an authenticated attribute makes such an
   |  attack significantly more difficult.  Therefore, the originator of
   |  a signed-data content type that includes signed attributes SHOULD
   |  include the CMSAlgorithmProtection attribute [RFC6211] as one of
   |  the signed attributes.  Likewise, the originator of an
   |  authenticated-data content type that includes authenticated
   |  attributes SHOULD include the CMSAlgorithmProtection attribute
   |  [RFC6211] as one of the authenticated attributes.

6. Security Considerations πŸ”

okay bestie, this section is the main character moment of the whole doc πŸ’… The CMS [RFC5652] signed-data and authenticated-data content types get upgraded so that algorithm identifiers are protected too. That makes algorithm substitution attacks way harder to pull off πŸ™…β€β™€οΈβœ¨

For signed-data, the upgrades here force an attacker to go after the hash algorithm substitution on the whole signature, not just the message digest in encapContentInfo eContent. That's a much bigger lift for them 😀πŸ”₯

Some signature algorithms stop hash function substitutions by including the digest algorithm identifier as an input to the signature itself. As [HASHID] explains, this kind of "firewall" might not work well, or might not be possible at all, with newer signature algorithms 😬 For example, RSASSA-PKCS1-v1_5 [RFC8017] protects the digest algorithm identifier, but RSASSA-PSS [RFC8017] does not. So it still matters that a signer has a way to tell a recipient which digest algorithms are allowed when verifying an overall signature 🫢 That signal can live in the signature algorithm's X.509v3 certificate extension [RFC5280], or be handled some other way. The Digital Signature Standard (DSS) [DSS] goes with the first option, requiring an "approved" one-way hash algorithm πŸŽ€

For authenticated-data, the upgrades here force an attacker to pull off a MAC algorithm substitution attack. That's honestly really hard, because the attacker doesn't know the authentication key πŸ§šπŸ’œ

The CMSAlgorithmProtection attribute [RFC6211] protects the algorithm identifiers used in signed-data and authenticated-data πŸ›‘οΈ But it does nothing for the algorithm identifiers in enveloped-data, digested-data, or encrypted-data. Same deal for authenticated-enveloped-data from [RFC5083]: CMSAlgorithmProtection doesn't cover it either πŸ’€ Figuring out a way to protect algorithm identifiers for these content types is a job for future us 🌈


7. References πŸ“š

7.1. Normative References

7.2. Informative References


Acknowledgements πŸ™

huge thanks to Jim Schaad and Peter Gutmann πŸ’– without even knowing it, they're the reason this doc exists ✨ Also thanks to Roman Danyliw, Ben Kaduk, and Peter Yee for their careful review and editing suggestions 🫢

Author's Address πŸ’Œ

Russ Housley
Vigil Security, LLC
516 Dranesville Road
Herndon, VA 20170
United States of America

Email: housley@vigilsec.com
πŸ“¦ where this page comes from