2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

use deterministic ecdsa for openssl >= 3.2

OpenSSL has added support for deterministic ECDSA (RFC 6979) with
version 3.2.

Use it by default as derandomization doesn't pose a risk for DNS
usecases and is allowed by FIPS 186-5.
This commit is contained in:
Aydın Mercan 2024-07-08 14:53:26 +03:00
parent 8b70722fcb
commit 596903a6b7
No known key found for this signature in database
2 changed files with 100 additions and 2 deletions

View File

@ -56,6 +56,37 @@
goto err; \
}
#if OPENSSL_VERSION_NUMBER >= 0x30200000L
static isc_result_t
opensslecdsa_set_deterministic(EVP_PKEY_CTX *pctx, unsigned int key_alg) {
unsigned int rfc6979 = 1;
const char *md = NULL;
OSSL_PARAM params[3];
switch (key_alg) {
case DST_ALG_ECDSA256:
md = "SHA256";
break;
case DST_ALG_ECDSA384:
md = "SHA384";
break;
default:
UNREACHABLE();
}
params[0] = OSSL_PARAM_construct_utf8_string("digest", UNCONST(md), 0);
params[1] = OSSL_PARAM_construct_uint("nonce-type", &rfc6979);
params[2] = OSSL_PARAM_construct_end();
if (EVP_PKEY_CTX_set_params(pctx, params) != 1) {
return dst__openssl_toresult2("EVP_PKEY_CTX_set_params",
DST_R_OPENSSLFAILURE);
}
return ISC_R_SUCCESS;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x30200000L */
static bool
opensslecdsa_valid_key_alg(unsigned int key_alg) {
switch (key_alg) {
@ -510,12 +541,12 @@ opensslecdsa_generate_pkey(unsigned int key_alg, const char *label,
DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new",
DST_R_OPENSSLFAILURE));
}
status = EVP_PKEY_keygen_init(ctx);
if (status != 1) {
DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init",
DST_R_OPENSSLFAILURE));
}
status = EVP_PKEY_keygen(ctx, retkey);
if (status != 1) {
DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen",
@ -647,6 +678,7 @@ static isc_result_t
opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_result_t ret = ISC_R_SUCCESS;
EVP_MD_CTX *evp_md_ctx;
EVP_PKEY_CTX *pctx = NULL;
const EVP_MD *type = NULL;
UNUSED(key);
@ -664,7 +696,7 @@ opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
}
if (dctx->use == DO_SIGN) {
if (EVP_DigestSignInit(evp_md_ctx, NULL, type, NULL,
if (EVP_DigestSignInit(evp_md_ctx, &pctx, type, NULL,
dctx->key->keydata.pkeypair.priv) != 1)
{
EVP_MD_CTX_destroy(evp_md_ctx);
@ -672,6 +704,14 @@ opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
"EVP_DigestSignInit",
ISC_R_FAILURE));
}
#if OPENSSL_VERSION_NUMBER >= 0x30200000L
ret = opensslecdsa_set_deterministic(pctx, dctx->key->key_alg);
if (ret != ISC_R_SUCCESS) {
goto err;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x30200000L */
} else {
if (EVP_DigestVerifyInit(evp_md_ctx, NULL, type, NULL,
dctx->key->keydata.pkeypair.pub) != 1)

View File

@ -421,9 +421,67 @@ ISC_RUN_TEST_IMPL(cmp_test) {
}
}
ISC_RUN_TEST_IMPL(ecdsa_determinism_test) {
isc_result_t result;
isc_buffer_t *sigbuf1 = NULL, *sigbuf2 = NULL;
isc_buffer_t databuf, keybuf;
isc_region_t datareg;
dns_fixedname_t fname;
dns_name_t *name = NULL;
dst_key_t *key = NULL;
dst_context_t *ctx = NULL;
unsigned int siglen;
const char *data = "these are some bytes to sign";
isc_buffer_constinit(&databuf, data, strlen(data));
isc_buffer_add(&databuf, strlen(data));
isc_buffer_region(&databuf, &datareg);
name = dns_fixedname_initname(&fname);
isc_buffer_constinit(&keybuf, "example.", strlen("example."));
isc_buffer_add(&keybuf, strlen("example."));
result = dns_name_fromtext(name, &keybuf, dns_rootname, 0, NULL);
assert_int_equal(result, ISC_R_SUCCESS);
result = dst_key_fromfile(name, 19786, DST_ALG_ECDSA256,
DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
TESTS_DIR "/comparekeys", mctx, &key);
assert_int_equal(result, ISC_R_SUCCESS);
result = dst_key_sigsize(key, &siglen);
assert_int_equal(result, ISC_R_SUCCESS);
isc_buffer_allocate(mctx, &sigbuf1, siglen);
result = dst_context_create(key, mctx, DNS_LOGCATEGORY_GENERAL, true, 0,
&ctx);
assert_int_equal(result, ISC_R_SUCCESS);
result = dst_context_sign(ctx, sigbuf1);
assert_int_equal(result, ISC_R_SUCCESS);
dst_context_destroy(&ctx);
isc_buffer_allocate(mctx, &sigbuf2, siglen);
result = dst_context_create(key, mctx, DNS_LOGCATEGORY_GENERAL, true, 0,
&ctx);
assert_int_equal(result, ISC_R_SUCCESS);
result = dst_context_sign(ctx, sigbuf2);
assert_int_equal(result, ISC_R_SUCCESS);
dst_context_destroy(&ctx);
#if OPENSSL_VERSION_NUMBER >= 0x30200000L
assert_memory_equal(sigbuf1->base, sigbuf2->base, siglen);
#else
assert_memory_not_equal(sigbuf1->base, sigbuf2->base, siglen);
#endif
isc_buffer_free(&sigbuf1);
isc_buffer_free(&sigbuf2);
dst_key_free(&key);
}
ISC_TEST_LIST_START
ISC_TEST_ENTRY(sig_test)
ISC_TEST_ENTRY(cmp_test)
ISC_TEST_ENTRY(ecdsa_determinism_test)
ISC_TEST_LIST_END
ISC_TEST_MAIN