diff options
Diffstat (limited to 'src/lib/crypto/dl_ossl.cpp')
-rw-r--r-- | src/lib/crypto/dl_ossl.cpp | 118 |
1 files changed, 94 insertions, 24 deletions
diff --git a/src/lib/crypto/dl_ossl.cpp b/src/lib/crypto/dl_ossl.cpp index 1e96218..4845baa 100644 --- a/src/lib/crypto/dl_ossl.cpp +++ b/src/lib/crypto/dl_ossl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, [Ribose Inc](https://www.ribose.com). + * Copyright (c) 2021, 2023 [Ribose Inc](https://www.ribose.com). * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -33,6 +33,34 @@ #include <openssl/dh.h> #include <openssl/err.h> #include <openssl/evp.h> +#if defined(CRYPTO_BACKEND_OPENSSL3) +#include <openssl/core_names.h> +#include <openssl/param_build.h> +#endif + +#if defined(CRYPTO_BACKEND_OPENSSL3) +static OSSL_PARAM * +dl_build_params(bignum_t *p, bignum_t *q, bignum_t *g, bignum_t *y, bignum_t *x) +{ + OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new(); + if (!bld) { + return NULL; // LCOV_EXCL_LINE + } + if (!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p) || + (q && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q)) || + !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g) || + !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, y) || + (x && !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, x))) { + /* LCOV_EXCL_START */ + OSSL_PARAM_BLD_free(bld); + return NULL; + /* LCOV_EXCL_END */ + } + OSSL_PARAM *param = OSSL_PARAM_BLD_to_param(bld); + OSSL_PARAM_BLD_free(bld); + return param; +} +#endif EVP_PKEY * dl_load_key(const pgp_mpi_t &mp, @@ -41,63 +69,89 @@ dl_load_key(const pgp_mpi_t &mp, const pgp_mpi_t &my, const pgp_mpi_t *mx) { - DH * dh = NULL; EVP_PKEY *evpkey = NULL; - bignum_t *p = mpi2bn(&mp); - bignum_t *q = mq ? mpi2bn(mq) : NULL; - bignum_t *g = mpi2bn(&mg); - bignum_t *y = mpi2bn(&my); - bignum_t *x = mx ? mpi2bn(mx) : NULL; + rnp::bn p(mpi2bn(&mp)); + rnp::bn q(mq ? mpi2bn(mq) : NULL); + rnp::bn g(mpi2bn(&mg)); + rnp::bn y(mpi2bn(&my)); + rnp::bn x(mx ? mpi2bn(mx) : NULL); - if (!p || (mq && !q) || !g || !y || (mx && !x)) { + if (!p.get() || (mq && !q.get()) || !g.get() || !y.get() || (mx && !x.get())) { + /* LCOV_EXCL_START */ RNP_LOG("out of memory"); - goto done; + return NULL; + /* LCOV_EXCL_END */ } - dh = DH_new(); +#if defined(CRYPTO_BACKEND_OPENSSL3) + OSSL_PARAM *params = dl_build_params(p.get(), q.get(), g.get(), y.get(), x.get()); + if (!params) { + /* LCOV_EXCL_START */ + RNP_LOG("failed to build dsa params"); + return NULL; + /* LCOV_EXCL_END */ + } + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); + if (!ctx) { + /* LCOV_EXCL_START */ + RNP_LOG("failed to create dl context"); + OSSL_PARAM_free(params); + return NULL; + /* LCOV_EXCL_END */ + } + if ((EVP_PKEY_fromdata_init(ctx) != 1) || + (EVP_PKEY_fromdata( + ctx, &evpkey, mx ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY, params) != 1)) { + /* LCOV_EXCL_START */ + RNP_LOG("failed to create key from data"); + evpkey = NULL; + /* LCOV_EXCL_END */ + } + OSSL_PARAM_free(params); + EVP_PKEY_CTX_free(ctx); + return evpkey; +#else + DH *dh = DH_new(); if (!dh) { + /* LCOV_EXCL_START */ RNP_LOG("out of memory"); - goto done; + return NULL; + /* LCOV_EXCL_END */ } - int res; /* line below must not fail */ - res = DH_set0_pqg(dh, p, q, g); + int res = DH_set0_pqg(dh, p.own(), q.own(), g.own()); assert(res == 1); if (res < 1) { goto done; } - p = NULL; - q = NULL; - g = NULL; /* line below must not fail */ - res = DH_set0_key(dh, y, x); + res = DH_set0_key(dh, y.own(), x.own()); assert(res == 1); if (res < 1) { goto done; } - y = NULL; - x = NULL; evpkey = EVP_PKEY_new(); if (!evpkey) { + /* LCOV_EXCL_START */ RNP_LOG("allocation failed"); goto done; + /* LCOV_EXCL_END */ } if (EVP_PKEY_set1_DH(evpkey, dh) <= 0) { + /* LCOV_EXCL_START */ RNP_LOG("Failed to set key: %lu", ERR_peek_last_error()); EVP_PKEY_free(evpkey); evpkey = NULL; + /* LCOV_EXCL_END */ } done: DH_free(dh); - bn_free(p); - bn_free(q); - bn_free(g); - bn_free(y); - bn_free(x); return evpkey; +#endif } +#if !defined(CRYPTO_BACKEND_OPENSSL3) static rnp_result_t dl_validate_secret_key(EVP_PKEY *dlkey, const pgp_mpi_t &mx) { @@ -117,22 +171,28 @@ dl_validate_secret_key(EVP_PKEY *dlkey, const pgp_mpi_t &mx) bignum_t *cy = bn_new(); if (!x || !cy || !ctx) { + /* LCOV_EXCL_START */ RNP_LOG("Allocation failed"); goto done; + /* LCOV_EXCL_END */ } if (!q) { /* if q is NULL then group order is (p - 1) / 2 */ p1 = BN_dup(p); if (!p1) { + /* LCOV_EXCL_START */ RNP_LOG("Allocation failed"); goto done; + /* LCOV_EXCL_END */ } int res; res = BN_rshift(p1, p1, 1); assert(res == 1); if (res < 1) { + /* LCOV_EXCL_START */ RNP_LOG("BN_rshift failed."); goto done; + /* LCOV_EXCL_END */ } q = p1; } @@ -154,6 +214,7 @@ done: bn_free(p1); return ret; } +#endif rnp_result_t dl_validate_key(EVP_PKEY *pkey, const pgp_mpi_t *x) @@ -161,8 +222,10 @@ dl_validate_key(EVP_PKEY *pkey, const pgp_mpi_t *x) rnp_result_t ret = RNP_ERROR_GENERIC; EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); if (!ctx) { + /* LCOV_EXCL_START */ RNP_LOG("Context allocation failed: %lu", ERR_peek_last_error()); goto done; + /* LCOV_EXCL_END */ } int res; res = EVP_PKEY_param_check(ctx); @@ -181,6 +244,12 @@ dl_validate_key(EVP_PKEY *pkey, const pgp_mpi_t *x) goto done; } } +#if defined(CRYPTO_BACKEND_OPENSSL3) + res = x ? EVP_PKEY_pairwise_check(ctx) : EVP_PKEY_public_check(ctx); + if (res == 1) { + ret = RNP_SUCCESS; + } +#else res = EVP_PKEY_public_check(ctx); if (res < 0) { RNP_LOG("Key validation error: %lu", ERR_peek_last_error()); @@ -194,6 +263,7 @@ dl_validate_key(EVP_PKEY *pkey, const pgp_mpi_t *x) goto done; } ret = dl_validate_secret_key(pkey, *x); +#endif done: EVP_PKEY_CTX_free(ctx); return ret; |