HMAC has been changed to use a FIPS indicator for its key check.
HKDF and Single Step use a salt rather than a key when using HMAC,
so we need a mechanism to bypass this check in HMAC.
A seperate 'internal' query table has been added to the FIPS provider
for MACS. Giving HMAC a seprate dispatch table allows KDF's to ignore
the key check. If a KDF requires the key check then it must do the
check itself. The normal MAC dipatch table is used if the user fetches
HMAC directly.
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/25049)
OPT_TLS_PRF_EMS_CHECK, OPT_NO_SHORT_MAC,
OPT_DISALLOW_PKCS15_PADDING, OPT_RSA_PSS_SALTLEN_CHECK,
OPT_DISALLOW_SIGNATURE_X931_PADDING,
+ OPT_HMAC_KEY_CHECK,
OPT_DISALLOW_DRGB_TRUNC_DIGEST,
OPT_SIGNATURE_DIGEST_CHECK,
OPT_HKDF_DIGEST_CHECK,
"Disallow truncated digests with Hash and HMAC DRBGs"},
{"signature_digest_check", OPT_SIGNATURE_DIGEST_CHECK, '-',
"Enable checking for approved digests for signatures"},
+ {"hmac_key_check", OPT_HMAC_KEY_CHECK, '-', "Enable key check for HMAC"},
{"hkdf_digest_check", OPT_HKDF_DIGEST_CHECK, '-',
"Enable digest check for HKDF"},
{"tls13_kdf_digest_check", OPT_TLS13_KDF_DIGEST_CHECK, '-',
unsigned int self_test_onload : 1;
unsigned int conditional_errors : 1;
unsigned int security_checks : 1;
+ unsigned int hmac_key_check : 1;
unsigned int tls_prf_ems_check : 1;
unsigned int no_short_mac : 1;
unsigned int drgb_no_trunc_dgst : 1;
1, /* self_test_onload */
1, /* conditional_errors */
1, /* security_checks */
+ 1, /* hmac_key_check */
1, /* tls_prf_ems_check */
1, /* no_short_mac */
1, /* drgb_no_trunc_dgst */
1, /* self_test_onload */
1, /* conditional_errors */
1, /* security_checks */
+ 0, /* hmac_key_check */
0, /* tls_prf_ems_check */
0, /* no_short_mac */
0, /* drgb_no_trunc_dgst */
opts->conditional_errors ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
opts->security_checks ? "1" : "0") <= 0
+ || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_HMAC_KEY_CHECK,
+ opts->hmac_key_check ? "1": "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK,
opts->tls_prf_ems_check ? "1" : "0") <= 0
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_PARAM_NO_SHORT_MAC,
goto end;
fips_opts.security_checks = 0;
break;
+ case OPT_HMAC_KEY_CHECK:
+ fips_opts.hmac_key_check = 1;
+ break;
case OPT_TLS_PRF_EMS_CHECK:
fips_opts.tls_prf_ems_check = 1;
break;
[B<-pedantic>]
[B<-no_conditional_errors>]
[B<-no_security_checks>]
+[B<-hmac_key_check>]
[B<-ems_check>]
[B<-no_drbg_truncated_digests>]
[B<-signature_digest_check>]
Configure the module to not allow short MAC outputs.
See SP 800-185 8.4.2 and FIPS 140-3 ID C.D for details.
+=item B<-hmac_key_check>
+
+Configure the module to not allow small keys sizes when using HMAC.
+See SP 800-131Ar2 for details.
+
=item B<-no_drbg_truncated_digests>
Configure the module to not allow truncated digests to be used with Hash and
The general description of these parameters can be found in
L<EVP_MAC(3)/PARAMETERS>.
-The following parameter can be set with EVP_MAC_CTX_set_params():
+The following parameters can be set with EVP_MAC_CTX_set_params():
=over 4
=item "tls-data-size" (B<OSSL_MAC_PARAM_TLS_DATA_SIZE>) <unsigned integer>
+=item "key-check" (B<OSSL_MAC_PARAM_FIPS_KEY_CHECK>) <integer>
+
+See L<provider-mac(7)/Mac Parameters>.
+
=back
=for comment The "flags" parameter is passed directly to HMAC_CTX_set_flags().
-The following parameter can be retrieved with EVP_MAC_CTX_get_params():
+The following parameters can be retrieved with EVP_MAC_CTX_get_params():
=over 4
The "size" parameter can also be retrieved with EVP_MAC_CTX_get_mac_size().
The length of the "size" parameter is equal to that of an B<unsigned int>.
-=back
-
-=over 4
-
=item "block-size" (B<OSSL_MAC_PARAM_BLOCK_SIZE>) <unsigned integer>
Gets the MAC block size. The "block-size" parameter can also be retrieved with
EVP_MAC_CTX_get_block_size().
+=item "fips-indicator" (B<OSSL_KDF_PARAM_FIPS_APPROVED_INDICATOR>) <integer>
+
+See L<provider-mac(7)/Mac Parameters>.
+
=back
=head1 SEE ALSO
=item "fips-indicator" (B<OSSL_MAC_PARAM_FIPS_APPROVED_INDICATOR>) <int>
A getter that returns 1 if the operation is FIPS approved, or 0 otherwise.
-This may be used after calling the final function. It may return 0 if
-"no-short-mac" are set to 0. This option is used by the OpenSSL FIPS
-provider.
+This may be used after calling the final function. It may return 0 if
+either "no-short-mac" or "key-check" are set to 0.
+This option is used by the OpenSSL FIPS provider.
=back
"fips-indicator" to 0. This option is used by the OpenSSL FIPS provider,
and breaks FIPS compliance if set to 0.
+=item "key-check" (B<OSSL_MAC_PARAM_FIPS_KEY_CHECK>) <integer>
+
+If required this parameter should be set before OSSL_FUNC_mac_init.
+The default value of 1 causes an error when small key sizes are
+asked for. Setting this to 0 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
=back
* This is enabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
-#define OSSL_PROV_FIPS_PARAM_NO_SHORT_MAC "no-short-mac"
+# define OSSL_PROV_FIPS_PARAM_NO_SHORT_MAC "no-short-mac"
+
+/*
+ * A boolean that determines if the runtime FIPS key check for HMAC is
+ * performed.
+ * This is enabled by default.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_HMAC_KEY_CHECK "hmac-key-check"
/*
* A boolean that determines if truncated digests can be used with Hash and HMAC
int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx);
int FIPS_no_short_mac(OSSL_LIB_CTX *libctx);
+int FIPS_hmac_key_check(OSSL_LIB_CTX *libctx);
int FIPS_restricted_drbg_digests_enabled(OSSL_LIB_CTX *libctx);
int FIPS_fips_signature_digest_check(OSSL_LIB_CTX *libctx);
int FIPS_hkdf_digest_check(OSSL_LIB_CTX *libctx);
# define OSSL_FIPS_IND_GET_CTX_PARAM(ctx, prms) \
ossl_FIPS_IND_get_ctx_param(&((ctx)->indicator), prms)
-# define OSSL_FIPS_IND_GET(ctx) &((ctx)->indicator)
+# define OSSL_FIPS_IND_GET(ctx) (&((ctx)->indicator))
# define OSSL_FIPS_IND_GET_PARAM(ctx, p, settable, id, name) \
*settable = ossl_FIPS_IND_get_settable(&((ctx)->indicator), id); \
if (*settable != OSSL_FIPS_IND_STATE_UNKNOWN) \
- *p = OSSL_PARAM_construct_int(name, settable); \
+ *p = OSSL_PARAM_construct_int(name, settable);
int ossl_fips_ind_rsa_key_check(OSSL_FIPS_IND *ind, int id, OSSL_LIB_CTX *libctx,
const RSA *rsa, const char *desc, int protect);
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);
+int ossl_mac_check_key_size(size_t keylen);
#ifndef OPENSSL_NO_EC
int ossl_ec_check_curve_allowed(const EC_GROUP *group);
#include "prov/securitycheck.h"
#include "prov/fipsindicator.h"
+#define OSSL_FIPS_MIN_SECURITY_STRENGTH_BITS 112
+
int ossl_rsa_key_op_get_protect(const RSA *rsa, int operation, int *outprotect)
{
int protect = 0;
*/
int ossl_kdf_check_key_size(size_t keylen)
{
- return (keylen * 8) >= 112;
+ return (keylen * 8) >= OSSL_FIPS_MIN_SECURITY_STRENGTH_BITS;
+}
+
+int ossl_mac_check_key_size(size_t keylen)
+{
+ return ossl_kdf_check_key_size(keylen);
}
#ifndef OPENSSL_NO_EC
* For signing or key agreement only allow curves with at least 112 bits of
* security strength
*/
- if (protect && strength < 112)
+ if (protect && strength < OSSL_FIPS_MIN_SECURITY_STRENGTH_BITS)
return 0;
return 1;
}
static OSSL_FUNC_provider_gettable_params_fn fips_gettable_params;
static OSSL_FUNC_provider_get_params_fn fips_get_params;
static OSSL_FUNC_provider_query_operation_fn fips_query;
+static OSSL_FUNC_provider_query_operation_fn fips_query_internal;
#define ALGC(NAMES, FUNC, CHECK) \
{ { NAMES, FIPS_DEFAULT_PROPERTIES, FUNC }, CHECK }
FIPS_OPTION fips_security_checks;
FIPS_OPTION fips_tls1_prf_ems_check;
FIPS_OPTION fips_no_short_mac;
+ FIPS_OPTION fips_hmac_key_check;
FIPS_OPTION fips_restricted_drgb_digests;
FIPS_OPTION fips_signature_digest_check;
FIPS_OPTION fips_hkdf_digest_check;
init_fips_option(&fgbl->fips_security_checks, 1);
init_fips_option(&fgbl->fips_tls1_prf_ems_check, 0); /* Disabled by default */
init_fips_option(&fgbl->fips_no_short_mac, 1);
+ init_fips_option(&fgbl->fips_hmac_key_check, 0);
init_fips_option(&fgbl->fips_restricted_drgb_digests, 0);
init_fips_option(&fgbl->fips_signature_digest_check, 0);
init_fips_option(&fgbl->fips_hkdf_digest_check, 0);
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SECURITY_CHECKS, OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK, OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NO_SHORT_MAC, OSSL_PARAM_INTEGER, NULL, 0),
+ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_HMAC_KEY_CHECK, OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST, OSSL_PARAM_INTEGER, NULL, 0),
OSSL_PARAM_DEFN(OSSL_PROV_PARAM_HKDF_DIGEST_CHECK, OSSL_PARAM_INTEGER, NULL,
0),
fips_tls1_prf_ems_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_NO_SHORT_MAC,
fips_no_short_mac);
+ FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_HMAC_KEY_CHECK,
+ fips_hmac_key_check);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_DRBG_TRUNC_DIGEST,
fips_restricted_drgb_digests);
FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_SIGNATURE_DIGEST_CHECK,
fips_tls1_prf_ems_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_NO_SHORT_MAC,
fips_no_short_mac);
+ FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_HMAC_KEY_CHECK,
+ fips_hmac_key_check);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST,
fips_restricted_drgb_digests);
FIPS_FEATURE_GET(fgbl, OSSL_PROV_FIPS_PARAM_SIGNATURE_DIGEST_CHECK,
{ NULL, NULL, NULL }
};
+static const OSSL_ALGORITHM fips_macs_internal[] = {
+#ifndef OPENSSL_NO_CMAC
+ { PROV_NAMES_CMAC, FIPS_DEFAULT_PROPERTIES, ossl_cmac_functions },
+#endif
+ { PROV_NAMES_HMAC, FIPS_DEFAULT_PROPERTIES, ossl_hmac_internal_functions },
+ { PROV_NAMES_KMAC_128, FIPS_DEFAULT_PROPERTIES, ossl_kmac128_functions },
+ { PROV_NAMES_KMAC_256, FIPS_DEFAULT_PROPERTIES, ossl_kmac256_functions },
+};
+
static const OSSL_ALGORITHM fips_kdfs[] = {
{ PROV_NAMES_HKDF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_hkdf_functions },
{ PROV_NAMES_TLS1_3_KDF, FIPS_DEFAULT_PROPERTIES,
return NULL;
}
+static const OSSL_ALGORITHM *fips_query_internal(void *provctx, int operation_id,
+ int *no_cache)
+{
+ *no_cache = 0;
+
+ if (!ossl_prov_is_running())
+ return NULL;
+
+ switch (operation_id) {
+ case OSSL_OP_DIGEST:
+ return fips_digests;
+ case OSSL_OP_CIPHER:
+ return exported_fips_ciphers;
+ case OSSL_OP_MAC:
+ return fips_macs_internal;
+ case OSSL_OP_KDF:
+ return fips_kdfs;
+ case OSSL_OP_RAND:
+ return fips_rands;
+ case OSSL_OP_KEYMGMT:
+ return fips_keymgmt;
+ case OSSL_OP_KEYEXCH:
+ return fips_keyexch;
+ case OSSL_OP_SIGNATURE:
+ return fips_signature;
+ case OSSL_OP_ASYM_CIPHER:
+ return fips_asym_cipher;
+ case OSSL_OP_KEM:
+ return fips_asym_kem;
+ }
+ return NULL;
+}
+
static void fips_teardown(void *provctx)
{
OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx));
/* Functions we provide to ourself */
static const OSSL_DISPATCH intern_dispatch_table[] = {
{ OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fips_intern_teardown },
- { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query },
+ { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query_internal },
OSSL_DISPATCH_END
};
FIPS_SET_OPTION(fgbl, fips_security_checks);
FIPS_SET_OPTION(fgbl, fips_tls1_prf_ems_check);
FIPS_SET_OPTION(fgbl, fips_no_short_mac);
+ FIPS_SET_OPTION(fgbl, fips_hmac_key_check);
FIPS_SET_OPTION(fgbl, fips_restricted_drgb_digests);
FIPS_SET_OPTION(fgbl, fips_signature_digest_check);
FIPS_SET_OPTION(fgbl, fips_hkdf_digest_check);
FIPS_FEATURE_CHECK(FIPS_security_check_enabled, fips_security_checks)
FIPS_FEATURE_CHECK(FIPS_tls_prf_ems_check, fips_tls1_prf_ems_check)
FIPS_FEATURE_CHECK(FIPS_no_short_mac, fips_no_short_mac)
+FIPS_FEATURE_CHECK(FIPS_hmac_key_check, fips_hmac_key_check)
FIPS_FEATURE_CHECK(FIPS_restricted_drbg_digests_enabled,
fips_restricted_drgb_digests)
FIPS_FEATURE_CHECK(FIPS_fips_signature_digest_check, fips_signature_digest_check)
extern const OSSL_DISPATCH ossl_cmac_functions[];
extern const OSSL_DISPATCH ossl_gmac_functions[];
extern const OSSL_DISPATCH ossl_hmac_functions[];
+#ifdef FIPS_MODULE
+extern const OSSL_DISPATCH ossl_hmac_internal_functions[];
+#endif
extern const OSSL_DISPATCH ossl_kmac128_functions[];
extern const OSSL_DISPATCH ossl_kmac256_functions[];
extern const OSSL_DISPATCH ossl_siphash_functions[];
return 0;
}
/* calc: PRK = HMAC-Hash(salt, IKM) */
- return
- EVP_Q_mac(libctx, "HMAC", NULL, EVP_MD_get0_name(evp_md), NULL, salt,
- salt_len, ikm, ikm_len, prk, EVP_MD_get_size(evp_md), NULL)
- != NULL;
+ return EVP_Q_mac(libctx, "HMAC", NULL, EVP_MD_get0_name(evp_md), NULL, salt,
+ salt_len, ikm, ikm_len, prk, EVP_MD_get_size(evp_md), NULL)
+ != NULL;
}
/*
#include <openssl/params.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include <openssl/proverr.h>
+#include <openssl/err.h>
#include "internal/ssl3_cbc.h"
#include "prov/provider_ctx.h"
#include "prov/provider_util.h"
#include "prov/providercommon.h"
+#include "prov/fipsindicator.h"
+#include "prov/securitycheck.h"
+#include "prov/fipscommon.h"
/*
* Forward declaration of everything implemented here. This is not strictly
int tls_header_set;
unsigned char tls_mac_out[EVP_MAX_MD_SIZE];
size_t tls_mac_out_size;
+#ifdef FIPS_MODULE
+ /*
+ * 'internal' is set to 1 if HMAC is used inside another algorithm such as a
+ * KDF. In this case it is the parent algorithm that is responsible for
+ * performing any conditional FIPS indicator related checks for the HMAC.
+ */
+ int internal;
+#endif
+ OSSL_FIPS_IND_DECLARE
};
static void *hmac_new(void *provctx)
return NULL;
}
macctx->provctx = provctx;
+ OSSL_FIPS_IND_INIT(macctx)
return macctx;
}
{
const EVP_MD *digest;
+#ifdef FIPS_MODULE
+ /*
+ * KDF's pass a salt rather than a key,
+ * which is why it skips the key check unless "HMAC" is fetched directly.
+ */
+ if (!macctx->internal) {
+ OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(macctx->provctx);
+ int approved = ossl_mac_check_key_size(keylen);
+
+ if (!approved) {
+ if (!OSSL_FIPS_IND_ON_UNAPPROVED(macctx, OSSL_FIPS_IND_SETTABLE0,
+ libctx, "HMAC", "keysize",
+ FIPS_hmac_key_check)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ }
+ }
+#endif
+
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 */
macctx->key = OPENSSL_secure_malloc(keylen > 0 ? keylen : 1);
if (macctx->key == NULL)
return 0;
+
memcpy(macctx->key, key, keylen);
macctx->keylen = keylen;
static const OSSL_PARAM known_gettable_ctx_params[] = {
OSSL_PARAM_size_t(OSSL_MAC_PARAM_SIZE, NULL),
OSSL_PARAM_size_t(OSSL_MAC_PARAM_BLOCK_SIZE, NULL),
+ OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
OSSL_PARAM_END
};
static const OSSL_PARAM *hmac_gettable_ctx_params(ossl_unused void *ctx,
&& !OSSL_PARAM_set_int(p, hmac_block_size(macctx)))
return 0;
+#ifdef FIPS_MODULE
+ p = OSSL_PARAM_locate(params, OSSL_MAC_PARAM_FIPS_APPROVED_INDICATOR);
+ if (p != NULL) {
+ int approved = 0;
+
+ if (!macctx->internal)
+ approved = OSSL_FIPS_IND_GET(macctx)->approved;
+ if (!OSSL_PARAM_set_int(p, approved))
+ return 0;
+ }
+#endif
return 1;
}
OSSL_PARAM_int(OSSL_MAC_PARAM_DIGEST_NOINIT, NULL),
OSSL_PARAM_int(OSSL_MAC_PARAM_DIGEST_ONESHOT, NULL),
OSSL_PARAM_size_t(OSSL_MAC_PARAM_TLS_DATA_SIZE, NULL),
+ OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_MAC_PARAM_FIPS_KEY_CHECK)
OSSL_PARAM_END
};
static const OSSL_PARAM *hmac_settable_ctx_params(ossl_unused void *ctx,
if (params == NULL)
return 1;
+ if (!OSSL_FIPS_IND_SET_CTX_PARAM(macctx, OSSL_FIPS_IND_SETTABLE0, params,
+ OSSL_MAC_PARAM_FIPS_KEY_CHECK))
+ return 0;
+
if (!ossl_prov_digest_load_from_params(&macctx->digest, params, ctx))
return 0;
if ((p = OSSL_PARAM_locate_const(params, OSSL_MAC_PARAM_KEY)) != NULL) {
if (p->data_type != OSSL_PARAM_OCTET_STRING)
return 0;
+
if (!hmac_setkey(macctx, p->data, p->data_size))
return 0;
}
{ OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))hmac_set_ctx_params },
OSSL_DISPATCH_END
};
+
+#ifdef FIPS_MODULE
+static OSSL_FUNC_mac_newctx_fn hmac_internal_new;
+
+static void *hmac_internal_new(void *provctx)
+{
+ struct hmac_data_st *macctx = hmac_new(provctx);
+
+ if (macctx != NULL)
+ macctx->internal = 1;
+ return macctx;
+}
+
+const OSSL_DISPATCH ossl_hmac_internal_functions[] = {
+ { OSSL_FUNC_MAC_NEWCTX, (void (*)(void))hmac_internal_new },
+ { OSSL_FUNC_MAC_DUPCTX, (void (*)(void))hmac_dup },
+ { OSSL_FUNC_MAC_FREECTX, (void (*)(void))hmac_free },
+ { OSSL_FUNC_MAC_INIT, (void (*)(void))hmac_init },
+ { OSSL_FUNC_MAC_UPDATE, (void (*)(void))hmac_update },
+ { OSSL_FUNC_MAC_FINAL, (void (*)(void))hmac_final },
+ { OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS,
+ (void (*)(void))hmac_gettable_ctx_params },
+ { OSSL_FUNC_MAC_GET_CTX_PARAMS, (void (*)(void))hmac_get_ctx_params },
+ { OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS,
+ (void (*)(void))hmac_settable_ctx_params },
+ { OSSL_FUNC_MAC_SET_CTX_PARAMS, (void (*)(void))hmac_set_ctx_params },
+ OSSL_DISPATCH_END
+};
+
+#endif /* FIPS_MODULE */
t->err = "MAC_CREATE_ERROR";
goto err;
}
- if (fips_provider_version_gt(libctx, 3, 2, 0))
+ if (fips_provider_version_gt(libctx, 3, 2, 0)) {
+ /* HMAC will put an error on the stack here (digest is not set yet) */
+ ERR_set_mark();
size_before_init = EVP_MAC_CTX_get_mac_size(ctx);
+ ERR_pop_to_mark();
+ }
if (!EVP_MAC_init(ctx, expected->key, expected->key_len, params)) {
t->err = "MAC_INIT_ERROR";
goto err;
Key = 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
Result = MAC_INIT_ERROR
+Title = HMAC FIPS short key test
+
+# Test HMAC with key < 112 bits is not allowed
+Availablein = fips
+FIPSversion = >=3.4.0
+MAC = HMAC
+Algorithm = SHA256
+Input = "Test Input"
+Key = 0001020304
+Result = MAC_INIT_ERROR
+
+Title = HMAC FIPS short key indicator test
+
+# Test HMAC with key < 112 bits is unapproved
+Availablein = fips
+FIPSversion = >=3.4.0
+MAC = HMAC
+Algorithm = SHA256
+Unapproved = 1
+Ctrl = key-check:0
+Input = "Test Input"
+Key = 0001020304
+Output = db70da6176d87813b059879ccc27bc53e295c6eca74db8bdc4e77d7e951d894b
+
Title = CMAC tests (from FIPS module)
MAC = CMAC
my $security_checks = 1;
my $ems_check = 1;
my $no_short_mac = 1;
+my $key_check = 1;
my $drgb_no_trunc_dgst = 1;
my $digest_check = 1;
my $dsa_sign_disabled = 1;
module-mac = $module_mac
tls1-prf-ems-check = $ems_check
no-short-mac = $no_short_mac
+hmac-key-check = $key_check
drbg-no-trunc-md = $drgb_no_trunc_dgst
signature-digest-check = $digest_check
dsa-sign-disabled = $dsa_sign_disabled
'PROV_PARAM_BUILDINFO' => "buildinfo", # utf8_ptr
'PROV_PARAM_STATUS' => "status", # uint
'PROV_PARAM_SECURITY_CHECKS' => "security-checks", # uint
+ 'PROV_PARAM_HMAC_KEY_CHECK' => "hmac-key-check", # uint
'PROV_PARAM_TLS1_PRF_EMS_CHECK' => "tls1-prf-ems-check", # uint
'PROV_PARAM_NO_SHORT_MAC' => "no-short-mac", # uint
'PROV_PARAM_DRBG_TRUNC_DIGEST' => "drbg-no-trunc-md", # uint
'MAC_PARAM_SIZE' => "size", # size_t
'MAC_PARAM_BLOCK_SIZE' => "block-size", # size_t
'MAC_PARAM_TLS_DATA_SIZE' => "tls-data-size", # size_t
+ 'MAC_PARAM_FIPS_KEY_CHECK' => '*PKEY_PARAM_FIPS_KEY_CHECK',
'MAC_PARAM_FIPS_APPROVED_INDICATOR' => '*ALG_PARAM_FIPS_APPROVED_INDICATOR',
# KDF / PRF parameters