diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 99947824..641d1307 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -538,29 +538,58 @@ static int wp_ecx_set_params(wp_Ecx* ecx, const OSSL_PARAM params[]) return ok; } +#if defined(WP_HAVE_X25519) || defined(WP_HAVE_X448) +/** + * Return an array of supported gettable parameters for the X25519/X448 key. + * + * @param [in] provCtx Provider context object. Unused. + * @return Array of parameters with data type. + */ +static const OSSL_PARAM* wp_ecx_x_gettable_params(WOLFPROV_CTX* provCtx) +{ + /** + * Supported gettable parameters for X25519/X448 key object. + */ + static const OSSL_PARAM wp_ecx_x_supported_gettable_params[] = { + OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), + OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), + OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_END + }; + (void)provCtx; + return wp_ecx_x_supported_gettable_params; +} +#endif + +#if defined(WP_HAVE_ED25519) || defined(WP_HAVE_ED448) /** - * Return an array of supported gettable parameters for the ECX key object. + * Return an array of supported gettable parameters for the Ed25519/Ed448 key. * * @param [in] provCtx Provider context object. Unused. * @return Array of parameters with data type. */ -static const OSSL_PARAM* wp_ecx_gettable_params(WOLFPROV_CTX* provCtx) +static const OSSL_PARAM* wp_ecx_ed_gettable_params(WOLFPROV_CTX* provCtx) { /** - * Supported gettable parameters for ECX key object. + * Supported gettable parameters for Ed25519/Ed448 key object. */ - static const OSSL_PARAM wp_ecx_supported_gettable_params[] = { + static const OSSL_PARAM wp_ecx_ed_supported_gettable_params[] = { OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0), OSSL_PARAM_END }; (void)provCtx; - return wp_ecx_supported_gettable_params; + return wp_ecx_ed_supported_gettable_params; } +#endif /** * Get the security bits for an ECX key. @@ -728,6 +757,14 @@ static int wp_ecx_get_params(wp_Ecx* ecx, OSSL_PARAM params[]) if (ok && (!wp_ecx_get_params_priv_key(ecx, params))) { ok = 0; } + if (ok && ((ecx->data->keyType == WP_KEY_TYPE_ED25519) || + (ecx->data->keyType == WP_KEY_TYPE_ED448))) { + /* Pure EdDSA: no digest. */ + p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MANDATORY_DIGEST); + if ((p != NULL) && !OSSL_PARAM_set_utf8_string(p, "")) { + ok = 0; + } + } WOLFPROV_LEAVE(WP_LOG_COMP_KE, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; @@ -1507,7 +1544,7 @@ const OSSL_DISPATCH wp_##alg##_keymgmt_functions[] = { \ { OSSL_FUNC_KEYMGMT_LOAD, (DFUNC)wp_ecx_load }, \ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (DFUNC)wp_ecx_get_params }, \ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, \ - (DFUNC)wp_ecx_gettable_params }, \ + (DFUNC)wp_ecx_##type##_gettable_params }, \ { OSSL_FUNC_KEYMGMT_SET_PARAMS, (DFUNC)wp_ecx_set_params }, \ { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, \ (DFUNC)wp_ecx_settable_params }, \ diff --git a/test/test_ecx.c b/test/test_ecx.c index faa83124..aaa928ab 100644 --- a/test/test_ecx.c +++ b/test/test_ecx.c @@ -1731,6 +1731,64 @@ int test_ecx_x_security_bits(void *data) #if defined(WP_HAVE_X25519) || defined(WP_HAVE_ED25519) || \ defined(WP_HAVE_X448) || defined(WP_HAVE_ED448) +/* Ed keys mandate no digest (one-shot signing); X keys have no default. */ +int test_ecx_default_digest(void *data) +{ + static const struct { + const char* name; + int isEd; + } types[] = { +#ifdef WP_HAVE_X25519 + { "X25519", 0 }, +#endif +#ifdef WP_HAVE_ED25519 + { "ED25519", 1 }, +#endif +#ifdef WP_HAVE_X448 + { "X448", 0 }, +#endif +#ifdef WP_HAVE_ED448 + { "ED448", 1 }, +#endif + }; + OSSL_LIB_CTX* libCtxs[2]; + int err = 0; + size_t i, j; + + (void)data; + libCtxs[0] = osslLibCtx; + libCtxs[1] = wpLibCtx; + + for (i = 0; (err == 0) && (i < ARRAY_SIZE(types)); i++) { + for (j = 0; (err == 0) && (j < ARRAY_SIZE(libCtxs)); j++) { + char md[32] = ""; + int rv; + int gettable; + EVP_PKEY* pkey = EVP_PKEY_Q_keygen(libCtxs[j], NULL, + types[i].name); + + err = (pkey == NULL); + if (err == 0) { + rv = EVP_PKEY_get_default_digest_name(pkey, md, sizeof(md)); + gettable = OSSL_PARAM_locate_const( + EVP_PKEY_gettable_params(pkey), + OSSL_PKEY_PARAM_MANDATORY_DIGEST) != NULL; + if ((rv != (types[i].isEd ? 2 : -2)) || + (types[i].isEd && (strcmp(md, "UNDEF") != 0)) || + ((j == 1) && (gettable != types[i].isEd))) { + PRINT_MSG("%s default digest (%s): %d '%s' gettable %d", + types[i].name, (j == 0) ? "OpenSSL" : "wolfProvider", + rv, md, gettable); + err = 1; + } + } + EVP_PKEY_free(pkey); + } + } + + return err; +} + int test_ecx_encoder_import_object(void *data) { static const char* names[] = { diff --git a/test/unit.c b/test/unit.c index be7f72a2..20d1cdcd 100644 --- a/test/unit.c +++ b/test/unit.c @@ -602,6 +602,7 @@ TEST_CASE test_case[] = { #endif #if defined(WP_HAVE_X25519) || defined(WP_HAVE_ED25519) || \ defined(WP_HAVE_X448) || defined(WP_HAVE_ED448) + TEST_DECL(test_ecx_default_digest, NULL), TEST_DECL(test_ecx_encoder_import_object, NULL), #endif diff --git a/test/unit.h b/test/unit.h index 35bc245b..e9b40511 100644 --- a/test/unit.h +++ b/test/unit.h @@ -639,6 +639,7 @@ int test_ecx_x_security_bits(void *data); #if defined(WP_HAVE_X25519) || defined(WP_HAVE_ED25519) || \ defined(WP_HAVE_X448) || defined(WP_HAVE_ED448) +int test_ecx_default_digest(void *data); int test_ecx_encoder_import_object(void *data); #endif