Page MenuHome GnuPG

gnupg should use the KDFs implemented in libgcrypt
Open, NormalPublic

Description

For encryption using EC keys, the "Concatenation Key Derivation Function" is used, but it is implemented inside of the gnupg.

This KDF is quite trivial, but for certification purposes, we should keep it inside of the FIPS boundary of libgcrypt, especially given that this is a FIPS-certifiable KDF.

The current implementation in gnupg: https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=g10/ecdh.c;h=c3337d1dc616a4d5456fc3f9af6bb77eb6612f1c;hb=HEAD#l203

Details

Version
master

Event Timeline

werner triaged this task as Normal priority.May 5 2022, 8:39 AM
werner edited projects, added gnupg (gpg23); removed gnupg.
werner added a subscriber: werner.

When we implemented this first, Libgcrypt had no appropriate KDF support. I recall that I considered to change this but it turned out the for 2.2 the changes are too large. For 2.3 we will consider such a change.

At first, we need to add/enhance new API for KDF in libgcrypt. Currently, the term "KDF" in libgcrypt is used with narrower focus, that is, only for password->key KDF.

What we will support are:

  • ConcatKDF {Hash, HMAC} (NIST SP 800-56A)
  • HKDF (NIST SP 800-56C), extract+expand and expand-only-skiping-extract
  • Key Based KDF {HMAC, CMAC, KMAC} (NIST SP 800-108 rev.1 draft)

We would use gcry_kdf_open/gcry_kdf_final API, stretching the semantics a bit, but I wonder if it's good. Adding new API is better?

I learned that it's now called "OneStep KDF" in SP 800-56Cr2.
It's "SSKDF" in OpenSSL (Single Step KDF, perhaps).

For libgcrypt, if we use gcry_kdf_open/gcry_kdf_final API, minimum addition is:

In OpenSSL, it also supports two of hkdf variants: hkdf and tls13_hkdf.

Added HKDF implementation to master.

I am a bit confused about NIST inconsistency(?) for two-step KDF.

  • NIST SP 800-108r1-draft defines KDF in Feedback Mode (and others)
  • NIST SP 800-56C Revision 2 addresses RFC 5869 (of HKDF)
    • HKDF construction (extract-expand) is exactly same as the one in SP800-56C
    • But... HKDF uses different method in the expand step
      • In NIST SP 800-108r1, counter comes after K(i-1) and L is appended
      • In HKDF, counter comes at the end

It seems that implementations with HKDF can be certified as FIPS compliant. I don't know why.

FIPS 140-3 (https://csrc.nist.gov/Projects/cryptographic-module-validation-program/fips-140-3-standards) points to SP 800-140Dr1 (https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-140Dr1.pdf) to list acceptable "Security Parameter Generation and Establishment Methods". From this document, RFC 5869 (i.e., HKDF with the counter at the end) can be reached via two paths:

  1. In section "6.2.8 Protocol-Suite Key Derivation", SP 800-140Dr1 links to section 7.1 of RFC 8446 (https://datatracker.ietf.org/doc/html/rfc8446#section-7.1), which describes the TLS 1.3 key schedule, which uses HKDF as Extract-and-Expand KDF and points to RFC 5869 (https://datatracker.ietf.org/doc/html/rfc5869) as its definition. As a consequence, HKDF as defined by RFC 5869 (i.e., with the counter at the end) must be approved at least for use in TLS 1.3.
  2. Section "6.2.7 Key Agreement Key Derivation" of SP 800-140Dr1 references SP 800-56Cr2 (https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Cr2.pdf). At the end of section 5.1, this document explicitly states that NIST considers RFC 5869 an extraction-then-expansion KDF according to this document: "RFC 5869 specifies a version of the above extraction-then-expansion key-derivation procedure using HMAC for both the extraction and expansion steps."

As a consequence, I do not expect problems when attempting to certify HKDF as specified in RFC 5869.

Pushed the change, although it is not enabled yet (since the feature will be only available by newer libgcrypt, 1.11).

Let's schedule that for 2.6