diff options
Diffstat (limited to 'crypto/dh/dh_pmeth.c')
-rw-r--r-- | crypto/dh/dh_pmeth.c | 225 |
1 files changed, 110 insertions, 115 deletions
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c index 1fd94deb4731..f201eede0df4 100644 --- a/crypto/dh/dh_pmeth.c +++ b/crypto/dh/dh_pmeth.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 */ +/* + * DH & DSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include <stdio.h> #include "internal/cryptlib.h" #include <openssl/asn1t.h> @@ -24,12 +30,11 @@ typedef struct { /* Parameter gen parameters */ int prime_len; int generator; - int use_dsa; + int paramgen_type; int subprime_len; int pad; /* message digest used for parameter generation */ const EVP_MD *md; - int rfc5114_param; int param_nid; /* Keygen callback info */ int gentmp[2]; @@ -51,7 +56,7 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx) DH_PKEY_CTX *dctx; if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) { - DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); return 0; } dctx->prime_len = 2048; @@ -69,6 +74,7 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx) static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) { DH_PKEY_CTX *dctx = ctx->data; + if (dctx != NULL) { OPENSSL_free(dctx->kdf_ukm); ASN1_OBJECT_free(dctx->kdf_oid); @@ -77,9 +83,10 @@ static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) } -static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { DH_PKEY_CTX *dctx, *sctx; + if (!pkey_dh_init(dst)) return 0; sctx = src->data; @@ -87,10 +94,9 @@ static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) dctx->prime_len = sctx->prime_len; dctx->subprime_len = sctx->subprime_len; dctx->generator = sctx->generator; - dctx->use_dsa = sctx->use_dsa; + dctx->paramgen_type = sctx->paramgen_type; dctx->pad = sctx->pad; dctx->md = sctx->md; - dctx->rfc5114_param = sctx->rfc5114_param; dctx->param_nid = sctx->param_nid; dctx->kdf_type = sctx->kdf_type; @@ -119,7 +125,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN: - if (dctx->use_dsa == 0) + if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR) return -2; dctx->subprime_len = p1; return 1; @@ -129,30 +135,30 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: - if (dctx->use_dsa) + if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR) return -2; dctx->generator = p1; return 1; case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE: #ifdef OPENSSL_NO_DSA - if (p1 != 0) + if (p1 != DH_PARAMGEN_TYPE_GENERATOR) return -2; #else if (p1 < 0 || p1 > 2) return -2; #endif - dctx->use_dsa = p1; + dctx->paramgen_type = p1; return 1; case EVP_PKEY_CTRL_DH_RFC5114: if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef) return -2; - dctx->rfc5114_param = p1; + dctx->param_nid = p1; return 1; case EVP_PKEY_CTRL_DH_NID: - if (p1 <= 0 || dctx->rfc5114_param != 0) + if (p1 <= 0 || dctx->param_nid != NID_undef) return -2; dctx->param_nid = p1; return 1; @@ -164,11 +170,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_DH_KDF_TYPE: if (p1 == -2) return dctx->kdf_type; -#ifdef OPENSSL_NO_CMS - if (p1 != EVP_PKEY_DH_KDF_NONE) -#else if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) -#endif return -2; dctx->kdf_type = p1; return 1; @@ -229,11 +231,12 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, } if (strcmp(type, "dh_rfc5114") == 0) { DH_PKEY_CTX *dctx = ctx->data; - int len; - len = atoi(value); - if (len < 0 || len > 3) + int id; + + id = atoi(value); + if (id < 0 || id > 3) return -2; - dctx->rfc5114_param = len; + dctx->param_nid = id; return 1; } if (strcmp(type, "dh_param") == 0) { @@ -241,7 +244,7 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, int nid = OBJ_sn2nid(value); if (nid == NID_undef) { - DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME); + ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME); return -2; } dctx->param_nid = nid; @@ -270,116 +273,91 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, return -2; } -#ifndef OPENSSL_NO_DSA - -extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, - const EVP_MD *evpmd, - const unsigned char *seed_in, size_t seed_len, - unsigned char *seed_out, int *counter_ret, - unsigned long *h_ret, BN_GENCB *cb); - -extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, - const unsigned char *seed_in, - size_t seed_len, int idx, - unsigned char *seed_out, int *counter_ret, - unsigned long *h_ret, BN_GENCB *cb); - -static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb) +static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx, + BN_GENCB *pcb) { - DSA *ret; + DH *ret; int rv = 0; + int res; int prime_len = dctx->prime_len; int subprime_len = dctx->subprime_len; - const EVP_MD *md = dctx->md; - if (dctx->use_dsa > 2) + + if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4) return NULL; - ret = DSA_new(); + ret = DH_new(); if (ret == NULL) return NULL; + if (subprime_len == -1) { if (prime_len >= 2048) subprime_len = 256; else subprime_len = 160; } - if (md == NULL) { - if (prime_len >= 2048) - md = EVP_sha256(); - else - md = EVP_sha1(); - } - if (dctx->use_dsa == 1) - rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md, - NULL, 0, NULL, NULL, NULL, pcb); - else if (dctx->use_dsa == 2) - rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md, - NULL, 0, -1, NULL, NULL, NULL, pcb); + + if (dctx->md != NULL) + ossl_ffc_set_digest(&ret->params, EVP_MD_get0_name(dctx->md), NULL); + +# ifndef FIPS_MODULE + if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2) + rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, &res, + pcb); + else +# endif + /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */ + if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) + rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params, + FFC_PARAM_TYPE_DH, + prime_len, subprime_len, &res, + pcb); if (rv <= 0) { - DSA_free(ret); + DH_free(ret); return NULL; } return ret; } -#endif - -static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey) { DH *dh = NULL; DH_PKEY_CTX *dctx = ctx->data; - BN_GENCB *pcb; + BN_GENCB *pcb = NULL; int ret; - if (dctx->rfc5114_param) { - switch (dctx->rfc5114_param) { - case 1: - dh = DH_get_1024_160(); - break; - case 2: - dh = DH_get_2048_224(); - break; + /* + * Look for a safe prime group for key establishment. Which uses + * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX). + * RFC_5114 is also handled here for param_nid = (1..3) + */ + if (dctx->param_nid != NID_undef) { + int type = dctx->param_nid <= 3 ? EVP_PKEY_DHX : EVP_PKEY_DH; - case 3: - dh = DH_get_2048_256(); - break; - - default: - return -2; - } - EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); - return 1; - } - - if (dctx->param_nid != 0) { if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL) return 0; - EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh); + EVP_PKEY_assign(pkey, type, dh); return 1; } - if (ctx->pkey_gencb) { + if (ctx->pkey_gencb != NULL) { pcb = BN_GENCB_new(); if (pcb == NULL) return 0; evp_pkey_set_cb_translate(pcb, ctx); - } else - pcb = NULL; -#ifndef OPENSSL_NO_DSA - if (dctx->use_dsa) { - DSA *dsa_dh; - dsa_dh = dsa_dh_generate(dctx, pcb); + } +# ifdef FIPS_MODULE + dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4; +# endif /* FIPS_MODULE */ + if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) { + dh = ffc_params_generate(NULL, dctx, pcb); BN_GENCB_free(pcb); - if (dsa_dh == NULL) - return 0; - dh = DSA_dup_DH(dsa_dh); - DSA_free(dsa_dh); - if (!dh) + if (dh == NULL) return 0; EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); return 1; } -#endif dh = DH_new(); if (dh == NULL) { BN_GENCB_free(pcb); @@ -400,11 +378,11 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) DH_PKEY_CTX *dctx = ctx->data; DH *dh = NULL; - if (ctx->pkey == NULL && dctx->param_nid == 0) { - DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); + if (ctx->pkey == NULL && dctx->param_nid == NID_undef) { + ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET); return 0; } - if (dctx->param_nid != 0) + if (dctx->param_nid != NID_undef) dh = DH_new_by_nid(dctx->param_nid); else dh = DH_new(); @@ -414,7 +392,7 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) /* Note: if error return, pkey is freed by parent routine */ if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey)) return 0; - return DH_generate_key(pkey->pkey.dh); + return DH_generate_key((DH *)EVP_PKEY_get0_DH(pkey)); } static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, @@ -422,33 +400,40 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, { int ret; DH *dh; + const DH *dhpub; DH_PKEY_CTX *dctx = ctx->data; - BIGNUM *dhpub; - if (!ctx->pkey || !ctx->peerkey) { - DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); + BIGNUM *dhpubbn; + + if (ctx->pkey == NULL || ctx->peerkey == NULL) { + ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET); + return 0; + } + dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey); + dhpub = EVP_PKEY_get0_DH(ctx->peerkey); + if (dhpub == NULL) { + ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET); return 0; } - dh = ctx->pkey->pkey.dh; - dhpub = ctx->peerkey->pkey.dh->pub_key; + dhpubbn = dhpub->pub_key; if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) { if (key == NULL) { *keylen = DH_size(dh); return 1; } if (dctx->pad) - ret = DH_compute_key_padded(key, dhpub, dh); + ret = DH_compute_key_padded(key, dhpubbn, dh); else - ret = DH_compute_key(key, dhpub, dh); + ret = DH_compute_key(key, dhpubbn, dh); if (ret < 0) return ret; *keylen = ret; return 1; } -#ifndef OPENSSL_NO_CMS else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { unsigned char *Z = NULL; - size_t Zlen = 0; + int Zlen = 0; + if (!dctx->kdf_outlen || !dctx->kdf_oid) return 0; if (key == NULL) { @@ -458,12 +443,13 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, if (*keylen != dctx->kdf_outlen) return 0; ret = 0; - Zlen = DH_size(dh); - Z = OPENSSL_malloc(Zlen); - if (Z == NULL) { - goto err; + if ((Zlen = DH_size(dh)) <= 0) + return 0; + if ((Z = OPENSSL_malloc(Zlen)) == NULL) { + ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE); + return 0; } - if (DH_compute_key_padded(Z, dhpub, dh) <= 0) + if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0) goto err; if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid, dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) @@ -474,11 +460,10 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, OPENSSL_clear_free(Z, Zlen); return ret; } -#endif return 0; } -const EVP_PKEY_METHOD dh_pkey_meth = { +static const EVP_PKEY_METHOD dh_pkey_meth = { EVP_PKEY_DH, 0, pkey_dh_init, @@ -512,7 +497,12 @@ const EVP_PKEY_METHOD dh_pkey_meth = { pkey_dh_ctrl_str }; -const EVP_PKEY_METHOD dhx_pkey_meth = { +const EVP_PKEY_METHOD *ossl_dh_pkey_method(void) +{ + return &dh_pkey_meth; +} + +static const EVP_PKEY_METHOD dhx_pkey_meth = { EVP_PKEY_DHX, 0, pkey_dh_init, @@ -545,3 +535,8 @@ const EVP_PKEY_METHOD dhx_pkey_meth = { pkey_dh_ctrl, pkey_dh_ctrl_str }; + +const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void) +{ + return &dhx_pkey_meth; +} |