]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Restrict the length of key-derivation key used in KDFs
authorpohsingwu <pohsingwu@synology.com>
Sun, 2 Jun 2024 11:34:13 +0000 (19:34 +0800)
committerslontis <shane.lontis@oracle.com>
Thu, 1 Aug 2024 06:47:12 +0000 (16:47 +1000)
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/23900)

24 files changed:
apps/fipsinstall.c
doc/man1/openssl-fipsinstall.pod.in
doc/man7/EVP_KDF-HKDF.pod
doc/man7/EVP_KDF-SS.pod
doc/man7/EVP_KDF-SSHKDF.pod
doc/man7/EVP_KDF-TLS13_KDF.pod
doc/man7/EVP_KDF-TLS1_PRF.pod
doc/man7/EVP_KDF-X963.pod
include/openssl/fips_names.h
providers/common/include/prov/fipscommon.h
providers/common/include/prov/securitycheck.h
providers/common/securitycheck.c
providers/fips/fipsprov.c
providers/implementations/kdfs/hkdf.c
providers/implementations/kdfs/sshkdf.c
providers/implementations/kdfs/sskdf.c
providers/implementations/kdfs/tls1_prf.c
ssl/quic/quic_record_util.c
test/recipes/30-test_evp_data/evpkdf_hkdf.txt
test/recipes/30-test_evp_data/evpkdf_ss.txt
test/recipes/30-test_evp_data/evpkdf_tls12_prf.txt
test/recipes/30-test_evp_data/evppkey_kdf_hkdf.txt
util/mk-fipsmodule-cnf.pl
util/perl/OpenSSL/paramnames.pm

index 4f54158d43232ac6c83d2f5bd4f29740084f2b79..caa0f39b8d85030dc94a758349545b985ef02077 100644 (file)
@@ -49,6 +49,12 @@ typedef enum OPTION_choice {
     OPT_X963KDF_DIGEST_CHECK,
     OPT_DISALLOW_DSA_SIGN,
     OPT_DISALLOW_TDES_ENCRYPT,
+    OPT_HKDF_KEY_CHECK,
+    OPT_TLS13_KDF_KEY_CHECK,
+    OPT_TLS1_PRF_KEY_CHECK,
+    OPT_SSHKDF_KEY_CHECK,
+    OPT_SSKDF_KEY_CHECK,
+    OPT_X963KDF_KEY_CHECK,
     OPT_SELF_TEST_ONLOAD, OPT_SELF_TEST_ONINSTALL
 } OPTION_CHOICE;
 
@@ -94,6 +100,18 @@ const OPTIONS fipsinstall_options[] = {
      "Disallow Triple-DES encryption"},
     {"rsa_sign_x931_disabled", OPT_DISALLOW_SIGNATURE_X931_PADDING, '-',
      "Disallow X931 Padding for RSA signing"},
+    {"hkdf_key_check", OPT_HKDF_KEY_CHECK, '-',
+     "Enable key check for HKDF"},
+    {"tls13_kdf_key_check", OPT_TLS13_KDF_KEY_CHECK, '-',
+     "Enable key check for TLS13-KDF"},
+    {"tls1_prf_key_check", OPT_TLS1_PRF_KEY_CHECK, '-',
+     "Enable key check for TLS1-PRF"},
+    {"sshkdf_key_check", OPT_SSHKDF_KEY_CHECK, '-',
+     "Enable key check for SSHKDF"},
+    {"sskdf_key_check", OPT_SSKDF_KEY_CHECK, '-',
+     "Enable key check for SSKDF"},
+    {"x963kdf_key_check", OPT_X963KDF_KEY_CHECK, '-',
+     "Enable key check for X963KDF"},
     OPT_SECTION("Input"),
     {"in", OPT_IN, '<', "Input config file, used when verifying"},
 
@@ -126,6 +144,12 @@ typedef struct {
     unsigned int dsa_sign_disabled : 1;
     unsigned int tdes_encrypt_disabled : 1;
     unsigned int sign_x931_padding_disabled : 1;
+    unsigned int hkdf_key_check : 1;
+    unsigned int tls13_kdf_key_check : 1;
+    unsigned int tls1_prf_key_check : 1;
+    unsigned int sshkdf_key_check : 1;
+    unsigned int sskdf_key_check : 1;
+    unsigned int x963kdf_key_check : 1;
 } FIPS_OPTS;
 
 /* Pedantic FIPS compliance */
@@ -145,6 +169,12 @@ static const FIPS_OPTS pedantic_opts = {
     1,      /* dsa_sign_disabled */
     1,      /* tdes_encrypt_disabled */
     1,      /* sign_x931_padding_disabled */
+    1,      /* hkdf_key_check */
+    1,      /* tls13_kdf_key_check */
+    1,      /* tls1_prf_key_check */
+    1,      /* sshkdf_key_check */
+    1,      /* sskdf_key_check */
+    1,      /* x963kdf_key_check */
 };
 
 /* Default FIPS settings for backward compatibility */
@@ -164,6 +194,12 @@ static FIPS_OPTS fips_opts = {
     0,      /* dsa_sign_disabled */
     0,      /* tdes_encrypt_disabled */
     0,      /* sign_x931_padding_disabled */
+    0,      /* hkdf_key_check */
+    0,      /* tls13_kdf_key_check */
+    0,      /* tls1_prf_key_check */
+    0,      /* sshkdf_key_check */
+    0,      /* sskdf_key_check */
+    0,      /* x963kdf_key_check */
 };
 
 static int check_non_pedantic_fips(int pedantic, const char *name)
@@ -312,6 +348,19 @@ static int write_config_fips_section(BIO *out, const char *section,
         || BIO_printf(out, "%s = %s\n",
                       OSSL_PROV_FIPS_PARAM_RSA_SIGN_X931_PAD_DISABLED,
                       opts->sign_x931_padding_disabled ? "1" : "0") <= 0
+        || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_HKDF_KEY_CHECK,
+                      opts->hkdf_key_check ? "1": "0") <= 0
+        || BIO_printf(out, "%s = %s\n",
+                      OSSL_PROV_FIPS_PARAM_TLS13_KDF_KEY_CHECK,
+                      opts->tls13_kdf_key_check ? "1": "0") <= 0
+        || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_TLS1_PRF_KEY_CHECK,
+                      opts->tls1_prf_key_check ? "1": "0") <= 0
+        || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SSHKDF_KEY_CHECK,
+                      opts->sshkdf_key_check ? "1": "0") <= 0
+        || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SSKDF_KEY_CHECK,
+                      opts->sskdf_key_check ? "1": "0") <= 0
+        || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_X963KDF_KEY_CHECK,
+                      opts->x963kdf_key_check ? "1": "0") <= 0
         || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
                       module_mac_len))
         goto end;
@@ -528,6 +577,24 @@ int fipsinstall_main(int argc, char **argv)
         case OPT_DISALLOW_SIGNATURE_X931_PADDING:
             fips_opts.sign_x931_padding_disabled = 1;
             break;
+        case OPT_HKDF_KEY_CHECK:
+            fips_opts.hkdf_key_check = 1;
+            break;
+        case OPT_TLS13_KDF_KEY_CHECK:
+            fips_opts.tls13_kdf_key_check = 1;
+            break;
+        case OPT_TLS1_PRF_KEY_CHECK:
+            fips_opts.tls1_prf_key_check = 1;
+            break;
+        case OPT_SSHKDF_KEY_CHECK:
+            fips_opts.sshkdf_key_check = 1;
+            break;
+        case OPT_SSKDF_KEY_CHECK:
+            fips_opts.sskdf_key_check = 1;
+            break;
+        case OPT_X963KDF_KEY_CHECK:
+            fips_opts.x963kdf_key_check = 1;
+            break;
         case OPT_QUIET:
             quiet = 1;
             /* FALLTHROUGH */
index e1eddf8ed6b9b62fafc9ba97a802e6e4a40255eb..f5b36e58ecfb4d58e6004ef8dfda99db2531f3c7 100644 (file)
@@ -34,6 +34,12 @@ B<openssl fipsinstall>
 [B<-no_short_mac>]
 [B<-tdes_encrypt_disabled>]
 [B<-rsa_sign_x931_disabled>]
+[B<-hkdf_key_check>]
+[B<-tls13_kdf_key_check>]
+[B<-tls1_prf_key_check>]
+[B<-sshkdf_key_check>]
+[B<-sskdf_key_check>]
+[B<-x963kdf_key_check>]
 [B<-self_test_onload>]
 [B<-self_test_oninstall>]
 [B<-corrupt_desc> I<selftest_description>]
@@ -257,6 +263,42 @@ See SP800-131Ar2 for details.
 Configure the module to not allow X9.31 padding be used when signing with RSA.
 See FIPS 140-3 IG C.K for details.
 
+=item B<-hkdf_key_check>
+
+Configure the module to enable a run-time short key-derivation key check when
+deriving a key by HKDF.
+See NIST SP 800-131Ar2 for details.
+
+=item B<-tls13_kdf_key_check>
+
+Configure the module to enable a run-time short key-derivation key check when
+deriving a key by TLS13 KDF.
+See NIST SP 800-131Ar2 for details.
+
+=item B<-tls1_prf_key_check>
+
+Configure the module to enable a run-time short key-derivation key check when
+deriving a key by TLS_PRF.
+See NIST SP 800-131Ar2 for details.
+
+=item B<-sshkdf_key_check>
+
+Configure the module to enable a run-time short key-derivation key check when
+deriving a key by SSHKDF.
+See NIST SP 800-131Ar2 for details.
+
+=item B<-sskdf_key_check>
+
+Configure the module to enable a run-time short key-derivation key check when
+deriving a key by SSKDF.
+See NIST SP 800-131Ar2 for details.
+
+=item B<-x963kdf_key_check>
+
+Configure the module to enable a run-time short key-derivation key check when
+deriving a key by X963KDF.
+See NIST SP 800-131Ar2 for details.
+
 =item B<-self_test_onload>
 
 Do not write the two fields related to the "test status indicator" and
index 5fc0a73241cca4bafb4b22a5abcb91dff5060048..54141c8065379541232a4ea45c5b7b26895df323 100644 (file)
@@ -80,6 +80,22 @@ an error will occur.
 
 =back
 
+=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
+
+A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
+This may be used after calling EVP_KDF_derive. It returns 0 if any "***-check"
+related parameter is set to 0 and the check fails.
+This option is used by the OpenSSL FIPS provider.
+
+=item "key-check" (B<OSSL_KDF_PARAM_FIPS_KEY_CHECK>) <integer>
+
+The default value of 1 causes an error during EVP_KDF_derive() if the length of
+used key-derivation key (B<OSSL_KDF_PARAM_KEY>) is shorter than 112 bits.
+Setting this to zero will ignore the error and set the approved
+"fips-indicator" to 0.
+This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
+set to 0.
+
 =back
 
 =head1 NOTES
index c8d19691a797b86fd11ecb9e89351e2606eeb28f..9a2b7c776cfcc9dbc8b7941ddff259495fe5f765 100644 (file)
@@ -61,6 +61,22 @@ This parameter set the shared secret that is used for key derivation.
 
 This parameter sets an optional value for fixedinfo, also known as otherinfo.
 
+=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
+
+A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
+This may be used after calling EVP_KDF_derive. It returns 0 if any "***-check"
+related parameter is set to 0 and the check fails.
+This option is used by the OpenSSL FIPS provider.
+
+=item "key-check" (B<OSSL_KDF_PARAM_FIPS_KEY_CHECK>) <integer>
+
+The default value of 1 causes an error during EVP_KDF_derive() if the length of
+used key-derivation key (B<OSSL_KDF_PARAM_KEY>) is shorter than 112 bits.
+Setting this to zero will ignore the error and set the approved
+"fips-indicator" to 0.
+This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
+set to 0.
+
 =back
 
 =head1 NOTES
index 3b5994e967401ee2bd4e7bba5ada373aea555ff9..1d0daf95b1405b8bd112987e82dd243f5c2843ac 100644 (file)
@@ -80,14 +80,14 @@ A single char of value 70 (ASCII char 'F').
 
 =back
 
-=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <int>
+=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
 
 A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
 This may be used after calling EVP_KDF_derive. It returns 0 if any "***-check"
 related parameter is set to 0 and the check fails.
 This option is used by the OpenSSL FIPS provider.
 
-=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
+=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <integer>
 
 The default value of 1 causes an error during EVP_KDF_derive() if
 used digest is not approved.
@@ -99,6 +99,15 @@ set to 0.
 According to SP 800-135r1, the following are approved digest algorithms: SHA-1,
 SHA2-224, SHA2-256, SHA2-384, SHA2-512.
 
+=item "key-check" (B<OSSL_KDF_PARAM_FIPS_KEY_CHECK>) <integer>
+
+The default value of 1 causes an error during EVP_KDF_derive() if the length of
+used key-derivation key (B<OSSL_KDF_PARAM_KEY>) is shorter than 112 bits.
+Setting this to zero will ignore the error and set the approved
+"fips-indicator" to 0.
+This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
+set to 0.
+
 =back
 
 =head1 NOTES
index 2dd32d33d49c9215242248e6fbee5837d7f2dd10..dd706e6b16fa3209c1f201cf559fb1b5b7bcba5e 100644 (file)
@@ -54,14 +54,14 @@ Refer to RFC 8446 section 7.1 "Key Schedule" for details.
 This parameter sets the mode for the TLS 1.3 KDF operation.
 There are two modes that are currently defined:
 
-=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <int>
+=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
 
 A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
 This may be used after calling EVP_KDF_derive. It returns 0 if any "***-check"
 related parameter is set to 0 and the check fails.
 This option is used by the OpenSSL FIPS provider.
 
-=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
+=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <integer>
 
 The default value of 1 causes an error during EVP_KDF_derive() if
 used digest is not approved.
@@ -73,6 +73,15 @@ set to 0.
 According to RFC 8446, the following are approved digest algorithms: SHA2-256,
 SHA2-384.
 
+=item "key-check" (B<OSSL_KDF_PARAM_FIPS_KEY_CHECK>) <integer>
+
+The default value of 1 causes an error during EVP_KDF_derive() if the length of
+used key-derivation key (B<OSSL_KDF_PARAM_KEY>) is shorter than 112 bits.
+Setting this to zero will ignore the error and set the approved
+"fips-indicator" to 0.
+This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
+set to 0.
+
 =over 4
 
 =item "EXTRACT_ONLY" or B<EVP_KDF_HKDF_MODE_EXTRACT_ONLY>
index 224340a624f2da2a8e06fff56a511f71119e9645..b09002b08a711833182a2dfec709b04493c44236 100644 (file)
@@ -59,7 +59,7 @@ will ignore the error and set the approved "fips-indicator" to 0.
 This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
 set to 0.
 
-=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <int>
+=item "digest-check" (B<OSSL_KDF_PARAM_FIPS_DIGEST_CHECK>) <integer>
 
 The default value of 1 causes an error during EVP_KDF_derive() if
 used digest is not approved.
@@ -71,6 +71,15 @@ set to 0.
 According to SP 800-135r1, the following are approved digest algorithms:
 SHA2-256, SHA2-384, SHA2-512.
 
+=item "key-check" (B<OSSL_KDF_PARAM_FIPS_KEY_CHECK>) <integer>
+
+The default value of 1 causes an error during EVP_KDF_derive() if the length of
+used key-derivation key (B<OSSL_KDF_PARAM_SECRET>) is shorter than 112 bits.
+Setting this to zero will ignore the error and set the approved
+"fips-indicator" to 0.
+This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
+set to 0.
+
 =back
 
 =head1 NOTES
index c6d4c66ef3c9eb1c91d66d8d26fc2e504ed4ed99..f7616ae260882c04ca2f2feadc1b4a9fc115c59b 100644 (file)
@@ -36,7 +36,7 @@ This parameter sets the secret.
 
 This parameter specifies an optional value for shared info.
 
-=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <int>
+=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
 
 A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
 This may be used after calling EVP_KDF_derive. It returns 0 if any "***-check"
@@ -56,6 +56,15 @@ According to ANSI X9.63-2001, the following are approved digest algorithms:
 SHA2-224, SHA2-256, SHA2-384, SHA2-512, SHA2-512/224, SHA2-512/256, SHA3-224,
 SHA3-256, SHA3-384, SHA3-512.
 
+=item "key-check" (B<OSSL_KDF_PARAM_FIPS_KEY_CHECK>) <integer>
+
+The default value of 1 causes an error during EVP_KDF_derive() if the length of
+used key-derivation key (B<OSSL_KDF_PARAM_KEY>) is shorter than 112 bits.
+Setting this to zero will ignore the error and set the approved
+"fips-indicator" to 0.
+This option is used by the OpenSSL FIPS provider, and breaks FIPS compliance if
+set to 0.
+
 =back
 
 =head1 NOTES
index 224fe24ed1a47e15381b8979f51855730b3cc294..730082014b1c9d907d9d7bbd33a346032f021590 100644 (file)
@@ -150,6 +150,54 @@ extern "C" {
  */
 # define OSSL_PROV_FIPS_PARAM_RSA_SIGN_X931_PAD_DISABLED "rsa-sign-x931-pad-disabled"
 
+/*
+ * A boolean that determines if the runtime FIPS key check for HKDF is
+ * performed.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_HKDF_KEY_CHECK "hkdf-key-check"
+
+/*
+ * A boolean that determines if the runtime FIPS key check for TLS13 KDF is
+ * performed.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_TLS13_KDF_KEY_CHECK "tls13-kdf-key-check"
+
+/*
+ * A boolean that determines if the runtime FIPS key check for TLS1_PRF is
+ * performed.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_TLS1_PRF_KEY_CHECK "tls1-prf-key-check"
+
+/*
+ * A boolean that determines if the runtime FIPS key check for SSHKDF is
+ * performed.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_SSHKDF_KEY_CHECK "sshkdf-key-check"
+
+/*
+ * A boolean that determines if the runtime FIPS key check for SSKDF is
+ * performed.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_SSKDF_KEY_CHECK "sskdf-key-check"
+
+/*
+ * A boolean that determines if the runtime FIPS key check for X963KDF is
+ * performed.
+ * This is disabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_X963KDF_KEY_CHECK "x963kdf-key-check"
+
 # ifdef __cplusplus
 }
 # endif
index d1f5d8879f21a3ea1abc7b087865d1987e677e78..7b99bce5d6af407e631123b385a0a52f1ea4647f 100644 (file)
@@ -23,5 +23,11 @@ int FIPS_x963kdf_digest_check(OSSL_LIB_CTX *libctx);
 int FIPS_dsa_sign_check(OSSL_LIB_CTX *libctx);
 int FIPS_tdes_encrypt_check(OSSL_LIB_CTX *libctx);
 int FIPS_rsa_sign_x931_disallowed(OSSL_LIB_CTX *libctx);
+int FIPS_hkdf_key_check(OSSL_LIB_CTX *libctx);
+int FIPS_tls13_kdf_key_check(OSSL_LIB_CTX *libctx);
+int FIPS_tls1_prf_key_check(OSSL_LIB_CTX *libctx);
+int FIPS_sshkdf_key_check(OSSL_LIB_CTX *libctx);
+int FIPS_sskdf_key_check(OSSL_LIB_CTX *libctx);
+int FIPS_x963kdf_key_check(OSSL_LIB_CTX *libctx);
 
 #endif
index 860fcaeca45262be43bfa1c1906f7d3c0b3f31f9..a9cb3c570db3b5b227071e3569e6b33d1bd8b30e 100644 (file)
@@ -17,6 +17,7 @@
 /* Functions that are common */
 int ossl_rsa_key_op_get_protect(const RSA *rsa, int operation, int *outprotect);
 int ossl_rsa_check_key_size(const RSA *rsa, int protect);
+int ossl_kdf_check_key_size(size_t keylen);
 
 #ifndef OPENSSL_NO_EC
 int ossl_ec_check_curve_allowed(const EC_GROUP *group);
index e8e1c2400a5a6981b6fa466effc9d07e96c5e123..47e10c673cb793065501bb5126ab33c1735671e3 100644 (file)
@@ -70,6 +70,15 @@ int ossl_rsa_check_key_size(const RSA *rsa, int protect)
     return 1;
 }
 
+/*
+ * FIPS requires a minimum security strength of 112 bits for key-derivation key.
+ * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf.
+ */
+int ossl_kdf_check_key_size(size_t keylen)
+{
+    return (keylen * 8) >= 112;
+}
+
 #ifndef OPENSSL_NO_EC
 
 int ossl_ec_check_curve_allowed(const EC_GROUP *group)
index a0445ee499da1adf5ff0a0a248f3a9c6a2c63f65..f27527607d00b6a93fc688c54cc4d8c338dc5f65 100644 (file)
@@ -98,6 +98,12 @@ typedef struct fips_global_st {
     FIPS_OPTION fips_dsa_sign_disallowed;
     FIPS_OPTION fips_tdes_encrypt_disallowed;
     FIPS_OPTION fips_rsa_sign_x931_disallowed;
+    FIPS_OPTION fips_hkdf_key_check;
+    FIPS_OPTION fips_tls13_kdf_key_check;
+    FIPS_OPTION fips_tls1_prf_key_check;
+    FIPS_OPTION fips_sshkdf_key_check;
+    FIPS_OPTION fips_sskdf_key_check;
+    FIPS_OPTION fips_x963kdf_key_check;
 } FIPS_GLOBAL;
 
 static void init_fips_option(FIPS_OPTION *opt, int enabled)
@@ -125,6 +131,12 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
     init_fips_option(&fgbl->fips_dsa_sign_disallowed, 0);
     init_fips_option(&fgbl->fips_tdes_encrypt_disallowed, 0);
     init_fips_option(&fgbl->fips_rsa_sign_x931_disallowed, 0);
+    init_fips_option(&fgbl->fips_hkdf_key_check, 0);
+    init_fips_option(&fgbl->fips_tls13_kdf_key_check, 0);
+    init_fips_option(&fgbl->fips_tls1_prf_key_check, 0);
+    init_fips_option(&fgbl->fips_sshkdf_key_check, 0);
+    init_fips_option(&fgbl->fips_sskdf_key_check, 0);
+    init_fips_option(&fgbl->fips_x963kdf_key_check, 0);
     return fgbl;
 }
 
@@ -161,6 +173,18 @@ static const OSSL_PARAM fips_param_types[] = {
                     NULL, 0),
     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED,
                     OSSL_PARAM_INTEGER, NULL, 0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_HKDF_KEY_CHECK, OSSL_PARAM_INTEGER, NULL,
+                    0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK, OSSL_PARAM_INTEGER,
+                    NULL, 0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK, OSSL_PARAM_INTEGER,
+                    NULL, 0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SSHKDF_KEY_CHECK, OSSL_PARAM_INTEGER, NULL,
+                    0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SSKDF_KEY_CHECK, OSSL_PARAM_INTEGER, NULL,
+                    0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_X963KDF_KEY_CHECK, OSSL_PARAM_INTEGER, NULL,
+                    0),
     OSSL_PARAM_END
 };
 
@@ -174,7 +198,7 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
     * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS and
     * OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK are not self test parameters.
     */
-    OSSL_PARAM core_params[20], *p = core_params;
+    OSSL_PARAM core_params[26], *p = core_params;
 
     *p++ = OSSL_PARAM_construct_utf8_ptr(
             OSSL_PROV_PARAM_CORE_MODULE_FILENAME,
@@ -233,6 +257,18 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
                         fips_tdes_encrypt_disallowed);
     FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_RSA_SIGN_X931_PAD_DISABLED,
                         fips_rsa_sign_x931_disallowed);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_HKDF_KEY_CHECK,
+                        fips_hkdf_key_check);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS13_KDF_KEY_CHECK,
+                        fips_tls13_kdf_key_check);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS1_PRF_KEY_CHECK,
+                        fips_tls1_prf_key_check);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_SSHKDF_KEY_CHECK,
+                        fips_sshkdf_key_check);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_SSKDF_KEY_CHECK,
+                        fips_sskdf_key_check);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_X963KDF_KEY_CHECK,
+                        fips_x963kdf_key_check);
 #undef FIPS_FEATURE_OPTION
 
     *p = OSSL_PARAM_construct_end();
@@ -300,6 +336,18 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
                      fips_tdes_encrypt_disallowed);
     FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED,
                      fips_rsa_sign_x931_disallowed);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_HKDF_KEY_CHECK,
+                     fips_hkdf_key_check);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK,
+                     fips_tls13_kdf_key_check);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK,
+                     fips_tls1_prf_key_check);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_SSHKDF_KEY_CHECK,
+                     fips_sshkdf_key_check);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_SSKDF_KEY_CHECK,
+                     fips_sskdf_key_check);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_X963KDF_KEY_CHECK,
+                     fips_x963kdf_key_check);
 #undef FIPS_FEATURE_GET
     return 1;
 }
@@ -844,6 +892,12 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
     FIPS_SET_OPTION(fgbl, fips_dsa_sign_disallowed);
     FIPS_SET_OPTION(fgbl, fips_tdes_encrypt_disallowed);
     FIPS_SET_OPTION(fgbl, fips_rsa_sign_x931_disallowed);
+    FIPS_SET_OPTION(fgbl, fips_hkdf_key_check);
+    FIPS_SET_OPTION(fgbl, fips_tls13_kdf_key_check);
+    FIPS_SET_OPTION(fgbl, fips_tls1_prf_key_check);
+    FIPS_SET_OPTION(fgbl, fips_sshkdf_key_check);
+    FIPS_SET_OPTION(fgbl, fips_sskdf_key_check);
+    FIPS_SET_OPTION(fgbl, fips_x963kdf_key_check);
 #undef FIPS_SET_OPTION
 
     ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers);
@@ -1056,6 +1110,12 @@ FIPS_FEATURE_CHECK(FIPS_dsa_sign_check, fips_dsa_sign_disallowed)
 FIPS_FEATURE_CHECK(FIPS_tdes_encrypt_check, fips_tdes_encrypt_disallowed)
 FIPS_FEATURE_CHECK(FIPS_rsa_sign_x931_disallowed,
                    fips_rsa_sign_x931_disallowed)
+FIPS_FEATURE_CHECK(FIPS_hkdf_key_check, fips_hkdf_key_check)
+FIPS_FEATURE_CHECK(FIPS_tls13_kdf_key_check, fips_tls13_kdf_key_check)
+FIPS_FEATURE_CHECK(FIPS_tls1_prf_key_check, fips_tls1_prf_key_check)
+FIPS_FEATURE_CHECK(FIPS_sshkdf_key_check, fips_sshkdf_key_check)
+FIPS_FEATURE_CHECK(FIPS_sskdf_key_check, fips_sskdf_key_check)
+FIPS_FEATURE_CHECK(FIPS_x963kdf_key_check, fips_x963kdf_key_check)
 
 #undef FIPS_FEATURE_CHECK
 
index 1efd1102bc1725d75abc012555a3ac5dbf37bb72..35276d81014335915b5173067a346c01cb397200 100644 (file)
@@ -194,6 +194,24 @@ static size_t kdf_hkdf_size(KDF_HKDF *ctx)
     return sz;
 }
 
+#ifdef FIPS_MODULE
+static int fips_hkdf_key_check_passed(KDF_HKDF *ctx)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    int key_approved = ossl_kdf_check_key_size(ctx->key_len);
+
+    if (!key_approved) {
+        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
+                                         libctx, "HKDF", "Key size",
+                                         FIPS_hkdf_key_check)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+    return 1;
+}
+#endif
+
 static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
                            const OSSL_PARAM params[])
 {
@@ -218,6 +236,11 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen,
         return 0;
     }
 
+#ifdef FIPS_MODULE
+    if (!fips_hkdf_key_check_passed(ctx))
+        return 0;
+#endif
+
     switch (ctx->mode) {
     case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
     default:
@@ -310,6 +333,10 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     if (params == NULL)
         return 1;
 
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
+                                     OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+        return 0;
+
     if (!hkdf_common_set_ctx_params(ctx, params))
         return 0;
 
@@ -327,6 +354,7 @@ static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx,
     static const OSSL_PARAM known_settable_ctx_params[] = {
         HKDF_COMMON_SETTABLES,
         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
         OSSL_PARAM_END
     };
     return known_settable_ctx_params;
@@ -368,6 +396,9 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
     if (!hkdf_common_get_ctx_params(ctx, params))
         return 0;
 
+    if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+        return 0;
+
     return 1;
 }
 
@@ -376,6 +407,7 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
 {
     static const OSSL_PARAM known_gettable_ctx_params[] = {
         HKDF_COMMON_GETTABLES,
+        OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
         OSSL_PARAM_END
     };
     return known_gettable_ctx_params;
@@ -730,6 +762,42 @@ static int fips_tls1_3_digest_check_passed(KDF_HKDF *ctx, const EVP_MD *md)
     }
     return 1;
 }
+
+/*
+ * Calculate the correct length of the secret key.
+ *
+ * RFC 8446:
+ *   If a given secret is not available, then the 0-value consisting of a
+ *   string of Hash.length bytes set to zeros is used.
+ */
+static size_t fips_tls1_3_key_size(KDF_HKDF *ctx)
+{
+    const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
+    size_t key_size = 0;
+
+    if (ctx->key != NULL)
+        key_size = ctx->key_len;
+    else if (md != NULL)
+        key_size = EVP_MD_size(md);
+
+    return key_size;
+}
+
+static int fips_tls1_3_key_check_passed(KDF_HKDF *ctx)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    int key_approved = ossl_kdf_check_key_size(fips_tls1_3_key_size(ctx));
+
+    if (!key_approved) {
+        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
+                                         libctx, "TLS13 KDF", "Key size",
+                                         FIPS_tls13_kdf_key_check)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+    return 1;
+}
 #endif
 
 static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,
@@ -747,6 +815,11 @@ static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen,
         return 0;
     }
 
+#ifdef FIPS_MODULE
+    if (!fips_tls1_3_key_check_passed(ctx))
+        return 0;
+#endif
+
     switch (ctx->mode) {
     default:
         return 0;
@@ -780,6 +853,9 @@ static int kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
                                      OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
         return 0;
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
+                                     OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+        return 0;
 
     if (!hkdf_common_set_ctx_params(ctx, params))
         return 0;
@@ -833,6 +909,7 @@ static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx,
         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL, NULL, 0),
         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_DATA, NULL, 0),
         OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
         OSSL_PARAM_END
     };
     return known_settable_ctx_params;
index d26047bee87704e8762f93ee713f75a4ba8cbbdb..c4e4971992928f6854dfbbe7246dd775a5be731f 100644 (file)
@@ -153,6 +153,22 @@ static int fips_digest_check_passed(KDF_SSHKDF *ctx, const EVP_MD *md)
     }
     return 1;
 }
+
+static int fips_key_check_passed(KDF_SSHKDF *ctx)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    int key_approved = ossl_kdf_check_key_size(ctx->key_len);
+
+    if (!key_approved) {
+        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
+                                         libctx, "SSHKDF", "Key size",
+                                         FIPS_sshkdf_key_check)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+    return 1;
+}
 #endif
 
 static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen,
@@ -186,6 +202,11 @@ static int kdf_sshkdf_derive(void *vctx, unsigned char *key, size_t keylen,
         return 0;
     }
 
+#ifdef FIPS_MODULE
+    if (!fips_key_check_passed(ctx))
+        return 0;
+#endif
+
     return SSHKDF(md, ctx->key, ctx->key_len,
                   ctx->xcghash, ctx->xcghash_len,
                   ctx->session_id, ctx->session_id_len,
@@ -204,6 +225,9 @@ static int kdf_sshkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
                                      OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
         return 0;
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
+                                     OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+        return 0;
 
     if (OSSL_PARAM_locate_const(params, OSSL_ALG_PARAM_DIGEST) != NULL) {
         const EVP_MD *md = NULL;
@@ -266,6 +290,7 @@ static const OSSL_PARAM *kdf_sshkdf_settable_ctx_params(ossl_unused void *ctx,
         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SSHKDF_SESSION_ID, NULL, 0),
         OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE, NULL, 0),
         OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
         OSSL_PARAM_END
     };
     return known_settable_ctx_params;
index c603525e3a34470e0c96554de30fb0feafe17ace..da72d405f5f9af45d9c7fa541200c488d779302c 100644 (file)
@@ -394,6 +394,24 @@ static size_t sskdf_size(KDF_SSKDF *ctx)
     return (len <= 0) ? 0 : (size_t)len;
 }
 
+#ifdef FIPS_MODULE
+static int fips_sskdf_key_check_passed(KDF_SSKDF *ctx)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    int key_approved = ossl_kdf_check_key_size(ctx->secret_len);
+
+    if (!key_approved) {
+        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
+                                         libctx, "SSKDF", "Key size",
+                                         FIPS_sskdf_key_check)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+    return 1;
+}
+#endif
+
 static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
                         const OSSL_PARAM params[])
 {
@@ -407,6 +425,11 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen,
         return 0;
     }
 
+#ifdef FIPS_MODULE
+    if (!fips_sskdf_key_check_passed(ctx))
+        return 0;
+#endif
+
     md = ossl_prov_digest_md(&ctx->digest);
 
     if (ctx->macctx != NULL) {
@@ -485,6 +508,22 @@ static int fips_x963kdf_digest_check_passed(KDF_SSKDF *ctx, const EVP_MD *md)
     }
     return 1;
 }
+
+static int fips_x963kdf_key_check_passed(KDF_SSKDF *ctx)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    int key_approved = ossl_kdf_check_key_size(ctx->secret_len);
+
+    if (!key_approved) {
+        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1,
+                                         libctx, "X963KDF", "Key size",
+                                         FIPS_x963kdf_key_check)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+    return 1;
+}
 #endif
 
 static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen,
@@ -506,6 +545,11 @@ static int x963kdf_derive(void *vctx, unsigned char *key, size_t keylen,
         return 0;
     }
 
+#ifdef FIPS_MODULE
+    if (!fips_x963kdf_key_check_passed(ctx))
+        return 0;
+#endif
+
     /* H(x) = hash */
     md = ossl_prov_digest_md(&ctx->digest);
     if (md == NULL) {
@@ -583,6 +627,10 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     if (params == NULL)
         return 1;
 
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
+                                     OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+        return 0;
+
     if (!sskdf_common_set_ctx_params(ctx, params))
         return 0;
 
@@ -594,6 +642,7 @@ static const OSSL_PARAM *sskdf_settable_ctx_params(ossl_unused void *ctx,
 {
     static const OSSL_PARAM known_settable_ctx_params[] = {
         SSKDF_COMMON_SETTABLES,
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
         OSSL_PARAM_END
     };
     return known_settable_ctx_params;
@@ -624,6 +673,9 @@ static int sskdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
     if (!sskdf_common_get_ctx_params(ctx, params))
         return 0;
 
+    if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+        return 0;
+
     return 1;
 }
 
@@ -632,6 +684,7 @@ static const OSSL_PARAM *sskdf_gettable_ctx_params(ossl_unused void *ctx,
 {
     static const OSSL_PARAM known_gettable_ctx_params[] = {
         SSKDF_COMMON_GETTABLES,
+        OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
         OSSL_PARAM_END
     };
     return known_gettable_ctx_params;
@@ -647,6 +700,9 @@ static int x963kdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
                                      OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
         return 0;
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
+                                     OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+        return 0;
 
     if (!sskdf_common_set_ctx_params(ctx, params))
         return 0;
@@ -669,6 +725,7 @@ static const OSSL_PARAM *x963kdf_settable_ctx_params(ossl_unused void *ctx,
     static const OSSL_PARAM known_settable_ctx_params[] = {
         SSKDF_COMMON_SETTABLES,
         OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
         OSSL_PARAM_END
     };
     return known_settable_ctx_params;
index 620b0c84c3fa9c7fea02e6befc131270bd0b624e..3d40b0b1193fc634d196e6a6fea4b1ecae711269 100644 (file)
@@ -228,6 +228,22 @@ static int fips_digest_check_passed(TLS1_PRF *ctx, const EVP_MD *md)
     }
     return 1;
 }
+
+static int fips_key_check_passed(TLS1_PRF *ctx)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    int key_approved = ossl_kdf_check_key_size(ctx->seclen);
+
+    if (!key_approved) {
+        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE2,
+                                         libctx, "TLS_PRF", "Key size",
+                                         FIPS_tls1_prf_key_check)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+    return 1;
+}
 #endif
 
 static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
@@ -258,6 +274,8 @@ static int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen,
 #ifdef FIPS_MODULE
     if (!fips_ems_check_passed(ctx))
         return 0;
+    if (!fips_key_check_passed(ctx))
+        return 0;
 #endif
 
     return tls1_prf_alg(ctx->P_hash, ctx->P_sha1,
@@ -281,6 +299,9 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, params,
                                      OSSL_KDF_PARAM_FIPS_DIGEST_CHECK))
         return 0;
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE2, params,
+                                     OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+        return 0;
 
     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) {
         PROV_DIGEST digest;
@@ -371,6 +392,7 @@ static const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params(
         OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0),
         OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_EMS_CHECK)
         OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_DIGEST_CHECK)
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
         OSSL_PARAM_END
     };
     return known_settable_ctx_params;
index e95a84c39b5df87b6ae634e3b8630d5e8574f838..738bc2d7b257616ce5ce8aff83e922a14d8ddf98 100644 (file)
@@ -29,7 +29,8 @@ int ossl_quic_hkdf_extract(OSSL_LIB_CTX *libctx,
     int ret = 0;
     EVP_KDF *kdf = NULL;
     EVP_KDF_CTX *kctx = NULL;
-    OSSL_PARAM params[7], *p = params;
+    OSSL_PARAM params[8], *p = params;
+    int key_check = 0;
     int mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
     const char *md_name;
 
@@ -38,6 +39,15 @@ int ossl_quic_hkdf_extract(OSSL_LIB_CTX *libctx,
         || (kctx = EVP_KDF_CTX_new(kdf)) == NULL)
         goto err;
 
+    /*
+     * According to RFC 9000, the length of destination connection ID must be
+     * at least 8 bytes. It means that the length of destination connection ID
+     * may be less than the minimum length for HKDF required by FIPS provider.
+     *
+     * Therefore, we need to set `key-check` to zero to allow using destionation
+     * connection ID as IKM.
+     */
+    *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_FIPS_KEY_CHECK, &key_check);
     *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
                                             (char *)md_name, 0);
index 82f10d803b2917f21d3a161a9606bdd80c13b3db..8ead91aa3d7fac101c217931d0f890eaa29da38d 100644 (file)
@@ -77,6 +77,7 @@ Ctrl.IKM = hexkey:19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb
 Ctrl.info = info:
 Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8
 
+Availablein = default
 KDF = HKDF
 Ctrl.digest = digest:SHA1
 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
@@ -84,6 +85,7 @@ Ctrl.salt = hexsalt:000102030405060708090a0b0c
 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
 Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896
 
+Availablein = default
 KDF = HKDF
 Ctrl.mode = mode:EXTRACT_ONLY
 Ctrl.digest = digest:SHA1
index b206f860863caec3fe01fb74b1ad472c10d98fcb..83937b00c59afb854a46c491f9b0f0da9a656e42 100644 (file)
@@ -280,36 +280,42 @@ Ctrl.hexsecret = hexsecret:ebe28edbae5a410b87a479243db3f690
 Ctrl.hexinfo = hexinfo:e60dd8b28228ce5b9be74d3b
 Output = b4a23963e07f485382cb358a493daec1759ac7043dbeac37152c6ddf105031f0f239f270b7f30616166f10e5d2b4cb11ba8bf4ba3f2276885abfbc3e811a568d480d9192
 
+Availablein = default
 KDF = SSKDF
 Ctrl.digest = digest:SHA1
 Ctrl.hexsecret = hexsecret:d7e6
 Ctrl.hexinfo = hexinfo:0bbe1fa8722023d7c3da4fff
 Output = 31e798e9931b612a3ad1b9b1008faa8c
 
+Availablein = default
 KDF = SSKDF
 Ctrl.digest = digest:SHA1
 Ctrl.hexsecret = hexsecret:4646779d
 Ctrl.hexinfo = hexinfo:0bbe1fa8722023d7c3da4fff
 Output = 139f68bcca879b490e268e569087d04d
 
+Availablein = default
 KDF = SSKDF
 Ctrl.digest = digest:SHA1
 Ctrl.hexsecret = hexsecret:d9811c81d4c6
 Ctrl.hexinfo = hexinfo:0bbe1fa8722023d7c3da4fff
 Output = 914dc4f09cb633a76e6c389e04c64485
 
+Availablein = default
 KDF = SSKDF
 Ctrl.digest = digest:SHA1
 Ctrl.hexsecret = hexsecret:8838f9d99ec46f09
 Ctrl.hexinfo = hexinfo:0bbe1fa8722023d7c3da4fff
 Output = 4f07dfb6f7a5bf348689e08b2e29c948
 
+Availablein = default
 KDF = SSKDF
 Ctrl.digest = digest:SHA1
 Ctrl.hexsecret = hexsecret:3e0939b33f34e779f30e
 Ctrl.hexinfo = hexinfo:0bbe1fa8722023d7c3da4fff
 Output = b42c7a98c23be19d1187ff960e87557f
 
+Availablein = default
 KDF = SSKDF
 Ctrl.digest = digest:SHA1
 Ctrl.hexsecret = hexsecret:f36230cacca4d245d303058c
@@ -781,6 +787,7 @@ Ctrl.hexsalt = hexsalt:0ad52c9357c85e4781296a36ca72039c
 Ctrl.hexinfo = hexinfo:c67c389580128f18f6cf8592
 Output = be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7fe193c9546d45849133d
 
+Availablein = default
 KDF = SSKDF
 Ctrl.mac = mac:HMAC
 Ctrl.digest = digest:SHA256
@@ -789,6 +796,7 @@ Ctrl.hexsalt = hexsalt:3638271ccd68a25dc24ecddd39ef3f89
 Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
 Output = 3f661ec46fcc1e110b88f33ee7dbc308
 
+Availablein = default
 KDF = SSKDF
 Ctrl.mac = mac:HMAC
 Ctrl.digest = digest:SHA256
@@ -797,6 +805,7 @@ Ctrl.hexsalt = hexsalt:3638271ccd68a25dc24ecddd39ef3f89
 Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
 Output = 73ccb357554ca44967d507518262e38d
 
+Availablein = default
 KDF = SSKDF
 Ctrl.mac = mac:HMAC
 Ctrl.digest = digest:SHA256
@@ -805,6 +814,7 @@ Ctrl.hexsalt = hexsalt:3638271ccd68a25dc24ecddd39ef3f89
 Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
 Output = c4f1cf190980b6777bb35107654b25f9
 
+Availablein = default
 KDF = SSKDF
 Ctrl.mac = mac:HMAC
 Ctrl.digest = digest:SHA256
@@ -813,6 +823,7 @@ Ctrl.hexsalt = hexsalt:3638271ccd68a25dc24ecddd39ef3f89
 Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
 Output = ddb2d7475d00cc65bff6904b4f0b54ba
 
+Availablein = default
 KDF = SSKDF
 Ctrl.mac = mac:HMAC
 Ctrl.digest = digest:SHA256
@@ -821,6 +832,7 @@ Ctrl.hexsalt = hexsalt:3638271ccd68a25dc24ecddd39ef3f89
 Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
 Output = 1100a6049ae9d8be01ab3829754cecc2
 
+Availablein = default
 KDF = SSKDF
 Ctrl.mac = mac:HMAC
 Ctrl.digest = digest:SHA256
index 7e9acbda98e4691dc30fbe419172634ca2a15a56..fdf39e9095426f80d4a88ea667298eb8843288dc 100644 (file)
@@ -42,6 +42,7 @@ Ctrl.client_random = hexseed:62e1fd91f23f558a605f28478c58cf72637b89784d959df7e94
 Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928
 
 # Missing digest.
+Availablein = default
 KDF = TLS1-PRF
 Ctrl.Secret = hexsecret:01
 Ctrl.Seed = hexseed:02
index 805f65abc47a7caf1c21849eb4c33bd34d59e136..7a4d056550bfb7f3709eb25f03f101e6e6f59bf0 100644 (file)
@@ -77,6 +77,7 @@ Ctrl.IKM = hexkey:19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb
 Ctrl.info = info:
 Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8
 
+Availablein = default
 PKEYKDF = HKDF
 Ctrl.md = md:SHA1
 Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
@@ -84,6 +85,7 @@ Ctrl.salt = hexsalt:000102030405060708090a0b0c
 Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
 Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896
 
+Availablein = default
 PKEYKDF = HKDF
 Ctrl.mode = mode:EXTRACT_ONLY
 Ctrl.md = md:SHA1
index 524b7a6f805499a46868c25b321fd52d790c7fd0..6c23153dcf6368c6d16ab367ad539b3eeecde85d 100644 (file)
@@ -19,6 +19,7 @@ my $kdf_digest_check = 1;
 my $dsa_sign_disabled = 1;
 my $tdes_encrypt_disabled = 1;
 my $rsa_sign_x931_pad_disabled = 1;
+my $kdf_key_check = 1;
 
 my $activate = 1;
 my $version = 1;
@@ -65,4 +66,10 @@ sskdf-digest-check = $kdf_digest_check
 x963kdf-digest-check = $kdf_digest_check
 tdes-encrypt-disabled = $tdes_encrypt_disabled
 rsa-sign-x931-pad-disabled = $rsa_sign_x931_pad_disabled
+hkdf-key-check = $kdf_key_check
+tls13-kdf-key-check = $kdf_key_check
+tls1-prf-key-check = $kdf_key_check
+sshkdf-key-check = $kdf_key_check
+sskdf-key-check = $kdf_key_check
+x963kdf-key-check = $kdf_key_check
 _____
index 8a9c7673bbcc8ffd00a912e3728732f1fcf3b872..5fdeea4b885abd24412f79cb196371fe3cc10e09 100644 (file)
@@ -43,6 +43,12 @@ my %params = (
     'PROV_PARAM_DSA_SIGN_DISABLED' =>      "dsa-sign-disabled",      # uint
     'PROV_PARAM_TDES_ENCRYPT_DISABLED' =>  "tdes-encrypt-disabled",  # uint
     'PROV_PARAM_RSA_SIGN_X931_PAD_DISABLED' =>  "rsa-sign-x931-pad-disabled",   # uint
+    'PROV_PARAM_HKDF_KEY_CHECK' =>         "hkdf-key-check",         # uint
+    'PROV_PARAM_TLS13_KDF_KEY_CHECK' =>    "tls13-kdf-key-check",    # uint
+    'PROV_PARAM_TLS1_PRF_KEY_CHECK' =>     "tls1-prf-key-check",     # uint
+    'PROV_PARAM_SSHKDF_KEY_CHECK' =>       "sshkdf-key-check",       # uint
+    'PROV_PARAM_SSKDF_KEY_CHECK' =>        "sskdf-key-check",        # uint
+    'PROV_PARAM_X963KDF_KEY_CHECK' =>      "x963kdf-key-check",      # uint
 
 # Self test callback parameters
     'PROV_PARAM_SELF_TEST_PHASE' =>  "st-phase",# utf8_string
@@ -207,6 +213,7 @@ my %params = (
     'KDF_PARAM_ARGON2_VERSION' => "version",                # uint32_t
     'KDF_PARAM_FIPS_EMS_CHECK' => "ems_check",              # int
     'KDF_PARAM_FIPS_DIGEST_CHECK' => '*PKEY_PARAM_FIPS_DIGEST_CHECK',
+    'KDF_PARAM_FIPS_KEY_CHECK' => '*PKEY_PARAM_FIPS_KEY_CHECK',
     'KDF_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
 
 # Known RAND names