diff options
Diffstat (limited to 'providers/implementations/exchange/dh_exch.c')
-rw-r--r-- | providers/implementations/exchange/dh_exch.c | 76 |
1 files changed, 63 insertions, 13 deletions
diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c index 1d8a2e27b30e..cfb3938810b8 100644 --- a/providers/implementations/exchange/dh_exch.c +++ b/providers/implementations/exchange/dh_exch.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2024 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 @@ -76,6 +76,7 @@ typedef struct { /* KDF output length */ size_t kdf_outlen; char *kdf_cekalg; + OSSL_FIPS_IND_DECLARE } PROV_DH_CTX; static void *dh_newctx(void *provctx) @@ -88,11 +89,36 @@ static void *dh_newctx(void *provctx) pdhctx = OPENSSL_zalloc(sizeof(PROV_DH_CTX)); if (pdhctx == NULL) return NULL; + OSSL_FIPS_IND_INIT(pdhctx) pdhctx->libctx = PROV_LIBCTX_OF(provctx); pdhctx->kdf_type = PROV_DH_KDF_NONE; return pdhctx; } +#ifdef FIPS_MODULE +static int dh_check_key(PROV_DH_CTX *ctx) +{ + int key_approved = ossl_dh_check_key(ctx->dh); + + if (!key_approved) { + if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, + ctx->libctx, "DH Init", "DH Key", + ossl_fips_config_securitycheck_enabled)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + } + return 1; +} + +static int digest_check(PROV_DH_CTX *ctx, const EVP_MD *md) +{ + return ossl_fips_ind_digest_exch_check(OSSL_FIPS_IND_GET(ctx), + OSSL_FIPS_IND_SETTABLE1, ctx->libctx, + md, "DH Set Ctx"); +} +#endif + static int dh_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[]) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; @@ -105,8 +131,15 @@ static int dh_init(void *vpdhctx, void *vdh, const OSSL_PARAM params[]) DH_free(pdhctx->dh); pdhctx->dh = vdh; pdhctx->kdf_type = PROV_DH_KDF_NONE; - return dh_set_ctx_params(pdhctx, params) - && ossl_dh_check_key(pdhctx->libctx, vdh); + + OSSL_FIPS_IND_SET_APPROVED(pdhctx) + if (!dh_set_ctx_params(pdhctx, params)) + return 0; +#ifdef FIPS_MODULE + if (!dh_check_key(pdhctx)) + return 0; +#endif + return 1; } /* The 2 parties must share the same domain parameters */ @@ -194,10 +227,8 @@ static int dh_X9_42_kdf_derive(void *vpdhctx, unsigned char *secret, } if (!dh_plain_derive(pdhctx, NULL, &stmplen, 0, 1)) return 0; - if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((stmp = OPENSSL_secure_malloc(stmplen)) == NULL) return 0; - } if (!dh_plain_derive(pdhctx, stmp, &stmplen, stmplen, 1)) goto err; @@ -316,9 +347,16 @@ static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[]) if (pdhctx == NULL) return 0; - if (params == NULL) + if (ossl_param_is_empty(params)) return 1; + if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE0, params, + OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK)) + return 0; + if (!OSSL_FIPS_IND_SET_CTX_PARAM(pdhctx, OSSL_FIPS_IND_SETTABLE1, params, + OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK)) + return 0; + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_TYPE); if (p != NULL) { str = name; @@ -351,12 +389,20 @@ static int dh_set_ctx_params(void *vpdhctx, const OSSL_PARAM params[]) EVP_MD_free(pdhctx->kdf_md); pdhctx->kdf_md = EVP_MD_fetch(pdhctx->libctx, name, mdprops); - if (!ossl_digest_is_allowed(pdhctx->libctx, pdhctx->kdf_md)) { + if (pdhctx->kdf_md == NULL) + return 0; + /* XOF digests are not allowed */ + if (EVP_MD_xof(pdhctx->kdf_md)) { + ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); + return 0; + } +#ifdef FIPS_MODULE + if (!digest_check(pdhctx, pdhctx->kdf_md)) { EVP_MD_free(pdhctx->kdf_md); pdhctx->kdf_md = NULL; - } - if (pdhctx->kdf_md == NULL) return 0; + } +#endif } p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_KDF_OUTLEN); @@ -417,6 +463,8 @@ static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, NULL), OSSL_PARAM_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, NULL, 0), OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_EXCHANGE_PARAM_FIPS_KEY_CHECK) + OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_EXCHANGE_PARAM_FIPS_DIGEST_CHECK) OSSL_PARAM_END }; @@ -433,6 +481,7 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_DEFN(OSSL_EXCHANGE_PARAM_KDF_UKM, OSSL_PARAM_OCTET_PTR, NULL, 0), OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_CEK_ALG, NULL, 0), + OSSL_FIPS_IND_GETTABLE_CTX_PARAM() OSSL_PARAM_END }; @@ -473,7 +522,7 @@ static int dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[]) if (p != NULL && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_md == NULL ? "" - : EVP_MD_get0_name(pdhctx->kdf_md))){ + : EVP_MD_get0_name(pdhctx->kdf_md))) { return 0; } @@ -491,7 +540,8 @@ static int dh_get_ctx_params(void *vpdhctx, OSSL_PARAM params[]) && !OSSL_PARAM_set_utf8_string(p, pdhctx->kdf_cekalg == NULL ? "" : pdhctx->kdf_cekalg)) return 0; - + if (!OSSL_FIPS_IND_GET_CTX_PARAM(pdhctx, params)) + return 0; return 1; } @@ -508,5 +558,5 @@ const OSSL_DISPATCH ossl_dh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))dh_get_ctx_params }, { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, (void (*)(void))dh_gettable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END }; |