Bug 2141695

Summary: In FIPS mode, openssl should reject KDF input and output key lengths < 112 bits or provide an indicator
Product: Red Hat Enterprise Linux 9 Reporter: Clemens Lang <cllang>
Component: opensslAssignee: Clemens Lang <cllang>
Status: CLOSED ERRATA QA Contact: Alicja Kario <hkario>
Severity: medium Docs Contact:
Priority: high    
Version: 9.0CC: cllang, dbelyavs, hkario, ssorce
Target Milestone: rcKeywords: Triaged, ZStream
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: openssl-3.0.7-2.el9 Doc Type: No Doc Update
Doc Text:
Story Points: ---
Clone Of:
: 2144019 2144020 (view as bug list) Environment:
Last Closed: 2023-05-09 08:20:47 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2144019, 2144020    
Attachments:
Description Flags
kdf.c
none
Updated reproducer that uses KBKDF and supports indicators none

Description Clemens Lang 2022-11-10 14:02:39 UTC
Description of problem:
According to NIST Special Publication 800-131Ar2, Section 8: Deriving Additional Keys from a Cryptographic Key, "[t]he length of the key-derivation key [i.e., the input key] shall be at least 112 bits". Additionally, for HMAC-based KDFs the document says: "The use of HMAC-based KDFs is acceptable using a hash function specified in FIPS 180 or FIPS 202 with a key whose length is at least 112 bits." This seems to refer to the output key length.

We should require lengths >= 112 bits for both key-derivation keys and derived keys and either reject shorter keys with an error message, or provide an explicit indicator that short keys are not FIPS-approved.

Version-Release number of selected component (if applicable):
3.0.1-43.el9_0

How reproducible:
Run the attached reproducer with values other than the permitted ones.

Steps to Reproduce:
1. cc -std=c99 -Wall -Werror -pedantic -D_XOPEN_SOURCE=600 -o kdf kdf.c -lcrypto
2. ./kdf sha256 16 $(( 112 / 8 )) $(( 112 / 8 )) (./kdf digest saltlen inkeylen outkeylen)

Actual results:
OK: 0x7afa9824958c5c1bcd6b7 (or some other derived key, salt and key-derivation key are randomly generated)

Expected results:
Failure because a short key was used.

See also https://bugzilla.redhat.com/show_bug.cgi?id=2136250, which imposes the same limit on HMAC keys.

Comment 1 Clemens Lang 2022-11-10 17:07:29 UTC
Created attachment 1923620 [details]
kdf.c

Comment 5 Clemens Lang 2022-11-17 14:33:29 UTC
Re-reading "The use of HMAC-based KDFs is acceptable using a hash function specified in FIPS 180 or FIPS 202 with a key whose length is at least 112 bits", this obviously refers to the length of the key used for HMAC, not the length of the derived secret.

Comment 6 Clemens Lang 2022-11-17 16:29:12 UTC
The attached reproducer tested HKDF, which is only approved for use in TLS anyway. The restriction in SP 800-131Ar2 section 8 refers to KDFs defined in SP 800-108, which OpenSSL calls "key-based KDFs" and implements in EVP_KDF-KB(7), see https://www.openssl.org/docs/man3.0/man7/EVP_KDF-KB.html.

I am attaching an updated reproducer that correctly uses KBKDF (in HMAC mode) and prints the indicator state, if supported. I verified that this correctly detects unapproved key lengths:

 $> $(head -n1 kdf.c | sed -E 's#^// ##g') && ./kdf sha256 16 $(( 112 / 8 )) $(( 112 / 8 ))
 OK (indicator: approved): 0xb7dfff7bf89bce1ecbb2eb979e
 $> $(head -n1 kdf.c | sed -E 's#^// ##g') && ./kdf sha256 16 $(( 112 / 8 - 1 )) $(( 112 / 8 ))
 OK (indicator: unapproved): 0x5e294ba2fd908be0c58fb8b86bb1

Note that testing with CMAC does not seem to be necessary, since CMAC requires a cipher that expects a fixed key length (e.g., 128 bits for AES-128 or 256 bits for AES-256).

Comment 7 Clemens Lang 2022-11-17 16:33:04 UTC
Created attachment 1925055 [details]
Updated reproducer that uses KBKDF and supports indicators

Comment 14 errata-xmlrpc 2023-05-09 08:20:47 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (Low: openssl security and bug fix update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2023:2523