Subject: Re: [jose] Open Issue: Multiple uses of the Concat KDF with the same secret

From: Mike Jones <[email-masked]>
Date: Sat, 28 Jul 2012 01:01:47 +0000

He's quoting from the NIST spec in which Concat is defined below.  I realize that our usage is common practice and I suspect there's no actual problem with it, but given it violates the letter of the spec in which Concat is defined, I felt that I needed to at least bring the issue to the attention of the working group so that we can make an informed decision.

                                                            -- Mike

From: Jim Schaad [mailto:[email-masked]]
Sent: Friday, July 27, 2012 5:56 PM
To: Mike Jones; [email-masked]
Subject: RE: [jose] Open Issue: Multiple uses of the Concat KDF with the same secret

Where did he get this idea?  This is very common practice in many protocols

Jim

From: [email-masked]<mailto:[email-masked]> [mailto:[email-masked]]<mailto:[mailto:[email-masked]]> On Behalf Of Mike Jones
Sent: Friday, July 27, 2012 3:44 PM
To: [email-masked]<mailto:[email-masked]>
Subject: [jose] Open Issue: Multiple uses of the Concat KDF with the same secret

In conversations during this week's W3C WebCrypto F2F, Vijay Bharadwaj pointed out that using the same input secret to the Concat KDF twice, as we currently do in JWA 4.12 http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-04#page-16, is prohibited.  Rather than using two different labels with the same secret as TLS does (in our case "Encryption" and "Integrity"), we're supposed to generate enough key bits for both keys in one operation.

I'll add this to the set of Open Issues for us to discuss next week.  Looking forward to seeing many of you then!

                                                                -- Mike

P.S.  BTW, the W3C WebCrypto WG wants to closely coordinate with JOSE, in part, to ensure that the WebCrypto output - a set of JavaScript crypto APIs - will be a great way to build JOSE implementations.

From: Vijay Bharadwaj
Sent: Tuesday, July 24, 2012 8:52 PM
To: Mike Jones
Subject: Key derivation and FIPS

The restriction I was talking about is in Section 5.8 of SP 800-56A<http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf>:

An Approved key derivation function (KDF) shall be used to derive secret keying material from a shared secret. The output from a KDF shall only be used for secret keying material, such as a symmetric key used for data encryption or message integrity, a secret initialization vector, or a master key that will be used to generate other keys (possibly using a different process). Non- secret keying material (such as a non-secret initialization vector) shall not be generated using the shared secret.

Each call to the KDF requires a freshly computed shared secret, and this shared secret shall be zeroized immediately following its use. The derived secret keying material shall be computed in its entirety before outputting any portion of it. In schemes using only static keys, the freshly computed shared secret may be the same as the previous shared secret. In these cases, the initiator supplied nonce (NonceU, see Section 6.3) used in the scheme will vary so the same keying material is not regenerated.

The derived secret keying material may be parsed into one or more keys or other secret cryptographic keying material (for example, secret initialization vectors). If Key Confirmation (KC) or implementation validation testing are to be performed as specified in Section 8 or Section 5.2.3, respectively, then the MAC key shall be formed from the first bits of the KDF output and zeroized after its use (i.e., the MAC key shall not be used for purposes other than key confirmation or implementation validation testing).

So as you can see, NIST pretty clearly advocates for the "generate a bunch of bits and chop them up" approach. The first part is implemented in CNG by causing BCryptDeriveKey to wipe the supplied shared secret.

---

From: "Jim Schaad" <[email-masked]>
Date: Fri, 27 Jul 2012 18:13:12 -0700

I believe that he is in error unless you are doing something that I don't
understand.  My understanding of the current specification is you do the
following

KA_Secret = EC(my private, their public, other data)

CMK = KDF1(KA_Secret)

CEK = KDF2(CMK, string)

CIK = KDF2(CMK, string)

This clearly does not violate what is said in the document.  It states that
KDF1 must always have a new set of input not KDF2.

Jim

From: Mike Jones [mailto:[email-masked]] 
Sent: Friday, July 27, 2012 6:02 PM
To: Jim Schaad; [email-masked]
Subject: RE: [jose] Open Issue: Multiple uses of the Concat KDF with the
same secret

He's quoting from the NIST spec in which Concat is defined below.  I realize
that our usage is common practice and I suspect there's no actual problem
with it, but given it violates the letter of the spec in which Concat is
defined, I felt that I needed to at least bring the issue to the attention
of the working group so that we can make an informed decision.

                                                            -- Mike

From: Jim Schaad [mailto:[email-masked]] 
Sent: Friday, July 27, 2012 5:56 PM
To: Mike Jones; [email-masked]
Subject: RE: [jose] Open Issue: Multiple uses of the Concat KDF with the
same secret

Jim

From: [email-masked] [mailto:[email-masked]] On Behalf Of Mike
Jones
Sent: Friday, July 27, 2012 3:44 PM
To: [email-masked]
Subject: [jose] Open Issue: Multiple uses of the Concat KDF with the same
secret

In conversations during this week's W3C WebCrypto F2F, Vijay Bharadwaj
pointed out that using the same input secret to the Concat KDF twice, as we
currently do in JWA 4.12
http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-04#page-16,
is prohibited.  Rather than using two different labels with the same secret
as TLS does (in our case "Encryption" and "Integrity"), we're supposed to
generate enough key bits for both keys in one operation.

I'll add this to the set of Open Issues for us to discuss next week.
Looking forward to seeing many of you then!

                                                                -- Mike

P.S.  BTW, the W3C WebCrypto WG wants to closely coordinate with JOSE, in
part, to ensure that the WebCrypto output - a set of JavaScript crypto APIs
- will be a great way to build JOSE implementations.

From: Vijay Bharadwaj 

The restriction I was talking about is in Section 5.8 of SP 800-56A
<http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar0
8-2007.pdf> :

An Approved key derivation function (KDF) shall be used to derive secret
keying material from a shared secret. The output from a KDF shall only be
used for secret keying material, such as a symmetric key used for data
encryption or message integrity, a secret initialization vector, or a master
key that will be used to generate other keys (possibly using a different
process). Non- secret keying material (such as a non-secret initialization
vector) shall not be generated using the shared secret. 

Each call to the KDF requires a freshly computed shared secret, and this
shared secret shall be zeroized immediately following its use. The derived
secret keying material shall be computed in its entirety before outputting
any portion of it. In schemes using only static keys, the freshly computed
shared secret may be the same as the previous shared secret. In these cases,
the initiator supplied nonce (NonceU, see Section 6.3) used in the scheme
will vary so the same keying material is not regenerated. 

The derived secret keying material may be parsed into one or more keys or
other secret cryptographic keying material (for example, secret
initialization vectors). If Key Confirmation (KC) or implementation
validation testing are to be performed as specified in Section 8 or Section
5.2.3, respectively, then the MAC key shall be formed from the first bits of
the KDF output and zeroized after its use (i.e., the MAC key shall not be
used for purposes other than key confirmation or implementation validation
testing).

So as you can see, NIST pretty clearly advocates for the "generate a bunch
of bits and chop them up" approach. The first part is implemented in CNG by
causing BCryptDeriveKey to wipe the supplied shared secret.