diff options
Diffstat (limited to 'crypto/ec/ec_pmeth.c')
| -rw-r--r-- | crypto/ec/ec_pmeth.c | 115 |
1 files changed, 79 insertions, 36 deletions
diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c index 64d2cc93a620..19e2f0d0c04d 100644 --- a/crypto/ec/ec_pmeth.c +++ b/crypto/ec/ec_pmeth.c @@ -1,12 +1,18 @@ /* - * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2021 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 */ +/* + * ECDH and ECDSA 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> @@ -43,7 +49,7 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx) EC_PKEY_CTX *dctx; if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) { - ECerr(EC_F_PKEY_EC_INIT, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } @@ -53,7 +59,7 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx) return 1; } -static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +static int pkey_ec_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) { EC_PKEY_CTX *dctx, *sctx; if (!pkey_ec_init(dst)) @@ -103,7 +109,12 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, int ret, type; unsigned int sltmp; EC_PKEY_CTX *dctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); const int sig_sz = ECDSA_size(ec); /* ensure cast to size_t is safe */ @@ -116,11 +127,11 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, } if (*siglen < (size_t)sig_sz) { - ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); + ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); return 0; } - type = (dctx->md != NULL) ? EVP_MD_type(dctx->md) : NID_sha1; + type = (dctx->md != NULL) ? EVP_MD_get_type(dctx->md) : NID_sha1; ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); @@ -136,10 +147,15 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx, { int ret, type; EC_PKEY_CTX *dctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; + /* + * Discard const. Its marked as const because this may be a cached copy of + * the "real" key. These calls don't make any modifications that need to + * be reflected back in the "original" key. + */ + EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); if (dctx->md) - type = EVP_MD_type(dctx->md); + type = EVP_MD_get_type(dctx->md); else type = NID_sha1; @@ -155,21 +171,32 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) size_t outlen; const EC_POINT *pubkey = NULL; EC_KEY *eckey; + const EC_KEY *eckeypub; EC_PKEY_CTX *dctx = ctx->data; - if (!ctx->pkey || !ctx->peerkey) { - ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); + + if (ctx->pkey == NULL || ctx->peerkey == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); + return 0; + } + eckeypub = EVP_PKEY_get0_EC_KEY(ctx->peerkey); + if (eckeypub == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET); return 0; } - eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec; + eckey = dctx->co_key ? dctx->co_key + : (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); if (!key) { const EC_GROUP *group; group = EC_KEY_get0_group(eckey); + + if (group == NULL) + return 0; *keylen = (EC_GROUP_get_degree(group) + 7) / 8; return 1; } - pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + pubkey = EC_KEY_get0_public_key(eckeypub); /* * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not @@ -203,14 +230,15 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, if (!pkey_ec_derive(ctx, NULL, &ktmplen)) return 0; if ((ktmp = OPENSSL_malloc(ktmplen)) == NULL) { - ECerr(EC_F_PKEY_EC_KDF_DERIVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); return 0; } if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) goto err; /* Do KDF stuff */ - if (!ecdh_KDF_X9_63(key, *keylen, ktmp, ktmplen, - dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) + if (!ossl_ecdh_kdf_X9_63(key, *keylen, ktmp, ktmplen, + dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md, + ctx->libctx, ctx->propquery)) goto err; rv = 1; @@ -228,7 +256,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: group = EC_GROUP_new_by_curve_name(p1); if (group == NULL) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); return 0; } EC_GROUP_free(dctx->gen_group); @@ -237,7 +265,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_EC_PARAM_ENC: if (!dctx->gen_group) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET); + ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); return 0; } EC_GROUP_set_asn1_flag(dctx->gen_group, p1); @@ -249,14 +277,23 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) if (dctx->cofactor_mode != -1) return dctx->cofactor_mode; else { - EC_KEY *ec_key = ctx->pkey->pkey.ec; + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ctx->pkey); return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; } } else if (p1 < -1 || p1 > 1) return -2; dctx->cofactor_mode = p1; if (p1 != -1) { - EC_KEY *ec_key = ctx->pkey->pkey.ec; + EC_KEY *ec_key = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey); + + /* + * We discarded the "const" above. This will only work if the key is + * a "real" legacy key, and not a cached copy of a provided key + */ + if (evp_pkey_is_provided(ctx->pkey)) { + ERR_raise(ERR_LIB_EC, ERR_R_UNSUPPORTED); + return 0; + } if (!ec_key->group) return -2; /* If cofactor is 1 cofactor mode does nothing */ @@ -318,17 +355,18 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return dctx->kdf_ukmlen; case EVP_PKEY_CTRL_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha512 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); + if (EVP_MD_get_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha512 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_224 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_256 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_384 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sha3_512 && + EVP_MD_get_type((const EVP_MD *)p2) != NID_sm3) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE); return 0; } dctx->md = p2; @@ -362,7 +400,7 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, if (nid == NID_undef) nid = OBJ_ln2nid(value); if (nid == NID_undef) { - ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); return 0; } return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); @@ -378,7 +416,7 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, } else if (strcmp(type, "ecdh_kdf_md") == 0) { const EVP_MD *md; if ((md = EVP_get_digestbyname(value)) == NULL) { - ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST); + ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST); return 0; } return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md); @@ -398,7 +436,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) int ret; if (dctx->gen_group == NULL) { - ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); + ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); @@ -417,7 +455,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) int ret; if (ctx->pkey == NULL && dctx->gen_group == NULL) { - ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); + ERR_raise(ERR_LIB_EC, EC_R_NO_PARAMETERS_SET); return 0; } ec = EC_KEY_new(); @@ -436,7 +474,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return ret ? EC_KEY_generate_key(ec) : 0; } -const EVP_PKEY_METHOD ec_pkey_meth = { +static const EVP_PKEY_METHOD ec_pkey_meth = { EVP_PKEY_EC, 0, pkey_ec_init, @@ -474,3 +512,8 @@ const EVP_PKEY_METHOD ec_pkey_meth = { pkey_ec_ctrl, pkey_ec_ctrl_str }; + +const EVP_PKEY_METHOD *ossl_ec_pkey_method(void) +{ + return &ec_pkey_meth; +} |
