mirror of
https://github.com/openssl/openssl.git
synced 2025-01-19 16:33:33 +08:00
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)
This commit is contained in:
parent
5adca946c3
commit
e8add4d379
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user