Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FYI 3.3 backport] fips: enforce minimum MAC key length of 112 bits #24225

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/man1/openssl-dgst.pod.in
Expand Up @@ -176,12 +176,14 @@ Following options are supported by both by B<HMAC> and B<gost-mac>:
Specifies MAC key as alphanumeric string (use if key contain printable
characters only). String length must conform to any restrictions of
the MAC algorithm for example exactly 32 chars for gost-mac.
FIPS provider minimum key length is 14 characters (112 bits).

=item B<hexkey>:I<string>

Specifies MAC key in hexadecimal form (two hex digits per byte).
Key length must conform to any restrictions of the MAC algorithm
for example exactly 32 chars for gost-mac.
FIPS provider minimum key length is 28 hexadecimals (112 bits).

=back

Expand Down
8 changes: 4 additions & 4 deletions doc/man1/openssl-kdf.pod.in
Expand Up @@ -149,13 +149,13 @@ SSHKDF, X942KDF-ASN1, X942KDF-CONCAT, X963KDF and SCRYPT.

Use TLS1-PRF to create a hex-encoded derived key from a secret key and seed:

openssl kdf -keylen 16 -kdfopt digest:SHA2-256 -kdfopt key:secret \
-kdfopt seed:seed TLS1-PRF
openssl kdf -keylen 16 -kdfopt digest:SHA2-256 -kdfopt key:16charlongsecret \
-kdfopt seed:a16charslongseed TLS1-PRF

Use HKDF to create a hex-encoded derived key from a secret key, salt and info:

openssl kdf -keylen 10 -kdfopt digest:SHA2-256 -kdfopt key:secret \
-kdfopt salt:salt -kdfopt info:label HKDF
openssl kdf -keylen 10 -kdfopt digest:SHA2-256 -kdfopt key:16charlongsecret \
-kdfopt salt:a16charslongsalt -kdfopt info:label HKDF

Use SSKDF with KMAC to create a hex-encoded derived key from a secret key, salt and info:

Expand Down
2 changes: 2 additions & 0 deletions doc/man1/openssl-mac.pod.in
Expand Up @@ -72,12 +72,14 @@ Common parameter names used by EVP_MAC_CTX_get_params() are:
Specifies the MAC key as an alphanumeric string (use if the key contains
printable characters only).
The string length must conform to any restrictions of the MAC algorithm.
FIPS provider minimum key length is 14 characters (112 bits).
A key must be specified for every MAC algorithm.

=item B<hexkey:>I<string>

Specifies the MAC key in hexadecimal form (two hex digits per byte).
The key length must conform to any restrictions of the MAC algorithm.
FIPS provider minimum key length is 28 hexadecimals (112 bits).
A key must be specified for every MAC algorithm.

=item B<iv:>I<string>
Expand Down
1 change: 1 addition & 0 deletions providers/common/include/prov/securitycheck.h
Expand Up @@ -14,6 +14,7 @@ int ossl_rsa_check_key(OSSL_LIB_CTX *ctx, const RSA *rsa, int operation);
int ossl_ec_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect);
int ossl_dsa_check_key(OSSL_LIB_CTX *ctx, const DSA *dsa, int sign);
int ossl_dh_check_key(OSSL_LIB_CTX *ctx, const DH *dh);
int ossl_mac_check_key(size_t min, size_t requested);

int ossl_digest_is_allowed(OSSL_LIB_CTX *ctx, const EVP_MD *md);
/* With security check enabled it can return -1 to indicate disallowed md */
Expand Down
13 changes: 13 additions & 0 deletions providers/common/securitycheck.c
Expand Up @@ -232,6 +232,19 @@ int ossl_dh_check_key(OSSL_LIB_CTX *ctx, const DH *dh)
}
#endif /* OPENSSL_NO_DH */

/*
* Check for valid MAC key size
*
*/
int ossl_mac_check_key(size_t min, size_t requested)
{
#ifndef FIPS_MODULE
return (requested >= min);
#else
return (requested >= 112);
# endif
}

int ossl_digest_get_approved_nid_with_sha1(OSSL_LIB_CTX *ctx, const EVP_MD *md,
int sha1_allowed)
{
Expand Down
34 changes: 26 additions & 8 deletions providers/fips/self_test_data.inc
Expand Up @@ -267,21 +267,39 @@ static const ST_KAT_CIPHER st_kat_cipher_tests[] = {
};

static const char hkdf_digest[] = "SHA256";
static const unsigned char hkdf_secret[] = { 's', 'e', 'c', 'r', 'e', 't' };
static const unsigned char hkdf_salt[] = { 's', 'a', 'l', 't' };
static const unsigned char hkdf_info[] = { 'l', 'a', 'b', 'e', 'l' };

/*
* Input parameters and expected result are from RFC 5869 test case 1, which is
* with a key-derivation key >= 112 bits required by NIST SP 800-131Ar2
* section 8.
*/
static const unsigned char hkdf_secret[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
};
static const unsigned char hkdf_salt[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d
};
static const unsigned char hkdf_info[] = {
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9
};
static const unsigned char hkdf_expected[] = {
0xcb, 0x95, 0xd0, 0x56, 0xd6, 0xba, 0x6f, 0x08,
0x4d, 0xf0, 0xa0, 0x3a, 0x33, 0x17, 0xbc, 0xca,
0x7f, 0x83, 0x77, 0x32, 0x04, 0xb7, 0x6f, 0x52,
0x7f, 0x4f, 0x06, 0x73, 0x61, 0x68, 0xa5, 0x2b,
0xbc, 0xd8, 0x88, 0x69, 0xa3, 0xa4, 0xe7, 0x97,
0x2d, 0xcd
};
static const ST_KAT_PARAM hkdf_params[] = {
ST_KAT_PARAM_UTF8STRING(OSSL_KDF_PARAM_DIGEST, hkdf_digest),
ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_KEY, hkdf_secret),
ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_SALT, hkdf_salt),
ST_KAT_PARAM_OCTET(OSSL_KDF_PARAM_INFO, hkdf_info),
ST_KAT_PARAM_END()
};
static const unsigned char hkdf_expected[] = {
0x2a, 0xc4, 0x36, 0x9f, 0x52, 0x59, 0x96, 0xf8,
0xde, 0x13
};

static const char sskdf_digest[] = "SHA224";
static const unsigned char sskdf_secret[] = {
Expand Down
2 changes: 1 addition & 1 deletion providers/implementations/kdfs/hkdf.c
Expand Up @@ -623,7 +623,7 @@ static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx,
}
if (prevsecret == NULL) {
prevsecret = default_zeros;
prevsecretlen = 0;
prevsecretlen = mdlen;
} else {
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
unsigned char hash[EVP_MAX_MD_SIZE];
Expand Down
5 changes: 5 additions & 0 deletions providers/implementations/kdfs/kbkdf.c
Expand Up @@ -43,6 +43,7 @@
#include "prov/provider_ctx.h"
#include "prov/provider_util.h"
#include "prov/providercommon.h"
#include "prov/securitycheck.h"

#include "internal/e_os.h"
#include "internal/params.h"
Expand Down Expand Up @@ -289,6 +290,10 @@ static int kbkdf_derive(void *vctx, unsigned char *key, size_t keylen,
ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
return 0;
}
if (!ossl_mac_check_key(0, ctx->ki_len * 8)) {
ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL);
return 0;
}
/* Could either be missing MAC or missing message digest or missing
* cipher - arbitrarily, I pick this one. */
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MAC);
Expand Down
8 changes: 8 additions & 0 deletions providers/implementations/macs/hmac_prov.c
Expand Up @@ -20,13 +20,16 @@
#include <openssl/params.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/err.h>
#include <openssl/proverr.h>

#include "internal/ssl3_cbc.h"

#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "prov/provider_util.h"
#include "prov/providercommon.h"
#include "prov/securitycheck.h"

/*
* Forward declaration of everything implemented here. This is not strictly
Expand Down Expand Up @@ -144,6 +147,11 @@ static int hmac_setkey(struct hmac_data_st *macctx,
{
const EVP_MD *digest;

if (!ossl_mac_check_key(0, keylen * 8)) {
ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL);
return 0;
}

if (macctx->key != NULL)
OPENSSL_secure_clear_free(macctx->key, macctx->keylen);
/* Keep a copy of the key in case we need it for TLS HMAC */
Expand Down
4 changes: 3 additions & 1 deletion providers/implementations/macs/kmac_prov.c
Expand Up @@ -59,6 +59,8 @@
#include "prov/provider_ctx.h"
#include "prov/provider_util.h"
#include "prov/providercommon.h"
#include "prov/securitycheck.h"

#include "internal/cryptlib.h" /* ossl_assert */

/*
Expand Down Expand Up @@ -245,7 +247,7 @@ static int kmac_setkey(struct kmac_data_st *kctx, const unsigned char *key,
const EVP_MD *digest = ossl_prov_digest_md(&kctx->digest);
int w = EVP_MD_get_block_size(digest);

if (keylen < KMAC_MIN_KEY || keylen > KMAC_MAX_KEY) {
if (!ossl_mac_check_key(KMAC_MIN_KEY * 8, keylen * 8) || keylen > KMAC_MAX_KEY) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
return 0;
}
Expand Down
59 changes: 59 additions & 0 deletions test/recipes/30-test_evp_data/evpkdf_hkdf.txt
Expand Up @@ -13,20 +13,54 @@

Title = HKDF tests (from RFC5869 test vectors)

Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Output = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865

Availablein = fips
KDF = HKDF
Ctrl.digest = digest:SHA256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Output = 00
Result = KDF_DERIVE_ERROR

KDF = HKDF
Ctrl.digest = digest:SHA256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c0d
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Output = cb95d056d6ba6f084df0a03a3317bcca7f83773204b76f527f4f06736168a52bbcd88869a3a4e7972dcd

Availablein = default
KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c
Output = 077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5

Availablein = fips
KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c
Output = 00
Result = KDF_DERIVE_ERROR

KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c0d
Output = eaa7f10b41718cdf952bf2d49c827fce9a2236f4f63c39b411bcde7020814e0b

KDF = HKDF
Ctrl.mode = mode:EXPAND_ONLY
Ctrl.digest = digest:SHA256
Expand Down Expand Up @@ -55,13 +89,15 @@ Ctrl.IKM = hexkey:06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc2
Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
Output = b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87

Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA256
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = salt:
Ctrl.info = info:
Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8

Availablein = default
KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA256
Expand All @@ -77,20 +113,36 @@ Ctrl.IKM = hexkey:19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb
Ctrl.info = info:
Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8

Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896

KDF = HKDF
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c0d
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Output = b4431465d787c20e01f15b478ece60c23a2caab329ce270da3fc3910d8f59b866cc9342c176f387e8719

Availablein = default
KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c
Output = 9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243

KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = hexsalt:000102030405060708090a0b0c0d
Output = 016a4409c1282267121497f9d592d9af02756012

KDF = HKDF
Ctrl.mode = mode:EXPAND_ONLY
Ctrl.digest = digest:SHA1
Expand Down Expand Up @@ -119,13 +171,15 @@ Ctrl.IKM = hexkey:8adae09a2a307059478d309b26c4115a224cfaf6
Ctrl.info = hexinfo:b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
Output = 0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4

Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
Ctrl.salt = salt:
Ctrl.info = info:
Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918

Availablein = default
KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA1
Expand All @@ -140,13 +194,15 @@ Ctrl.IKM = hexkey:da8c8a73c7fa77288ec6f5e7c297786aa0d32d01
Ctrl.info = info:
Output = 0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918

Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
Ctrl.salt = salt:
Ctrl.info = info:
Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48

Availablein = default
KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA1
Expand Down Expand Up @@ -175,18 +231,21 @@ Ctrl.info = info:
Output = 00
Result = KDF_DERIVE_ERROR

Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
Ctrl.info = info:
Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48

Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
Ctrl.salt = salt:
Output = 2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48

Availablein = default
KDF = HKDF
Ctrl.mode = mode:EXTRACT_AND_EXPAND
Ctrl.digest = digest:SHA1
Expand Down