From: Timo Teräs Date: Sat, 28 Jan 2023 10:53:14 +0000 (+0200) Subject: OpenSSL EDDSA introduce and use openssleddsa_alg_info() X-Git-Tag: v9.19.12~93^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=28da7670b63bb4117c722e4a8a9973522e583f42;p=thirdparty%2Fbind9.git OpenSSL EDDSA introduce and use openssleddsa_alg_info() Move the common code into a helper function that returns the EDDSA parameters (pkey type, nid, keysize, sigsize). --- diff --git a/lib/dns/openssleddsa_link.c b/lib/dns/openssleddsa_link.c index f89672b26e1..331292f0158 100644 --- a/lib/dns/openssleddsa_link.c +++ b/lib/dns/openssleddsa_link.c @@ -56,28 +56,44 @@ #endif /* ifndef NID_ED448 */ #endif /* HAVE_OPENSSL_ED448 */ -static isc_result_t -raw_key_to_ossl(unsigned int key_alg, int private, const unsigned char *key, - size_t *key_len, EVP_PKEY **pkey) { - isc_result_t ret; - int pkey_type = EVP_PKEY_NONE; - size_t len = 0; +typedef struct eddsa_alginfo { + int pkey_type, nid; + unsigned int key_size, sig_size; +} eddsa_alginfo_t; +static const eddsa_alginfo_t * +openssleddsa_alg_info(unsigned int key_alg) { #if HAVE_OPENSSL_ED25519 if (key_alg == DST_ALG_ED25519) { - pkey_type = EVP_PKEY_ED25519; - len = DNS_KEY_ED25519SIZE; + static const eddsa_alginfo_t ed25519_alginfo = { + .pkey_type = EVP_PKEY_ED25519, + .nid = NID_ED25519, + .key_size = DNS_KEY_ED25519SIZE, + .sig_size = DNS_SIG_ED25519SIZE, + }; + return &ed25519_alginfo; } #endif /* HAVE_OPENSSL_ED25519 */ #if HAVE_OPENSSL_ED448 if (key_alg == DST_ALG_ED448) { - pkey_type = EVP_PKEY_ED448; - len = DNS_KEY_ED448SIZE; + static const eddsa_alginfo_t ed448_alginfo = { + .pkey_type = EVP_PKEY_ED448, + .nid = NID_ED448, + .key_size = DNS_KEY_ED448SIZE, + .sig_size = DNS_SIG_ED448SIZE, + }; + return &ed448_alginfo; } #endif /* HAVE_OPENSSL_ED448 */ - if (pkey_type == EVP_PKEY_NONE) { - return (ISC_R_NOTIMPLEMENTED); - } + return NULL; +} + +static isc_result_t +raw_key_to_ossl(const eddsa_alginfo_t *alginfo, int private, + const unsigned char *key, size_t *key_len, EVP_PKEY **pkey) { + isc_result_t ret; + int pkey_type = alginfo->pkey_type; + size_t len = alginfo->key_size; ret = (private ? DST_R_INVALIDPRIVATEKEY : DST_R_INVALIDPUBLICKEY); if (*key_len < len) { @@ -104,10 +120,11 @@ openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, static isc_result_t openssleddsa_createctx(dst_key_t *key, dst_context_t *dctx) { isc_buffer_t *buf = NULL; + const eddsa_alginfo_t *alginfo = + openssleddsa_alg_info(dctx->key->key_alg); UNUSED(key); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); isc_buffer_allocate(dctx->mctx, &buf, 64); dctx->ctxdata.generic = buf; @@ -118,9 +135,10 @@ openssleddsa_createctx(dst_key_t *key, dst_context_t *dctx) { static void openssleddsa_destroyctx(dst_context_t *dctx) { isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; + const eddsa_alginfo_t *alginfo = + openssleddsa_alg_info(dctx->key->key_alg); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (buf != NULL) { isc_buffer_free(&buf); } @@ -134,9 +152,10 @@ openssleddsa_adddata(dst_context_t *dctx, const isc_region_t *data) { isc_region_t r; unsigned int length; isc_result_t result; + const eddsa_alginfo_t *alginfo = + openssleddsa_alg_info(dctx->key->key_alg); - REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 || - dctx->key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); result = isc_buffer_copyregion(buf, data); if (result == ISC_R_SUCCESS) { @@ -163,21 +182,16 @@ openssleddsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { EVP_PKEY *pkey = key->keydata.pkey; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); size_t siglen; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (ctx == NULL) { return (ISC_R_NOMEMORY); } - if (key->key_alg == DST_ALG_ED25519) { - siglen = DNS_SIG_ED25519SIZE; - } else { - siglen = DNS_SIG_ED448SIZE; - } - + siglen = alginfo->sig_size; isc_buffer_availableregion(sig, &sigreg); if (sigreg.length < (unsigned int)siglen) { DST_RET(ISC_R_NOSPACE); @@ -215,30 +229,15 @@ openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { EVP_PKEY *pkey = key->keydata.pkey; EVP_MD_CTX *ctx = EVP_MD_CTX_new(); isc_buffer_t *buf = (isc_buffer_t *)dctx->ctxdata.generic; - unsigned int siglen = 0; + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (ctx == NULL) { return (ISC_R_NOMEMORY); } -#if HAVE_OPENSSL_ED25519 - if (key->key_alg == DST_ALG_ED25519) { - siglen = DNS_SIG_ED25519SIZE; - } -#endif /* if HAVE_OPENSSL_ED25519 */ -#if HAVE_OPENSSL_ED448 - if (key->key_alg == DST_ALG_ED448) { - siglen = DNS_SIG_ED448SIZE; - } -#endif /* if HAVE_OPENSSL_ED448 */ - if (siglen == 0) { - DST_RET(ISC_R_NOTIMPLEMENTED); - } - - if (sig->length != siglen) { + if (sig->length != alginfo->sig_size) { DST_RET(DST_R_VERIFYFAILURE); } @@ -249,7 +248,7 @@ openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { dctx->category, "EVP_DigestVerifyInit", ISC_R_FAILURE)); } - status = EVP_DigestVerify(ctx, sig->base, siglen, tbsreg.base, + status = EVP_DigestVerify(ctx, sig->base, sig->length, tbsreg.base, tbsreg.length); switch (status) { @@ -297,30 +296,14 @@ openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { isc_result_t ret; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; - int nid = 0, status; + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); + int status; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); UNUSED(unused); UNUSED(callback); -#if HAVE_OPENSSL_ED25519 - if (key->key_alg == DST_ALG_ED25519) { - nid = NID_ED25519; - key->key_size = DNS_KEY_ED25519SIZE * 8; - } -#endif /* if HAVE_OPENSSL_ED25519 */ -#if HAVE_OPENSSL_ED448 - if (key->key_alg == DST_ALG_ED448) { - nid = NID_ED448; - key->key_size = DNS_KEY_ED448SIZE * 8; - } -#endif /* if HAVE_OPENSSL_ED448 */ - if (nid == 0) { - return (ISC_R_NOTIMPLEMENTED); - } - - ctx = EVP_PKEY_CTX_new_id(nid, NULL); + ctx = EVP_PKEY_CTX_new_id(alginfo->nid, NULL); if (ctx == NULL) { return (dst__openssl_toresult2("EVP_PKEY_CTX_new_id", DST_R_OPENSSLFAILURE)); @@ -338,6 +321,7 @@ openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { DST_R_OPENSSLFAILURE)); } + key->key_size = alginfo->key_size * 8; key->keydata.pkey = pkey; ret = ISC_R_SUCCESS; @@ -376,20 +360,15 @@ openssleddsa_destroy(dst_key_t *key) { static isc_result_t openssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); EVP_PKEY *pkey = key->keydata.pkey; isc_region_t r; size_t len; REQUIRE(pkey != NULL); - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - - if (key->key_alg == DST_ALG_ED25519) { - len = DNS_KEY_ED25519SIZE; - } else { - len = DNS_KEY_ED448SIZE; - } + REQUIRE(alginfo != NULL); + len = alginfo->key_size; isc_buffer_availableregion(data, &r); if (r.length < len) { return (ISC_R_NOSPACE); @@ -405,13 +384,13 @@ openssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) { static isc_result_t openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); isc_result_t ret; isc_region_t r; size_t len; EVP_PKEY *pkey; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); isc_buffer_remainingregion(data, &r); if (r.length == 0) { @@ -419,7 +398,7 @@ openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { } len = r.length; - ret = raw_key_to_ossl(key->key_alg, 0, r.base, &len, &pkey); + ret = raw_key_to_ossl(alginfo, 0, r.base, &len, &pkey); if (ret != ISC_R_SUCCESS) { return ret; } @@ -432,14 +411,14 @@ openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { static isc_result_t openssleddsa_tofile(const dst_key_t *key, const char *directory) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); isc_result_t ret; dst_private_t priv; unsigned char *buf = NULL; size_t len; int i; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); if (key->keydata.pkey == NULL) { return (DST_R_NULLKEY); @@ -453,11 +432,7 @@ openssleddsa_tofile(const dst_key_t *key, const char *directory) { i = 0; if (openssleddsa_isprivate(key)) { - if (key->key_alg == DST_ALG_ED25519) { - len = DNS_KEY_ED25519SIZE; - } else { - len = DNS_KEY_ED448SIZE; - } + len = alginfo->key_size; buf = isc_mem_get(key->mctx, len); if (EVP_PKEY_get_raw_private_key(key->keydata.pkey, buf, &len) != 1) @@ -507,6 +482,7 @@ eddsa_check(EVP_PKEY *pkey, EVP_PKEY *pubpkey) { static isc_result_t openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); dst_private_t priv; isc_result_t ret; int i, privkey_index = -1; @@ -515,8 +491,7 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { size_t len; isc_mem_t *mctx = key->mctx; - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); + REQUIRE(alginfo != NULL); /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_ED25519, lexer, mctx, &priv); @@ -574,8 +549,8 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } len = priv.elements[privkey_index].length; - ret = raw_key_to_ossl(key->key_alg, 1, - priv.elements[privkey_index].data, &len, &pkey); + ret = raw_key_to_ossl(alginfo, 1, priv.elements[privkey_index].data, + &len, &pkey); if (ret != ISC_R_SUCCESS) { goto err; } @@ -597,29 +572,13 @@ static isc_result_t openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, const char *pin) { #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 + const eddsa_alginfo_t *alginfo = openssleddsa_alg_info(key->key_alg); isc_result_t ret; ENGINE *e; EVP_PKEY *pkey = NULL, *pubpkey = NULL; - int baseid = EVP_PKEY_NONE; UNUSED(pin); - - REQUIRE(key->key_alg == DST_ALG_ED25519 || - key->key_alg == DST_ALG_ED448); - -#if HAVE_OPENSSL_ED25519 - if (key->key_alg == DST_ALG_ED25519) { - baseid = EVP_PKEY_ED25519; - } -#endif /* if HAVE_OPENSSL_ED25519 */ -#if HAVE_OPENSSL_ED448 - if (key->key_alg == DST_ALG_ED448) { - baseid = EVP_PKEY_ED448; - } -#endif /* if HAVE_OPENSSL_ED448 */ - if (baseid == EVP_PKEY_NONE) { - return (ISC_R_NOTIMPLEMENTED); - } + REQUIRE(alginfo != NULL); if (engine == NULL) { return (DST_R_NOENGINE); @@ -633,7 +592,7 @@ openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, return (dst__openssl_toresult2("ENGINE_load_private_key", ISC_R_NOTFOUND)); } - if (EVP_PKEY_base_id(pkey) != baseid) { + if (EVP_PKEY_base_id(pkey) != alginfo->pkey_type) { DST_RET(DST_R_INVALIDPRIVATEKEY); }