diff options
-rw-r--r-- | doc/man7/EVP_KDF-SS.pod | 6 | ||||
-rw-r--r-- | providers/implementations/kdfs/sskdf.c | 25 | ||||
-rw-r--r-- | test/evp_kdf_test.c | 13 |
3 files changed, 33 insertions, 11 deletions
diff --git a/doc/man7/EVP_KDF-SS.pod b/doc/man7/EVP_KDF-SS.pod index 7f7f992fe1..fbc4a6acec 100644 --- a/doc/man7/EVP_KDF-SS.pod +++ b/doc/man7/EVP_KDF-SS.pod @@ -43,6 +43,8 @@ The supported parameters are: =item "digest" (B<OSSL_KDF_PARAM_DIGEST>) <UTF8 string> +This parameter is ignored for KMAC. + =item "mac" (B<OSSL_KDF_PARAM_MAC>) <UTF8 string> =item "maclen" (B<OSSL_KDF_PARAM_MAC_SIZE>) <unsigned integer> @@ -133,7 +135,7 @@ fixedinfo value "label", salt of "salt" and KMAC outlen of 20: EVP_KDF *kdf; EVP_KDF_CTX *kctx; unsigned char out[10]; - OSSL_PARAM params[7], *p = params; + OSSL_PARAM params[6], *p = params; kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); kctx = EVP_KDF_CTX_new(kdf); @@ -141,8 +143,6 @@ fixedinfo value "label", salt of "salt" and KMAC outlen of 20: *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, SN_kmac128, strlen(SN_kmac128)); - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, - SN_sha256, strlen(SN_sha256)); *p++ = OSSL_PARAM_construct_octet_string(EVP_KDF_CTRL_SET_KEY, "secret", (size_t)6); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, 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) diff --git a/test/evp_kdf_test.c b/test/evp_kdf_test.c index e020c0e47d..fb30fca1ef 100644 --- a/test/evp_kdf_test.c +++ b/test/evp_kdf_test.c @@ -1528,6 +1528,7 @@ static int test_kdf_kbkdf_kmac(void) kctx = get_kdfbyname("KBKDF"); ret = TEST_ptr(kctx) + && TEST_size_t_eq(EVP_KDF_CTX_get_kdf_size(kctx), SIZE_MAX) && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result), params), 0) && TEST_mem_eq(result, sizeof(result), output, sizeof(output)); @@ -1580,7 +1581,7 @@ static int test_kdf_ss_kmac(void) { int ret; EVP_KDF_CTX *kctx; - OSSL_PARAM params[6], *p = params; + OSSL_PARAM params[7], *p = params; unsigned char out[64]; size_t mac_size = 20; static unsigned char z[] = { @@ -1603,6 +1604,9 @@ static int test_kdf_ss_kmac(void) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, (char *)OSSL_MAC_NAME_KMAC128, 0); + /* The digest parameter is not needed here and should be ignored */ + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)"SHA256", 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, z, sizeof(z)); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, other, sizeof(other)); @@ -1613,7 +1617,12 @@ static int test_kdf_ss_kmac(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSKDF)) - && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), params), 0) + && TEST_size_t_eq(EVP_KDF_CTX_get_kdf_size(kctx), 0) + && TEST_int_eq(EVP_KDF_CTX_set_params(kctx, params), 1) + /* The bug fix for KMAC returning SIZE_MAX was added in 3.0.8 */ + && (fips_provider_version_lt(NULL, 3, 0, 8) + || TEST_size_t_eq(EVP_KDF_CTX_get_kdf_size(kctx), SIZE_MAX)) + && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out), NULL), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); EVP_KDF_CTX_free(kctx); |