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;
"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"},
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 */
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 */
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)
|| 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;
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 */
[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>]
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
=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
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
=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.
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
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.
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>
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.
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
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"
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
*/
# 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
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
/* 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);
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)
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)
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;
}
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
};
* 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,
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();
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;
}
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);
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
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[])
{
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:
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;
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;
if (!hkdf_common_get_ctx_params(ctx, params))
return 0;
+ if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+ return 0;
+
return 1;
}
{
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;
}
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,
return 0;
}
+#ifdef FIPS_MODULE
+ if (!fips_tls1_3_key_check_passed(ctx))
+ return 0;
+#endif
+
switch (ctx->mode) {
default:
return 0;
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;
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;
}
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,
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,
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;
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;
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[])
{
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) {
}
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,
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) {
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;
{
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;
if (!sskdf_common_get_ctx_params(ctx, params))
return 0;
+ if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+ return 0;
+
return 1;
}
{
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;
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;
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;
}
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,
#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,
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;
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;
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;
|| (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);
Ctrl.info = info:
Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8
+Availablein = default
KDF = HKDF
Ctrl.digest = digest:SHA1
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896
+Availablein = default
KDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.digest = digest:SHA1
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
Ctrl.hexinfo = hexinfo:c67c389580128f18f6cf8592
Output = be32e7d306d891028be088f213f9f947c50420d9b5a12ca69818dd9995dedd8e6137c7104d67f2ca90915dda0ab68af2f355b904f9eb0388b5b7fe193c9546d45849133d
+Availablein = default
KDF = SSKDF
Ctrl.mac = mac:HMAC
Ctrl.digest = digest:SHA256
Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
Output = 3f661ec46fcc1e110b88f33ee7dbc308
+Availablein = default
KDF = SSKDF
Ctrl.mac = mac:HMAC
Ctrl.digest = digest:SHA256
Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
Output = 73ccb357554ca44967d507518262e38d
+Availablein = default
KDF = SSKDF
Ctrl.mac = mac:HMAC
Ctrl.digest = digest:SHA256
Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
Output = c4f1cf190980b6777bb35107654b25f9
+Availablein = default
KDF = SSKDF
Ctrl.mac = mac:HMAC
Ctrl.digest = digest:SHA256
Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
Output = ddb2d7475d00cc65bff6904b4f0b54ba
+Availablein = default
KDF = SSKDF
Ctrl.mac = mac:HMAC
Ctrl.digest = digest:SHA256
Ctrl.hexinfo = hexinfo:348a37a27ef1282f5f020dcc
Output = 1100a6049ae9d8be01ab3829754cecc2
+Availablein = default
KDF = SSKDF
Ctrl.mac = mac:HMAC
Ctrl.digest = digest:SHA256
Output = d06139889fffac1e3a71865f504aa5d0d2a2e89506c6f2279b670c3e1b74f531016a2530c51a3a0f7e1d6590d0f0566b2f387f8d11fd4f731cdd572d2eae927f6f2f81410b25e6960be68985add6c38445ad9f8c64bf8068bf9a6679485d966f1ad6f68b43495b10a683755ea2b858d70ccac7ec8b053c6bd41ca299d4e51928
# Missing digest.
+Availablein = default
KDF = TLS1-PRF
Ctrl.Secret = hexsecret:01
Ctrl.Seed = hexseed:02
Ctrl.info = info:
Output = 8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8
+Availablein = default
PKEYKDF = HKDF
Ctrl.md = md:SHA1
Ctrl.IKM = hexkey:0b0b0b0b0b0b0b0b0b0b0b
Ctrl.info = hexinfo:f0f1f2f3f4f5f6f7f8f9
Output = 085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896
+Availablein = default
PKEYKDF = HKDF
Ctrl.mode = mode:EXTRACT_ONLY
Ctrl.md = md:SHA1
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;
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
_____
'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
'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