diff options
author | slontis <shane.lontis@oracle.com> | 2022-12-20 13:44:18 +1000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2023-01-12 12:13:47 +0100 |
commit | e8add4d379075a6daef2591edd830297d469b9f4 (patch) | |
tree | 0c00fa3f52019c49ec1102ab9b65cbaabc142973 /providers | |
parent | 5adca946c3b6f779eb593bff6dbefe0a85238d84 (diff) | |
download | openssl-new-e8add4d379075a6daef2591edd830297d469b9f4.tar.gz |
SSKDF with KMAC should return SIZE_MAX when EVP_KDF_CTX_get_kdf_size()
is used.
Fixes #19934
The existing code was looking for the digest size, and then returned
zero.
The example code in EVP_KDF-SS.pod has been corrected to not use a
digest.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19935)
Diffstat (limited to 'providers')
-rw-r--r-- | providers/implementations/kdfs/sskdf.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c index 378aeb5d30..68408bb03b 100644 --- a/providers/implementations/kdfs/sskdf.c +++ b/providers/implementations/kdfs/sskdf.c @@ -62,6 +62,7 @@ typedef struct { unsigned char *salt; size_t salt_len; size_t out_len; /* optional KMAC parameter */ + int is_kmac; } KDF_SSKDF; #define SSKDF_MAX_INLEN (1<<30) @@ -340,6 +341,7 @@ static void *sskdf_dup(void *vctx) || !ossl_prov_digest_copy(&dest->digest, &src->digest)) goto err; dest->out_len = src->out_len; + dest->is_kmac = src->is_kmac; } return dest; @@ -361,8 +363,12 @@ static int sskdf_set_buffer(unsigned char **out, size_t *out_len, static size_t sskdf_size(KDF_SSKDF *ctx) { int len; - const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); + const EVP_MD *md = NULL; + if (ctx->is_kmac) + return SIZE_MAX; + + md = ossl_prov_digest_md(&ctx->digest); if (md == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); return 0; @@ -402,8 +408,7 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen, default_salt_len = EVP_MD_get_size(md); if (default_salt_len <= 0) return 0; - } else if (EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC128) - || EVP_MAC_is_a(mac, OSSL_MAC_NAME_KMAC256)) { + } else if (ctx->is_kmac) { /* H(x) = KMACzzz(x, salt, custom) */ custom = kmac_custom_str; custom_len = sizeof(kmac_custom_str); @@ -479,12 +484,20 @@ static int sskdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) if (params == NULL) return 1; - if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) - return 0; - if (!ossl_prov_macctx_load_from_params(&ctx->macctx, params, NULL, NULL, NULL, libctx)) return 0; + if (ctx->macctx != NULL) { + if (EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), + OSSL_MAC_NAME_KMAC128) + || EVP_MAC_is_a(EVP_MAC_CTX_get0_mac(ctx->macctx), + OSSL_MAC_NAME_KMAC256)) { + ctx->is_kmac = 1; + } + } + + if (!ossl_prov_digest_load_from_params(&ctx->digest, params, libctx)) + return 0; if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL || (p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY)) != NULL) |