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
--- /dev/null
+/*
+ * Copyright 2020 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 <string.h>
+
+#include <openssl/err.h>
+#include <openssl/opensslv.h>
+
+#include <openssl/core_names.h>
+#include "crypto/evp.h"
+
+#include "ec_local.h"
+
+/*
+ * This file is meant to contain functions to provide EVP_PKEY support for EC
+ * keys.
+ */
+
+static ossl_inline
+int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX *ctx)
+{
+ if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_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 key type not EC return error */
+ if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_EC)
+ return -1;
+
+ return 1;
+}
+
+int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /*
+ * Valid input values are:
+ * * 0 for disable
+ * * 1 for enable
+ * * -1 for reset to default for associated priv key
+ */
+ if (cofactor_mode < -1 || cofactor_mode > 1) {
+ /* Uses the same return value of pkey_ec_ctrl() */
+ return -2;
+ }
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_EC_ECDH_COFACTOR,
+ cofactor_mode, NULL);
+
+ *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
+ &cofactor_mode);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_set_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+
+ return ret;
+}
+
+int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx)
+{
+ int ret, mode;
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL);
+
+ *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
+ &mode);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_get_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ } else if (ret != 1) {
+ return -1;
+ }
+
+ if (mode < 0 || mode > 1) {
+ /*
+ * The provider should return either 0 or 1, any other value is a
+ * provider error.
+ */
+ return -1;
+ }
+
+ return mode;
+}
+
+int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
+{
+ int ret;
+ const char *kdf_type;
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ switch (kdf) {
+ case EVP_PKEY_ECDH_KDF_NONE:
+ kdf_type = "";
+ break;
+ case EVP_PKEY_ECDH_KDF_X9_63:
+ kdf_type = OSSL_KDF_NAME_X963KDF;
+ break;
+ default:
+ return -2;
+ }
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL);
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
+ /*
+ * Cast away the const. This is read
+ * only so should be safe
+ */
+ (char *)kdf_type, 0);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_set_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+
+ return ret;
+}
+
+int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx)
+{
+ int ret;
+ /* 80 should be big enough */
+ char kdf_type[80];
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL);
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
+ kdf_type, sizeof(kdf_type));
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_get_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ } else if (ret != 1) {
+ return -1;
+ }
+
+ if (kdf_type[0] == '\0')
+ return EVP_PKEY_ECDH_KDF_NONE;
+ else if (strcmp(kdf_type, OSSL_KDF_NAME_X963KDF) == 0)
+ return EVP_PKEY_ECDH_KDF_X9_63;
+
+ return -1;
+}
+
+int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+ const char *md_name = NULL;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md));
+
+ md_name = (md == NULL) ? "" : EVP_MD_name(md);
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
+ /*
+ * Cast away the const. This is read
+ * only so should be safe
+ */
+ (char *)md_name, 0);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_set_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+ return ret;
+}
+
+int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
+{
+ /* 80 should be big enough */
+ char name[80] = "";
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd));
+
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
+ name, sizeof(name));
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_get_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ } else if (ret != 1) {
+ return -1;
+ }
+
+ /* May be NULL meaning "unknown" */
+ *pmd = EVP_get_digestbyname(name);
+
+ return 1;
+}
+
+int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int in)
+{
+ int ret;
+ size_t len = in;
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_EC_KDF_OUTLEN, in, NULL);
+
+ if (in <= 0) {
+ /*
+ * This would ideally be -1 or 0, but we have to retain compatibility
+ * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
+ * in <= 0
+ */
+ return -2;
+ }
+
+ *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
+ &len);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_set_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+ return ret;
+}
+
+int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
+{
+ size_t len = UINT_MAX;
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0,
+ (void *)(plen));
+
+ *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
+ &len);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_get_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ } else if (ret != 1) {
+ return -1;
+ }
+
+ if (len > INT_MAX)
+ return -1;
+
+ *plen = (int)len;
+
+ return 1;
+}
+
+int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
+{
+ int ret;
+ OSSL_PARAM params[2], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_EC_KDF_UKM, len, (void *)(ukm));
+
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
+ /*
+ * Cast away the const. This is read
+ * only so should be safe
+ */
+ (void *)ukm,
+ (size_t)len);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_set_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ }
+ if (ret == 1)
+ OPENSSL_free(ukm);
+ return ret;
+}
+
+int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
+{
+ size_t ukmlen;
+ int ret;
+ OSSL_PARAM params[3], *p = params;
+
+ ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
+ if (ret != 1)
+ return ret;
+
+ /* TODO(3.0): Remove this eventually when no more legacy */
+ if (ctx->op.kex.exchprovctx == NULL)
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
+ EVP_PKEY_OP_DERIVE,
+ EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0,
+ (void *)(pukm));
+
+ *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
+ (void **)pukm, 0);
+ *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN,
+ &ukmlen);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = evp_pkey_ctx_get_params_strict(ctx, params);
+ if (ret == -2) {
+ ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
+ /* Uses the same return values as EVP_PKEY_CTX_ctrl */
+ return -2;
+ } else if (ret != 1) {
+ return -1;
+ }
+
+ if (ukmlen > INT_MAX)
+ return -1;
+
+ 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
+++ /dev/null
-/*
- * Copyright 2020 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 <string.h>
-
-#include <openssl/err.h>
-#include <openssl/opensslv.h>
-
-#include <openssl/core_names.h>
-#include "crypto/evp.h"
-
-#include "ec_local.h"
-
-/*
- * This file is meant to contain functions to provide EVP_PKEY support for EC
- * keys.
- */
-
-static ossl_inline
-int evp_pkey_ctx_getset_ecdh_param_checks(const EVP_PKEY_CTX *ctx)
-{
- if (ctx == NULL || !EVP_PKEY_CTX_IS_DERIVE_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 key type not EC return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_EC)
- return -1;
-
- return 1;
-}
-
-int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int cofactor_mode)
-{
- int ret;
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /*
- * Valid input values are:
- * * 0 for disable
- * * 1 for enable
- * * -1 for reset to default for associated priv key
- */
- if (cofactor_mode < -1 || cofactor_mode > 1) {
- /* Uses the same return value of pkey_ec_ctrl() */
- return -2;
- }
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_EC_ECDH_COFACTOR,
- cofactor_mode, NULL);
-
- *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
- &cofactor_mode);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_set_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- }
-
- return ret;
-}
-
-int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx)
-{
- int ret, mode;
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL);
-
- *p++ = OSSL_PARAM_construct_int(OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE,
- &mode);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_get_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- } else if (ret != 1) {
- return -1;
- }
-
- if (mode < 0 || mode > 1) {
- /*
- * The provider should return either 0 or 1, any other value is a
- * provider error.
- */
- return -1;
- }
-
- return mode;
-}
-
-int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
-{
- int ret;
- const char *kdf_type;
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- switch (kdf) {
- case EVP_PKEY_ECDH_KDF_NONE:
- kdf_type = "";
- break;
- case EVP_PKEY_ECDH_KDF_X9_63:
- kdf_type = OSSL_KDF_NAME_X963KDF;
- break;
- default:
- return -2;
- }
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL);
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
- /*
- * Cast away the const. This is read
- * only so should be safe
- */
- (char *)kdf_type, 0);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_set_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- }
-
- return ret;
-}
-
-int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx)
-{
- int ret;
- /* 80 should be big enough */
- char kdf_type[80];
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL);
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE,
- kdf_type, sizeof(kdf_type));
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_get_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- } else if (ret != 1) {
- return -1;
- }
-
- if (kdf_type[0] == '\0')
- return EVP_PKEY_ECDH_KDF_NONE;
- else if (strcmp(kdf_type, OSSL_KDF_NAME_X963KDF) == 0)
- return EVP_PKEY_ECDH_KDF_X9_63;
-
- return -1;
-}
-
-int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
-{
- int ret;
- OSSL_PARAM params[2], *p = params;
- const char *md_name = NULL;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)(md));
-
- md_name = (md == NULL) ? "" : EVP_MD_name(md);
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
- /*
- * Cast away the const. This is read
- * only so should be safe
- */
- (char *)md_name, 0);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_set_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- }
- return ret;
-}
-
-int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
-{
- /* 80 should be big enough */
- char name[80] = "";
- int ret;
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)(pmd));
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST,
- name, sizeof(name));
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_get_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- } else if (ret != 1) {
- return -1;
- }
-
- /* May be NULL meaning "unknown" */
- *pmd = EVP_get_digestbyname(name);
-
- return 1;
-}
-
-int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int in)
-{
- int ret;
- size_t len = in;
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_EC_KDF_OUTLEN, in, NULL);
-
- if (in <= 0) {
- /*
- * This would ideally be -1 or 0, but we have to retain compatibility
- * with legacy behaviour of EVP_PKEY_CTX_ctrl() which returned -2 if
- * in <= 0
- */
- return -2;
- }
-
- *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
- &len);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_set_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- }
- return ret;
-}
-
-int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
-{
- size_t len = UINT_MAX;
- int ret;
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0,
- (void *)(plen));
-
- *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN,
- &len);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_get_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- } else if (ret != 1) {
- return -1;
- }
-
- if (len > INT_MAX)
- return -1;
-
- *plen = (int)len;
-
- return 1;
-}
-
-int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *ukm, int len)
-{
- int ret;
- OSSL_PARAM params[2], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_EC_KDF_UKM, len, (void *)(ukm));
-
- *p++ = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM,
- /*
- * Cast away the const. This is read
- * only so should be safe
- */
- (void *)ukm,
- (size_t)len);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_set_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- }
- if (ret == 1)
- OPENSSL_free(ukm);
- return ret;
-}
-
-int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
-{
- size_t ukmlen;
- int ret;
- OSSL_PARAM params[3], *p = params;
-
- ret = evp_pkey_ctx_getset_ecdh_param_checks(ctx);
- if (ret != 1)
- return ret;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.kex.exchprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
- EVP_PKEY_OP_DERIVE,
- EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0,
- (void *)(pukm));
-
- *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_EXCHANGE_PARAM_KDF_UKM,
- (void **)pukm, 0);
- *p++ = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_UKM_LEN,
- &ukmlen);
- *p++ = OSSL_PARAM_construct_end();
-
- ret = evp_pkey_ctx_get_params_strict(ctx, params);
- if (ret == -2) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- } else if (ret != 1) {
- return -1;
- }
-
- if (ukmlen > INT_MAX)
- return -1;
-
- return (int)ukmlen;
-}
-
/*
* Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
*
# 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);
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)
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)
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,
#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);
=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
# 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, \
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