providers/implementations/keymgmt/slh_dsa_kmgmt.inc
providers/implementations/keymgmt/template_kmgmt.inc
providers/implementations/signature/eddsa_sig.inc
+providers/implementations/signature/mac_legacy_sig.inc
providers/implementations/signature/ml_dsa_sig.inc
providers/implementations/signature/rsa_sig.inc
providers/implementations/signature/slh_dsa_sig.inc
providers/implementations/signature/dsa_sig.inc \
providers/implementations/signature/ecdsa_sig.inc \
providers/implementations/signature/eddsa_sig.inc \
+ providers/implementations/signature/mac_legacy_sig.inc \
providers/implementations/signature/ml_dsa_sig.inc \
providers/implementations/signature/rsa_sig.inc \
providers/implementations/signature/slh_dsa_sig.inc \
providers/implementations/signature/dsa_sig.inc \
providers/implementations/signature/ecdsa_sig.inc \
providers/implementations/signature/eddsa_sig.inc \
+ providers/implementations/signature/mac_legacy_sig.inc \
providers/implementations/signature/ml_dsa_sig.inc \
providers/implementations/signature/rsa_sig.inc \
providers/implementations/signature/slh_dsa_sig.inc \
providers/implementations/signature/ecdsa_sig.inc.in
GENERATE[providers/implementations/signature/eddsa_sig.inc]=\
providers/implementations/signature/eddsa_sig.inc.in
+GENERATE[providers/implementations/signature/mac_legacy_sig.inc]=\
+ providers/implementations/signature/mac_legacy_sig.inc.in
GENERATE[providers/implementations/signature/ml_dsa_sig.inc]=\
providers/implementations/signature/ml_dsa_sig.inc.in
GENERATE[providers/implementations/signature/rsa_sig.inc]=\
* https://www.openssl.org/source/license.html
*/
+#include <stdbool.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/core_dispatch.h>
#include "prov/provider_ctx.h"
#include "prov/macsignature.h"
#include "prov/providercommon.h"
+#include "prov/securitycheck.h"
+#include "internal/fips.h"
+#include "internal/common.h"
+
+#ifndef FIPS_MODULE
+#define mac_legacy_get_ctx_params_decoder
+#define mac_legacy_set_ctx_params_decoder
+#endif
+#include "providers/implementations/signature/mac_legacy_sig.inc"
static OSSL_FUNC_signature_newctx_fn mac_hmac_newctx;
static OSSL_FUNC_signature_newctx_fn mac_siphash_newctx;
char *propq;
MAC_KEY *key;
EVP_MAC_CTX *macctx;
+#ifdef FIPS_MODULE
+ bool hmac_keysize_check;
+ OSSL_FIPS_IND_DECLARE
+#endif
} PROV_MAC_CTX;
static void *mac_newctx(void *provctx, const char *propq, const char *macname)
goto err;
EVP_MAC_free(mac);
-
+#ifdef FIPS_MODULE
+ pmacctx->hmac_keysize_check = (strcmp(macname, "HMAC") == 0);
+ /* Set FIPS indicator to approved */
+ OSSL_FIPS_IND_INIT(pmacctx)
+#endif
return pmacctx;
err:
MAC_NEWCTX(poly1305, "POLY1305")
MAC_NEWCTX(cmac, "CMAC")
+#ifdef FIPS_MODULE
+/*
+ * The fips indicator check is done at this level because HMAC will be created
+ * as an 'internal' sub-algorithm which will not perform the tests in hmac_prov.c
+ */
+static int hmac_check_key(PROV_MAC_CTX *macctx, const unsigned char *key, size_t keylen)
+{
+ int approved = ossl_mac_check_key_size(keylen);
+
+ if (!approved) {
+ if (!OSSL_FIPS_IND_ON_UNAPPROVED(macctx, OSSL_FIPS_IND_SETTABLE0,
+ macctx->libctx, "HMAC", "keysize",
+ FIPS_CONFIG_HMAC_KEY_CHECK)) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
+ }
+ return 1;
+}
+#endif
+
static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey,
const OSSL_PARAM params[])
{
pmacctx->key->properties, params))
return 0;
+#ifdef FIPS_MODULE
+ if (pmacctx->hmac_keysize_check
+ && !hmac_check_key(pmacctx, pmacctx->key->priv_key, pmacctx->key->priv_key_len))
+ return 0;
+#endif
if (!EVP_MAC_init(pmacctx->macctx, pmacctx->key->priv_key,
pmacctx->key->priv_key_len, NULL))
return 0;
{
PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
+#ifdef FIPS_MODULE
+ if (ctx->hmac_keysize_check) {
+ struct mac_legacy_set_ctx_params_st p;
+
+ if (!mac_legacy_set_ctx_params_decoder(params, &p))
+ return 0;
+ if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind_k))
+ return 0;
+ if (p.key != NULL) {
+ if (p.key->data_type != OSSL_PARAM_OCTET_STRING)
+ return 0;
+ if (!hmac_check_key(ctx, p.key->data, p.key->data_size))
+ return 0;
+ }
+ }
+#endif
return EVP_MAC_CTX_set_params(ctx->macctx, params);
}
return params;
}
+static const OSSL_PARAM *mac_gettable_ctx_params(ossl_unused void *vctx,
+ ossl_unused void *provctx)
+{
+ return mac_legacy_get_ctx_params_list;
+}
+
+static int mac_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+ PROV_MAC_CTX *ctx = vctx;
+
+ if (ctx == NULL)
+ return 0;
+
+#ifdef FIPS_MODULE
+ struct mac_legacy_get_ctx_params_st p;
+
+ if (!mac_legacy_get_ctx_params_decoder(params, &p))
+ return 0;
+ if (p.ind != NULL) {
+ int approved = OSSL_FIPS_IND_GET(ctx)->approved;
+ if (!OSSL_PARAM_set_int(p.ind, approved))
+ return 0;
+ }
+#endif
+ return 1;
+}
+
#define MAC_SETTABLE_CTX_PARAMS(funcname, macname) \
static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *ctx, \
void *provctx) \
(void (*)(void))mac_set_ctx_params }, \
{ OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \
(void (*)(void))mac_##funcname##_settable_ctx_params }, \
+ { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \
+ (void (*)(void))mac_get_ctx_params }, \
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \
+ (void (*)(void))mac_gettable_ctx_params }, \
OSSL_DISPATCH_END \
};
--- /dev/null
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the \"License\"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+{-
+use OpenSSL::paramnames qw(produce_param_decoder);
+-}
+
+{- produce_param_decoder('mac_legacy_get_ctx_params',
+ (['OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int', 'fips'],
+ )); -}
+
+{- produce_param_decoder('mac_legacy_set_ctx_params',
+ (['OSSL_MAC_PARAM_KEY', 'key', 'octet_string'],
+ ['OSSL_MAC_PARAM_FIPS_KEY_CHECK', 'ind_k', 'int', 'fips'],
+ )); -}
use strict;
use warnings;
-use OpenSSL::Test qw(:DEFAULT data_file);
+use OpenSSL::Test qw(:DEFAULT data_file srctop_file);
use OpenSSL::Test::Utils;
use Storable qw(dclone);
push @mac_fail_tests, @siphash_fail_tests unless disabled("siphash");
-plan tests => (scalar @mac_tests * 2) + scalar @mac_fail_tests;
+plan tests => (scalar @mac_tests * 2) + (scalar @mac_fail_tests) + 2;
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
my $test_count = 0;
foreach (@mac_tests) {
ok(compareline($_->{cmd}, $_->{type}, $_->{input}, $_->{expected}, $_->{err}), $_->{desc});
}
+SKIP: {
+ skip "Skipping FIPS tests", 2
+ if $no_fips;
+
+ my $fipsconf = srctop_file("test", "fips-and-base.cnf");
+
+ # This is only valid after OpenSSL 4.1
+ run(test(["fips_version_test", "-config", $fipsconf, ">=4.1.0"]),
+ capture => 1, statusvar => \my $exit);
+ skip "FIPS provider version is too old for this test", 2
+ if !$exit;
+
+ $ENV{OPENSSL_CONF} = $fipsconf;
+ ok(!run(app(['openssl', 'dgst', '-provider', 'fips', '-sha256', '-hmac',
+ '1234', srctop_file("test", "testec-p112r1.pem")])),
+ "Checking bad key size fails in FIPS provider");
+ ok(run(app(['openssl', 'dgst', '-provider', 'fips', '-sha256', '-hmac',
+ '123456789ABCDE', srctop_file("test", "testec-p112r1.pem")])),
+ "Checking good key size passes in FIPS provider");
+ delete $ENV{OPENSSL_CONF};
+}
+
# Create a temp input file and save the input data into it, and
# then compare the stdout output matches the expected value.
sub compareline {