Subject: [lamps] Benjamin Kaduk's Discuss on draft-ietf-lamps-cms-mix-with-psk-06: (with DISCUSS and COMMENT)

From: Benjamin Kaduk via Datatracker <[email-masked]>
Date: Fri, 16 Aug 2019 10:21:58 -0700

Benjamin Kaduk has entered the following ballot position for
draft-ietf-lamps-cms-mix-with-psk-06: Discuss

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about IESG DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-lamps-cms-mix-with-psk/

----------------------------------------------------------------------
DISCUSS:
----------------------------------------------------------------------

I think we need to have a discussion about the abstract API for a
KEY-DERIVATION instance and how that relates to what we need for a key
combination operation.  In Section 5 we assume that we can use the
HKDF terminology, but that doesn't seem to hold universally for
KEY-DERIVATION; for example, while HKDF has IKM, salt, and info, PBKDF2
(from RFC 3211 that AFAICT introduces keyDerivationalgorithm for CMS) is
specified by RFC 2898 as taking just the input secret (password) and a
salt, with no separate 'info' (and of course the different iteration
count and PRF parameters needed for its construction).  I note (with
chagrin, as sponsoring AD) that RFC 8619 says "PARAMS ARE absent" for
the HKDF-based KEY-DERIVATION instances but is silent about how one is
supposed to know what to pass for salt/info (the IKM we can perhaps
assume will be obvious).

In short, should we be seeking to define a distinct key combination
operation like KRB-FX-CF2 (RFC6113) rather than trying to repurpose key
derivation?  Some KDFs support this fairly well, but it's not clear to
me that it is a universal property.  For example, the proof in [H2019]
seems to be assuming HKDF but this draft does not (as is clearly seen
from the use of the X9.63 KDF in one of the examples).

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

Do we need to document the risk of "algorithm mismatch" that is present
because we use separate algorithm identifiers for KDF, key-encryption,
key-agreement, etc. (vs. a "cipher-suite"-like approach that bundles
together a known-good combination)?  In particular, I see we talk about
the key length for content- and key-encryption algorithms, but are there
other constraints that should be applied?

Section 2

                                  The PSK MUST be distributed to the
   sender and all of the recipients by some out-of-band means that does
   not make it vulnerable to the future invention of a large-scale
   quantum computer, and an identifier MUST be assigned to the PSK.

What are the uniqueness/scope requirements for that identifier?

Section 3

      ktris contains one KeyTransRecipientInfo type for each recipient;
      it uses a key transport algorithm to establish the key-derivation
      key.  KeyTransRecipientInfo is described in Section 6.2.1 of
      [RFC5652].

I think we need to be more clear that the 'encryptedKey' member of
KeyTransRecipientInfo contains not the "result of encrypting the
content-encryption key for this recipient" per RFC 5652, but rather the
"result of encrypting the key-derivation key for this recipient".  That
is, to call out how we are deviating from RFC 5652.

Section 5

   Many key derivation functions (KDFs) internally employ a one-way hash
   function.  When this is the case, the hash function that is used is
   identified by the KeyDerivationAlgorithmIdentifier.  HKDF [RFC5869]

(editorial?) This reads as if the KeyDerivationAlgorithmIdentifier is
going to be (e.g.) 2.16.840.1.101.3.4.2.1 for regular SHA-256, which is
presumably not the case.  It sounds more like "indicated by" or
"indicated as part of the semantics of the" would be more appropriate.

(side note) Is there a story behind using 5 and 10 for the ENUMERATED
values?

         CMSORIforPSKOtherInfo ::= SEQUENCE {
           psk                    OCTET STRING,
           keyMgmtAlgType         ENUMERATED {
             keyTrans               (5),
             keyAgree               (10) },
           keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
           pskLength              INTEGER (1..MAX),
           kdkLength              INTEGER (1..MAX) }

If psk is encoded as an OCTET STRING (i.e., including its length), why
do we need a separate pskLength field?

Section 7

   material.  Compromise of the key-encryption key may result in the
   disclosure of all content-encryption keys or content-authenticated-
   encryption keys that were protected with that keying material, which
   in turn may result in the disclosure of the content.

a nit, but for the key-agreement variant we have two things that we call
"key-encryption key"s, so use of the definite article here is
potentially ambiguous.

   This specification does not require that PSK is known only by the
   sender and recipients.  The PSK may be known to a group.  Since
   confidentiality depends on the key transport or key agreement
   algorithm, knowledge of the PSK by other parties does not enable
   eavesdropping.  However, group members can record the traffic of

Would it be appropriate to add either "inherently" (enable
eavesdropping) or "with currently available technology"?

   Implementers should be aware that cryptographic algorithms become
   weaker with time.  As new cryptoanalysis techniques are developed and

nit: "cryptanalysis"

Section 8

With respect to "not really making privacy worse", this does seem to
risk exposing that a group of (identified) recipients/participants share
access to a single PSK (identity), which could potentially correlate
them for other sorts of surveillance/attack.

Section 10.2

Don't RFCs 5911, 5912, and 6268 need to be normative since we import
from them in the ASN.1 module?

Section A.1

[I did not attempt to validate the examples.]

   The pre-shared key known to Alice and Bob:
      c244cdd11a0d1f39d9b61282770244fb0f6befb91ab7f96cb05213365cf95b15

(Should we say it's in hex?  Similarly for other non-ASCII-armored
fields, especially the PSK identifier which looks like it is more of a
string than a hex-encoded binary blob)

---

From: Russ Housley <[email-masked]>
Date: Fri, 16 Aug 2019 14:09:03 -0400

Ben:

Thanks for doing all of the reading necessary to raise this question.

I want to respond to the DISCUSS in this note.  I'll tackle the non-blocking comments is a separate message.

NIST SP 800-56 Revision 1 offers this high-level interface to the KDF:

   KDF(Z, OtherInput)

  - Z: a byte string that represents the shared secret.  This ic called IKM in the HKDF terminology.

  - OtherInput includes:

   -- salt - a non-null (secret  or non-secret) byte string.
   
   -- L - a  positive  integer  that  indicates  the  length  (in  bits)  of  the  secret  keying  material to be derived.

   -- FixedInfo - a bit string of context-specific data that is appropriate for the relying key-establishment scheme.

I do not think that this very high level of API really solves your concern, but it did guide my thinking in writing the document.

The KDF algorithm identifier has this structure:

   AlgorithmIdentifier  ::=  SEQUENCE  {
        algorithm               OBJECT IDENTIFIER,
        parameters              ANY DEFINED BY algorithm OPTIONAL  }

The algorithm part lets us name many different KDFs.  As you point out, the examples in Appendix A and Appendix B use HKDF and X9.63 KDF.

Recent discussions in the LAMPS WG show a big bias against complex parameter strictures.  Instead, people have voiced a strong preference for an object identifier that names all of the options.  This leads to more object identifier assignments, but clear understanding of all options when one is chosen or negotiated.  The one exception is an initialization vector, where a fresh value is expected each time the algorithm is invoked.

So, in this document, I have defined a structure of the OtherInput portion of the NIST API.  If a particular KDF needs to use a value from that structure in a particular way, is can do so.  The document uses HKDF terminology.

If a KDF requires a salt, then it should be provided as a parameter.  I can certainly add that to the document.  I believe that KMAC128 and KMAC256 are algorithms that require a salt.

Russ

---

From: Russ Housley <[email-masked]>
Date: Wed, 21 Aug 2019 16:02:51 -0400

Ben:

I responded to the DISCUSS part of this ballot position last week.  This note responds to the very thoughtful non-blocking COMMENT portion of your ballot position.

Some of this is covered in [RFC5652] and [RFC5083].  So, I suggest:

   The security considerations in related to the CMS enveloped-data
   content type in [RFC5652] and the security considerations related to
   the CMS authenticated-enveloped-data content type in [RFC5083]
   continue to apply.

As you indicate, some more of this is already covered by existing text:

   When using a PSK with a key transport or a key agreement algorithm, a
   key-encryption key is produced to encrypt the content-encryption key
   or content-authenticated-encryption key.  If the key-encryption
   algorithm is different than the algorithm used to protect the
   content, then the effective security is determined by the weaker of
   the two algorithms.  If, for example, content is encrypted with
   256-bit AES, and the key is wrapped with 128-bit AES, then at most
   128 bits of protection is provided.  Implementers must ensure that
   the key-encryption algorithm is as strong or stronger than the
   content-encryption algorithm or content-authenticated-encryption
   algorithm.

I suggest we also add some advice about KDF algorithms:

   The selection of the key-derivation function imposes an upper bound
   on the strength of the resulting key-encryption key.  The strength of
   the selected key-derivation function should be at least as strong as
   the key-encryption algorithm that is selected.  NIST SP 800-56C
   Revision 1 [NIST2018] offers advice on the security strength of
   several popular key-derivation functions.

> What are the uniqueness/scope requirements for that identifier?

It is best if each PSK has a unique identifier; however, if a recipient has more than one PSK with the same identifier, the recipient can try each of them in turn.  I will add that to the end of that paragraph.

> is, to call out how we are deviating from RFC 5652.

Okay.  I suggest:

      ktris contains one KeyTransRecipientInfo type for each recipient;
      it uses a key transport algorithm to establish the key-derivation
      key.  That is, the encryptedKey field of KeyTransRecipientInfo
      contains the key-derivation key instead of the content-encryption
      key.  KeyTransRecipientInfo is described in Section 6.2.1 of
      [RFC5652].

> "indicated as part of the semantics of the" would be more appropriate.

This applies to KDFs that are built on encryption algorithms too.  I suggest:

   Many key derivation functions (KDFs) internally employ a one-way hash
   function.  When this is the case, the hash function that is used is
   indirectly indicated by the KeyDerivationAlgorithmIdentifier.  HKDF
   [RFC5869] is one example of a KDF that makes use of a hash function.

   Other KDFs internally employ an encryption algorithm.  When this is
   the case, the encryption that is used is indirectly indicated by the
   KeyDerivationAlgorithmIdentifier.  For example, AES-128-CMAC can be
   used for randomness extraction in a KDF as described in [NIST2018].

>           kdkLength              INTEGER (1..MAX) }

5 = b'0101'
10 = b'1010'

Just so more bits change on the input to the KDF.

> do we need a separate pskLength field?

Yes, this is redundant.  The length is input as part of the OCTET STRING encoding and as an INTEGER.  Joim Schaad pointed this out a long time ago.  It is an artifact of a change that was made between -00 and -01 of this document.

> "key-encryption key"s, so use of the definite article here is

I suggest that the key-encryption key and the KDF be moved to their own paragraph:

   Implementations of the key derivation function must compute the
   entire result, which in this specification is a key-encryption key,
   before outputting any portion of the result.  The resulting key-
   encryption key must be protected.  Compromise of the key-encryption
   key may result in the disclosure of all content-encryption keys or
   content-authenticated-encryption keys that were protected with that
   keying material, which in turn may result in the disclosure of the
   content.  Note that there are two key-encryption keys when a PSK with
   a key agreement algorithm is used, with similar consequence for the
   compromise of either one of these keys.

> eavesdropping) or "with currently available technology"?

Sure.  I'll add "inherently".

>   weaker with time.  As new cryptoanalysis techniques are developed and

Good catch.  I read past that many, many times.

> them for other sorts of surveillance/attack.

I think that the correlation of key transport public identifiers and key agreement public keys would have similar consequences.

> from them in the ASN.1 module?

RFC 5911 is not needed.

RFC 5912 and RFC 6268 are both in the downref registry, so no further process is needed to normatively reference them.

> string than a hex-encoded binary blob)

I suggest:

   The pre-shared key known to Alice and Bob, in hexadecimal:

Russ

---

From: Benjamin Kaduk <[email-masked]>
Date: Thu, 22 Aug 2019 21:00:08 -0500

Hi Russ,

> I want to respond to the DISCUSS in this note.  I'll tackle the non-blocking comments is a separate message.

Sorry that I did not more effectively make use of the extra lead time you
gave me.

> I do not think that this very high level of API really solves your concern, but it did guide my thinking in writing the document.

It is helpful to see this and understand the origin of what's in the
document.  (Also that the salt is listed as "secret or non-secret" here, as
in at least one other place I looked at during my background reading I saw
it listed as "not-secret", which would be problematic when we want to put a
secret key in it!)

> Recent discussions in the LAMPS WG show a big bias against complex parameter strictures.  Instead, people have voiced a strong preference for an object identifier that names all of the options.  Th…

Agreed.

> If a KDF requires a salt, then it should be provided as a parameter.  I can certainly add that to the document.  I believe that KMAC128 and KMAC256 are algorithms that require a salt.

Okay, but I'm not sure we've really gotten onto the same page.

I think my main question is whether we're comfortable using a KDF
abstraction like the above (KDF(secret, otherInput)) in a fully general
sense, and asking for this mix-with-psk to work properly for all possible
KDFs.  For example, would you be comfortable using the construction in this
document with PBKDF1 as the KDF?  I don't even see where we could slot in
the PSK from this document into PBKDF1 -- the API just doesn't seem to be
flexible enough.  PBKDF2 allows a more-than-8-octet salt, but is that going
to provide the kind of mixing that we need?

I just don't know if all KDFs are going to guarantee the contributory
behavior from the otherInput that we need in order for this scheme to work.

-Ben

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 22 Aug 2019 23:07:12 -0400

On Thu, Aug 22, 2019 at 10:00 PM Benjamin Kaduk <[email-masked]> wrote:

> > I want to respond to the DISCUSS in this note.  I'll tackle the
> non-blocking comments is a separate message.
>
> >    -- L - a  positive  integer  that  indicates  the  length  (in
> bits)  of  the  secret  keying  material to be derived.
> >
> >    -- FixedInfo - a bit string of context-specific data that is
> appropriate for the relying key-establishment scheme.
> >
> > I do not think that this very high level of API really solves your
> concern, but it did guide my thinking in writing the document.
>
> > The algorithm part lets us name many different KDFs.  As you point out,
> the examples in Appendix A and Appendix B use HKDF and X9.63 KDF.
> >
> > Recent discussions in the LAMPS WG show a big bias against complex
> parameter strictures.  Instead, people have voiced a strong preference for
> an object identifier that names all of the options.  This leads to more
> object identifier assignments, but clear understanding of all options when
> one is chosen or negotiated.  The one exception is an initialization
> vector, where a fresh value is expected each time the algorithm is invoked.
>
> Agreed.
>
> > So, in this document, I have defined a structure of the OtherInput
> portion of the NIST API.  If a particular KDF needs to use a value from
> that structure in a particular way, is can do so.  The document uses HKDF
> terminology.
> >
> > If a KDF requires a salt, then it should be provided as a parameter.  I
> can certainly add that to the document.  I believe that KMAC128 and KMAC256
> are algorithms that require a salt.
>

The ability to change algorithm is a good thing. But proliferation of
mechanisms is not. I really dislike the fact that we have three dozen SASL
mechanisms that do the same thing.

The ability to use a KDF keyed by a different hash function seems like it
is useful agility.

I really cannot imagine a situation in which we discovered an urgent need
to move away from HKDF that didn't require us to think really hard about
the replacement algorithm as well.

---

From: Benjamin Kaduk <[email-masked]>
Date: Fri, 23 Aug 2019 11:57:08 -0500

>    several popular key-derivation functions.

That all sounds good; thanks.

>       key.  KeyTransRecipientInfo is described in Section 6.2.1 of

Works for me.

>    used for randomness extraction in a KDF as described in [NIST2018].

Sure.

> Just so more bits change on the input to the KDF.

:)

> Yes, this is redundant.  The length is input as part of the OCTET STRING encoding and as an INTEGER.  Joim Schaad pointed this out a long time ago.  It is an artifact of a change that was made betw…

Okay.

>    compromise of either one of these keys.

Thanks.

> I think that the correlation of key transport public identifiers and key agreement public keys would have similar consequences.

Thanks for thinking about it; that's reasonable.

>    The pre-shared key known to Alice and Bob, in hexadecimal:

Thanks!

-Ben

---

From: Benjamin Kaduk <[email-masked]>
Date: Fri, 23 Aug 2019 11:58:42 -0500

Hi Phill,

> the replacement algorithm as well.

While I agree with you, I'm not entirely sure what you see as the
consequences for this document.  Are you proposing that we just restrict
its usage to HKDF-based KDFs for now?

Thanks,

Ben

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 23 Aug 2019 14:10:11 -0400

> its usage to HKDF-based KDFs for now?

Given your comments, I think that works better than trying to abstract out
an API and then map other KDFs onto it.

Since we build KDFs on a hash function, the API pretty much defines the KDF
structure. There are design choices in a KDF but I really hope they are not
security concerns because that would suggest HMAC is broken or we don't
know how to use a MAC.

I see the choice of KDF as being a part of the CMS specification that just
happens to be available for re-use in other specifications. While there may
be good reason to add to the number of KDFs supported, I don't think we
need to anticipate or plan for that.

---

From: Russ Housley <[email-masked]>
Date: Fri, 23 Aug 2019 14:23:14 -0400

> it listed as "not-secret", which would be problematic when we want to put a

In thins case, I do not see a need for a secret salt, but the NIST SP 800-56C API allows for it.

> Okay, but I'm not sure we've really gotten onto the same page.

No, we were not on the same page.  The paragraph below really helps me understand your point.

I few things regarding RFC 2631, RFC 3211, RFC 5912, and RFC 5990 just to make sure we are totally on the same page.

RFC 2631 (Diffie-Hellman Key Agreement Method) and X9.42 use a KDF to compute a KEK from a Diffie-Hellman shared secret and an OtherInfo structure.  RFC 2631 does not call it a KDF, but X9.42 does so.  The API looks a lot like the one for HKDF, except there is no salt.  In fact, the X9.42 KDF could work just fine in with this document.

RFC 3211 (Password-based Encryption for CMS) introduced the KeyDerivationAlgorithmIdentifer, but it does not really offer an API.  It just says that the algorithm is "used to convert the password into a KEK."  It makes PBKDF2, which is specified in RFC 2898, the mandatory to implement algorithm, but I do not think it would be straightforward to specify the use of HKDF for this purpose.  (I am not sure there is a need to do this; PBKDF2 works just fine with modern hash functions.)

RFC 5912 (New ASN.1 Modules for the Public Key Infrastructure Using X.509 (PKIX)) introduced the KEY-DERIVATION class.  It does not nail down an API.  It couples the object identifier to a parameter structure for the KeyDerivationAlgorithmIdentifer.  RFC5912 uses PBKDF2 as an example, so there is no doubt that it was intended to support RFC 321.  I do not see anything to prevent the use of the KeyDerivationAlgorithmIdentifer with HDDF, X9.63, and many others.

RFC 5990 (Use of the RSA-KEM Key Transport Algorithm in the Cryptographic Message Syntax (CMS)) uses the ALGORITHM class, which is very similar to the KEY-DERIVATION class, for two KDFs, whch are defined in X9.44:

   KeyDerivationFunction ::= AlgorithmIdentifier {{KDFAlgorithms}}

Both of these KDFs would seem to fit well with this document.

> document with PBKDF1 as the KDF?

No.

> I don't even see where we could slot in
> flexible enough.  

Correct.  There is no place to input the CMSORIforPSKOtherInfo to be input.

> PBKDF2 allows a more-than-8-octet salt, but is that going

Yes, I think it would, but conventions would need to be specified for mapping the IKM and info inputs into the password input.  Simple concatenation would be okay I suspect.  (Again, I am not sure there is a need to do this.)

> behavior from the otherInput that we need in order for this scheme to work.

So, would text in Section 6 that says an acceptable KDF MUST accept IKM, L, and info inputs, and it MAY also accept salt and other inputs.

Russ

---

From: Benjamin Kaduk <[email-masked]>
Date: Fri, 23 Aug 2019 14:53:58 -0500

> Both of these KDFs would seem to fit well with this document.

Thanks for laying these out -- I was looking at RFCs 3211 and 5912 when
doing my review, and agree with your conclusions about 2631 and 5990 as
well.

> Yes, I think it would, but conventions would need to be specified for mapping the IKM and info inputs into the password input.  Simple concatenation would be okay I suspect.  (Again, I am not sure…

(I'm not sure there's a need, either.)

> So, would text in Section 6 that says an acceptable KDF MUST accept IKM, L, and info inputs, and it MAY also accept salt and other inputs.

I think that addresses the core of my concern, yes, and would be enough to
resolve the Discuss.  (Technically it doesn't really require that the info
input gets fully mixed in, but if anyone defines a KDF that does that, they
probably deserve what they get.)

Thanks,

Ben

---

From: Russ Housley <[email-masked]>
Date: Fri, 23 Aug 2019 16:02:20 -0400

> probably deserve what they get.)

I will add a sentence that all of the inputs MUST influence the output of the KDF.  I do not want to turn this into a how-to for KDF design...

Russ