summaryrefslogtreecommitdiffstats
path: root/crypto
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 /crypto
parent1f185f51a7899e1eddc9161d7781e3d5ae86ab78 (diff)
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)
Diffstat (limited to 'crypto')
-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
3 files changed, 89 insertions, 2 deletions
diff --git a/crypto/ec/build.info b/crypto/ec/build.info
index 8f12e2e39e..590bbbde53 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 e4d7815993..314ebe6181 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 dffc2dd5d1..6a86b26ded 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)