aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-03-19 14:02:42 +0100
committerRichard Levitte <levitte@openssl.org>2020-04-15 11:04:28 +0200
commit10d756a70e2aeaff0c08e86014075a8623f3e0ab (patch)
treeecd68e887037765cf453ae5593740002e04d4897
parent1f185f51a7899e1eddc9161d7781e3d5ae86ab78 (diff)
downloadopenssl-10d756a70e2aeaff0c08e86014075a8623f3e0ab.zip
openssl-10d756a70e2aeaff0c08e86014075a8623f3e0ab.tar.gz
openssl-10d756a70e2aeaff0c08e86014075a8623f3e0ab.tar.bz2
EC: Refactor EVP_PKEY_CTX curve setting macros for param generation
The macros are converted to functions, and are modified to support provider implementations. Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com> (Merged from https://github.com/openssl/openssl/pull/11328)
-rw-r--r--crypto/ec/build.info2
-rw-r--r--crypto/ec/ec_ctrl.c (renamed from crypto/ec/ec_evp_lib.c)66
-rw-r--r--crypto/evp/pmeth_lib.c23
-rw-r--r--doc/man3/EVP_PKEY_CTX_ctrl.pod26
-rw-r--r--include/openssl/ec.h9
-rw-r--r--util/libcrypto.num3
6 files changed, 119 insertions, 10 deletions
diff --git a/crypto/ec/build.info b/crypto/ec/build.info
index 8f12e2e..590bbbd 100644
--- a/crypto/ec/build.info
+++ b/crypto/ec/build.info
@@ -53,7 +53,7 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
$ECASM ec_backend.c ecx_backend.c
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
- ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
+ ec_err.c ecdh_kdf.c eck_prn.c ec_ctrl.c
SOURCE[../../providers/libfips.a]=$COMMON
# Implementations are now spread across several libraries, so the defines
diff --git a/crypto/ec/ec_evp_lib.c b/crypto/ec/ec_ctrl.c
index e4d7815..314ebe6 100644
--- a/crypto/ec/ec_evp_lib.c
+++ b/crypto/ec/ec_ctrl.c
@@ -420,3 +420,69 @@ int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
return (int)ukmlen;
}
+
+int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+ const char *name)
+{
+ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ OSSL_PARAM *p = params;
+
+ if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+
+ if (name == NULL)
+ return -1;
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
+ (char *)name, 0);
+ return EVP_PKEY_CTX_set_params(ctx, params);
+}
+
+int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+ char *name, size_t namelen)
+{
+ OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ OSSL_PARAM *p = params;
+
+ if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+
+ if (name == NULL)
+ return -1;
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
+ name, namelen);
+ if (!EVP_PKEY_CTX_get_params(ctx, params))
+ return -1;
+ return 1;
+}
+
+#ifndef FIPS_MODE
+int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid)
+{
+ if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+
+ /* Legacy: if key type not EC return error */
+ if (ctx->pmeth != NULL
+ && EVP_PKEY_type(ctx->pmeth->pkey_id) != EVP_PKEY_EC)
+ return -1;
+
+ if (ctx->op.keymgmt.genctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
+ nid, NULL);
+
+ return EVP_PKEY_CTX_set_ec_paramgen_curve_name(ctx, OBJ_nid2sn(nid));
+}
+#endif
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index dffc2dd..6a86b26 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -1,4 +1,3 @@
-
/*
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
*
@@ -820,6 +819,8 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype,
# ifndef OPENSSL_NO_EC
if (keytype == EVP_PKEY_EC) {
switch (cmd) {
+ case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+ return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, p1);
case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
if (p1 == -2) {
return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx);
@@ -965,6 +966,24 @@ int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
const char *value)
{
+
+ /* Special cases that we intercept */
+# ifndef OPENSSL_NO_EC
+ /*
+ * We don't support encoding settings for providers, i.e. the only
+ * possible encoding is "named_curve", so we simply fail when something
+ * else is given, and otherwise just pretend all is fine.
+ */
+ if (strcmp(name, "ec_param_enc") == 0) {
+ if (strcmp(value, "named_curve") == 0) {
+ return 1;
+ } else {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ return -2;
+ }
+ }
+# endif
+
if (strcmp(name, "rsa_padding_mode") == 0)
name = OSSL_ASYM_CIPHER_PARAM_PAD_MODE;
else if (strcmp(name, "rsa_mgf1_md") == 0)
@@ -986,6 +1005,8 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
name = OSSL_EXCHANGE_PARAM_PAD;
# endif
# ifndef OPENSSL_NO_EC
+ else if (strcmp(name, "ec_paramgen_curve") == 0)
+ name = OSSL_PKEY_PARAM_EC_NAME;
else if (strcmp(name, "ecdh_cofactor_mode") == 0)
name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE;
else if (strcmp(name, "ecdh_kdf_md") == 0)
diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod
index ca1b1fa..829bdb9 100644
--- a/doc/man3/EVP_PKEY_CTX_ctrl.pod
+++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod
@@ -51,6 +51,8 @@ EVP_PKEY_CTX_set_dh_kdf_outlen,
EVP_PKEY_CTX_get_dh_kdf_outlen,
EVP_PKEY_CTX_set0_dh_kdf_ukm,
EVP_PKEY_CTX_get0_dh_kdf_ukm,
+EVP_PKEY_CTX_set_ec_paramgen_curve_name,
+EVP_PKEY_CTX_get_ec_paramgen_curve_name,
EVP_PKEY_CTX_set_ec_paramgen_curve_nid,
EVP_PKEY_CTX_set_ec_param_enc,
EVP_PKEY_CTX_set_ecdh_cofactor_mode,
@@ -143,6 +145,10 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
#include <openssl/ec.h>
+ int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+ const char *name);
+ int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+ char *name, size_t namelen);
int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc);
int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode);
@@ -513,12 +519,24 @@ by the library and should not be freed by the caller.
=head2 EC parameters
-The EVP_PKEY_CTX_set_ec_paramgen_curve_nid() sets the EC curve for EC parameter
-generation to I<nid>. For EC parameter generation this macro must be called
-or an error occurs because there is no default curve.
-This function can also be called to set the curve explicitly when
+EVP_PKEY_CTX_set_ec_paramgen_curve_name() sets the EC curve to I<name> for EC
+parameter generation.
+
+EVP_PKEY_CTX_set_ec_paramgen_curve_nid() does the same as
+EVP_PKEY_CTX_set_ec_paramgen_curve_name(), but uses a I<nid> rather than a
+name string.
+
+For EC parameter generation, one of EVP_PKEY_CTX_set_ec_paramgen_curve_name()
+or EVP_PKEY_CTX_set_ec_paramgen_curve_nid() must be called or an error occurs
+because there is no default curve.
+These function can also be called to set the curve explicitly when
generating an EC key.
+EVP_PKEY_CTX_get_ec_paramgen_curve_name() finds the curve name that's currently
+set with I<ctx>, and writes it to the location that I<name> points at, as long
+as its size I<namelen> is large enough to store that name, including a
+terminating NUL byte.
+
The EVP_PKEY_CTX_set_ec_param_enc() macro sets the EC parameter encoding to
I<param_enc> when generating EC parameters or an EC key. The encoding can be
B<OPENSSL_EC_EXPLICIT_CURVE> for explicit parameters (the default in versions
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index c5d5fc0..de3698a 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -1450,10 +1450,11 @@ DEPRECATEDIN_3_0(void EC_KEY_METHOD_get_verify
# endif
# endif
-# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \
- EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
- EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \
- EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL)
+int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+ const char *name);
+int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
+ char *name, size_t namelen);
+int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 983c74a..60202b9 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5047,3 +5047,6 @@ CTLOG_new_from_base64_with_libctx ? 3_0_0 EXIST::FUNCTION:CT
CTLOG_STORE_new_with_libctx ? 3_0_0 EXIST::FUNCTION:CT
EVP_PKEY_set_ex_data ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_get_ex_data ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_CTX_set_ec_paramgen_curve_name ? 3_0_0 EXIST::FUNCTION:EC
+EVP_PKEY_CTX_get_ec_paramgen_curve_name ? 3_0_0 EXIST::FUNCTION:EC
+EVP_PKEY_CTX_set_ec_paramgen_curve_nid ? 3_0_0 EXIST::FUNCTION:EC