diff options
Diffstat (limited to 'providers/common')
-rw-r--r-- | providers/common/build.info | 2 | ||||
-rw-r--r-- | providers/common/exchange/build.info | 2 | ||||
-rw-r--r-- | providers/common/exchange/dh_exch.c (renamed from providers/common/exchange/dh.c) | 70 | ||||
-rw-r--r-- | providers/common/include/internal/provider_algs.h | 5 | ||||
-rw-r--r-- | providers/common/keymgmt/build.info | 5 | ||||
-rw-r--r-- | providers/common/keymgmt/dh_kmgmt.c | 88 |
6 files changed, 113 insertions, 59 deletions
diff --git a/providers/common/build.info b/providers/common/build.info index c77606a259..bc106d0b0f 100644 --- a/providers/common/build.info +++ b/providers/common/build.info @@ -1,4 +1,4 @@ -SUBDIRS=digests ciphers exchange +SUBDIRS=digests ciphers exchange keymgmt SOURCE[../../libcrypto]=\ provider_err.c provlib.c diff --git a/providers/common/exchange/build.info b/providers/common/exchange/build.info index 7957f51314..c99c9d81b5 100644 --- a/providers/common/exchange/build.info +++ b/providers/common/exchange/build.info @@ -1,7 +1,7 @@ LIBS=../../../libcrypto IF[{- !$disabled{dh} -}] SOURCE[../../../libcrypto]=\ - dh.c + dh_exch.c ENDIF diff --git a/providers/common/exchange/dh.c b/providers/common/exchange/dh_exch.c index ca6f0fc2cb..439b28a27e 100644 --- a/providers/common/exchange/dh.c +++ b/providers/common/exchange/dh_exch.c @@ -21,6 +21,11 @@ static OSSL_OP_keyexch_derive_fn dh_derive; static OSSL_OP_keyexch_freectx_fn dh_freectx; static OSSL_OP_keyexch_dupctx_fn dh_dupctx; +/* + * What's passed as an actual key is defined by the KEYMGMT interface. + * We happen to know that our KEYMGMT simply passes DH structures, so + * we use that here too. + */ typedef struct { DH *dh; @@ -33,71 +38,24 @@ static void *dh_newctx(void *provctx) return OPENSSL_zalloc(sizeof(PROV_DH_CTX)); } -static DH *param_to_dh(OSSL_PARAM params[], int priv) -{ - DH *dh = DH_new(); - OSSL_PARAM *paramptr; - BIGNUM *p = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL; - - if (dh == NULL) - return NULL; - - paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_P); - if (paramptr == NULL - || !OSSL_PARAM_get_BN(paramptr, &p)) - goto err; - - paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_G); - if (paramptr == NULL || !OSSL_PARAM_get_BN(paramptr, &g)) - goto err; - - if (!DH_set0_pqg(dh, p, NULL, g)) - goto err; - p = g = NULL; - - paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_PUB_KEY); - if (paramptr == NULL || !OSSL_PARAM_get_BN(paramptr, &pub_key)) - goto err; - - /* Private key is optional */ - if (priv) { - paramptr = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DH_PRIV_KEY); - if (paramptr == NULL - || (priv_key = BN_secure_new()) == NULL - || !OSSL_PARAM_get_BN(paramptr, &priv_key)) - goto err; - } - - if (!DH_set0_key(dh, pub_key, priv_key)) - goto err; - - return dh; - - err: - BN_free(p); - BN_free(g); - BN_free(pub_key); - BN_free(priv_key); - DH_free(dh); - return NULL; -} - -static int dh_init(void *vpdhctx, OSSL_PARAM params[]) +static int dh_init(void *vpdhctx, void *vdh) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; DH_free(pdhctx->dh); - pdhctx->dh = param_to_dh(params, 1); + pdhctx->dh = vdh; + DH_up_ref(pdhctx->dh); return pdhctx->dh != NULL; } -static int dh_set_peer(void *vpdhctx, OSSL_PARAM params[]) +static int dh_set_peer(void *vpdhctx, void *vdh) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; DH_free(pdhctx->dhpeer); - pdhctx->dhpeer = param_to_dh(params, 0); + pdhctx->dhpeer = vdh; + DH_up_ref(pdhctx->dhpeer); return pdhctx->dhpeer != NULL; } @@ -164,7 +122,7 @@ static void *dh_dupctx(void *vpdhctx) return dstctx; } -static int dh_set_params(void *vpdhctx, OSSL_PARAM params[]) +static int dh_set_params(void *vpdhctx, const OSSL_PARAM params[]) { PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx; const OSSL_PARAM *p; @@ -173,7 +131,7 @@ static int dh_set_params(void *vpdhctx, OSSL_PARAM params[]) if (pdhctx == NULL || params == NULL) return 0; - p = OSSL_PARAM_locate(params, OSSL_EXCHANGE_PARAM_PAD); + p = OSSL_PARAM_locate_const(params, OSSL_EXCHANGE_PARAM_PAD); if (p == NULL || !OSSL_PARAM_get_int(p, &pad)) return 0; @@ -182,7 +140,7 @@ static int dh_set_params(void *vpdhctx, OSSL_PARAM params[]) return 1; } -const OSSL_DISPATCH dh_functions[] = { +const OSSL_DISPATCH dh_keyexch_functions[] = { { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))dh_newctx }, { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))dh_init }, { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))dh_derive }, diff --git a/providers/common/include/internal/provider_algs.h b/providers/common/include/internal/provider_algs.h index dbc79a5742..80946ca6e2 100644 --- a/providers/common/include/internal/provider_algs.h +++ b/providers/common/include/internal/provider_algs.h @@ -58,5 +58,8 @@ extern const OSSL_DISPATCH aes256ctr_functions[]; extern const OSSL_DISPATCH aes192ctr_functions[]; extern const OSSL_DISPATCH aes128ctr_functions[]; +/* Key management */ +extern const OSSL_DISPATCH dh_keymgmt_functions[]; + /* Key Exchange */ -extern const OSSL_DISPATCH dh_functions[]; +extern const OSSL_DISPATCH dh_keyexch_functions[]; diff --git a/providers/common/keymgmt/build.info b/providers/common/keymgmt/build.info new file mode 100644 index 0000000000..a41f3dac6e --- /dev/null +++ b/providers/common/keymgmt/build.info @@ -0,0 +1,5 @@ +LIBS=../../../libcrypto +IF[{- !$disabled{dh} -}] + SOURCE[../../../libcrypto]=\ + dh_kmgmt.c +ENDIF diff --git a/providers/common/keymgmt/dh_kmgmt.c b/providers/common/keymgmt/dh_kmgmt.c new file mode 100644 index 0000000000..67e3205edc --- /dev/null +++ b/providers/common/keymgmt/dh_kmgmt.c @@ -0,0 +1,88 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/core_numbers.h> +#include <openssl/core_names.h> +#include <openssl/bn.h> +#include <openssl/dh.h> +#include <openssl/params.h> +#include "internal/provider_algs.h" + +static OSSL_OP_keymgmt_importkey_fn dh_importkey; + +static int params_to_key(DH *dh, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *param_p, *param_g, *param_priv_key, *param_pub_key; + BIGNUM *p = NULL, *g = NULL, *priv_key = NULL, *pub_key = NULL; + + if (dh == NULL) + return 0; + + param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_P); + param_g = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_G); + param_priv_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_KEY); + param_pub_key = + OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PUB_KEY); + + /* + * DH documentation says that a public key must be present if a + * private key is present. + * We want to have at least a public key either way, so we end up + * requiring it unconditionally. + */ + if (param_pub_key == NULL) + return 0; + + if ((param_p != NULL && !OSSL_PARAM_get_BN(param_p, &p)) + || (param_g != NULL && !OSSL_PARAM_get_BN(param_g, &g)) + || (param_priv_key != NULL + && !OSSL_PARAM_get_BN(param_priv_key, &priv_key)) + || !OSSL_PARAM_get_BN(param_pub_key, &pub_key)) + goto err; + + if (!DH_set0_pqg(dh, p, NULL, g)) + goto err; + p = g = NULL; + + if (!DH_set0_key(dh, pub_key, priv_key)) + goto err; + priv_key = pub_key = NULL; + + return 1; + + err: + BN_free(p); + BN_free(g); + BN_free(priv_key); + BN_free(pub_key); + return 0; +} + +static void *dh_importkey(void *provctx, const OSSL_PARAM params[]) +{ + DH *dh; + + if ((dh = DH_new()) == NULL + || !params_to_key(dh, params)) { + DH_free(dh); + dh = NULL; + } + return dh; +} + +const OSSL_DISPATCH dh_keymgmt_functions[] = { + /* + * TODO(3.0) When implementing OSSL_FUNC_KEYMGMT_GENKEY, remember to also + * implement OSSL_FUNC_KEYMGMT_EXPORTKEY. + */ + { OSSL_FUNC_KEYMGMT_IMPORTKEY, (void (*)(void))dh_importkey }, + { OSSL_FUNC_KEYMGMT_FREEKEY, (void (*)(void))DH_free }, + { 0, NULL } +}; |