diff --git a/doc/man1/openssl-dgst.pod.in b/doc/man1/openssl-dgst.pod.in index 5dcdbe548e6922..8a110829e61592 100644 --- a/doc/man1/openssl-dgst.pod.in +++ b/doc/man1/openssl-dgst.pod.in @@ -176,12 +176,14 @@ Following options are supported by both by B and B: 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:I 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 diff --git a/doc/man1/openssl-kdf.pod.in b/doc/man1/openssl-kdf.pod.in index 6eed74d70d4c86..205bb5c49e311f 100644 --- a/doc/man1/openssl-kdf.pod.in +++ b/doc/man1/openssl-kdf.pod.in @@ -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: diff --git a/doc/man1/openssl-mac.pod.in b/doc/man1/openssl-mac.pod.in index 5d6008f002b3f8..955f6da169e722 100644 --- a/doc/man1/openssl-mac.pod.in +++ b/doc/man1/openssl-mac.pod.in @@ -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 BI 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 BI diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h index 611c6d531b1369..ee6c5cebc531a6 100644 --- a/providers/common/include/prov/securitycheck.h +++ b/providers/common/include/prov/securitycheck.h @@ -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 */ diff --git a/providers/common/securitycheck.c b/providers/common/securitycheck.c index 0d3acdbe56e2ff..65358931807bd3 100644 --- a/providers/common/securitycheck.c +++ b/providers/common/securitycheck.c @@ -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) { diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc index a637efe616264c..352e0ca92204f3 100644 --- a/providers/fips/self_test_data.inc +++ b/providers/fips/self_test_data.inc @@ -279,19 +279,19 @@ static const unsigned char hkdf_secret[] = { }; static const unsigned char hkdf_salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c + 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[] = { - 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, - 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, - 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, - 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, - 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, - 0x58, 0x65 + 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), diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c index e6855d57324041..3c41490d6caec9 100644 --- a/providers/implementations/kdfs/kbkdf.c +++ b/providers/implementations/kdfs/kbkdf.c @@ -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" @@ -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); diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c index c72c1e6c0fca81..63ee5d9a32753b 100644 --- a/providers/implementations/macs/hmac_prov.c +++ b/providers/implementations/macs/hmac_prov.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "internal/ssl3_cbc.h" @@ -27,6 +29,7 @@ #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 @@ -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 */ diff --git a/providers/implementations/macs/kmac_prov.c b/providers/implementations/macs/kmac_prov.c index 82cbb4c3879f09..965885700762ef 100644 --- a/providers/implementations/macs/kmac_prov.c +++ b/providers/implementations/macs/kmac_prov.c @@ -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 */ /* @@ -98,7 +100,6 @@ static OSSL_FUNC_mac_final_fn kmac_final; /* Maximum key size in bytes = 512 (4096 bits) */ #define KMAC_MAX_KEY 512 -#define KMAC_MIN_KEY 4 /* * Maximum Encoded Key size will be padded to a multiple of the blocksize @@ -251,7 +252,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(32, keylen * 8) || keylen > KMAC_MAX_KEY) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); return 0; }