mirror of
https://github.com/openssl/openssl.git
synced 2025-01-18 13:44:20 +08:00
Add Explicit EC parameter support to providers.
This was added for backward compatability. Added EC_GROUP_new_from_params() that supports explicit curve parameters. This fixes the 15-test_genec.t TODO. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12604)
This commit is contained in:
parent
a02c715c18
commit
c0f39ded68
@ -606,43 +606,6 @@ size_t ec_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
return pkey->pkey.ec->dirty_cnt;
|
||||
}
|
||||
|
||||
static ossl_inline
|
||||
int ecparams_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl)
|
||||
{
|
||||
const EC_GROUP *ecg;
|
||||
int curve_nid;
|
||||
|
||||
if (eckey == NULL)
|
||||
return 0;
|
||||
|
||||
ecg = EC_KEY_get0_group(eckey);
|
||||
if (ecg == NULL)
|
||||
return 0;
|
||||
|
||||
curve_nid = EC_GROUP_get_curve_name(ecg);
|
||||
|
||||
if (curve_nid == NID_undef) {
|
||||
/* explicit parameters */
|
||||
|
||||
/*
|
||||
* TODO(3.0): should we support explicit parameters curves?
|
||||
*/
|
||||
return 0;
|
||||
} else {
|
||||
/* named curve */
|
||||
const char *curve_name = NULL;
|
||||
|
||||
if ((curve_name = OBJ_nid2sn(curve_nid)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
curve_name, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
@ -650,7 +613,7 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
{
|
||||
const EC_KEY *eckey = NULL;
|
||||
const EC_GROUP *ecg = NULL;
|
||||
unsigned char *pub_key_buf = NULL;
|
||||
unsigned char *pub_key_buf = NULL, *gen_buf = NULL;
|
||||
size_t pub_key_buflen;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
OSSL_PARAM *params = NULL;
|
||||
@ -676,8 +639,17 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* EC_POINT_point2buf() can generate random numbers in some
|
||||
* implementations so we need to ensure we use the correct libctx.
|
||||
*/
|
||||
bnctx = BN_CTX_new_ex(libctx);
|
||||
if (bnctx == NULL)
|
||||
goto err;
|
||||
BN_CTX_start(bnctx);
|
||||
|
||||
/* export the domain parameters */
|
||||
if (!ecparams_to_params(eckey, tmpl))
|
||||
if (!ec_group_todata(ecg, tmpl, NULL, libctx, propq, bnctx, &gen_buf))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||
|
||||
@ -685,14 +657,6 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
pub_point = EC_KEY_get0_public_key(eckey);
|
||||
|
||||
if (pub_point != NULL) {
|
||||
/*
|
||||
* EC_POINT_point2buf() can generate random numbers in some
|
||||
* implementations so we need to ensure we use the correct libctx.
|
||||
*/
|
||||
bnctx = BN_CTX_new_ex(libctx);
|
||||
if (bnctx == NULL)
|
||||
goto err;
|
||||
|
||||
/* convert pub_point to a octet string according to the SECG standard */
|
||||
if ((pub_key_buflen = EC_POINT_point2buf(ecg, pub_point,
|
||||
POINT_CONVERSION_COMPRESSED,
|
||||
@ -779,6 +743,8 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
OPENSSL_free(pub_key_buf);
|
||||
OPENSSL_free(gen_buf);
|
||||
BN_CTX_end(bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
return rv;
|
||||
}
|
||||
@ -794,7 +760,7 @@ static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ec_key_domparams_fromdata(ec, params)
|
||||
if (!ec_group_fromdata(ec, params)
|
||||
|| !ec_key_otherparams_fromdata(ec, params)
|
||||
|| !ec_key_fromdata(ec, params, 1)
|
||||
|| !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
||||
|
@ -23,75 +23,6 @@
|
||||
|
||||
#ifndef FIPS_MODULE
|
||||
|
||||
int EC_GROUP_get_basis_type(const EC_GROUP *group)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field)
|
||||
/* everything else is currently not supported */
|
||||
return 0;
|
||||
|
||||
/* Find the last non-zero element of group->poly[] */
|
||||
for (i = 0;
|
||||
i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0;
|
||||
i++)
|
||||
continue;
|
||||
|
||||
if (i == 4)
|
||||
return NID_X9_62_ppBasis;
|
||||
else if (i == 2)
|
||||
return NID_X9_62_tpBasis;
|
||||
else
|
||||
/* everything else is currently not supported */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
|
||||
{
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] == 0))) {
|
||||
ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k)
|
||||
*k = group->poly[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
|
||||
unsigned int *k2, unsigned int *k3)
|
||||
{
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] != 0) && (group->poly[3] != 0)
|
||||
&& (group->poly[4] == 0))) {
|
||||
ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k1)
|
||||
*k1 = group->poly[3];
|
||||
if (k2)
|
||||
*k2 = group->poly[2];
|
||||
if (k3)
|
||||
*k3 = group->poly[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* some structures needed for the asn1 encoding */
|
||||
typedef struct x9_62_pentanomial_st {
|
||||
int32_t k1;
|
||||
@ -444,7 +375,7 @@ static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve)
|
||||
}
|
||||
|
||||
ECPARAMETERS *EC_GROUP_get_ecparameters(const EC_GROUP *group,
|
||||
ECPARAMETERS *params)
|
||||
ECPARAMETERS *params)
|
||||
{
|
||||
size_t len = 0;
|
||||
ECPARAMETERS *ret = NULL;
|
||||
|
@ -10,15 +10,178 @@
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/err.h>
|
||||
#include "crypto/bn.h"
|
||||
#include "crypto/ec.h"
|
||||
#include "ec_local.h"
|
||||
#include "e_os.h"
|
||||
#include "internal/param_build_set.h"
|
||||
|
||||
/* Mapping between a flag and a name */
|
||||
static const OSSL_ITEM encoding_nameid_map[] = {
|
||||
{ OPENSSL_EC_EXPLICIT_CURVE, OSSL_PKEY_EC_ENCODING_EXPLICIT },
|
||||
{ OPENSSL_EC_NAMED_CURVE, OSSL_PKEY_EC_ENCODING_GROUP },
|
||||
};
|
||||
|
||||
int ec_encoding_name2id(const char *name)
|
||||
{
|
||||
size_t i, sz;
|
||||
|
||||
/* Return the default value if there is no name */
|
||||
if (name == NULL)
|
||||
return OPENSSL_EC_NAMED_CURVE;
|
||||
|
||||
for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) {
|
||||
if (strcasecmp(name, encoding_nameid_map[i].ptr) == 0)
|
||||
return encoding_nameid_map[i].id;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *ec_param_encoding_id2name(int id)
|
||||
{
|
||||
size_t i, sz;
|
||||
|
||||
for (i = 0, sz = OSSL_NELEM(encoding_nameid_map); i < sz; i++) {
|
||||
if (id == (int)encoding_nameid_map[i].id)
|
||||
return encoding_nameid_map[i].ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
|
||||
OSSL_PARAM params[], OPENSSL_CTX *libctx, const char *propq,
|
||||
BN_CTX *bnctx, unsigned char **genbuf)
|
||||
{
|
||||
int ret = 0, curve_nid, encoding_flag;
|
||||
const char *field_type, *encoding_name;
|
||||
const BIGNUM *cofactor, *order;
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL;
|
||||
point_conversion_form_t genform;
|
||||
const EC_POINT *genpt;
|
||||
unsigned char *seed = NULL;
|
||||
size_t genbuf_len, seed_len;
|
||||
|
||||
if (group == NULL) {
|
||||
ECerr(0,EC_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE;
|
||||
encoding_name = ec_param_encoding_id2name(encoding_flag);
|
||||
if (encoding_name == NULL
|
||||
|| !ossl_param_build_set_utf8_string(tmpl, params,
|
||||
OSSL_PKEY_PARAM_EC_ENCODING,
|
||||
encoding_name)) {
|
||||
ECerr(0, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
curve_nid = EC_GROUP_get_curve_name(group);
|
||||
if (curve_nid == NID_undef) {
|
||||
/* explicit curve */
|
||||
int fid = EC_GROUP_get_field_type(group);
|
||||
|
||||
if (fid == NID_X9_62_prime_field) {
|
||||
field_type = SN_X9_62_prime_field;
|
||||
} else if (fid == NID_X9_62_characteristic_two_field) {
|
||||
field_type = SN_X9_62_characteristic_two_field;
|
||||
} else {
|
||||
ECerr(0, EC_R_INVALID_FIELD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = BN_CTX_get(bnctx);
|
||||
a = BN_CTX_get(bnctx);
|
||||
b = BN_CTX_get(bnctx);
|
||||
if (b == NULL) {
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_curve(group, p, a, b, bnctx)) {
|
||||
ECerr(0, EC_R_INVALID_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL) {
|
||||
ECerr(0, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
genpt = EC_GROUP_get0_generator(group);
|
||||
if (genpt == NULL) {
|
||||
ECerr(0, EC_R_INVALID_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
genform = EC_GROUP_get_point_conversion_form(group);
|
||||
genbuf_len = EC_POINT_point2buf(group, genpt, genform, genbuf, bnctx);
|
||||
if (genbuf_len == 0) {
|
||||
ECerr(0, EC_R_INVALID_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ossl_param_build_set_utf8_string(tmpl, params,
|
||||
OSSL_PKEY_PARAM_EC_FIELD_TYPE,
|
||||
field_type)
|
||||
|| !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p)
|
||||
|| !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a)
|
||||
|| !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b)
|
||||
|| !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER,
|
||||
order)
|
||||
|| !ossl_param_build_set_octet_string(tmpl, params,
|
||||
OSSL_PKEY_PARAM_EC_GENERATOR,
|
||||
*genbuf, genbuf_len)) {
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
cofactor = EC_GROUP_get0_cofactor(group);
|
||||
if (cofactor != NULL
|
||||
&& !ossl_param_build_set_bn(tmpl, params,
|
||||
OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) {
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
seed = EC_GROUP_get0_seed(group);
|
||||
seed_len = EC_GROUP_get_seed_len(group);
|
||||
if (seed != NULL
|
||||
&& seed_len > 0
|
||||
&& !ossl_param_build_set_octet_string(tmpl, params,
|
||||
OSSL_PKEY_PARAM_EC_SEED,
|
||||
seed, seed_len)) {
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
#ifdef OPENSSL_NO_EC2M
|
||||
if (fid == NID_X9_62_characteristic_two_field) {
|
||||
ECerr(0, EC_R_GF2M_NOT_SUPPORTED);
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* named curve */
|
||||
const char *curve_name = curve_name = ec_curve_nid2name(curve_nid);
|
||||
|
||||
if (curve_name == NULL
|
||||
|| !ossl_param_build_set_utf8_string(tmpl, params,
|
||||
OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
curve_name)) {
|
||||
ECerr(0, EC_R_INVALID_CURVE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The intention with the "backend" source file is to offer backend support
|
||||
* for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
|
||||
* implementations alike.
|
||||
*/
|
||||
|
||||
int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode)
|
||||
{
|
||||
const EC_GROUP *ecg = EC_KEY_get0_group(ec);
|
||||
@ -163,52 +326,27 @@ int ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_private)
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_domparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
int ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *param_ec_name;
|
||||
EC_GROUP *ecg = NULL;
|
||||
char *curve_name = NULL;
|
||||
int ok = 0;
|
||||
EC_GROUP *group = NULL;
|
||||
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
|
||||
param_ec_name = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
|
||||
if (param_ec_name == NULL) {
|
||||
/* explicit parameters */
|
||||
group = EC_GROUP_new_from_params(params, ec_key_get_libctx(ec),
|
||||
ec_key_get0_propq(ec));
|
||||
|
||||
/*
|
||||
* TODO(3.0): should we support explicit parameters curves?
|
||||
*/
|
||||
return 0;
|
||||
} else {
|
||||
/* named curve */
|
||||
int curve_nid;
|
||||
|
||||
if (!OSSL_PARAM_get_utf8_string(param_ec_name, &curve_name, 0)
|
||||
|| curve_name == NULL
|
||||
|| (curve_nid = ec_curve_name2nid(curve_name)) == NID_undef)
|
||||
goto err;
|
||||
|
||||
if ((ecg = EC_GROUP_new_by_curve_name_with_libctx(ec_key_get_libctx(ec),
|
||||
ec_key_get0_propq(ec),
|
||||
curve_nid)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_KEY_set_group(ec, ecg))
|
||||
if (!EC_KEY_set_group(ec, group))
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* TODO(3.0): if the group has changed, should we invalidate the private and
|
||||
* public key?
|
||||
*/
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
OPENSSL_free(curve_name);
|
||||
EC_GROUP_free(ecg);
|
||||
err:
|
||||
EC_GROUP_free(group);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -227,5 +365,6 @@ int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
|| !ec_set_ecdh_cofactor_mode(ec, mode))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -44,7 +44,10 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
|
||||
"i2d ecpkparameters failure"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INCOMPATIBLE_OBJECTS),
|
||||
"incompatible objects"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_A), "invalid a"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ARGUMENT), "invalid argument"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_B), "invalid b"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COFACTOR), "invalid cofactor"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSED_POINT),
|
||||
"invalid compressed point"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSION_BIT),
|
||||
@ -55,14 +58,19 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ENCODING), "invalid encoding"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FIELD), "invalid field"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FORM), "invalid form"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GENERATOR), "invalid generator"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GROUP_ORDER), "invalid group order"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_KEY), "invalid key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_NAMED_GROUP_CONVERSION),
|
||||
"invalid named group conversion"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_OUTPUT_LENGTH),
|
||||
"invalid output length"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_P), "invalid p"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PEER_KEY), "invalid peer key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PENTANOMIAL_BASIS),
|
||||
"invalid pentanomial basis"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_SEED), "invalid seed"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_TRINOMIAL_BASIS),
|
||||
"invalid trinomial basis"},
|
||||
{ERR_PACK(ERR_LIB_EC, 0, EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
|
||||
|
@ -15,11 +15,14 @@
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h>
|
||||
|
||||
#include "crypto/ec.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "ec_local.h"
|
||||
#include "e_os.h" /* strcasecmp */
|
||||
|
||||
/* functions for EC_GROUP objects */
|
||||
|
||||
@ -1317,3 +1320,407 @@ int ec_point_blind_coordinates(const EC_GROUP *group, EC_POINT *p, BN_CTX *ctx)
|
||||
|
||||
return group->meth->blind_coordinates(group, p, ctx);
|
||||
}
|
||||
|
||||
int EC_GROUP_get_basis_type(const EC_GROUP *group)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field)
|
||||
/* everything else is currently not supported */
|
||||
return 0;
|
||||
|
||||
/* Find the last non-zero element of group->poly[] */
|
||||
for (i = 0;
|
||||
i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0;
|
||||
i++)
|
||||
continue;
|
||||
|
||||
if (i == 4)
|
||||
return NID_X9_62_ppBasis;
|
||||
else if (i == 2)
|
||||
return NID_X9_62_tpBasis;
|
||||
else
|
||||
/* everything else is currently not supported */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
|
||||
{
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] == 0))) {
|
||||
ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k)
|
||||
*k = group->poly[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
|
||||
unsigned int *k2, unsigned int *k3)
|
||||
{
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
|
||||
if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field
|
||||
|| !((group->poly[0] != 0) && (group->poly[1] != 0)
|
||||
&& (group->poly[2] != 0) && (group->poly[3] != 0)
|
||||
&& (group->poly[4] == 0))) {
|
||||
ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS,
|
||||
ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (k1)
|
||||
*k1 = group->poly[3];
|
||||
if (k2)
|
||||
*k2 = group->poly[2];
|
||||
if (k3)
|
||||
*k3 = group->poly[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if the explicit parameters group matches any built-in curves.
|
||||
*
|
||||
* We create a copy of the group just built, so that we can remove optional
|
||||
* fields for the lookup: we do this to avoid the possibility that one of
|
||||
* the optional parameters is used to force the library into using a less
|
||||
* performant and less secure EC_METHOD instead of the specialized one.
|
||||
* In any case, `seed` is not really used in any computation, while a
|
||||
* cofactor different from the one in the built-in table is just
|
||||
* mathematically wrong anyway and should not be used.
|
||||
*/
|
||||
static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group,
|
||||
OPENSSL_CTX *libctx,
|
||||
const char *propq,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
EC_GROUP *ret_group = NULL, *dup = NULL;
|
||||
int curve_name_nid;
|
||||
|
||||
const EC_POINT *point = EC_GROUP_get0_generator(group);
|
||||
const BIGNUM *order = EC_GROUP_get0_order(group);
|
||||
int no_seed = (EC_GROUP_get0_seed(group) == NULL);
|
||||
|
||||
if ((dup = EC_GROUP_dup(group)) == NULL
|
||||
|| EC_GROUP_set_seed(dup, NULL, 0) != 1
|
||||
|| !EC_GROUP_set_generator(dup, point, order, NULL))
|
||||
goto err;
|
||||
if ((curve_name_nid = ec_curve_nid_from_params(dup, ctx)) != NID_undef) {
|
||||
/*
|
||||
* The input explicit parameters successfully matched one of the
|
||||
* built-in curves: often for built-in curves we have specialized
|
||||
* methods with better performance and hardening.
|
||||
*
|
||||
* In this case we replace the `EC_GROUP` created through explicit
|
||||
* parameters with one created from a named group.
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
/*
|
||||
* NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
|
||||
* the same curve, we prefer the SECP nid when matching explicit
|
||||
* parameters as that is associated with a specialized EC_METHOD.
|
||||
*/
|
||||
if (curve_name_nid == NID_wap_wsg_idm_ecid_wtls12)
|
||||
curve_name_nid = NID_secp224r1;
|
||||
#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
|
||||
|
||||
ret_group = EC_GROUP_new_by_curve_name_with_libctx(libctx, propq,
|
||||
curve_name_nid);
|
||||
if (ret_group == NULL)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* Set the flag so that EC_GROUPs created from explicit parameters are
|
||||
* serialized using explicit parameters by default.
|
||||
*/
|
||||
EC_GROUP_set_asn1_flag(ret_group, OPENSSL_EC_EXPLICIT_CURVE);
|
||||
|
||||
/*
|
||||
* If the input params do not contain the optional seed field we make
|
||||
* sure it is not added to the returned group.
|
||||
*
|
||||
* The seed field is not really used inside libcrypto anyway, and
|
||||
* adding it to parsed explicit parameter keys would alter their DER
|
||||
* encoding output (because of the extra field) which could impact
|
||||
* applications fingerprinting keys by their DER encoding.
|
||||
*/
|
||||
if (no_seed) {
|
||||
if (EC_GROUP_set_seed(ret_group, NULL, 0) != 1)
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
ret_group = (EC_GROUP *)group;
|
||||
}
|
||||
EC_GROUP_free(dup);
|
||||
return ret_group;
|
||||
err:
|
||||
EC_GROUP_free(dup);
|
||||
EC_GROUP_free(ret_group);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ec_encoding_param2id(const OSSL_PARAM *p, int *id)
|
||||
{
|
||||
const char *name = NULL;
|
||||
int status = 0;
|
||||
|
||||
switch (p->data_type) {
|
||||
case OSSL_PARAM_UTF8_STRING:
|
||||
/* The OSSL_PARAM functions have no support for this */
|
||||
name = p->data;
|
||||
status = (name != NULL);
|
||||
break;
|
||||
case OSSL_PARAM_UTF8_PTR:
|
||||
status = OSSL_PARAM_get_utf8_ptr(p, &name);
|
||||
break;
|
||||
}
|
||||
if (status) {
|
||||
int i = ec_encoding_name2id(name);
|
||||
|
||||
if (i >= 0) {
|
||||
*id = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EC_GROUP *group_new_from_name(const OSSL_PARAM *p,
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
int ok = 0, nid;
|
||||
const char *curve_name = NULL;
|
||||
|
||||
switch (p->data_type) {
|
||||
case OSSL_PARAM_UTF8_STRING:
|
||||
/* The OSSL_PARAM functions have no support for this */
|
||||
curve_name = p->data;
|
||||
ok = (curve_name != NULL);
|
||||
break;
|
||||
case OSSL_PARAM_UTF8_PTR:
|
||||
ok = OSSL_PARAM_get_utf8_ptr(p, &curve_name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
nid = ec_curve_name2nid(curve_name);
|
||||
if (nid == NID_undef) {
|
||||
ECerr(0, EC_R_INVALID_CURVE);
|
||||
return NULL;
|
||||
} else {
|
||||
return EC_GROUP_new_by_curve_name_with_libctx(libctx, propq, nid);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
const OSSL_PARAM *ptmp, *pa, *pb;
|
||||
int ok = 0;
|
||||
EC_GROUP *group = NULL, *named_group = NULL;
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL, *cofactor = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
int field_bits = 0;
|
||||
int is_prime_field = 1;
|
||||
BN_CTX *bnctx = NULL;
|
||||
const unsigned char *buf = NULL;
|
||||
int encoding_flag = -1;
|
||||
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING);
|
||||
if (ptmp != NULL && !ec_encoding_param2id(ptmp, &encoding_flag)) {
|
||||
ECerr(0, EC_R_INVALID_ENCODING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
|
||||
if (ptmp != NULL) {
|
||||
group = group_new_from_name(ptmp, libctx, propq);
|
||||
if (group != NULL)
|
||||
EC_GROUP_set_asn1_flag(group, encoding_flag);
|
||||
else
|
||||
ECerr(0, ERR_R_EC_LIB);
|
||||
return group;
|
||||
}
|
||||
bnctx = BN_CTX_new_ex(libctx);
|
||||
if (bnctx == NULL) {
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
BN_CTX_start(bnctx);
|
||||
|
||||
p = BN_CTX_get(bnctx);
|
||||
a = BN_CTX_get(bnctx);
|
||||
b = BN_CTX_get(bnctx);
|
||||
order = BN_CTX_get(bnctx);
|
||||
if (order == NULL) {
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE);
|
||||
if (ptmp == NULL || ptmp->data_type != OSSL_PARAM_UTF8_STRING) {
|
||||
ECerr(0, EC_R_INVALID_FIELD);
|
||||
goto err;
|
||||
}
|
||||
if (strcasecmp(ptmp->data, SN_X9_62_prime_field) == 0) {
|
||||
is_prime_field = 1;
|
||||
} else if (strcasecmp(ptmp->data, SN_X9_62_characteristic_two_field) == 0) {
|
||||
is_prime_field = 0;
|
||||
} else {
|
||||
/* Invalid field */
|
||||
ECerr(0, EC_R_UNSUPPORTED_FIELD);
|
||||
goto err;
|
||||
}
|
||||
|
||||
pa = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A);
|
||||
if (!OSSL_PARAM_get_BN(pa, &a)) {
|
||||
ECerr(0, EC_R_INVALID_A);
|
||||
goto err;
|
||||
}
|
||||
pb = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B);
|
||||
if (!OSSL_PARAM_get_BN(pb, &b)) {
|
||||
ECerr(0, EC_R_INVALID_B);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* extract the prime number or irreducible polynomial */
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P);
|
||||
if (!OSSL_PARAM_get_BN(ptmp, &p)) {
|
||||
ECerr(0, EC_R_INVALID_P);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (is_prime_field) {
|
||||
if (BN_is_negative(p) || BN_is_zero(p)) {
|
||||
ECerr(0, EC_R_INVALID_P);
|
||||
goto err;
|
||||
}
|
||||
field_bits = BN_num_bits(p);
|
||||
if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
|
||||
ECerr(0, EC_R_FIELD_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* create the EC_GROUP structure */
|
||||
group = EC_GROUP_new_curve_GFp(p, a, b, bnctx);
|
||||
} else {
|
||||
#ifdef OPENSSL_NO_EC2M
|
||||
ECerr(0, EC_R_GF2M_NOT_SUPPORTED);
|
||||
goto err;
|
||||
#else
|
||||
/* create the EC_GROUP structure */
|
||||
group = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
|
||||
if (group != NULL) {
|
||||
field_bits = EC_GROUP_get_degree(group);
|
||||
if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) {
|
||||
ECerr(0, EC_R_FIELD_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif /* OPENSSL_NO_EC2M */
|
||||
}
|
||||
|
||||
if (group == NULL) {
|
||||
ECerr(0, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Optional seed */
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED);
|
||||
if (ptmp != NULL) {
|
||||
if (ptmp->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ECerr(0, EC_R_INVALID_SEED);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_GROUP_set_seed(group, ptmp->data, ptmp->data_size))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* generator base point */
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR);
|
||||
if (ptmp == NULL
|
||||
|| ptmp->data_type != OSSL_PARAM_OCTET_STRING) {
|
||||
ECerr(0, EC_R_INVALID_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
buf = (const unsigned char *)(ptmp->data);
|
||||
if ((point = EC_POINT_new(group)) == NULL)
|
||||
goto err;
|
||||
EC_GROUP_set_point_conversion_form(group,
|
||||
(point_conversion_form_t)buf[0] & ~0x01);
|
||||
if (!EC_POINT_oct2point(group, point, buf, ptmp->data_size, bnctx)) {
|
||||
ECerr(0, EC_R_INVALID_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* order */
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER);
|
||||
if (!OSSL_PARAM_get_BN(ptmp, &order)
|
||||
|| (BN_is_negative(order) || BN_is_zero(order))
|
||||
|| (BN_num_bits(order) > (int)field_bits + 1)) { /* Hasse bound */
|
||||
ECerr(0, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Optional cofactor */
|
||||
ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR);
|
||||
if (ptmp != NULL) {
|
||||
cofactor = BN_CTX_get(bnctx);
|
||||
if (cofactor == NULL || !OSSL_PARAM_get_BN(ptmp, &cofactor)) {
|
||||
ECerr(0, EC_R_INVALID_COFACTOR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the generator, order and cofactor (if present) */
|
||||
if (!EC_GROUP_set_generator(group, point, order, cofactor)) {
|
||||
ECerr(0, EC_R_INVALID_GENERATOR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
named_group = ec_group_explicit_to_named(group, libctx, propq, bnctx);
|
||||
if (named_group == NULL) {
|
||||
ECerr(0, EC_R_INVALID_NAMED_GROUP_CONVERSION);
|
||||
goto err;
|
||||
}
|
||||
if (named_group == group) {
|
||||
/*
|
||||
* If we did not find a named group then the encoding should be explicit
|
||||
* if it was specified
|
||||
*/
|
||||
if (encoding_flag == OPENSSL_EC_NAMED_CURVE) {
|
||||
ECerr(0, EC_R_INVALID_ENCODING);
|
||||
goto err;
|
||||
}
|
||||
EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
|
||||
} else {
|
||||
EC_GROUP_free(group);
|
||||
group = named_group;
|
||||
}
|
||||
ok = 1;
|
||||
err:
|
||||
if (!ok) {
|
||||
EC_GROUP_free(group);
|
||||
group = NULL;
|
||||
}
|
||||
EC_POINT_free(point);
|
||||
BN_CTX_end(bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
@ -2421,7 +2421,10 @@ EC_R_GF2M_NOT_SUPPORTED:147:gf2m not supported
|
||||
EC_R_GROUP2PKPARAMETERS_FAILURE:120:group2pkparameters failure
|
||||
EC_R_I2D_ECPKPARAMETERS_FAILURE:121:i2d ecpkparameters failure
|
||||
EC_R_INCOMPATIBLE_OBJECTS:101:incompatible objects
|
||||
EC_R_INVALID_A:168:invalid a
|
||||
EC_R_INVALID_ARGUMENT:112:invalid argument
|
||||
EC_R_INVALID_B:169:invalid b
|
||||
EC_R_INVALID_COFACTOR:171:invalid cofactor
|
||||
EC_R_INVALID_COMPRESSED_POINT:110:invalid compressed point
|
||||
EC_R_INVALID_COMPRESSION_BIT:109:invalid compression bit
|
||||
EC_R_INVALID_CURVE:141:invalid curve
|
||||
@ -2430,12 +2433,16 @@ EC_R_INVALID_DIGEST_TYPE:138:invalid digest type
|
||||
EC_R_INVALID_ENCODING:102:invalid encoding
|
||||
EC_R_INVALID_FIELD:103:invalid field
|
||||
EC_R_INVALID_FORM:104:invalid form
|
||||
EC_R_INVALID_GENERATOR:173:invalid generator
|
||||
EC_R_INVALID_GROUP_ORDER:122:invalid group order
|
||||
EC_R_INVALID_KEY:116:invalid key
|
||||
EC_R_INVALID_NAMED_GROUP_CONVERSION:174:invalid named group conversion
|
||||
EC_R_INVALID_OUTPUT_LENGTH:161:invalid output length
|
||||
EC_R_INVALID_P:172:invalid p
|
||||
EC_R_INVALID_PEER_KEY:133:invalid peer key
|
||||
EC_R_INVALID_PENTANOMIAL_BASIS:132:invalid pentanomial basis
|
||||
EC_R_INVALID_PRIVATE_KEY:123:invalid private key
|
||||
EC_R_INVALID_SEED:175:invalid seed
|
||||
EC_R_INVALID_TRINOMIAL_BASIS:137:invalid trinomial basis
|
||||
EC_R_KDF_PARAMETER_ERROR:148:kdf parameter error
|
||||
EC_R_KEYS_NOT_SET:140:keys not set
|
||||
|
@ -1277,24 +1277,6 @@ 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, "md") == 0)
|
||||
name = OSSL_ALG_PARAM_DIGEST;
|
||||
else if (strcmp(name, "rsa_padding_mode") == 0)
|
||||
@ -1352,6 +1334,8 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name,
|
||||
name = OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE;
|
||||
else if (strcmp(name, "ecdh_kdf_md") == 0)
|
||||
name = OSSL_EXCHANGE_PARAM_KDF_DIGEST;
|
||||
else if (strcmp(name, "ec_param_enc") == 0)
|
||||
name = OSSL_PKEY_PARAM_EC_ENCODING;
|
||||
# endif
|
||||
else if (strcmp(name, "N") == 0)
|
||||
name = OSSL_KDF_PARAM_SCRYPT_N;
|
||||
|
@ -4,9 +4,10 @@
|
||||
|
||||
EC_GROUP_get_ecparameters,
|
||||
EC_GROUP_get_ecpkparameters,
|
||||
EC_GROUP_new,
|
||||
EC_GROUP_new_from_params,
|
||||
EC_GROUP_new_from_ecparameters,
|
||||
EC_GROUP_new_from_ecpkparameters,
|
||||
EC_GROUP_new,
|
||||
EC_GROUP_free,
|
||||
EC_GROUP_clear_free,
|
||||
EC_GROUP_new_curve_GFp,
|
||||
@ -26,6 +27,8 @@ objects
|
||||
|
||||
#include <openssl/ec.h>
|
||||
|
||||
EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
|
||||
OPENSSL_CTX *libctx, const char *propq);
|
||||
EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params);
|
||||
EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params);
|
||||
void EC_GROUP_free(EC_GROUP *group);
|
||||
@ -93,6 +96,14 @@ used.
|
||||
It is then necessary to call EC_GROUP_set_curve() to set the curve parameters.
|
||||
Applications should instead use one of the other EC_GROUP_new_* constructors.
|
||||
|
||||
EC_GROUP_new_from_params() creates a group with parameters specified by I<params>.
|
||||
The library context I<libctx> (see L<OPENSSL_CTX(3)>) and property query string
|
||||
I<propq> are used to fetch algorithms from providers.
|
||||
I<params> may be either a list of explicit params or a named group,
|
||||
The values for I<ctx> and I<propq> may be NULL.
|
||||
The I<params> that can be used are described in
|
||||
L<B<EVP_PKEY-EC>(7)|EVP_PKEY-EC(7)/Common EC parameters>.
|
||||
|
||||
EC_GROUP_new_from_ecparameters() will create a group from the
|
||||
specified I<params> and
|
||||
EC_GROUP_new_from_ecpkparameters() will create a group from the specific PK
|
||||
@ -177,7 +188,7 @@ EC_GROUP_get_curve_GF2m() return 1 on success or 0 on error.
|
||||
L<crypto(7)>, L<EC_GROUP_copy(3)>,
|
||||
L<EC_POINT_new(3)>, L<EC_POINT_add(3)>, L<EC_KEY_new(3)>,
|
||||
L<EC_GFp_simple_method(3)>, L<d2i_ECPKParameters(3)>,
|
||||
L<OPENSSL_CTX(3)>
|
||||
L<OPENSSL_CTX(3)>, L<EVP_PKEY-EC(7)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
@ -187,7 +198,8 @@ L<OPENSSL_CTX(3)>
|
||||
|
||||
EC_GROUP_new() was deprecated in OpenSSL 3.0.
|
||||
|
||||
EC_GROUP_new_by_curve_name_with_libctx() was added in OpenSSL 3.0.
|
||||
EC_GROUP_new_by_curve_name_with_libctx() and EC_GROUP_new_from_params() were
|
||||
added in OpenSSL 3.0.
|
||||
|
||||
=item *
|
||||
|
||||
|
@ -149,7 +149,7 @@ TODO Write a set of cookbook documents and link to them.
|
||||
0x47
|
||||
};
|
||||
const OSSL_PARAM params[] = {
|
||||
OSSL_PARAM_utf8_string("curve-name", "prime256v1"),
|
||||
OSSL_PARAM_utf8_string("group", "prime256v1"),
|
||||
OSSL_PARAM_BN("priv", priv, sizeof(priv)),
|
||||
OSSL_PARAM_BN("pub", pub, sizeof(pub)),
|
||||
OSSL_PARAM_END
|
||||
|
@ -12,7 +12,15 @@ The B<EC> keytype is implemented in OpenSSL's default provider.
|
||||
|
||||
=head2 Common EC parameters
|
||||
|
||||
The following Import/Export types are available for the built-in EC algorithm:
|
||||
The normal way of specifying domain parameters for an EC curve is via the
|
||||
curve name "group". For curves with no curve name, explicit parameters can be
|
||||
used that specify "field-type", "p", "a", "b", "generator" and "order".
|
||||
Explicit parameters are supported for backwards compability reasons, but they
|
||||
are not compliant with multiple standards (including RFC5915) which only allow
|
||||
named curves.
|
||||
|
||||
The following KeyGen/Gettable/Import/Export types are available for the
|
||||
built-in EC algorithm:
|
||||
|
||||
=over 4
|
||||
|
||||
@ -20,12 +28,56 @@ The following Import/Export types are available for the built-in EC algorithm:
|
||||
|
||||
The curve name.
|
||||
|
||||
=item "field-type" (B<OSSL_PKEY_PARAM_EC_FIELD_TYPE>) <utf8 string>
|
||||
|
||||
The value should be either "prime-field" or "characteristic-two-field",
|
||||
which correspond to prime field Fp and binary field F2^m.
|
||||
|
||||
=item "p" (B<OSSL_PKEY_PARAM_EC_P>) <unsigned integer>
|
||||
|
||||
For a curve over Fp I<p> is the prime for the field. For a curve over F2^m I<p>
|
||||
represents the irreducible polynomial - each bit represents a term in the
|
||||
polynomial. Therefore, there will either be three or five bits set dependent on
|
||||
whether the polynomial is a trinomial or a pentanomial.
|
||||
|
||||
=item "a" (B<OSSL_PKEY_PARAM_EC_A>) <unsigned integer>
|
||||
|
||||
=item "b" (B<OSSL_PKEY_PARAM_EC_B>) <unsigned integer>
|
||||
|
||||
=item "seed" (B<OSSL_PKEY_PARAM_EC_SEED>) <octet string>
|
||||
|
||||
I<a> and I<b> represents the coefficients of the curve
|
||||
For Fp: y^2 mod p = x^3 +ax + b mod p OR
|
||||
For F2^m: y^2 + xy = x^3 + ax^2 + b
|
||||
|
||||
I<seed> is an optional value that is for information purposes only.
|
||||
It represents the random number seed used to generate the coefficient I<b> from a
|
||||
random number.
|
||||
|
||||
=item "generator" (B<OSSL_PKEY_PARAM_EC_GENERATOR>) <octet string>
|
||||
|
||||
=item "order" (B<OSSL_PKEY_PARAM_EC_ORDER>) <unsigned integer>
|
||||
|
||||
=item "cofactor" (B<OSSL_PKEY_PARAM_EC_COFACTOR>) <unsigned integer>
|
||||
|
||||
The I<generator> is a well defined point on the curve chosen for cryptographic
|
||||
operations. The encoding conforms with Sec. 2.3.3 of the SECG SEC 1 ("Elliptic Curve
|
||||
Cryptography") standard. See EC_POINT_oct2point().
|
||||
Integers used for point multiplications will be between 0 and
|
||||
I<order> - 1.
|
||||
I<cofactor> is an optional value.
|
||||
I<order> multiplied by the I<cofactor> gives the number of points on the curve.
|
||||
|
||||
=item "use-cofactor-flag" (B<OSSL_PKEY_PARAM_USE_COFACTOR_ECDH>) <integer>
|
||||
|
||||
Enable Cofactor DH (ECC CDH) if this value is 1, otherwise it uses normal EC DH
|
||||
if the value is zero. The cofactor variant multiplies the shared secret by the
|
||||
EC curve's cofactor (note for some curves the cofactor is 1).
|
||||
|
||||
=item "encoding" (B<OSSL_PKEY_PARAM_EC_ENCODING>) <utf8 string>
|
||||
|
||||
Set the format used for serializing the EC group parameters.
|
||||
Valid values are "explicit" or "named_curve". The default value is "named_curve".
|
||||
|
||||
See also L<EVP_KEYEXCH-ECDH(7)> for the related
|
||||
B<OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE> parameter that can be set on a
|
||||
@ -46,6 +98,36 @@ exchange message for the TLS protocol.
|
||||
|
||||
=back
|
||||
|
||||
The following Gettable types are also available for the built-in EC algorithm:
|
||||
|
||||
=over 4
|
||||
|
||||
=item "basis-type" (B<OSSL_PKEY_PARAM_EC_CHAR2_TYPE>) <utf8 string>
|
||||
|
||||
Supports the values "tpBasis" for a trinomial or "ppBasis" for a pentanomial.
|
||||
This field is only used for a binary field F2^m.
|
||||
|
||||
=item "m" (B<OSSL_PKEY_PARAM_EC_CHAR2_M>) <integer>
|
||||
|
||||
=item "tp" (B<OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS>) <integer>
|
||||
|
||||
=item "k1" (B<OSSL_PKEY_PARAM_EC_CHAR2_PP_K1>) <integer>
|
||||
|
||||
=item "k2" (B<OSSL_PKEY_PARAM_EC_CHAR2_PP_K2>) <integer>
|
||||
|
||||
=item "k3" (B<OSSL_PKEY_PARAM_EC_CHAR2_PP_K3>) <integer>
|
||||
|
||||
These fields are only used for a binary field F2^m.
|
||||
I<m> is the degree of the binary field.
|
||||
|
||||
I<tp> is the middle bit of a trinomial so its value must be in the
|
||||
range m > tp > 0.
|
||||
|
||||
I<k1>, I<k2> and I<k3> are used to get the middle bits of a pentanomial such
|
||||
that m > k3 > k2 > k1 > 0
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
An B<EVP_PKEY> context can be obtained by calling:
|
||||
|
@ -59,10 +59,14 @@ const char *ec_curve_nid2name(int nid);
|
||||
int ec_curve_name2nid(const char *name);
|
||||
|
||||
/* Backend support */
|
||||
int ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
|
||||
OSSL_PARAM params[], OPENSSL_CTX *libctx, const char *propq,
|
||||
BN_CTX *bnctx, unsigned char **genbuf);
|
||||
int ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]);
|
||||
int ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[], int include_private);
|
||||
int ec_key_domparams_fromdata(EC_KEY *ecx, const OSSL_PARAM params[]);
|
||||
int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]);
|
||||
int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode);
|
||||
int ec_encoding_name2id(const char *name);
|
||||
|
||||
# endif /* OPENSSL_NO_EC */
|
||||
#endif
|
||||
|
@ -107,18 +107,18 @@ struct ossl_param_st {
|
||||
# define OSSL_PARAM_REAL 3
|
||||
/*-
|
||||
* OSSL_PARAM_UTF8_STRING
|
||||
* is a printable string. Is expteced to be printed as it is.
|
||||
* is a printable string. It is expected to be printed as it is.
|
||||
*/
|
||||
# define OSSL_PARAM_UTF8_STRING 4
|
||||
/*-
|
||||
* OSSL_PARAM_OCTET_STRING
|
||||
* is a string of bytes with no further specification. Is expected to be
|
||||
* is a string of bytes with no further specification. It is expected to be
|
||||
* printed as a hexdump.
|
||||
*/
|
||||
# define OSSL_PARAM_OCTET_STRING 5
|
||||
/*-
|
||||
* OSSL_PARAM_UTF8_PTR
|
||||
* is a pointer to a printable string. Is expteced to be printed as it is.
|
||||
* is a pointer to a printable string. It is expected to be printed as it is.
|
||||
*
|
||||
* The difference between this and OSSL_PARAM_UTF8_STRING is that only pointers
|
||||
* are manipulated for this type.
|
||||
|
@ -269,6 +269,22 @@ extern "C" {
|
||||
#define OSSL_PKEY_PARAM_EC_PUB_X "qx"
|
||||
#define OSSL_PKEY_PARAM_EC_PUB_Y "qy"
|
||||
|
||||
/* Elliptic Curve Explicit Domain Parameters */
|
||||
#define OSSL_PKEY_PARAM_EC_FIELD_TYPE "field-type"
|
||||
#define OSSL_PKEY_PARAM_EC_P "p"
|
||||
#define OSSL_PKEY_PARAM_EC_A "a"
|
||||
#define OSSL_PKEY_PARAM_EC_B "b"
|
||||
#define OSSL_PKEY_PARAM_EC_GENERATOR "generator"
|
||||
#define OSSL_PKEY_PARAM_EC_ORDER "order"
|
||||
#define OSSL_PKEY_PARAM_EC_COFACTOR "cofactor"
|
||||
#define OSSL_PKEY_PARAM_EC_SEED "seed"
|
||||
#define OSSL_PKEY_PARAM_EC_CHAR2_M "m"
|
||||
#define OSSL_PKEY_PARAM_EC_CHAR2_TYPE "basis-type"
|
||||
#define OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS "tp"
|
||||
#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K1 "k1"
|
||||
#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K2 "k2"
|
||||
#define OSSL_PKEY_PARAM_EC_CHAR2_PP_K3 "k3"
|
||||
|
||||
/* Elliptic Curve Key Parameters */
|
||||
#define OSSL_PKEY_PARAM_USE_COFACTOR_FLAG "use-cofactor-flag"
|
||||
#define OSSL_PKEY_PARAM_USE_COFACTOR_ECDH \
|
||||
@ -352,6 +368,12 @@ extern "C" {
|
||||
#define OSSL_PKEY_PARAM_FFC_DIGEST OSSL_PKEY_PARAM_DIGEST
|
||||
#define OSSL_PKEY_PARAM_FFC_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES
|
||||
|
||||
#define OSSL_PKEY_PARAM_EC_ENCODING "encoding" /* utf8_string */
|
||||
|
||||
/* OSSL_PKEY_PARAM_EC_ENCODING values */
|
||||
#define OSSL_PKEY_EC_ENCODING_EXPLICIT "explicit"
|
||||
#define OSSL_PKEY_EC_ENCODING_GROUP "named_curve"
|
||||
|
||||
/* Key Exchange parameters */
|
||||
#define OSSL_EXCHANGE_PARAM_PAD "pad" /* uint */
|
||||
#define OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE "ecdh-cofactor-mode" /* int */
|
||||
|
@ -47,6 +47,7 @@ typedef enum {
|
||||
POINT_CONVERSION_HYBRID = 6
|
||||
} point_conversion_form_t;
|
||||
|
||||
# include <openssl/params.h>
|
||||
# ifndef OPENSSL_NO_DEPRECATED_3_0
|
||||
typedef struct ec_method_st EC_METHOD;
|
||||
# endif
|
||||
@ -379,6 +380,19 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a,
|
||||
const BIGNUM *b, BN_CTX *ctx);
|
||||
# endif
|
||||
|
||||
/**
|
||||
* Creates a EC_GROUP object with a curve specified by parameters.
|
||||
* The parameters may be explicit or a named curve,
|
||||
* \param params A list of parameters describing the group.
|
||||
* \param libctx The associated library context or NULL for the default
|
||||
* context
|
||||
* \param propq A property query string
|
||||
* \return newly created EC_GROUP object with specified parameters or NULL
|
||||
* if an error occurred
|
||||
*/
|
||||
EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
|
||||
OPENSSL_CTX *libctx, const char *propq);
|
||||
|
||||
/**
|
||||
* Creates a EC_GROUP object with a curve specified by a NID
|
||||
* \param libctx The associated library context or NULL for the default
|
||||
|
@ -243,7 +243,10 @@ int ERR_load_EC_strings(void);
|
||||
# define EC_R_GROUP2PKPARAMETERS_FAILURE 120
|
||||
# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121
|
||||
# define EC_R_INCOMPATIBLE_OBJECTS 101
|
||||
# define EC_R_INVALID_A 168
|
||||
# define EC_R_INVALID_ARGUMENT 112
|
||||
# define EC_R_INVALID_B 169
|
||||
# define EC_R_INVALID_COFACTOR 171
|
||||
# define EC_R_INVALID_COMPRESSED_POINT 110
|
||||
# define EC_R_INVALID_COMPRESSION_BIT 109
|
||||
# define EC_R_INVALID_CURVE 141
|
||||
@ -252,12 +255,16 @@ int ERR_load_EC_strings(void);
|
||||
# define EC_R_INVALID_ENCODING 102
|
||||
# define EC_R_INVALID_FIELD 103
|
||||
# define EC_R_INVALID_FORM 104
|
||||
# define EC_R_INVALID_GENERATOR 173
|
||||
# define EC_R_INVALID_GROUP_ORDER 122
|
||||
# define EC_R_INVALID_KEY 116
|
||||
# define EC_R_INVALID_NAMED_GROUP_CONVERSION 174
|
||||
# define EC_R_INVALID_OUTPUT_LENGTH 161
|
||||
# define EC_R_INVALID_P 172
|
||||
# define EC_R_INVALID_PEER_KEY 133
|
||||
# define EC_R_INVALID_PENTANOMIAL_BASIS 132
|
||||
# define EC_R_INVALID_PRIVATE_KEY 123
|
||||
# define EC_R_INVALID_SEED 175
|
||||
# define EC_R_INVALID_TRINOMIAL_BASIS 137
|
||||
# define EC_R_KDF_PARAMETER_ERROR 148
|
||||
# define EC_R_KEYS_NOT_SET 140
|
||||
|
@ -23,22 +23,134 @@ void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
|
||||
*ec_import = ossl_prov_get_keymgmt_import(ec_keymgmt_functions);
|
||||
}
|
||||
|
||||
static int ossl_prov_print_ec_param(BIO *out, const EC_GROUP *group)
|
||||
static int ossl_prov_print_ec_param_explicit_curve(BIO *out,
|
||||
const EC_GROUP *group,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
const char *curve_name;
|
||||
int curve_nid = EC_GROUP_get_curve_name(group);
|
||||
const char *plabel = "Prime:";
|
||||
BIGNUM *p = NULL, *a = NULL, *b = NULL;
|
||||
|
||||
/* TODO(3.0): Explicit parameters are currently not supported */
|
||||
if (curve_nid == NID_undef)
|
||||
p = BN_CTX_get(ctx);
|
||||
a = BN_CTX_get(ctx);
|
||||
b = BN_CTX_get(ctx);
|
||||
if (b == NULL
|
||||
|| !EC_GROUP_get_curve(group, p, a, b, ctx))
|
||||
return 0;
|
||||
|
||||
if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
|
||||
if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) {
|
||||
int basis_type = EC_GROUP_get_basis_type(group);
|
||||
|
||||
/* print the 'short name' of the base type OID */
|
||||
if (basis_type == NID_undef
|
||||
|| BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0)
|
||||
return 0;
|
||||
plabel = "Polynomial:";
|
||||
}
|
||||
return ossl_prov_print_labeled_bignum(out, plabel, p)
|
||||
&& ossl_prov_print_labeled_bignum(out, "A: ", a)
|
||||
&& ossl_prov_print_labeled_bignum(out, "B: ", b);
|
||||
}
|
||||
|
||||
static int ossl_prov_print_ec_param_explicit_gen(BIO *out,
|
||||
const EC_GROUP *group,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
const EC_POINT *point = NULL;
|
||||
BIGNUM *gen = NULL;
|
||||
const char *glabel = NULL;
|
||||
point_conversion_form_t form;
|
||||
|
||||
form = EC_GROUP_get_point_conversion_form(group);
|
||||
point = EC_GROUP_get0_generator(group);
|
||||
gen = BN_CTX_get(ctx);
|
||||
|
||||
if (gen == NULL
|
||||
|| point == NULL
|
||||
|| EC_POINT_point2bn(group, point, form, gen, ctx) == NULL)
|
||||
return 0;
|
||||
|
||||
/* TODO(3.0): Only named curves are currently supported */
|
||||
curve_name = EC_curve_nid2nist(curve_nid);
|
||||
return (curve_name == NULL
|
||||
|| BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
|
||||
if (gen != NULL) {
|
||||
switch (form) {
|
||||
case POINT_CONVERSION_COMPRESSED:
|
||||
glabel = "Generator (compressed):";
|
||||
break;
|
||||
case POINT_CONVERSION_UNCOMPRESSED:
|
||||
glabel = "Generator (uncompressed):";
|
||||
break;
|
||||
case POINT_CONVERSION_HYBRID:
|
||||
glabel = "Generator (hybrid):";
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return ossl_prov_print_labeled_bignum(out, glabel, gen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Print explicit parameters */
|
||||
static int ossl_prov_print_ec_param_explicit(BIO *out, const EC_GROUP *group,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
int ret = 0, tmp_nid;
|
||||
BN_CTX *ctx = NULL;
|
||||
const BIGNUM *order = NULL, *cofactor = NULL;
|
||||
const unsigned char *seed;
|
||||
size_t seed_len = 0;
|
||||
|
||||
ctx = BN_CTX_new_ex(libctx);
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(ctx);
|
||||
|
||||
tmp_nid = EC_GROUP_get_field_type(group);
|
||||
order = EC_GROUP_get0_order(group);
|
||||
if (order == NULL)
|
||||
goto err;
|
||||
|
||||
seed = EC_GROUP_get0_seed(group);
|
||||
if (seed != NULL)
|
||||
seed_len = EC_GROUP_get_seed_len(group);
|
||||
cofactor = EC_GROUP_get0_cofactor(group);
|
||||
|
||||
/* print the 'short name' of the field type */
|
||||
if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0
|
||||
|| !ossl_prov_print_ec_param_explicit_curve(out, group, ctx)
|
||||
|| !ossl_prov_print_ec_param_explicit_gen(out, group, ctx)
|
||||
|| !ossl_prov_print_labeled_bignum(out, "Order: ", order)
|
||||
|| (cofactor != NULL
|
||||
&& !ossl_prov_print_labeled_bignum(out, "Cofactor: ", cofactor))
|
||||
|| (seed != NULL
|
||||
&& !ossl_prov_print_labeled_buf(out, "Seed:", seed, seed_len)))
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ossl_prov_print_ec_param(BIO *out, const EC_GROUP *group,
|
||||
OPENSSL_CTX *libctx)
|
||||
{
|
||||
if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) {
|
||||
const char *curve_name;
|
||||
int curve_nid = EC_GROUP_get_curve_name(group);
|
||||
|
||||
/* Explicit parameters */
|
||||
if (curve_nid == NID_undef)
|
||||
return 0;
|
||||
|
||||
if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
|
||||
return 0;
|
||||
|
||||
/* TODO(3.0): Only named curves are currently supported */
|
||||
curve_name = EC_curve_nid2nist(curve_nid);
|
||||
return (curve_name == NULL
|
||||
|| BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
|
||||
} else {
|
||||
return ossl_prov_print_ec_param_explicit(out, group, libctx);
|
||||
}
|
||||
}
|
||||
|
||||
int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type)
|
||||
@ -94,7 +206,7 @@ int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type)
|
||||
if (pub != NULL
|
||||
&& !ossl_prov_print_labeled_buf(out, "pub:", pub, pub_len))
|
||||
goto err;
|
||||
ret = ossl_prov_print_ec_param(out, group);
|
||||
ret = ossl_prov_print_ec_param(out, group, ec_key_get_libctx(eckey));
|
||||
err:
|
||||
OPENSSL_clear_free(priv, priv_len);
|
||||
OPENSSL_free(pub);
|
||||
@ -104,30 +216,58 @@ null_err:
|
||||
goto err;
|
||||
}
|
||||
|
||||
static int ossl_prov_prepare_ec_explicit_params(const void *eckey,
|
||||
void **pstr, int *pstrtype)
|
||||
{
|
||||
ASN1_STRING *params = ASN1_STRING_new();
|
||||
|
||||
if (params == NULL) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
params->length = i2d_ECParameters(eckey, ¶ms->data);
|
||||
if (params->length <= 0) {
|
||||
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
|
||||
ASN1_STRING_free(params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pstrtype = V_ASN1_SEQUENCE;
|
||||
*pstr = params;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_prov_prepare_ec_params(const void *eckey, int nid,
|
||||
void **pstr, int *pstrtype)
|
||||
{
|
||||
int curve_nid;
|
||||
const EC_GROUP *group = EC_KEY_get0_group(eckey);
|
||||
ASN1_OBJECT *params;
|
||||
ASN1_OBJECT *params = NULL;
|
||||
|
||||
if (group == NULL
|
||||
|| ((curve_nid = EC_GROUP_get_curve_name(group)) == NID_undef)
|
||||
|| ((params = OBJ_nid2obj(curve_nid)) == NULL)) {
|
||||
/* TODO(3.0): Explicit curves are not supported */
|
||||
if (group == NULL)
|
||||
return 0;
|
||||
curve_nid = EC_GROUP_get_curve_name(group);
|
||||
if (curve_nid != NID_undef) {
|
||||
params = OBJ_nid2obj(curve_nid);
|
||||
if (params == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (OBJ_length(params) == 0) {
|
||||
/* Some curves might not have an associated OID */
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
|
||||
ASN1_OBJECT_free(params);
|
||||
return 0;
|
||||
if (curve_nid != NID_undef
|
||||
&& (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) {
|
||||
if (OBJ_length(params) == 0) {
|
||||
/* Some curves might not have an associated OID */
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
|
||||
ASN1_OBJECT_free(params);
|
||||
return 0;
|
||||
}
|
||||
*pstr = params;
|
||||
*pstrtype = V_ASN1_OBJECT;
|
||||
return 1;
|
||||
} else {
|
||||
return ossl_prov_prepare_ec_explicit_params(eckey, pstr, pstrtype);
|
||||
}
|
||||
|
||||
*pstr = params;
|
||||
*pstrtype = V_ASN1_OBJECT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder)
|
||||
|
@ -13,6 +13,8 @@
|
||||
*/
|
||||
#include "internal/deprecated.h"
|
||||
|
||||
#include "e_os.h" /* strcasecmp */
|
||||
#include <string.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/bn.h>
|
||||
@ -64,41 +66,6 @@ const char *ec_query_operation_name(int operation_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ossl_inline
|
||||
int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
|
||||
OSSL_PARAM params[])
|
||||
{
|
||||
const EC_GROUP *ecg;
|
||||
int curve_nid;
|
||||
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
|
||||
ecg = EC_KEY_get0_group(ec);
|
||||
if (ecg == NULL)
|
||||
return 0;
|
||||
|
||||
curve_nid = EC_GROUP_get_curve_name(ecg);
|
||||
|
||||
if (curve_nid == NID_undef) {
|
||||
/* TODO(3.0): should we support explicit parameters curves? */
|
||||
return 0;
|
||||
} else {
|
||||
/* named curve */
|
||||
const char *curve_name = NULL;
|
||||
|
||||
if ((curve_name = ec_curve_nid2name(curve_nid)) == NULL)
|
||||
return 0;
|
||||
if (!ossl_param_build_set_utf8_string(tmpl, params,
|
||||
OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
curve_name))
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callers of key_to_params MUST make sure that domparams_to_params is also
|
||||
* called!
|
||||
@ -319,7 +286,7 @@ int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
|
||||
/*
|
||||
* In this implementation, we can export/import only keydata in the
|
||||
* following combinations:
|
||||
* - domain parameters only
|
||||
* - domain parameters (+optional other params)
|
||||
* - public key with associated domain parameters (+optional other params)
|
||||
* - private key with associated public key and domain parameters
|
||||
* (+optional other params)
|
||||
@ -327,19 +294,16 @@ int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
|
||||
* This means:
|
||||
* - domain parameters must always be requested
|
||||
* - private key must be requested alongside public key
|
||||
* - other parameters must be requested only alongside a key
|
||||
* - other parameters are always optional
|
||||
*/
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
|
||||
return 0;
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
|
||||
&& (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
|
||||
return 0;
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0
|
||||
&& (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
|
||||
return 0;
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && ec_key_domparams_fromdata(ec, params);
|
||||
ok = ok && ec_group_fromdata(ec, params);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
|
||||
int include_private =
|
||||
selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
|
||||
@ -359,7 +323,8 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
|
||||
EC_KEY *ec = keydata;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
OSSL_PARAM *params = NULL;
|
||||
unsigned char *pub_key = NULL;
|
||||
unsigned char *pub_key = NULL, *genbuf = NULL;
|
||||
BN_CTX *bnctx = NULL;
|
||||
int ok = 1;
|
||||
|
||||
if (ec == NULL)
|
||||
@ -368,7 +333,7 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
|
||||
/*
|
||||
* In this implementation, we can export/import only keydata in the
|
||||
* following combinations:
|
||||
* - domain parameters only
|
||||
* - domain parameters (+optional other params)
|
||||
* - public key with associated domain parameters (+optional other params)
|
||||
* - private key with associated public key and domain parameters
|
||||
* (+optional other params)
|
||||
@ -376,7 +341,7 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
|
||||
* This means:
|
||||
* - domain parameters must always be requested
|
||||
* - private key must be requested alongside public key
|
||||
* - other parameters must be requested only alongside a key
|
||||
* - other parameters are always optional
|
||||
*/
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
|
||||
return 0;
|
||||
@ -391,8 +356,14 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && domparams_to_params(ec, tmpl, NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
|
||||
bnctx = BN_CTX_new_ex(ec_key_get_libctx(ec));
|
||||
BN_CTX_start(bnctx);
|
||||
ok = ok && (bnctx != NULL);
|
||||
ok = ok && ec_group_todata(EC_KEY_get0_group(ec), tmpl, NULL,
|
||||
ec_key_get_libctx(ec), ec_key_get0_propq(ec),
|
||||
bnctx, &genbuf);
|
||||
}
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
|
||||
int include_private =
|
||||
@ -409,18 +380,31 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
OPENSSL_free(pub_key);
|
||||
OPENSSL_free(genbuf);
|
||||
BN_CTX_end(bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* IMEXPORT = IMPORT + EXPORT */
|
||||
|
||||
# define EC_IMEXPORTABLE_DOM_PARAMETERS \
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0)
|
||||
# define EC_IMEXPORTABLE_PUBLIC_KEY \
|
||||
# define EC_IMEXPORTABLE_DOM_PARAMETERS \
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), \
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), \
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), \
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), \
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), \
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), \
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), \
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), \
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), \
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0)
|
||||
|
||||
# define EC_IMEXPORTABLE_PUBLIC_KEY \
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
|
||||
# define EC_IMEXPORTABLE_PRIVATE_KEY \
|
||||
# define EC_IMEXPORTABLE_PRIVATE_KEY \
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
|
||||
# define EC_IMEXPORTABLE_OTHER_PARAMETERS \
|
||||
# define EC_IMEXPORTABLE_OTHER_PARAMETERS \
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL)
|
||||
|
||||
/*
|
||||
@ -465,19 +449,81 @@ const OSSL_PARAM *ec_export_types(int selection)
|
||||
return ec_imexport_types(selection);
|
||||
}
|
||||
|
||||
static int ec_get_ecm_params(const EC_GROUP *group, OSSL_PARAM params[])
|
||||
{
|
||||
#ifdef OPENSSL_NO_EC2M
|
||||
return 1;
|
||||
#else
|
||||
int ret = 0, m;
|
||||
unsigned int k1 = 0, k2 = 0, k3 = 0;
|
||||
int basis_nid;
|
||||
const char *basis_name = NULL;
|
||||
int fid = EC_GROUP_get_field_type(group);
|
||||
|
||||
if (fid != NID_X9_62_characteristic_two_field)
|
||||
return 1;
|
||||
|
||||
basis_nid = EC_GROUP_get_basis_type(group);
|
||||
if (basis_nid == NID_X9_62_tpBasis)
|
||||
basis_name = SN_X9_62_tpBasis;
|
||||
else if (basis_nid == NID_X9_62_ppBasis)
|
||||
basis_name = SN_X9_62_ppBasis;
|
||||
else
|
||||
goto err;
|
||||
|
||||
m = EC_GROUP_get_degree(group);
|
||||
if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m)
|
||||
|| !ossl_param_build_set_utf8_string(NULL, params,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_TYPE,
|
||||
basis_name))
|
||||
goto err;
|
||||
|
||||
if (basis_nid == NID_X9_62_tpBasis) {
|
||||
if (!EC_GROUP_get_trinomial_basis(group, &k1)
|
||||
|| !ossl_param_build_set_int(NULL, params,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS,
|
||||
(int)k1))
|
||||
goto err;
|
||||
} else {
|
||||
if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)
|
||||
|| !ossl_param_build_set_int(NULL, params,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1)
|
||||
|| !ossl_param_build_set_int(NULL, params,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2)
|
||||
|| !ossl_param_build_set_int(NULL, params,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
return ret;
|
||||
#endif /* OPENSSL_NO_EC2M */
|
||||
}
|
||||
|
||||
static
|
||||
int ec_get_params(void *key, OSSL_PARAM params[])
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
EC_KEY *eck = key;
|
||||
const EC_GROUP *ecg = NULL;
|
||||
OSSL_PARAM *p;
|
||||
unsigned char *pub_key = NULL;
|
||||
unsigned char *pub_key = NULL, *genbuf = NULL;
|
||||
OPENSSL_CTX *libctx;
|
||||
const char *propq;
|
||||
BN_CTX *bnctx = NULL;
|
||||
|
||||
ecg = EC_KEY_get0_group(eck);
|
||||
if (ecg == NULL)
|
||||
return 0;
|
||||
|
||||
libctx = ec_key_get_libctx(eck);
|
||||
propq = ec_key_get0_propq(eck);
|
||||
|
||||
bnctx = BN_CTX_new_ex(libctx);
|
||||
if (bnctx == NULL)
|
||||
return 0;
|
||||
BN_CTX_start(bnctx);
|
||||
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
|
||||
&& !OSSL_PARAM_set_int(p, ECDSA_size(eck)))
|
||||
return 0;
|
||||
@ -537,32 +583,45 @@ int ec_get_params(void *key, OSSL_PARAM params[])
|
||||
return 0;
|
||||
}
|
||||
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) {
|
||||
BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(key));
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
p->return_size = EC_POINT_point2oct(EC_KEY_get0_group(key),
|
||||
EC_KEY_get0_public_key(key),
|
||||
POINT_CONVERSION_UNCOMPRESSED,
|
||||
p->data, p->return_size, ctx);
|
||||
BN_CTX_free(ctx);
|
||||
p->data, p->return_size, bnctx);
|
||||
if (p->return_size == 0)
|
||||
return 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = domparams_to_params(eck, NULL, params)
|
||||
ret = ec_get_ecm_params(ecg, params)
|
||||
&& ec_group_todata(ecg, NULL, params, libctx, propq, bnctx, &genbuf)
|
||||
&& key_to_params(eck, NULL, params, 1, &pub_key)
|
||||
&& otherparams_to_params(eck, NULL, params);
|
||||
err:
|
||||
OPENSSL_free(genbuf);
|
||||
OPENSSL_free(pub_key);
|
||||
BN_CTX_end(bnctx);
|
||||
BN_CTX_free(bnctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
# define EC2M_GETTABLE_DOM_PARAMS \
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_M, NULL), \
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_CHAR2_TYPE, NULL, 0), \
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, NULL), \
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, NULL), \
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, NULL), \
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, NULL),
|
||||
#else
|
||||
# define EC2M_GETTABLE_DOM_PARAMS
|
||||
#endif
|
||||
|
||||
static const OSSL_PARAM ec_known_gettable_params[] = {
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
|
||||
EC_IMEXPORTABLE_DOM_PARAMETERS,
|
||||
EC2M_GETTABLE_DOM_PARAMS
|
||||
EC_IMEXPORTABLE_PUBLIC_KEY,
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0),
|
||||
@ -643,9 +702,15 @@ int ec_validate(void *keydata, int selection)
|
||||
|
||||
struct ec_gen_ctx {
|
||||
OPENSSL_CTX *libctx;
|
||||
EC_GROUP *gen_group;
|
||||
char *group_name;
|
||||
char *encoding;
|
||||
char *field_type;
|
||||
BIGNUM *p, *a, *b, *order, *cofactor;
|
||||
unsigned char *gen, *seed;
|
||||
size_t gen_len, seed_len;
|
||||
int selection;
|
||||
int ecdh_mode;
|
||||
EC_GROUP *gen_group;
|
||||
};
|
||||
|
||||
static void *ec_gen_init(void *provctx, int selection)
|
||||
@ -658,19 +723,18 @@ static void *ec_gen_init(void *provctx, int selection)
|
||||
|
||||
if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
|
||||
gctx->libctx = libctx;
|
||||
gctx->gen_group = NULL;
|
||||
gctx->selection = selection;
|
||||
gctx->ecdh_mode = 0;
|
||||
}
|
||||
return gctx;
|
||||
}
|
||||
|
||||
static int ec_gen_set_group(void *genctx, int nid)
|
||||
static int ec_gen_set_group(void *genctx, const EC_GROUP *src)
|
||||
{
|
||||
struct ec_gen_ctx *gctx = genctx;
|
||||
EC_GROUP *group;
|
||||
|
||||
group = EC_GROUP_new_by_curve_name_with_libctx(gctx->libctx, NULL, nid);
|
||||
group = EC_GROUP_dup(src);
|
||||
if (group == NULL) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
|
||||
return 0;
|
||||
@ -679,6 +743,7 @@ static int ec_gen_set_group(void *genctx, int nid)
|
||||
gctx->gen_group = group;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ec_gen_set_template(void *genctx, void *templ)
|
||||
{
|
||||
struct ec_gen_ctx *gctx = genctx;
|
||||
@ -689,48 +754,144 @@ static int ec_gen_set_template(void *genctx, void *templ)
|
||||
return 0;
|
||||
if ((ec_group = EC_KEY_get0_group(ec)) == NULL)
|
||||
return 0;
|
||||
return ec_gen_set_group(gctx, EC_GROUP_get_curve_name(ec_group));
|
||||
return ec_gen_set_group(gctx, ec_group);
|
||||
}
|
||||
|
||||
#define COPY_INT_PARAM(params, key, val) \
|
||||
p = OSSL_PARAM_locate_const(params, key); \
|
||||
if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \
|
||||
goto err;
|
||||
|
||||
#define COPY_UTF8_PARAM(params, key, val) \
|
||||
p = OSSL_PARAM_locate_const(params, key); \
|
||||
if (p != NULL) { \
|
||||
if (p->data_type != OSSL_PARAM_UTF8_STRING) \
|
||||
goto err; \
|
||||
OPENSSL_free(val); \
|
||||
val = OPENSSL_strdup(p->data); \
|
||||
if (val == NULL) \
|
||||
goto err; \
|
||||
}
|
||||
|
||||
#define COPY_OCTET_PARAM(params, key, val, len) \
|
||||
p = OSSL_PARAM_locate_const(params, key); \
|
||||
if (p != NULL) { \
|
||||
if (p->data_type != OSSL_PARAM_OCTET_STRING) \
|
||||
goto err; \
|
||||
OPENSSL_free(val); \
|
||||
len = p->data_size; \
|
||||
val = OPENSSL_memdup(p->data, p->data_size); \
|
||||
if (val == NULL) \
|
||||
goto err; \
|
||||
}
|
||||
|
||||
#define COPY_BN_PARAM(params, key, bn) \
|
||||
p = OSSL_PARAM_locate_const(params, key); \
|
||||
if (p != NULL) { \
|
||||
if (bn == NULL) \
|
||||
bn = BN_new(); \
|
||||
if (bn == NULL || !OSSL_PARAM_get_BN(p, &bn)) \
|
||||
goto err; \
|
||||
}
|
||||
|
||||
static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[])
|
||||
{
|
||||
int ret = 0;
|
||||
struct ec_gen_ctx *gctx = genctx;
|
||||
const OSSL_PARAM *p;
|
||||
EC_GROUP *group = NULL;
|
||||
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH))
|
||||
!= NULL) {
|
||||
if (!OSSL_PARAM_get_int(p, &gctx->ecdh_mode))
|
||||
return 0;
|
||||
COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode);
|
||||
|
||||
COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name);
|
||||
COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type);
|
||||
COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding);
|
||||
|
||||
COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p);
|
||||
COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a);
|
||||
COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b);
|
||||
COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order);
|
||||
COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor);
|
||||
|
||||
COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len);
|
||||
COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen,
|
||||
gctx->gen_len);
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
EC_GROUP_free(group);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx)
|
||||
{
|
||||
int ret = 0;
|
||||
OSSL_PARAM_BLD *bld;
|
||||
OSSL_PARAM *params = NULL;
|
||||
EC_GROUP *group = NULL;
|
||||
|
||||
bld = OSSL_PARAM_BLD_new();
|
||||
if (bld == NULL)
|
||||
return 0;
|
||||
|
||||
if (gctx->encoding != NULL
|
||||
&& !OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_ENCODING,
|
||||
gctx->encoding, 0))
|
||||
goto err;
|
||||
|
||||
if (gctx->group_name != NULL) {
|
||||
if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
gctx->group_name, 0))
|
||||
goto err;
|
||||
/* Ignore any other parameters if there is a group name */
|
||||
goto build;
|
||||
} else if (gctx->field_type != NULL) {
|
||||
if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE,
|
||||
gctx->field_type, 0))
|
||||
goto err;
|
||||
} else {
|
||||
goto err;
|
||||
}
|
||||
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME))
|
||||
!= NULL) {
|
||||
const char *curve_name = NULL;
|
||||
int ret = 0;
|
||||
if (gctx->p == NULL
|
||||
|| gctx->a == NULL
|
||||
|| gctx->b == NULL
|
||||
|| gctx->order == NULL
|
||||
|| !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, gctx->p)
|
||||
|| !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, gctx->a)
|
||||
|| !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, gctx->b)
|
||||
|| !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER, gctx->order))
|
||||
goto err;
|
||||
|
||||
switch (p->data_type) {
|
||||
case OSSL_PARAM_UTF8_STRING:
|
||||
/* The OSSL_PARAM functions have no support for this */
|
||||
curve_name = p->data;
|
||||
ret = (curve_name != NULL);
|
||||
break;
|
||||
case OSSL_PARAM_UTF8_PTR:
|
||||
ret = OSSL_PARAM_get_utf8_ptr(p, &curve_name);
|
||||
break;
|
||||
}
|
||||
if (gctx->cofactor != NULL
|
||||
&& !OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
|
||||
gctx->cofactor))
|
||||
goto err;
|
||||
|
||||
if (ret) {
|
||||
int nid = ec_curve_name2nid(curve_name);
|
||||
if (gctx->seed != NULL
|
||||
&& !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_SEED,
|
||||
gctx->seed, gctx->seed_len))
|
||||
goto err;
|
||||
|
||||
if (nid == NID_undef) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = ec_gen_set_group(gctx, nid);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
if (gctx->gen == NULL
|
||||
|| !OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_EC_GENERATOR,
|
||||
gctx->gen, gctx->gen_len))
|
||||
goto err;
|
||||
build:
|
||||
params = OSSL_PARAM_BLD_to_param(bld);
|
||||
if (params == NULL)
|
||||
goto err;
|
||||
group = EC_GROUP_new_from_params(params, gctx->libctx, NULL);
|
||||
if (group == NULL)
|
||||
goto err;
|
||||
|
||||
EC_GROUP_free(gctx->gen_group);
|
||||
gctx->gen_group = group;
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
OSSL_PARAM_BLD_free(bld);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const OSSL_PARAM *ec_gen_settable_params(void *provctx)
|
||||
@ -738,6 +899,15 @@ static const OSSL_PARAM *ec_gen_settable_params(void *provctx)
|
||||
static OSSL_PARAM settable[] = {
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
|
||||
OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0),
|
||||
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0),
|
||||
OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0),
|
||||
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
@ -760,14 +930,27 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
|
||||
{
|
||||
struct ec_gen_ctx *gctx = genctx;
|
||||
EC_KEY *ec = NULL;
|
||||
int ret = 1; /* Start optimistically */
|
||||
int ret = 0;
|
||||
|
||||
if (gctx == NULL
|
||||
|| (ec = EC_KEY_new_with_libctx(gctx->libctx, NULL)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (gctx->gen_group == NULL) {
|
||||
if (!ec_gen_set_group_from_params(gctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (gctx->encoding) {
|
||||
int flags = ec_encoding_name2id(gctx->encoding);
|
||||
if (flags < 0)
|
||||
goto err;
|
||||
EC_GROUP_set_asn1_flag(gctx->gen_group, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* We must always assign a group, no matter what */
|
||||
ret = ec_gen_assign_group(ec, gctx->gen_group);
|
||||
|
||||
/* Whether you want it or not, you get a keypair, not just one half */
|
||||
if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
|
||||
ret = ret && EC_KEY_generate_key(ec);
|
||||
@ -777,7 +960,7 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
|
||||
|
||||
if (ret)
|
||||
return ec;
|
||||
|
||||
err:
|
||||
/* Something went wrong, throw the key away */
|
||||
EC_KEY_free(ec);
|
||||
return NULL;
|
||||
@ -791,6 +974,16 @@ static void ec_gen_cleanup(void *genctx)
|
||||
return;
|
||||
|
||||
EC_GROUP_free(gctx->gen_group);
|
||||
BN_free(gctx->p);
|
||||
BN_free(gctx->a);
|
||||
BN_free(gctx->b);
|
||||
BN_free(gctx->order);
|
||||
BN_free(gctx->cofactor);
|
||||
OPENSSL_free(gctx->group_name);
|
||||
OPENSSL_free(gctx->field_type);;
|
||||
OPENSSL_free(gctx->encoding);
|
||||
OPENSSL_free(gctx->seed);
|
||||
OPENSSL_free(gctx->gen);
|
||||
OPENSSL_free(gctx);
|
||||
}
|
||||
|
||||
|
224
test/ectest.c
224
test/ectest.c
@ -2340,6 +2340,225 @@ static int ec_point_hex2point_test(int id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx,
|
||||
unsigned char *gen, int gen_size)
|
||||
{
|
||||
int ret = 0, i_out;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkeyparam = NULL;
|
||||
OSSL_PARAM_BLD *bld = NULL;
|
||||
const char *field_name;
|
||||
OSSL_PARAM *params = NULL;
|
||||
const OSSL_PARAM *gettable;
|
||||
BIGNUM *p, *a, *b;
|
||||
BIGNUM *p_out = NULL, *a_out = NULL, *b_out = NULL;
|
||||
BIGNUM *order_out = NULL, *cofactor_out = NULL;
|
||||
char name[80];
|
||||
unsigned char buf[1024];
|
||||
size_t buf_len, name_len;
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
unsigned int k1 = 0, k2 = 0, k3 = 0;
|
||||
const char *basis_name = NULL;
|
||||
#endif
|
||||
|
||||
p = BN_CTX_get(ctx);
|
||||
a = BN_CTX_get(ctx);
|
||||
b = BN_CTX_get(ctx);
|
||||
|
||||
if (!TEST_ptr(b)
|
||||
|| !TEST_ptr(bld = OSSL_PARAM_BLD_new()))
|
||||
goto err;
|
||||
|
||||
if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
|
||||
field_name = SN_X9_62_prime_field;
|
||||
} else {
|
||||
field_name = SN_X9_62_characteristic_two_field;
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
|
||||
basis_name = SN_X9_62_tpBasis;
|
||||
if (!TEST_true(EC_GROUP_get_trinomial_basis(group, &k1)))
|
||||
goto err;
|
||||
} else {
|
||||
basis_name = SN_X9_62_ppBasis;
|
||||
if (!TEST_true(EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)))
|
||||
goto err;
|
||||
}
|
||||
#endif /* OPENSSL_NO_EC2M */
|
||||
}
|
||||
if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))
|
||||
|| !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_FIELD_TYPE, field_name, 0))
|
||||
|| !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, p))
|
||||
|| !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
|
||||
|| !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b)))
|
||||
goto err;
|
||||
|
||||
if (EC_GROUP_get0_seed(group) != NULL) {
|
||||
if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_SEED, EC_GROUP_get0_seed(group),
|
||||
EC_GROUP_get_seed_len(group))))
|
||||
goto err;
|
||||
}
|
||||
if (EC_GROUP_get0_cofactor(group) != NULL) {
|
||||
if (!TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
|
||||
EC_GROUP_get0_cofactor(group))))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_size))
|
||||
|| !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER,
|
||||
EC_GROUP_get0_order(group))))
|
||||
goto err;
|
||||
|
||||
if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
|
||||
|| !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL))
|
||||
|| !TEST_int_gt(EVP_PKEY_param_fromdata_init(pctx), 0)
|
||||
|| !TEST_int_gt(EVP_PKEY_fromdata(pctx, &pkeyparam, params), 0))
|
||||
goto err;
|
||||
|
||||
/*- Check that all the set values are retrievable -*/
|
||||
|
||||
/* There should be no match to a group name since the generator changed */
|
||||
if (!TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_GROUP_NAME, name, sizeof(name),
|
||||
&name_len)))
|
||||
goto err;
|
||||
|
||||
/* The encoding should be explicit as it has no group */
|
||||
if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_ENCODING,
|
||||
name, sizeof(name), &name_len))
|
||||
|| !TEST_str_eq(name, OSSL_PKEY_EC_ENCODING_EXPLICIT))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_FIELD_TYPE, name, sizeof(name),
|
||||
&name_len))
|
||||
|| !TEST_str_eq(name, field_name))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_GENERATOR, buf, sizeof(buf), &buf_len))
|
||||
|| !TEST_mem_eq(buf, (int)buf_len, gen, gen_size))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_P, &p_out))
|
||||
|| !TEST_BN_eq(p_out, p)
|
||||
|| !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_A,
|
||||
&a_out))
|
||||
|| !TEST_BN_eq(a_out, a)
|
||||
|| !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_B,
|
||||
&b_out))
|
||||
|| !TEST_BN_eq(b_out, b)
|
||||
|| !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_ORDER,
|
||||
&order_out))
|
||||
|| !TEST_BN_eq(order_out, EC_GROUP_get0_order(group)))
|
||||
goto err;
|
||||
|
||||
if (EC_GROUP_get0_cofactor(group) != NULL) {
|
||||
if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_COFACTOR, &cofactor_out))
|
||||
|| !TEST_BN_eq(cofactor_out, EC_GROUP_get0_cofactor(group)))
|
||||
goto err;
|
||||
}
|
||||
if (EC_GROUP_get0_seed(group) != NULL) {
|
||||
if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_SEED, buf, sizeof(buf), &buf_len))
|
||||
|| !TEST_mem_eq(buf, buf_len, EC_GROUP_get0_seed(group),
|
||||
EC_GROUP_get_seed_len(group)))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) {
|
||||
/* No extra fields should be set for a prime field */
|
||||
if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
|
||||
|| !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
|
||||
|| !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
|
||||
|| !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
|
||||
|| !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
|
||||
|| !TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
|
||||
&name_len)))
|
||||
goto err;
|
||||
} else {
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out))
|
||||
|| !TEST_int_eq(EC_GROUP_get_degree(group), i_out)
|
||||
|| !TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name),
|
||||
&name_len))
|
||||
|| !TEST_str_eq(name, basis_name))
|
||||
goto err;
|
||||
|
||||
if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) {
|
||||
if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
|
||||
|| !TEST_int_eq(k1, i_out)
|
||||
|| !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
|
||||
|| !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
|
||||
|| !TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out)))
|
||||
goto err;
|
||||
} else {
|
||||
if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out))
|
||||
|| !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out))
|
||||
|| !TEST_int_eq(k1, i_out)
|
||||
|| !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out))
|
||||
|| !TEST_int_eq(k2, i_out)
|
||||
|| !TEST_true(EVP_PKEY_get_int_param(pkeyparam,
|
||||
OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))
|
||||
|| !TEST_int_eq(k3, i_out))
|
||||
goto err;
|
||||
}
|
||||
#endif /* OPENSSL_NO_EC2M */
|
||||
}
|
||||
if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pkeyparam))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_GROUP_NAME))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ENCODING))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_FIELD_TYPE))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_P))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_A))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_B))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_GENERATOR))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ORDER))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_COFACTOR))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_SEED))
|
||||
#ifndef OPENSSL_NO_EC2M
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_M))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TYPE))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K1))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K2))
|
||||
|| !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K3))
|
||||
#endif
|
||||
)
|
||||
goto err;
|
||||
ret = 1;
|
||||
err:
|
||||
BN_free(order_out);
|
||||
BN_free(cofactor_out);
|
||||
BN_free(a_out);
|
||||
BN_free(b_out);
|
||||
BN_free(p_out);
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
OSSL_PARAM_BLD_free(bld);
|
||||
EVP_PKEY_free(pkeyparam);
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* check the EC_METHOD respects the supplied EC_GROUP_set_generator G
|
||||
*/
|
||||
@ -2406,14 +2625,17 @@ static int custom_generator_test(int id)
|
||||
|| !TEST_mem_eq(b1, bsize, b2, bsize))
|
||||
goto err;
|
||||
|
||||
if (!do_test_custom_explicit_fromdata(group, ctx, b1, bsize))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_end(ctx);
|
||||
EC_POINT_free(Q1);
|
||||
EC_POINT_free(Q2);
|
||||
EC_POINT_free(G2);
|
||||
EC_GROUP_free(group);
|
||||
BN_CTX_end(ctx);
|
||||
BN_CTX_free(ctx);
|
||||
OPENSSL_free(b1);
|
||||
OPENSSL_free(b2);
|
||||
|
@ -12,7 +12,9 @@
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/param_build.h>
|
||||
#include <openssl/encoder.h>
|
||||
#include <openssl/decoder.h>
|
||||
|
||||
@ -21,6 +23,21 @@
|
||||
|
||||
#include "testutil.h"
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
static BN_CTX *bnctx = NULL;
|
||||
static OSSL_PARAM_BLD *bld_prime_nc = NULL;
|
||||
static OSSL_PARAM_BLD *bld_prime = NULL;
|
||||
static OSSL_PARAM *ec_explicit_prime_params_nc = NULL;
|
||||
static OSSL_PARAM *ec_explicit_prime_params_explicit = NULL;
|
||||
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
static OSSL_PARAM_BLD *bld_tri_nc = NULL;
|
||||
static OSSL_PARAM_BLD *bld_tri = NULL;
|
||||
static OSSL_PARAM *ec_explicit_tri_params_nc = NULL;
|
||||
static OSSL_PARAM *ec_explicit_tri_params_explicit = NULL;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TODO(3.0) Modify PEM_write_bio_PrivateKey_traditional() to handle
|
||||
* provider side EVP_PKEYs (which don't necessarily have an ameth)
|
||||
@ -75,7 +92,6 @@ static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
|
||||
return pkey;
|
||||
}
|
||||
|
||||
|
||||
/* Main test driver */
|
||||
|
||||
/*
|
||||
@ -754,6 +770,16 @@ IMPLEMENT_TEST_SUITE_PVK(DSA, "DSA")
|
||||
#ifndef OPENSSL_NO_EC
|
||||
DOMAIN_KEYS(EC);
|
||||
IMPLEMENT_TEST_SUITE(EC, "EC")
|
||||
DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
|
||||
IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC")
|
||||
DOMAIN_KEYS(ECExplicitPrime2G);
|
||||
IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC")
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
DOMAIN_KEYS(ECExplicitTriNamedCurve);
|
||||
IMPLEMENT_TEST_SUITE(ECExplicitTriNamedCurve, "EC")
|
||||
DOMAIN_KEYS(ECExplicitTri2G);
|
||||
IMPLEMENT_TEST_SUITE(ECExplicitTri2G, "EC")
|
||||
# endif
|
||||
KEYS(ED25519);
|
||||
IMPLEMENT_TEST_SUITE(ED25519, "ED25519")
|
||||
KEYS(ED448);
|
||||
@ -774,6 +800,189 @@ IMPLEMENT_TEST_SUITE_PVK(RSA, "RSA")
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
/* Explicit parameters that match a named curve */
|
||||
static int do_create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld,
|
||||
const unsigned char *gen,
|
||||
size_t gen_len)
|
||||
{
|
||||
BIGNUM *a, *b, *prime, *order;
|
||||
|
||||
/* Curve prime256v1 */
|
||||
static const unsigned char prime_data[] = {
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff
|
||||
};
|
||||
static const unsigned char a_data[] = {
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfc
|
||||
};
|
||||
static const unsigned char b_data[] = {
|
||||
0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
|
||||
0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
|
||||
0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
|
||||
0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
|
||||
};
|
||||
static const unsigned char seed[] = {
|
||||
0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93,
|
||||
0x6a, 0x66, 0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7,
|
||||
0x81, 0x9f, 0x7e, 0x90
|
||||
};
|
||||
static const unsigned char order_data[] = {
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e,
|
||||
0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51
|
||||
};
|
||||
return TEST_ptr(a = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(b = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(prime = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(order = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(BN_bin2bn(prime_data, sizeof(prime_data), prime))
|
||||
&& TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
|
||||
&& TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
|
||||
&& TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_FIELD_TYPE, SN_X9_62_prime_field,
|
||||
0))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, prime))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld,
|
||||
OSSL_PKEY_PARAM_EC_ORDER, order))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_SEED, seed, sizeof(seed)))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
|
||||
BN_value_one()));
|
||||
}
|
||||
|
||||
static int create_ec_explicit_prime_params_namedcurve(OSSL_PARAM_BLD *bld)
|
||||
{
|
||||
static const unsigned char prime256v1_gen[] = {
|
||||
0x04,
|
||||
0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
|
||||
0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
|
||||
0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
|
||||
0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
|
||||
0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
|
||||
0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
|
||||
0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
|
||||
0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
|
||||
};
|
||||
return do_create_ec_explicit_prime_params(bld, prime256v1_gen,
|
||||
sizeof(prime256v1_gen));
|
||||
}
|
||||
|
||||
static int create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld)
|
||||
{
|
||||
/* 2G */
|
||||
static const unsigned char prime256v1_gen2[] = {
|
||||
0x04,
|
||||
0xe4, 0x97, 0x08, 0xbe, 0x7d, 0xfa, 0xa2, 0x9a,
|
||||
0xa3, 0x12, 0x6f, 0xe4, 0xe7, 0xd0, 0x25, 0xe3,
|
||||
0x4a, 0xc1, 0x03, 0x15, 0x8c, 0xd9, 0x33, 0xc6,
|
||||
0x97, 0x42, 0xf5, 0xdc, 0x97, 0xb9, 0xd7, 0x31,
|
||||
0xe9, 0x7d, 0x74, 0x3d, 0x67, 0x6a, 0x3b, 0x21,
|
||||
0x08, 0x9c, 0x31, 0x73, 0xf8, 0xc1, 0x27, 0xc9,
|
||||
0xd2, 0xa0, 0xa0, 0x83, 0x66, 0xe0, 0xc9, 0xda,
|
||||
0xa8, 0xc6, 0x56, 0x2b, 0x94, 0xb1, 0xae, 0x55
|
||||
};
|
||||
return do_create_ec_explicit_prime_params(bld, prime256v1_gen2,
|
||||
sizeof(prime256v1_gen2));
|
||||
}
|
||||
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
static int do_create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld,
|
||||
const unsigned char *gen,
|
||||
size_t gen_len)
|
||||
{
|
||||
BIGNUM *a, *b, *poly, *order, *cofactor;
|
||||
/* sect233k1 characteristic-two-field tpBasis */
|
||||
static const unsigned char poly_data[] = {
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
};
|
||||
static const unsigned char a_data[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static const unsigned char b_data[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
static const unsigned char order_data[] = {
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB,
|
||||
0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
|
||||
};
|
||||
static const unsigned char cofactor_data[]= {
|
||||
0x4
|
||||
};
|
||||
return TEST_ptr(a = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(b = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(poly = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(order = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(cofactor = BN_CTX_get(bnctx))
|
||||
&& TEST_ptr(BN_bin2bn(poly_data, sizeof(poly_data), poly))
|
||||
&& TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
|
||||
&& TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
|
||||
&& TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
|
||||
&& TEST_ptr(BN_bin2bn(cofactor_data, sizeof(cofactor_data), cofactor))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_FIELD_TYPE,
|
||||
SN_X9_62_characteristic_two_field, 0))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, poly))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld,
|
||||
OSSL_PKEY_PARAM_EC_ORDER, order))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
|
||||
OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
|
||||
&& TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
|
||||
cofactor));
|
||||
}
|
||||
|
||||
static int create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD *bld)
|
||||
{
|
||||
static const unsigned char gen[] = {
|
||||
0x04,
|
||||
0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2,
|
||||
0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C,
|
||||
0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
|
||||
0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A,
|
||||
0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0,
|
||||
0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3
|
||||
};
|
||||
return do_create_ec_explicit_trinomial_params(bld, gen, sizeof(gen));
|
||||
}
|
||||
|
||||
static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld)
|
||||
{
|
||||
static const unsigned char gen2[] = {
|
||||
0x04,
|
||||
0x00, 0xd7, 0xba, 0xd0, 0x26, 0x6c, 0x31, 0x6a, 0x78, 0x76, 0x01, 0xd1,
|
||||
0x32, 0x4b, 0x8f, 0x30, 0x29, 0x2d, 0x78, 0x30, 0xca, 0x43, 0xaa, 0xf0,
|
||||
0xa2, 0x5a, 0xd4, 0x0f, 0xb3, 0xf4,
|
||||
0x00, 0x85, 0x4b, 0x1b, 0x8d, 0x50, 0x10, 0xa5, 0x1c, 0x80, 0xf7, 0x86,
|
||||
0x40, 0x62, 0x4c, 0x87, 0xd1, 0x26, 0x7a, 0x9c, 0x5c, 0xe9, 0x82, 0x29,
|
||||
0xd1, 0x67, 0x70, 0x41, 0xea, 0xcb
|
||||
};
|
||||
return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2));
|
||||
}
|
||||
# endif /* OPENSSL_NO_EC2M */
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
int ok = 1;
|
||||
@ -803,7 +1012,28 @@ int setup_tests(void)
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
if (!TEST_ptr(bnctx = BN_CTX_new_ex(NULL))
|
||||
|| !TEST_ptr(bld_prime_nc = OSSL_PARAM_BLD_new())
|
||||
|| !TEST_ptr(bld_prime = OSSL_PARAM_BLD_new())
|
||||
|| !create_ec_explicit_prime_params_namedcurve(bld_prime_nc)
|
||||
|| !create_ec_explicit_prime_params(bld_prime)
|
||||
|| !TEST_ptr(ec_explicit_prime_params_nc = OSSL_PARAM_BLD_to_param(bld_prime_nc))
|
||||
|| !TEST_ptr(ec_explicit_prime_params_explicit = OSSL_PARAM_BLD_to_param(bld_prime))
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
|| !TEST_ptr(bld_tri_nc = OSSL_PARAM_BLD_new())
|
||||
|| !TEST_ptr(bld_tri = OSSL_PARAM_BLD_new())
|
||||
|| !create_ec_explicit_trinomial_params_namedcurve(bld_tri_nc)
|
||||
|| !create_ec_explicit_trinomial_params(bld_tri)
|
||||
|| !TEST_ptr(ec_explicit_tri_params_nc = OSSL_PARAM_BLD_to_param(bld_tri_nc))
|
||||
|| !TEST_ptr(ec_explicit_tri_params_explicit = OSSL_PARAM_BLD_to_param(bld_tri))
|
||||
# endif
|
||||
)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
TEST_info("Generating keys...");
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
MAKE_DOMAIN_KEYS(DH, "DH", NULL);
|
||||
MAKE_DOMAIN_KEYS(DHX, "X9.42 DH", NULL);
|
||||
@ -813,6 +1043,12 @@ int setup_tests(void)
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
|
||||
MAKE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve, "EC", ec_explicit_prime_params_nc);
|
||||
MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit);
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
MAKE_DOMAIN_KEYS(ECExplicitTriNamedCurve, "EC", ec_explicit_tri_params_nc);
|
||||
MAKE_DOMAIN_KEYS(ECExplicitTri2G, "EC", ec_explicit_tri_params_explicit);
|
||||
# endif
|
||||
MAKE_KEYS(ED25519, "ED25519", NULL);
|
||||
MAKE_KEYS(ED448, "ED448", NULL);
|
||||
MAKE_KEYS(X25519, "X25519", NULL);
|
||||
@ -836,6 +1072,12 @@ int setup_tests(void)
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
ADD_TEST_SUITE(EC);
|
||||
ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
|
||||
ADD_TEST_SUITE(ECExplicitPrime2G);
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
ADD_TEST_SUITE(ECExplicitTriNamedCurve);
|
||||
ADD_TEST_SUITE(ECExplicitTri2G);
|
||||
# endif
|
||||
ADD_TEST_SUITE(ED25519);
|
||||
ADD_TEST_SUITE(ED448);
|
||||
ADD_TEST_SUITE(X25519);
|
||||
@ -856,6 +1098,20 @@ int setup_tests(void)
|
||||
|
||||
void cleanup_tests(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_EC
|
||||
OSSL_PARAM_BLD_free_params(ec_explicit_prime_params_nc);
|
||||
OSSL_PARAM_BLD_free_params(ec_explicit_prime_params_explicit);
|
||||
OSSL_PARAM_BLD_free(bld_prime_nc);
|
||||
OSSL_PARAM_BLD_free(bld_prime);
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
OSSL_PARAM_BLD_free_params(ec_explicit_tri_params_nc);
|
||||
OSSL_PARAM_BLD_free_params(ec_explicit_tri_params_explicit);
|
||||
OSSL_PARAM_BLD_free(bld_tri_nc);
|
||||
OSSL_PARAM_BLD_free(bld_tri);
|
||||
# endif
|
||||
BN_CTX_free(bnctx);
|
||||
#endif /* OPENSSL_NO_EC */
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
FREE_DOMAIN_KEYS(DH);
|
||||
FREE_DOMAIN_KEYS(DHX);
|
||||
@ -865,6 +1121,12 @@ void cleanup_tests(void)
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
FREE_DOMAIN_KEYS(EC);
|
||||
FREE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
|
||||
FREE_DOMAIN_KEYS(ECExplicitPrime2G);
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
FREE_DOMAIN_KEYS(ECExplicitTriNamedCurve);
|
||||
FREE_DOMAIN_KEYS(ECExplicitTri2G);
|
||||
# endif
|
||||
FREE_KEYS(ED25519);
|
||||
FREE_KEYS(ED448);
|
||||
FREE_KEYS(X25519);
|
||||
|
@ -29,30 +29,12 @@ sub supported_pass {
|
||||
ok(run(@_), $str);
|
||||
}
|
||||
|
||||
sub unsupported_pass {
|
||||
my $str = shift;
|
||||
TODO: {
|
||||
local $TODO = "Currently not supported";
|
||||
|
||||
ok(run(@_), $str);
|
||||
}
|
||||
}
|
||||
|
||||
sub supported_fail {
|
||||
my $str = shift;
|
||||
|
||||
ok(!run(@_), $str);
|
||||
}
|
||||
|
||||
sub unsupported_fail {
|
||||
my $str = shift;
|
||||
TODO: {
|
||||
local $TODO = "Currently not supported";
|
||||
|
||||
ok(!run(@_), $str);
|
||||
}
|
||||
}
|
||||
|
||||
setup("test_genec");
|
||||
|
||||
plan skip_all => "This test is unsupported in a no-ec build"
|
||||
@ -183,7 +165,7 @@ push(@curve_list, @curve_aliases);
|
||||
my %params_encodings =
|
||||
(
|
||||
'named_curve' => \&supported_pass,
|
||||
'explicit' => \&unsupported_pass
|
||||
'explicit' => \&supported_pass
|
||||
);
|
||||
|
||||
my @output_formats = ('PEM', 'DER');
|
||||
@ -273,7 +255,7 @@ subtest "test curves that only support explicit parameters encoding" => sub {
|
||||
my %params_encodings =
|
||||
(
|
||||
'named_curve' => \&supported_fail,
|
||||
'explicit' => \&unsupported_pass
|
||||
'explicit' => \&supported_pass
|
||||
);
|
||||
|
||||
foreach my $curvename (@explicit_only_curves) {
|
||||
|
@ -5271,3 +5271,4 @@ OSSL_STORE_INFO_get1_PUBKEY ? 3_0_0 EXIST::FUNCTION:
|
||||
PEM_read_bio_PUBKEY_ex ? 3_0_0 EXIST::FUNCTION:
|
||||
PEM_read_PUBKEY_ex ? 3_0_0 EXIST::FUNCTION:STDIO
|
||||
PEM_read_bio_Parameters_ex ? 3_0_0 EXIST::FUNCTION:
|
||||
EC_GROUP_new_from_params ? 3_0_0 EXIST::FUNCTION:EC
|
||||
|
Loading…
Reference in New Issue
Block a user