Latest update.
This commit is contained in:
@@ -51,9 +51,9 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
|
||||
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c \
|
||||
curve448/arch_32/f_impl.c curve448/f_generic.c curve448/scalar.c \
|
||||
curve448/curve448_tables.c curve448/eddsa.c curve448/curve448.c \
|
||||
$ECASM
|
||||
$ECASM ec_backend.c ecx_backend.c
|
||||
SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ecx_key.c \
|
||||
ec_err.c ecdh_kdf.c eck_prn.c ec_evp_lib.c
|
||||
ec_err.c ecdh_kdf.c eck_prn.c ec_ctrl.c
|
||||
SOURCE[../../providers/libfips.a]=$COMMON
|
||||
|
||||
# Implementations are now spread across several libraries, so the defines
|
||||
|
||||
@@ -5438,13 +5438,14 @@ static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b,
|
||||
}
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[32], const uint8_t private_key[32])
|
||||
const uint8_t public_key[32], const uint8_t private_key[32],
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
uint8_t az[SHA512_DIGEST_LENGTH];
|
||||
uint8_t nonce[SHA512_DIGEST_LENGTH];
|
||||
ge_p3 R;
|
||||
uint8_t hram[SHA512_DIGEST_LENGTH];
|
||||
EVP_MD *sha512 = EVP_MD_fetch(NULL, SN_sha512, NULL);
|
||||
EVP_MD *sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
|
||||
EVP_MD_CTX *hash_ctx = EVP_MD_CTX_new();
|
||||
unsigned int sz;
|
||||
int res = 0;
|
||||
@@ -5493,7 +5494,8 @@ err:
|
||||
static const char allzeroes[15];
|
||||
|
||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[64], const uint8_t public_key[32])
|
||||
const uint8_t signature[64], const uint8_t public_key[32],
|
||||
OPENSSL_CTX *libctx, const char *propq)
|
||||
{
|
||||
int i;
|
||||
ge_p3 A;
|
||||
@@ -5548,7 +5550,7 @@ int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
fe_neg(A.X, A.X);
|
||||
fe_neg(A.T, A.T);
|
||||
|
||||
sha512 = EVP_MD_fetch(NULL, SN_sha512, NULL);
|
||||
sha512 = EVP_MD_fetch(libctx, SN_sha512, propq);
|
||||
if (sha512 == NULL)
|
||||
return 0;
|
||||
hash_ctx = EVP_MD_CTX_new();
|
||||
|
||||
@@ -10,15 +10,6 @@
|
||||
# define OSSL_CRYPTO_EC_CURVE448_LOCAL_H
|
||||
# include "curve448utils.h"
|
||||
|
||||
int ED448_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t *message,
|
||||
size_t message_len, const uint8_t public_key[57],
|
||||
const uint8_t private_key[57], const uint8_t *context,
|
||||
size_t context_len);
|
||||
|
||||
int ED448_verify(OPENSSL_CTX *ctx, const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[114], const uint8_t public_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
int ED448ph_sign(OPENSSL_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64],
|
||||
const uint8_t public_key[57], const uint8_t private_key[57],
|
||||
const uint8_t *context, size_t context_len);
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "crypto/ecx.h"
|
||||
#include "curve448_local.h"
|
||||
#include "word.h"
|
||||
#include "ed448.h"
|
||||
|
||||
+70
-28
@@ -23,7 +23,7 @@
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "ec_local.h"
|
||||
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
@@ -611,7 +611,7 @@ int ecparams_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl)
|
||||
if ((curve_name = OBJ_nid2sn(curve_nid)) == NULL)
|
||||
return 0;
|
||||
|
||||
if (!ossl_param_bld_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME, curve_name, 0))
|
||||
if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME, curve_name, 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -620,47 +620,65 @@ int ecparams_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl)
|
||||
|
||||
static
|
||||
int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
const EC_KEY *eckey = NULL;
|
||||
const EC_GROUP *ecg = NULL;
|
||||
unsigned char *pub_key_buf = NULL;
|
||||
size_t pub_key_buflen;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl;
|
||||
OSSL_PARAM *params = NULL;
|
||||
const BIGNUM *priv_key = NULL;
|
||||
const EC_POINT *pub_point = NULL;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
BN_CTX *bnctx = NULL;
|
||||
|
||||
if (from == NULL
|
||||
|| (eckey = from->pkey.ec) == NULL
|
||||
|| (ecg = EC_KEY_get0_group(eckey)) == NULL)
|
||||
return 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
/*
|
||||
* If the EC_KEY method is foreign, then we can't be sure of anything,
|
||||
* and can therefore not export or pretend to export.
|
||||
*/
|
||||
if (EC_KEY_get_method(eckey) != EC_KEY_OpenSSL())
|
||||
return 0;
|
||||
|
||||
tmpl = OSSL_PARAM_BLD_new();
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
|
||||
/* export the domain parameters */
|
||||
if (!ecparams_to_params(eckey, &tmpl))
|
||||
return 0;
|
||||
if (!ecparams_to_params(eckey, tmpl))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
|
||||
|
||||
priv_key = EC_KEY_get0_private_key(eckey);
|
||||
pub_point = EC_KEY_get0_public_key(eckey);
|
||||
|
||||
/* public_key must be present, priv_key is optional */
|
||||
if (pub_point == NULL)
|
||||
return 0;
|
||||
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,
|
||||
&pub_key_buf, NULL)) == 0)
|
||||
return 0;
|
||||
|
||||
if (!ossl_param_bld_push_octet_string(&tmpl,
|
||||
OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key_buf,
|
||||
pub_key_buflen))
|
||||
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,
|
||||
&pub_key_buf, bnctx)) == 0
|
||||
|| !OSSL_PARAM_BLD_push_octet_string(tmpl,
|
||||
OSSL_PKEY_PARAM_PUB_KEY,
|
||||
pub_key_buf,
|
||||
pub_key_buflen))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
}
|
||||
|
||||
if (priv_key != NULL) {
|
||||
size_t sz;
|
||||
@@ -705,10 +723,11 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
goto err;
|
||||
|
||||
sz = (ecbits + 7 ) / 8;
|
||||
if (!ossl_param_bld_push_BN_pad(&tmpl,
|
||||
if (!OSSL_PARAM_BLD_push_BN_pad(tmpl,
|
||||
OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
priv_key, sz))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
|
||||
/*
|
||||
* The ECDH Cofactor Mode is defined only if the EC_KEY actually
|
||||
@@ -719,24 +738,46 @@ int ec_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
(EC_KEY_get_flags(eckey) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
|
||||
|
||||
/* Export the ECDH_COFACTOR_MODE parameter */
|
||||
if (!ossl_param_bld_push_int(&tmpl,
|
||||
if (!OSSL_PARAM_BLD_push_int(tmpl,
|
||||
OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
|
||||
ecdh_cofactor_mode))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
|
||||
}
|
||||
|
||||
params = ossl_param_bld_to_param(&tmpl);
|
||||
params = OSSL_PARAM_BLD_to_param(tmpl);
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
err:
|
||||
ossl_param_bld_free(params);
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
OPENSSL_free(pub_key_buf);
|
||||
BN_CTX_free(bnctx);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ec_pkey_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
EC_KEY *ec = EC_KEY_new();
|
||||
|
||||
if (ec == NULL) {
|
||||
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ec_key_domparams_fromdata(ec, params)
|
||||
|| !ec_key_otherparams_fromdata(ec, params)
|
||||
|| !ec_key_fromdata(ec, params, 1)
|
||||
|| !EVP_PKEY_assign_EC_KEY(pkey, ec)) {
|
||||
EC_KEY_free(ec);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
EVP_PKEY_EC,
|
||||
EVP_PKEY_EC,
|
||||
@@ -782,7 +823,8 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
|
||||
0, /* get_pub_key */
|
||||
|
||||
ec_pkey_dirty_cnt,
|
||||
ec_pkey_export_to
|
||||
ec_pkey_export_to,
|
||||
ec_pkey_import_from
|
||||
};
|
||||
|
||||
#if !defined(OPENSSL_NO_SM2)
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/params.h>
|
||||
#include "crypto/bn.h"
|
||||
#include "crypto/ec.h"
|
||||
|
||||
/*
|
||||
* 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_param_ecdh_cofactor_mode(EC_KEY *ec, const OSSL_PARAM *p)
|
||||
{
|
||||
const EC_GROUP *ecg = EC_KEY_get0_group(ec);
|
||||
const BIGNUM *cofactor;
|
||||
int mode;
|
||||
|
||||
if (!OSSL_PARAM_get_int(p, &mode))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* mode can be only 0 for disable, or 1 for enable here.
|
||||
*
|
||||
* This is in contrast with the same parameter on an ECDH EVP_PKEY_CTX that
|
||||
* also supports mode == -1 with the meaning of "reset to the default for
|
||||
* the associated key".
|
||||
*/
|
||||
if (mode < 0 || mode > 1)
|
||||
return 0;
|
||||
|
||||
if ((cofactor = EC_GROUP_get0_cofactor(ecg)) == NULL )
|
||||
return 0;
|
||||
|
||||
/* ECDH cofactor mode has no effect if cofactor is 1 */
|
||||
if (BN_is_one(cofactor))
|
||||
return 1;
|
||||
|
||||
if (mode == 1)
|
||||
EC_KEY_set_flags(ec, EC_FLAG_COFACTOR_ECDH);
|
||||
else if (mode == 0)
|
||||
EC_KEY_clear_flags(ec, EC_FLAG_COFACTOR_ECDH);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callers of ec_key_fromdata MUST make sure that ec_key_params_fromdata has
|
||||
* been called before!
|
||||
*
|
||||
* This function only gets the bare keypair, domain parameters and other
|
||||
* parameters are treated separately, and domain parameters are required to
|
||||
* define a keypair.
|
||||
*/
|
||||
int ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_private)
|
||||
{
|
||||
const OSSL_PARAM *param_priv_key = NULL, *param_pub_key = NULL;
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *priv_key = NULL;
|
||||
unsigned char *pub_key = NULL;
|
||||
size_t pub_key_len;
|
||||
const EC_GROUP *ecg = NULL;
|
||||
EC_POINT *pub_point = NULL;
|
||||
int ok = 0;
|
||||
|
||||
ecg = EC_KEY_get0_group(ec);
|
||||
if (ecg == NULL)
|
||||
return 0;
|
||||
|
||||
param_pub_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
if (include_private)
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
|
||||
ctx = BN_CTX_new_ex(ec_key_get_libctx(ec));
|
||||
if (ctx == NULL)
|
||||
goto err;
|
||||
|
||||
/* OpenSSL decree: If there's a private key, there must be a public key */
|
||||
if (param_priv_key != NULL && param_pub_key == NULL)
|
||||
goto err;
|
||||
|
||||
if (param_pub_key != NULL)
|
||||
if (!OSSL_PARAM_get_octet_string(param_pub_key,
|
||||
(void **)&pub_key, 0, &pub_key_len)
|
||||
|| (pub_point = EC_POINT_new(ecg)) == NULL
|
||||
|| !EC_POINT_oct2point(ecg, pub_point, pub_key, pub_key_len, ctx))
|
||||
goto err;
|
||||
|
||||
if (param_priv_key != NULL && include_private) {
|
||||
int fixed_words;
|
||||
const BIGNUM *order;
|
||||
|
||||
/*
|
||||
* Key import/export should never leak the bit length of the secret
|
||||
* scalar in the key.
|
||||
*
|
||||
* For this reason, on export we use padded BIGNUMs with fixed length.
|
||||
*
|
||||
* When importing we also should make sure that, even if short lived,
|
||||
* the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
|
||||
* soon as possible, so that any processing of this BIGNUM might opt for
|
||||
* constant time implementations in the backend.
|
||||
*
|
||||
* Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
|
||||
* to preallocate the BIGNUM internal buffer to a fixed public size big
|
||||
* enough that operations performed during the processing never trigger
|
||||
* a realloc which would leak the size of the scalar through memory
|
||||
* accesses.
|
||||
*
|
||||
* Fixed Length
|
||||
* ------------
|
||||
*
|
||||
* The order of the large prime subgroup of the curve is our choice for
|
||||
* a fixed public size, as that is generally the upper bound for
|
||||
* generating a private key in EC cryptosystems and should fit all valid
|
||||
* secret scalars.
|
||||
*
|
||||
* For padding on export we just use the bit length of the order
|
||||
* converted to bytes (rounding up).
|
||||
*
|
||||
* For preallocating the BIGNUM storage we look at the number of "words"
|
||||
* required for the internal representation of the order, and we
|
||||
* preallocate 2 extra "words" in case any of the subsequent processing
|
||||
* might temporarily overflow the order length.
|
||||
*/
|
||||
order = EC_GROUP_get0_order(ecg);
|
||||
if (order == NULL || BN_is_zero(order))
|
||||
goto err;
|
||||
|
||||
fixed_words = bn_get_top(order) + 2;
|
||||
|
||||
if ((priv_key = BN_secure_new()) == NULL)
|
||||
goto err;
|
||||
if (bn_wexpand(priv_key, fixed_words) == NULL)
|
||||
goto err;
|
||||
BN_set_flags(priv_key, BN_FLG_CONSTTIME);
|
||||
|
||||
if (!OSSL_PARAM_get_BN(param_priv_key, &priv_key))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (priv_key != NULL
|
||||
&& !EC_KEY_set_private_key(ec, priv_key))
|
||||
goto err;
|
||||
|
||||
if (pub_point != NULL
|
||||
&& !EC_KEY_set_public_key(ec, pub_point))
|
||||
goto err;
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
BN_clear_free(priv_key);
|
||||
OPENSSL_free(pub_key);
|
||||
EC_POINT_free(pub_point);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_domparams_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;
|
||||
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
|
||||
param_ec_name = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME);
|
||||
if (param_ec_name == NULL) {
|
||||
/* explicit parameters */
|
||||
|
||||
/*
|
||||
* 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_ex(ec_key_get_libctx(ec),
|
||||
curve_nid)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EC_KEY_set_group(ec, ecg))
|
||||
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);
|
||||
return ok;
|
||||
}
|
||||
|
||||
int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[])
|
||||
{
|
||||
const OSSL_PARAM *p;
|
||||
|
||||
if (ec == NULL)
|
||||
return 0;
|
||||
|
||||
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
|
||||
if (p != NULL && !ec_set_param_ecdh_cofactor_mode(ec, p))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
+10
-10
@@ -19,27 +19,27 @@
|
||||
int EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only,
|
||||
BN_CTX *ctx)
|
||||
{
|
||||
int nid = NID_undef;
|
||||
#ifndef FIPS_MODE
|
||||
int nid;
|
||||
BN_CTX *new_ctx = NULL;
|
||||
|
||||
if (group == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
ctx = new_ctx = BN_CTX_new();
|
||||
ctx = new_ctx = BN_CTX_new_ex(NULL);
|
||||
if (ctx == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_CHECK_NAMED_CURVE, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
ECerr(0, ERR_R_MALLOC_FAILURE);
|
||||
return NID_undef;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nid = ec_curve_nid_from_params(group, ctx);
|
||||
if (nid > 0 && nist_only && EC_curve_nid2nist(nid) == NULL)
|
||||
nid = NID_undef;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
#endif
|
||||
BN_CTX_free(new_ctx);
|
||||
return nid;
|
||||
}
|
||||
|
||||
|
||||
@@ -420,3 +420,69 @@ int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pukm)
|
||||
|
||||
return (int)ukmlen;
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
|
||||
const char *name)
|
||||
{
|
||||
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
OSSL_PARAM *p = params;
|
||||
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
|
||||
(char *)name, 0);
|
||||
return EVP_PKEY_CTX_set_params(ctx, params);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ec_paramgen_curve_name(EVP_PKEY_CTX *ctx,
|
||||
char *name, size_t namelen)
|
||||
{
|
||||
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
|
||||
OSSL_PARAM *p = params;
|
||||
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
|
||||
*p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME,
|
||||
name, namelen);
|
||||
if (!EVP_PKEY_CTX_get_params(ctx, params))
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid)
|
||||
{
|
||||
if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
|
||||
/* Uses the same return values as EVP_PKEY_CTX_ctrl */
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Legacy: if key type not EC return error */
|
||||
if (ctx->pmeth != NULL
|
||||
&& EVP_PKEY_type(ctx->pmeth->pkey_id) != EVP_PKEY_EC)
|
||||
return -1;
|
||||
|
||||
if (ctx->op.keymgmt.genctx == NULL)
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
|
||||
EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID,
|
||||
nid, NULL);
|
||||
|
||||
return EVP_PKEY_CTX_set_ec_paramgen_curve_name(ctx, OBJ_nid2sn(nid));
|
||||
}
|
||||
#endif
|
||||
+169
-122
@@ -20,6 +20,7 @@
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
#include "internal/nelem.h"
|
||||
#include "e_os.h" /* strcasecmp required by windows */
|
||||
|
||||
typedef struct {
|
||||
int field_type, /* either NID_X9_62_prime_field or
|
||||
@@ -2816,6 +2817,7 @@ static const struct {
|
||||
#endif /* OPENSSL_NO_SM2 */
|
||||
|
||||
typedef struct _ec_list_element_st {
|
||||
const char *name;
|
||||
int nid;
|
||||
const EC_CURVE_DATA *data;
|
||||
const EC_METHOD *(*meth) (void);
|
||||
@@ -2826,15 +2828,15 @@ typedef struct _ec_list_element_st {
|
||||
static const ec_list_element curve_list[] = {
|
||||
/* prime field curves */
|
||||
/* secg curves */
|
||||
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
{"secp224r1", NID_secp224r1, &_EC_NIST_PRIME_224.h,
|
||||
# if !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
EC_GFp_nistp224_method,
|
||||
# else
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
0,
|
||||
# endif
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
|
||||
{NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
{"secp384r1", NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp384_method,
|
||||
# else
|
||||
@@ -2842,7 +2844,7 @@ static const ec_list_element curve_list[] = {
|
||||
# endif
|
||||
"NIST/SECG curve over a 384 bit prime field"},
|
||||
|
||||
{NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
{"secp521r1", NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp521_method,
|
||||
# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
@@ -2853,9 +2855,9 @@ static const ec_list_element curve_list[] = {
|
||||
"NIST/SECG curve over a 521 bit prime field"},
|
||||
|
||||
/* X9.62 curves */
|
||||
{NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
{"prime192v1", NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
"NIST/X9.62/SECG curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
{"prime256v1", NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
# if defined(ECP_NISTZ256_ASM)
|
||||
EC_GFp_nistz256_method,
|
||||
# elif defined(S390X_EC_ASM)
|
||||
@@ -2870,25 +2872,25 @@ static const ec_list_element curve_list[] = {
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
/* characteristic two field curves */
|
||||
/* NIST/SECG curves */
|
||||
{NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
{"sect163k1", NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 163 bit binary field"},
|
||||
{NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
{"sect163r2", NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
"NIST/SECG curve over a 163 bit binary field"},
|
||||
{NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
{"sect233k1", NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
{"sect233r1", NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
{"sect283k1", NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
{"sect283r1", NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
{"sect409k1", NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
{"sect409r1", NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
{"sect571k1", NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
{NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
{"sect571r1", NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
# endif
|
||||
};
|
||||
@@ -2898,43 +2900,43 @@ static const ec_list_element curve_list[] = {
|
||||
static const ec_list_element curve_list[] = {
|
||||
/* prime field curves */
|
||||
/* secg curves */
|
||||
{NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
{"secp112r1", NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
"SECG/WTLS curve over a 112 bit prime field"},
|
||||
{NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0,
|
||||
{"secp112r2", NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0,
|
||||
"SECG curve over a 112 bit prime field"},
|
||||
{NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0,
|
||||
{"secp128r1", NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0,
|
||||
"SECG curve over a 128 bit prime field"},
|
||||
{NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0,
|
||||
{"secp128r2", NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0,
|
||||
"SECG curve over a 128 bit prime field"},
|
||||
{NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0,
|
||||
{"secp160k1", NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0,
|
||||
"SECG curve over a 160 bit prime field"},
|
||||
{NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0,
|
||||
{"secp160r1", NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0,
|
||||
"SECG curve over a 160 bit prime field"},
|
||||
{NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
{"secp160r2", NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
"SECG/WTLS curve over a 160 bit prime field"},
|
||||
/* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */
|
||||
{NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0,
|
||||
{"secp192k1", NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0,
|
||||
"SECG curve over a 192 bit prime field"},
|
||||
{NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
|
||||
{"secp224k1", NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0,
|
||||
"SECG curve over a 224 bit prime field"},
|
||||
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
|
||||
{"secp224r1", NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
# else
|
||||
{NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
|
||||
{"secp224r1", NID_secp224r1, &_EC_NIST_PRIME_224.h, 0,
|
||||
"NIST/SECG curve over a 224 bit prime field"},
|
||||
# endif
|
||||
{NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
|
||||
{"secp256k1", NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0,
|
||||
"SECG curve over a 256 bit prime field"},
|
||||
/* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */
|
||||
{NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
{"secp384r1", NID_secp384r1, &_EC_NIST_PRIME_384.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp384_method,
|
||||
# else
|
||||
0,
|
||||
# endif
|
||||
"NIST/SECG curve over a 384 bit prime field"},
|
||||
{NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
{"secp521r1", NID_secp521r1, &_EC_NIST_PRIME_521.h,
|
||||
# if defined(S390X_EC_ASM)
|
||||
EC_GFp_s390x_nistp521_method,
|
||||
# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
@@ -2944,19 +2946,19 @@ static const ec_list_element curve_list[] = {
|
||||
# endif
|
||||
"NIST/SECG curve over a 521 bit prime field"},
|
||||
/* X9.62 curves */
|
||||
{NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
{"prime192v1", NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0,
|
||||
"NIST/X9.62/SECG curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0,
|
||||
{"prime192v2", NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0,
|
||||
"X9.62 curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0,
|
||||
{"prime192v3", NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0,
|
||||
"X9.62 curve over a 192 bit prime field"},
|
||||
{NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0,
|
||||
{"prime239v1", NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0,
|
||||
"X9.62 curve over a 239 bit prime field"},
|
||||
{NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0,
|
||||
{"prime239v2", NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0,
|
||||
"X9.62 curve over a 239 bit prime field"},
|
||||
{NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
|
||||
{"prime239v3", NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0,
|
||||
"X9.62 curve over a 239 bit prime field"},
|
||||
{NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
{"prime256v1", NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h,
|
||||
# if defined(ECP_NISTZ256_ASM)
|
||||
EC_GFp_nistz256_method,
|
||||
# elif defined(S390X_EC_ASM)
|
||||
@@ -2970,144 +2972,144 @@ static const ec_list_element curve_list[] = {
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
/* characteristic two field curves */
|
||||
/* NIST/SECG curves */
|
||||
{NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
{"sect113r1", NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
"SECG curve over a 113 bit binary field"},
|
||||
{NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0,
|
||||
{"sect113r2", NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0,
|
||||
"SECG curve over a 113 bit binary field"},
|
||||
{NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0,
|
||||
{ "sect131r1", NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0,
|
||||
"SECG/WTLS curve over a 131 bit binary field"},
|
||||
{NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0,
|
||||
{ "sect131r2", NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0,
|
||||
"SECG curve over a 131 bit binary field"},
|
||||
{NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
{"sect163k1", NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 163 bit binary field"},
|
||||
{NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0,
|
||||
{"sect163r1", NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0,
|
||||
"SECG curve over a 163 bit binary field"},
|
||||
{NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
{"sect163r2", NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0,
|
||||
"NIST/SECG curve over a 163 bit binary field"},
|
||||
{NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0,
|
||||
{"sect193r1", NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0,
|
||||
"SECG curve over a 193 bit binary field"},
|
||||
{NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0,
|
||||
{"sect193r2", NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0,
|
||||
"SECG curve over a 193 bit binary field"},
|
||||
{NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
{"sect233k1", NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
{"sect233r1", NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0,
|
||||
{"sect239k1", NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0,
|
||||
"SECG curve over a 239 bit binary field"},
|
||||
{NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
{"sect283k1", NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
{"sect283r1", NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0,
|
||||
"NIST/SECG curve over a 283 bit binary field"},
|
||||
{NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
{"sect409k1", NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
{"sect409r1", NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0,
|
||||
"NIST/SECG curve over a 409 bit binary field"},
|
||||
{NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
{"sect571k1", NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
{NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
{"sect571r1", NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0,
|
||||
"NIST/SECG curve over a 571 bit binary field"},
|
||||
/* X9.62 curves */
|
||||
{NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
{"c2pnb163v1", NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
{NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0,
|
||||
{"c2pnb163v2", NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
{NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0,
|
||||
{"c2pnb163v3", NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
{NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0,
|
||||
{"c2pnb176v1", NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0,
|
||||
"X9.62 curve over a 176 bit binary field"},
|
||||
{NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0,
|
||||
{"c2tnb191v1", NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0,
|
||||
"X9.62 curve over a 191 bit binary field"},
|
||||
{NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0,
|
||||
{"c2tnb191v2", NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0,
|
||||
"X9.62 curve over a 191 bit binary field"},
|
||||
{NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0,
|
||||
{"c2tnb191v3", NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0,
|
||||
"X9.62 curve over a 191 bit binary field"},
|
||||
{NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0,
|
||||
{"c2pnb208w1", NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0,
|
||||
"X9.62 curve over a 208 bit binary field"},
|
||||
{NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0,
|
||||
{"c2tnb239v1", NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0,
|
||||
"X9.62 curve over a 239 bit binary field"},
|
||||
{NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0,
|
||||
{"c2tnb239v2", NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0,
|
||||
"X9.62 curve over a 239 bit binary field"},
|
||||
{NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0,
|
||||
{"c2tnb239v3", NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0,
|
||||
"X9.62 curve over a 239 bit binary field"},
|
||||
{NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0,
|
||||
{"c2pnb272w1", NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0,
|
||||
"X9.62 curve over a 272 bit binary field"},
|
||||
{NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0,
|
||||
{"c2pnb304w1", NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0,
|
||||
"X9.62 curve over a 304 bit binary field"},
|
||||
{NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0,
|
||||
{"c2tnb359v1", NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0,
|
||||
"X9.62 curve over a 359 bit binary field"},
|
||||
{NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0,
|
||||
{"c2pnb368w1", NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0,
|
||||
"X9.62 curve over a 368 bit binary field"},
|
||||
{NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0,
|
||||
{"c2tnb431r1", NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0,
|
||||
"X9.62 curve over a 431 bit binary field"},
|
||||
/*
|
||||
* the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves
|
||||
* from X9.62]
|
||||
*/
|
||||
{NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls1", NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0,
|
||||
"WTLS curve over a 113 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls3", NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 163 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls4", NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0,
|
||||
"SECG curve over a 113 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls5", NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0,
|
||||
"X9.62 curve over a 163 bit binary field"},
|
||||
# endif
|
||||
{NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls6", NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0,
|
||||
"SECG/WTLS curve over a 112 bit prime field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls7", NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0,
|
||||
"SECG/WTLS curve over a 160 bit prime field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls8", NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0,
|
||||
"WTLS curve over a 112 bit prime field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls9", NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0,
|
||||
"WTLS curve over a 160 bit prime field"},
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
{NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls10", NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
{NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls11", NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0,
|
||||
"NIST/SECG/WTLS curve over a 233 bit binary field"},
|
||||
# endif
|
||||
{NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
|
||||
{"wap-wsg-idm-ecid-wtls12", NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0,
|
||||
"WTLS curve over a 224 bit prime field"},
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
/* IPSec curves */
|
||||
{NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
|
||||
{"Oakley-EC2N-3", NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0,
|
||||
"\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n"
|
||||
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
|
||||
{NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
|
||||
{"Oakley-EC2N-4", NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0,
|
||||
"\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n"
|
||||
"\tNot suitable for ECDSA.\n\tQuestionable extension field!"},
|
||||
# endif
|
||||
/* brainpool curves */
|
||||
{NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0,
|
||||
{"brainpoolP160r1", NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0,
|
||||
"RFC 5639 curve over a 160 bit prime field"},
|
||||
{NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0,
|
||||
{"brainpoolP160t1", NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0,
|
||||
"RFC 5639 curve over a 160 bit prime field"},
|
||||
{NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0,
|
||||
{"brainpoolP192r1", NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0,
|
||||
"RFC 5639 curve over a 192 bit prime field"},
|
||||
{NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0,
|
||||
{"brainpoolP192t1", NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0,
|
||||
"RFC 5639 curve over a 192 bit prime field"},
|
||||
{NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0,
|
||||
{"brainpoolP224r1", NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0,
|
||||
"RFC 5639 curve over a 224 bit prime field"},
|
||||
{NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0,
|
||||
{"brainpoolP224t1", NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0,
|
||||
"RFC 5639 curve over a 224 bit prime field"},
|
||||
{NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0,
|
||||
{"brainpoolP256r1", NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0,
|
||||
"RFC 5639 curve over a 256 bit prime field"},
|
||||
{NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0,
|
||||
{"brainpoolP256t1", NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0,
|
||||
"RFC 5639 curve over a 256 bit prime field"},
|
||||
{NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0,
|
||||
{"brainpoolP320r1", NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0,
|
||||
"RFC 5639 curve over a 320 bit prime field"},
|
||||
{NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0,
|
||||
{"brainpoolP320t1", NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0,
|
||||
"RFC 5639 curve over a 320 bit prime field"},
|
||||
{NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0,
|
||||
{"brainpoolP384r1", NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0,
|
||||
"RFC 5639 curve over a 384 bit prime field"},
|
||||
{NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0,
|
||||
{"brainpoolP384t1", NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0,
|
||||
"RFC 5639 curve over a 384 bit prime field"},
|
||||
{NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0,
|
||||
{"brainpoolP512r1", NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0,
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
{NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
|
||||
{"brainpoolP512t1", NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
# ifndef OPENSSL_NO_SM2
|
||||
{NID_sm2, &_EC_sm2p256v1.h, 0,
|
||||
{"SM2", NID_sm2, &_EC_sm2p256v1.h, 0,
|
||||
"SM2 curve over a 256 bit prime field"},
|
||||
# endif
|
||||
};
|
||||
@@ -3115,6 +3117,68 @@ static const ec_list_element curve_list[] = {
|
||||
|
||||
#define curve_list_length OSSL_NELEM(curve_list)
|
||||
|
||||
static const ec_list_element *ec_curve_nid2curve(int nid)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (nid <= 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < curve_list_length; i++) {
|
||||
if (curve_list[i].nid == nid)
|
||||
return &curve_list[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const ec_list_element *ec_curve_name2curve(const char *name)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < curve_list_length; i++) {
|
||||
if (strcasecmp(curve_list[i].name, name) == 0)
|
||||
return &curve_list[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *ec_curve_nid2name(int nid)
|
||||
{
|
||||
/*
|
||||
* TODO(3.0) Figure out if we should try to find the nid with
|
||||
* EC_curve_nid2nist() first, i.e. make it a priority to return
|
||||
* NIST names if there is one for the NID. This is related to
|
||||
* the TODO comment in ec_curve_name2nid().
|
||||
*/
|
||||
const ec_list_element *curve = ec_curve_nid2curve(nid);
|
||||
|
||||
if (curve != NULL)
|
||||
return curve->name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ec_curve_name2nid(const char *name)
|
||||
{
|
||||
const ec_list_element *curve = NULL;
|
||||
int nid;
|
||||
|
||||
if ((nid = EC_curve_nist2nid(name)) != NID_undef)
|
||||
return nid;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
/*
|
||||
* TODO(3.0) Figure out if we can use other names than the NIST names
|
||||
* ("B-163", "K-163" & "P-192") in the FIPS module, or if other names
|
||||
* are allowed as well as long as they lead to the same curve data.
|
||||
* If only the NIST names are allowed in the FIPS module, we should
|
||||
* move '#endif' to just before 'return NID_undef'.
|
||||
*/
|
||||
#endif
|
||||
if ((curve = ec_curve_name2curve(name)) != NULL)
|
||||
return curve->nid;
|
||||
return NID_undef;
|
||||
}
|
||||
|
||||
static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
const ec_list_element curve)
|
||||
{
|
||||
@@ -3226,28 +3290,11 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx,
|
||||
|
||||
EC_GROUP *EC_GROUP_new_by_curve_name_ex(OPENSSL_CTX *libctx, int nid)
|
||||
{
|
||||
size_t i;
|
||||
EC_GROUP *ret = NULL;
|
||||
const ec_list_element *curve;
|
||||
|
||||
if (nid <= 0)
|
||||
return NULL;
|
||||
|
||||
#ifdef FIPS_MODE
|
||||
/*
|
||||
* Only use approved NIST curves in FIPS.
|
||||
* NOTE: "B-163", "K-163" & "P-192" can only be used for legacy use
|
||||
* (i.e- ECDSA signature verification).
|
||||
*/
|
||||
if (EC_curve_nid2nist(nid) == NULL)
|
||||
return NULL;
|
||||
#endif /* FIPS_MODE */
|
||||
for (i = 0; i < curve_list_length; i++)
|
||||
if (curve_list[i].nid == nid) {
|
||||
ret = ec_group_new_from_data(libctx, curve_list[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == NULL) {
|
||||
if ((curve = ec_curve_nid2curve(nid)) == NULL
|
||||
|| (ret = ec_group_new_from_data(libctx, *curve)) == NULL) {
|
||||
ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME_EX, EC_R_UNKNOWN_GROUP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+126
-63
@@ -417,6 +417,120 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.3.3 ECC Full Public-Key Validation.
|
||||
*/
|
||||
int ec_key_public_check(const EC_KEY *eckey, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
EC_POINT *point = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 1): Q != infinity */
|
||||
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
|
||||
ECerr(0, EC_R_POINT_AT_INFINITY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
point = EC_POINT_new(eckey->group);
|
||||
if (point == NULL)
|
||||
return 0;
|
||||
|
||||
/* 5.6.2.3.3 (Step 2) Test if the public key is in range */
|
||||
if (!ec_key_public_range_check(ctx, eckey)) {
|
||||
ECerr(0, EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */
|
||||
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
|
||||
ECerr(0, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = eckey->group->order;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(0, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
/* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */
|
||||
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
|
||||
ECerr(0, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
|
||||
ECerr(0, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.1.2 Owner Assurance of Private-Key Validity
|
||||
* The private key is in the range [1, order-1]
|
||||
*/
|
||||
int ec_key_private_check(const EC_KEY *eckey)
|
||||
{
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->priv_key == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (BN_cmp(eckey->priv_key, BN_value_one()) < 0
|
||||
|| BN_cmp(eckey->priv_key, eckey->group->order) >= 0) {
|
||||
ECerr(0, EC_R_INVALID_PRIVATE_KEY);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b)
|
||||
* Check if generator * priv_key = pub_key
|
||||
*/
|
||||
int ec_key_pairwise_check(const EC_KEY *eckey, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
if (eckey == NULL
|
||||
|| eckey->group == NULL
|
||||
|| eckey->pub_key == NULL
|
||||
|| eckey->priv_key == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
point = EC_POINT_new(eckey->group);
|
||||
if (point == NULL)
|
||||
goto err;
|
||||
|
||||
|
||||
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
|
||||
ECerr(0, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
|
||||
ECerr(0, EC_R_INVALID_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
EC_POINT_free(point);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ECC Key validation as specified in SP800-56A R3.
|
||||
* Section 5.6.2.3.3 ECC Full Public-Key Validation
|
||||
@@ -431,81 +545,25 @@ int ec_key_simple_check_key(const EC_KEY *eckey)
|
||||
{
|
||||
int ok = 0;
|
||||
BN_CTX *ctx = NULL;
|
||||
const BIGNUM *order = NULL;
|
||||
EC_POINT *point = NULL;
|
||||
|
||||
if (eckey == NULL || eckey->group == NULL || eckey->pub_key == NULL) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
if (eckey == NULL) {
|
||||
ECerr(0, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 1): Q != infinity */
|
||||
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_AT_INFINITY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL)
|
||||
goto err;
|
||||
return 0;
|
||||
|
||||
if ((point = EC_POINT_new(eckey->group)) == NULL)
|
||||
if (!ec_key_public_check(eckey, ctx))
|
||||
goto err;
|
||||
|
||||
/* 5.6.2.3.3 (Step 2) Test if the public key is in range */
|
||||
if (!ec_key_public_range_check(ctx, eckey)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_COORDINATES_OUT_OF_RANGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 5.6.2.3.3 (Step 3) is the pub_key on the elliptic curve */
|
||||
if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
order = eckey->group->order;
|
||||
if (BN_is_zero(order)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_GROUP_ORDER);
|
||||
goto err;
|
||||
}
|
||||
/* 5.6.2.3.3 (Step 4) : pub_key * order is the point at infinity. */
|
||||
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (eckey->priv_key != NULL) {
|
||||
/*
|
||||
* 5.6.2.1.2 Owner Assurance of Private-Key Validity
|
||||
* The private key is in the range [1, order-1]
|
||||
*/
|
||||
if (BN_cmp(eckey->priv_key, BN_value_one()) < 0
|
||||
|| BN_cmp(eckey->priv_key, order) >= 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_WRONG_ORDER);
|
||||
if (!ec_key_private_check(eckey)
|
||||
|| !ec_key_pairwise_check(eckey, ctx))
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* Section 5.6.2.1.4 Owner Assurance of Pair-wise Consistency (b)
|
||||
* Check if generator * priv_key = pub_key
|
||||
*/
|
||||
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key,
|
||||
NULL, NULL, ctx)) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
|
||||
ECerr(EC_F_EC_KEY_SIMPLE_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
ok = 1;
|
||||
err:
|
||||
err:
|
||||
BN_CTX_free(ctx);
|
||||
EC_POINT_free(point);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -569,6 +627,11 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
|
||||
|
||||
}
|
||||
|
||||
OPENSSL_CTX *ec_key_get_libctx(const EC_KEY *key)
|
||||
{
|
||||
return key->libctx;
|
||||
}
|
||||
|
||||
const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
|
||||
{
|
||||
return key->group;
|
||||
|
||||
+29
-23
@@ -599,12 +599,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
BIGNUM *a1, *a2, *a3, *b1, *b2, *b3;
|
||||
#ifndef FIPS_MODE
|
||||
BN_CTX *ctx_new = NULL;
|
||||
|
||||
if (ctx == NULL)
|
||||
ctx_new = ctx = BN_CTX_new();
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
/* compare the field types */
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
|
||||
@@ -617,6 +612,13 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
|
||||
if (a->meth->flags & EC_FLAGS_CUSTOM_CURVE)
|
||||
return 0;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL)
|
||||
ctx_new = ctx = BN_CTX_new();
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return -1;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
a1 = BN_CTX_get(ctx);
|
||||
a2 = BN_CTX_get(ctx);
|
||||
@@ -1047,7 +1049,24 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
size_t i = 0;
|
||||
#ifndef FIPS_MODE
|
||||
BN_CTX *new_ctx = NULL;
|
||||
#endif
|
||||
|
||||
if (!ec_point_is_compat(r, group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (scalar == NULL && num == 0)
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!ec_point_is_compat(points[i], group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL)
|
||||
ctx = new_ctx = BN_CTX_secure_new();
|
||||
#endif
|
||||
@@ -1056,21 +1075,6 @@ int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((scalar == NULL) && (num == 0)) {
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
}
|
||||
|
||||
if (!ec_point_is_compat(r, group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!ec_point_is_compat(points[i], group)) {
|
||||
ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (group->meth->mul != NULL)
|
||||
ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx);
|
||||
else
|
||||
@@ -1183,16 +1187,18 @@ static int ec_field_inverse_mod_ord(const EC_GROUP *group, BIGNUM *r,
|
||||
int ret = 0;
|
||||
#ifndef FIPS_MODE
|
||||
BN_CTX *new_ctx = NULL;
|
||||
#endif
|
||||
|
||||
if (group->mont_data == NULL)
|
||||
return 0;
|
||||
|
||||
#ifndef FIPS_MODE
|
||||
if (ctx == NULL)
|
||||
ctx = new_ctx = BN_CTX_secure_new();
|
||||
#endif
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if (group->mont_data == NULL)
|
||||
goto err;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
if ((e = BN_CTX_get(ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
@@ -679,10 +679,6 @@ ECDSA_SIG *ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len,
|
||||
int ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len,
|
||||
const ECDSA_SIG *sig, EC_KEY *eckey);
|
||||
|
||||
int ED25519_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
|
||||
const uint8_t public_key[32], const uint8_t private_key[32]);
|
||||
int ED25519_verify(const uint8_t *message, size_t message_len,
|
||||
const uint8_t signature[64], const uint8_t public_key[32]);
|
||||
void ED25519_public_from_private(uint8_t out_public_key[32],
|
||||
const uint8_t private_key[32]);
|
||||
|
||||
|
||||
+18
-11
@@ -266,17 +266,10 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Apply coordinate blinding for EC_POINT.
|
||||
*
|
||||
* The underlying EC_METHOD can optionally implement this function:
|
||||
* ec_point_blind_coordinates() returns 0 in case of errors or 1 on
|
||||
* success or if coordinate blinding is not implemented for this
|
||||
* group.
|
||||
*/
|
||||
if (!ec_point_blind_coordinates(group, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);
|
||||
goto err;
|
||||
/* ensure input point is in affine coords for ladder step efficiency */
|
||||
if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) {
|
||||
ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Initialize the Montgomery ladder */
|
||||
@@ -753,6 +746,20 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
|
||||
if (r_is_at_infinity) {
|
||||
if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))
|
||||
goto err;
|
||||
|
||||
/*-
|
||||
* Apply coordinate blinding for EC_POINT.
|
||||
*
|
||||
* The underlying EC_METHOD can optionally implement this function:
|
||||
* ec_point_blind_coordinates() returns 0 in case of errors or 1 on
|
||||
* success or if coordinate blinding is not implemented for this
|
||||
* group.
|
||||
*/
|
||||
if (!ec_point_blind_coordinates(group, r, ctx)) {
|
||||
ECerr(EC_F_EC_WNAF_MUL, EC_R_POINT_COORDINATES_BLIND_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
r_is_at_infinity = 0;
|
||||
} else {
|
||||
if (!EC_POINT_add
|
||||
|
||||
+168
-139
@@ -1381,6 +1381,7 @@ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
* Computes the multiplicative inverse of a in GF(p), storing the result in r.
|
||||
* If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
|
||||
* Since we don't have a Mont structure here, SCA hardening is with blinding.
|
||||
* NB: "a" must be in _decoded_ form. (i.e. field_decode must precede.)
|
||||
*/
|
||||
int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
|
||||
BN_CTX *ctx)
|
||||
@@ -1441,112 +1442,133 @@ int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
|
||||
temp = BN_CTX_get(ctx);
|
||||
if (temp == NULL) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* make sure lambda is not zero */
|
||||
/*-
|
||||
* Make sure lambda is not zero.
|
||||
* If the RNG fails, we cannot blind but nevertheless want
|
||||
* code to continue smoothly and not clobber the error stack.
|
||||
*/
|
||||
do {
|
||||
if (!BN_priv_rand_range_ex(lambda, group->field, ctx)) {
|
||||
ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_BN_LIB);
|
||||
goto err;
|
||||
ERR_set_mark();
|
||||
ret = BN_priv_rand_range_ex(lambda, group->field, ctx);
|
||||
ERR_pop_to_mark();
|
||||
if (ret == 0) {
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
} while (BN_is_zero(lambda));
|
||||
|
||||
/* if field_encode defined convert between representations */
|
||||
if (group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, lambda, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->Z, p->Z, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_sqr(group, temp, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->X, p->X, temp, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, temp, temp, lambda, ctx))
|
||||
goto err;
|
||||
if (!group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
|
||||
goto err;
|
||||
p->Z_is_one = 0;
|
||||
if ((group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, lambda, lambda, ctx))
|
||||
|| !group->meth->field_mul(group, p->Z, p->Z, lambda, ctx)
|
||||
|| !group->meth->field_sqr(group, temp, lambda, ctx)
|
||||
|| !group->meth->field_mul(group, p->X, p->X, temp, ctx)
|
||||
|| !group->meth->field_mul(group, temp, temp, lambda, ctx)
|
||||
|| !group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
|
||||
goto end;
|
||||
|
||||
p->Z_is_one = 0;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
end:
|
||||
BN_CTX_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Set s := p, r := 2p.
|
||||
* Input:
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* Output:
|
||||
* - s := p, r := 2p: blinded projective (homogeneous) coordinates
|
||||
*
|
||||
* For doubling we use Formula 3 from Izu-Takagi "A fast parallel elliptic curve
|
||||
* multiplication resistant against side channel attacks" appendix, as described
|
||||
* at
|
||||
* multiplication resistant against side channel attacks" appendix, described at
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2
|
||||
* simplified for Z1=1.
|
||||
*
|
||||
* The input point p will be in randomized Jacobian projective coords:
|
||||
* x = X/Z**2, y=Y/Z**3
|
||||
*
|
||||
* The output points p, s, and r are converted to standard (homogeneous)
|
||||
* projective coords:
|
||||
* x = X/Z, y=Y/Z
|
||||
* Blinding uses the equivalence relation (\lambda X, \lambda Y, \lambda Z)
|
||||
* for any non-zero \lambda that holds for projective (homogeneous) coords.
|
||||
*/
|
||||
int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
BIGNUM *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
|
||||
BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL;
|
||||
|
||||
t1 = r->Z;
|
||||
t2 = r->Y;
|
||||
t1 = s->Z;
|
||||
t2 = r->Z;
|
||||
t3 = s->X;
|
||||
t4 = r->X;
|
||||
t5 = s->Y;
|
||||
t6 = s->Z;
|
||||
|
||||
/* convert p: (X,Y,Z) -> (XZ,Y,Z**3) */
|
||||
if (!group->meth->field_mul(group, p->X, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, t1, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, p->Z, p->Z, t1, ctx)
|
||||
/* r := 2p */
|
||||
|| !group->meth->field_sqr(group, t2, p->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t3, group->a, ctx)
|
||||
|| !BN_mod_sub_quick(t5, t2, t4, group->field)
|
||||
|| !BN_mod_add_quick(t2, t2, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t3, group->b, ctx)
|
||||
|| !group->meth->field_mul(group, t1, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t1, t6, ctx)
|
||||
|| !BN_mod_lshift_quick(t4, t4, 3, group->field)
|
||||
if (!p->Z_is_one /* r := 2p */
|
||||
|| !group->meth->field_sqr(group, t3, p->X, ctx)
|
||||
|| !BN_mod_sub_quick(t4, t3, group->a, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t5, p->X, group->b, ctx)
|
||||
|| !BN_mod_lshift_quick(t5, t5, 3, group->field)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t5, t4, group->field)
|
||||
|| !group->meth->field_mul(group, t1, t1, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t2, t3, t6, ctx)
|
||||
|| !BN_mod_add_quick(t1, t1, t2, group->field)
|
||||
|| !BN_mod_sub_quick(r->X, t4, t5, group->field)
|
||||
|| !BN_mod_add_quick(t1, t3, group->a, group->field)
|
||||
|| !group->meth->field_mul(group, t2, p->X, t1, ctx)
|
||||
|| !BN_mod_add_quick(t2, group->b, t2, group->field)
|
||||
/* r->Z coord output */
|
||||
|| !BN_mod_lshift_quick(r->Z, t1, 2, group->field)
|
||||
|| !EC_POINT_copy(s, p))
|
||||
|| !BN_mod_lshift_quick(r->Z, t2, 2, group->field))
|
||||
return 0;
|
||||
|
||||
/* make sure lambda (r->Y here for storage) is not zero */
|
||||
do {
|
||||
if (!BN_priv_rand_range_ex(r->Y, group->field, ctx))
|
||||
return 0;
|
||||
} while (BN_is_zero(r->Y));
|
||||
|
||||
/* make sure lambda (s->Z here for storage) is not zero */
|
||||
do {
|
||||
if (!BN_priv_rand_range_ex(s->Z, group->field, ctx))
|
||||
return 0;
|
||||
} while (BN_is_zero(s->Z));
|
||||
|
||||
/* if field_encode defined convert between representations */
|
||||
if (group->meth->field_encode != NULL
|
||||
&& (!group->meth->field_encode(group, r->Y, r->Y, ctx)
|
||||
|| !group->meth->field_encode(group, s->Z, s->Z, ctx)))
|
||||
return 0;
|
||||
|
||||
/* blind r and s independently */
|
||||
if (!group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
|
||||
|| !group->meth->field_mul(group, r->X, r->X, r->Y, ctx)
|
||||
|| !group->meth->field_mul(group, s->X, p->X, s->Z, ctx)) /* s := p */
|
||||
return 0;
|
||||
|
||||
r->Z_is_one = 0;
|
||||
s->Z_is_one = 0;
|
||||
p->Z_is_one = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
|
||||
* Input:
|
||||
* - s, r: projective (homogeneous) coordinates
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* Output:
|
||||
* - s := r + s, r := 2r: projective (homogeneous) coordinates
|
||||
*
|
||||
* Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
|
||||
* "A fast parallel elliptic curve multiplication resistant against side channel
|
||||
* attacks", as described at
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-ladd-2002-it-4
|
||||
* https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-mladd-2002-it-4
|
||||
*/
|
||||
int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
||||
EC_POINT *r, EC_POINT *s,
|
||||
EC_POINT *p, BN_CTX *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6, *t7 = NULL;
|
||||
BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
|
||||
|
||||
BN_CTX_start(ctx);
|
||||
t0 = BN_CTX_get(ctx);
|
||||
@@ -1556,50 +1578,47 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
||||
t4 = BN_CTX_get(ctx);
|
||||
t5 = BN_CTX_get(ctx);
|
||||
t6 = BN_CTX_get(ctx);
|
||||
t7 = BN_CTX_get(ctx);
|
||||
|
||||
if (t7 == NULL
|
||||
|| !group->meth->field_mul(group, t0, r->X, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t1, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->X, s->Z, ctx)
|
||||
if (t6 == NULL
|
||||
|| !group->meth->field_mul(group, t6, r->X, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, r->X, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t3, r->Z, s->X, ctx)
|
||||
|| !group->meth->field_mul(group, t4, group->a, t1, ctx)
|
||||
|| !BN_mod_add_quick(t0, t0, t4, group->field)
|
||||
|| !BN_mod_add_quick(t4, t3, t2, group->field)
|
||||
|| !group->meth->field_mul(group, t0, t4, t0, ctx)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !BN_mod_lshift_quick(t7, group->b, 2, group->field)
|
||||
|| !group->meth->field_mul(group, t1, t7, t1, ctx)
|
||||
|| !BN_mod_lshift1_quick(t0, t0, group->field)
|
||||
|| !BN_mod_add_quick(t0, t1, t0, group->field)
|
||||
|| !BN_mod_sub_quick(t1, t2, t3, group->field)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t3, t1, p->X, ctx)
|
||||
|| !group->meth->field_mul(group, t0, p->Z, t0, ctx)
|
||||
/* s->X coord output */
|
||||
|| !BN_mod_sub_quick(s->X, t0, t3, group->field)
|
||||
/* s->Z coord output */
|
||||
|| !group->meth->field_mul(group, s->Z, p->Z, t1, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, r->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t2, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t2, group->a, ctx)
|
||||
|| !BN_mod_add_quick(t5, r->X, r->Z, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, t5, ctx)
|
||||
|| !BN_mod_sub_quick(t5, t5, t3, group->field)
|
||||
|| !BN_mod_sub_quick(t5, t5, t2, group->field)
|
||||
|| !BN_mod_sub_quick(t6, t3, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t6, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t2, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t7, t0, ctx)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t6, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t5, group->a, t0, ctx)
|
||||
|| !BN_mod_add_quick(t5, t6, t5, group->field)
|
||||
|| !BN_mod_add_quick(t6, t3, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t3, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t7, t3, t7, ctx)
|
||||
|| !group->meth->field_mul(group, t5, t5, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t5, t6, t5, ctx)
|
||||
|| !group->meth->field_sqr(group, t0, t0, ctx)
|
||||
|| !BN_mod_lshift_quick(t2, group->b, 2, group->field)
|
||||
|| !group->meth->field_mul(group, t0, t2, t0, ctx)
|
||||
|| !BN_mod_lshift1_quick(t5, t5, group->field)
|
||||
|| !BN_mod_sub_quick(t3, t4, t3, group->field)
|
||||
/* s->Z coord output */
|
||||
|| !group->meth->field_sqr(group, s->Z, t3, ctx)
|
||||
|| !group->meth->field_mul(group, t4, s->Z, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t0, t0, t5, group->field)
|
||||
/* s->X coord output */
|
||||
|| !BN_mod_sub_quick(s->X, t0, t4, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, r->X, ctx)
|
||||
|| !group->meth->field_sqr(group, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t5, group->a, ctx)
|
||||
|| !BN_mod_add_quick(t1, r->X, r->Z, group->field)
|
||||
|| !group->meth->field_sqr(group, t1, t1, ctx)
|
||||
|| !BN_mod_sub_quick(t1, t1, t4, group->field)
|
||||
|| !BN_mod_sub_quick(t1, t1, t5, group->field)
|
||||
|| !BN_mod_sub_quick(t3, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t3, t3, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t5, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t2, t0, ctx)
|
||||
/* r->X coord output */
|
||||
|| !BN_mod_sub_quick(r->X, t3, t0, group->field)
|
||||
|| !BN_mod_add_quick(t3, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t4, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t4, t4, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t1, t1, t3, ctx)
|
||||
|| !BN_mod_lshift1_quick(t1, t1, group->field)
|
||||
/* r->Z coord output */
|
||||
|| !BN_mod_add_quick(r->Z, t7, t5, group->field))
|
||||
|| !BN_mod_add_quick(r->Z, t4, t1, group->field))
|
||||
goto err;
|
||||
|
||||
ret = 1;
|
||||
@@ -1610,17 +1629,23 @@ int ec_GFp_simple_ladder_step(const EC_GROUP *group,
|
||||
}
|
||||
|
||||
/*-
|
||||
* Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
|
||||
* Elliptic Curves and Side-Channel Attacks", modified to work in projective
|
||||
* coordinates and return r in Jacobian projective coordinates.
|
||||
* Input:
|
||||
* - s, r: projective (homogeneous) coordinates
|
||||
* - p: affine coordinates
|
||||
*
|
||||
* X4 = two*Y1*X2*Z3*Z2*Z1;
|
||||
* Y4 = two*b*Z3*SQR(Z2*Z1) + Z3*(a*Z2*Z1+X1*X2)*(X1*Z2+X2*Z1) - X3*SQR(X1*Z2-X2*Z1);
|
||||
* Z4 = two*Y1*Z3*SQR(Z2)*Z1;
|
||||
* Output:
|
||||
* - r := (x,y): affine coordinates
|
||||
*
|
||||
* Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
|
||||
* Elliptic Curves and Side-Channel Attacks", modified to work in mixed
|
||||
* projective coords, i.e. p is affine and (r,s) in projective (homogeneous)
|
||||
* coords, and return r in affine coordinates.
|
||||
*
|
||||
* X4 = two*Y1*X2*Z3*Z2;
|
||||
* Y4 = two*b*Z3*SQR(Z2) + Z3*(a*Z2+X1*X2)*(X1*Z2+X2) - X3*SQR(X1*Z2-X2);
|
||||
* Z4 = two*Y1*Z3*SQR(Z2);
|
||||
*
|
||||
* Z4 != 0 because:
|
||||
* - Z1==0 implies p is at infinity, which would have caused an early exit in
|
||||
* the caller;
|
||||
* - Z2==0 implies r is at infinity (handled by the BN_is_zero(r->Z) branch);
|
||||
* - Z3==0 implies s is at infinity (handled by the BN_is_zero(s->Z) branch);
|
||||
* - Y1==0 implies p has order 2, so either r or s are infinity and handled by
|
||||
@@ -1637,11 +1662,7 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group,
|
||||
return EC_POINT_set_to_infinity(group, r);
|
||||
|
||||
if (BN_is_zero(s->Z)) {
|
||||
/* (X,Y,Z) -> (XZ,YZ**2,Z) */
|
||||
if (!group->meth->field_mul(group, r->X, p->X, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, r->Z, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, p->Y, r->Z, ctx)
|
||||
|| !BN_copy(r->Z, p->Z)
|
||||
if (!EC_POINT_copy(r, p)
|
||||
|| !EC_POINT_invert(group, r, ctx))
|
||||
return 0;
|
||||
return 1;
|
||||
@@ -1657,38 +1678,46 @@ int ec_GFp_simple_ladder_post(const EC_GROUP *group,
|
||||
t6 = BN_CTX_get(ctx);
|
||||
|
||||
if (t6 == NULL
|
||||
|| !BN_mod_lshift1_quick(t0, p->Y, group->field)
|
||||
|| !group->meth->field_mul(group, t1, r->X, p->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, t2, t1, t2, ctx)
|
||||
|| !group->meth->field_mul(group, t3, t2, t0, ctx)
|
||||
|| !group->meth->field_mul(group, t2, r->Z, p->Z, ctx)
|
||||
|| !group->meth->field_sqr(group, t4, t2, ctx)
|
||||
|| !BN_mod_lshift1_quick(t5, group->b, group->field)
|
||||
|| !group->meth->field_mul(group, t4, t4, t5, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t2, group->a, ctx)
|
||||
|| !group->meth->field_mul(group, t5, r->X, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t5, t6, t5, group->field)
|
||||
|| !group->meth->field_mul(group, t6, r->Z, p->X, ctx)
|
||||
|| !BN_mod_add_quick(t2, t6, t1, group->field)
|
||||
|| !group->meth->field_mul(group, t5, t5, t2, ctx)
|
||||
|| !BN_mod_sub_quick(t6, t6, t1, group->field)
|
||||
|| !group->meth->field_sqr(group, t6, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t6, t6, s->X, ctx)
|
||||
|| !BN_mod_add_quick(t4, t5, t4, group->field)
|
||||
|| !group->meth->field_mul(group, t4, t4, s->Z, ctx)
|
||||
|| !BN_mod_sub_quick(t4, t4, t6, group->field)
|
||||
|| !group->meth->field_sqr(group, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, p->Z, s->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, t5, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Z, r->Z, t0, ctx)
|
||||
/* t3 := X, t4 := Y */
|
||||
/* (X,Y,Z) -> (XZ,YZ**2,Z) */
|
||||
|| !group->meth->field_mul(group, r->X, t3, r->Z, ctx)
|
||||
|| !BN_mod_lshift1_quick(t4, p->Y, group->field)
|
||||
|| !group->meth->field_mul(group, t6, r->X, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t6, s->Z, t6, ctx)
|
||||
|| !group->meth->field_mul(group, t5, r->Z, t6, ctx)
|
||||
|| !BN_mod_lshift1_quick(t1, group->b, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t1, ctx)
|
||||
|| !group->meth->field_sqr(group, t3, r->Z, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, t4, t3, ctx))
|
||||
|| !group->meth->field_mul(group, t2, t3, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t6, r->Z, group->a, ctx)
|
||||
|| !group->meth->field_mul(group, t1, p->X, r->X, ctx)
|
||||
|| !BN_mod_add_quick(t1, t1, t6, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t1, ctx)
|
||||
|| !group->meth->field_mul(group, t0, p->X, r->Z, ctx)
|
||||
|| !BN_mod_add_quick(t6, r->X, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t6, t6, t1, ctx)
|
||||
|| !BN_mod_add_quick(t6, t6, t2, group->field)
|
||||
|| !BN_mod_sub_quick(t0, t0, r->X, group->field)
|
||||
|| !group->meth->field_sqr(group, t0, t0, ctx)
|
||||
|| !group->meth->field_mul(group, t0, t0, s->X, ctx)
|
||||
|| !BN_mod_sub_quick(t0, t6, t0, group->field)
|
||||
|| !group->meth->field_mul(group, t1, s->Z, t4, ctx)
|
||||
|| !group->meth->field_mul(group, t1, t3, t1, ctx)
|
||||
|| (group->meth->field_decode != NULL
|
||||
&& !group->meth->field_decode(group, t1, t1, ctx))
|
||||
|| !group->meth->field_inv(group, t1, t1, ctx)
|
||||
|| (group->meth->field_encode != NULL
|
||||
&& !group->meth->field_encode(group, t1, t1, ctx))
|
||||
|| !group->meth->field_mul(group, r->X, t5, t1, ctx)
|
||||
|| !group->meth->field_mul(group, r->Y, t0, t1, ctx))
|
||||
goto err;
|
||||
|
||||
if (group->meth->field_set_to_one != NULL) {
|
||||
if (!group->meth->field_set_to_one(group, r->Z, ctx))
|
||||
goto err;
|
||||
} else {
|
||||
if (!BN_one(r->Z))
|
||||
goto err;
|
||||
}
|
||||
|
||||
r->Z_is_one = 1;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include "crypto/ecx.h"
|
||||
#include "ecx_backend.h"
|
||||
|
||||
/*
|
||||
* 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 ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
|
||||
int include_private)
|
||||
{
|
||||
size_t privkeylen = 0, pubkeylen;
|
||||
const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;
|
||||
unsigned char *pubkey;
|
||||
|
||||
if (ecx == NULL)
|
||||
return 0;
|
||||
|
||||
param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
|
||||
if (include_private)
|
||||
param_priv_key =
|
||||
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
|
||||
/*
|
||||
* If a private key is present then a public key must also be present.
|
||||
* Alternatively we've just got a public key.
|
||||
*/
|
||||
if (param_pub_key == NULL)
|
||||
return 0;
|
||||
|
||||
if (param_priv_key != NULL
|
||||
&& !OSSL_PARAM_get_octet_string(param_priv_key,
|
||||
(void **)&ecx->privkey, ecx->keylen,
|
||||
&privkeylen))
|
||||
return 0;
|
||||
|
||||
pubkey = ecx->pubkey;
|
||||
if (!OSSL_PARAM_get_octet_string(param_pub_key,
|
||||
(void **)&pubkey,
|
||||
sizeof(ecx->pubkey), &pubkeylen))
|
||||
return 0;
|
||||
|
||||
if (pubkeylen != ecx->keylen
|
||||
|| (param_priv_key != NULL && privkeylen != ecx->keylen))
|
||||
return 0;
|
||||
|
||||
ecx->haspubkey = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#define ISX448(id) ((id) == EVP_PKEY_X448)
|
||||
#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
|
||||
#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
|
||||
: ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
|
||||
: ED448_KEYLEN))
|
||||
#define KEYNID2TYPE(id) \
|
||||
(IS25519(id) ? ECX_KEY_TYPE_X25519 \
|
||||
: ((id) == EVP_PKEY_X448 ? ECX_KEY_TYPE_X448 \
|
||||
: ((id) == EVP_PKEY_ED25519 ? ECX_KEY_TYPE_ED25519 \
|
||||
: ECX_KEY_TYPE_ED448)))
|
||||
#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
|
||||
+16
-2
@@ -10,7 +10,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include "crypto/ecx.h"
|
||||
|
||||
ECX_KEY *ecx_key_new(size_t keylen, int haspubkey)
|
||||
ECX_KEY *ecx_key_new(ECX_KEY_TYPE type, int haspubkey)
|
||||
{
|
||||
ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
|
||||
|
||||
@@ -18,7 +18,21 @@ ECX_KEY *ecx_key_new(size_t keylen, int haspubkey)
|
||||
return NULL;
|
||||
|
||||
ret->haspubkey = haspubkey;
|
||||
ret->keylen = keylen;
|
||||
switch (type) {
|
||||
case ECX_KEY_TYPE_X25519:
|
||||
ret->keylen = X25519_KEYLEN;
|
||||
break;
|
||||
case ECX_KEY_TYPE_X448:
|
||||
ret->keylen = X448_KEYLEN;
|
||||
break;
|
||||
case ECX_KEY_TYPE_ED25519:
|
||||
ret->keylen = ED25519_KEYLEN;
|
||||
break;
|
||||
case ECX_KEY_TYPE_ED448:
|
||||
ret->keylen = ED448_KEYLEN;
|
||||
break;
|
||||
}
|
||||
ret->type = type;
|
||||
ret->references = 1;
|
||||
|
||||
ret->lock = CRYPTO_THREAD_lock_new();
|
||||
|
||||
+72
-27
@@ -19,20 +19,13 @@
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include "internal/param_build.h"
|
||||
#include "openssl/param_build.h"
|
||||
#include "crypto/asn1.h"
|
||||
#include "crypto/evp.h"
|
||||
#include "crypto/ecx.h"
|
||||
#include "ec_local.h"
|
||||
#include "curve448/curve448_local.h"
|
||||
|
||||
#define ISX448(id) ((id) == EVP_PKEY_X448)
|
||||
#define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
|
||||
#define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
|
||||
: ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
|
||||
: ED448_KEYLEN))
|
||||
#define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
|
||||
|
||||
#include "ecx_backend.h"
|
||||
|
||||
typedef enum {
|
||||
KEY_OP_PUBLIC,
|
||||
@@ -65,7 +58,7 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
|
||||
}
|
||||
}
|
||||
|
||||
key = ecx_key_new(KEYLENID(id), 1);
|
||||
key = ecx_key_new(KEYNID2TYPE(id), 1);
|
||||
if (key == NULL) {
|
||||
ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
@@ -413,38 +406,67 @@ static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
|
||||
}
|
||||
|
||||
static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
|
||||
EVP_KEYMGMT *to_keymgmt)
|
||||
EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
|
||||
const char *propq)
|
||||
{
|
||||
const ECX_KEY *key = from->pkey.ecx;
|
||||
OSSL_PARAM_BLD tmpl;
|
||||
OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
|
||||
OSSL_PARAM *params = NULL;
|
||||
int selection = 0;
|
||||
int rv = 0;
|
||||
|
||||
ossl_param_bld_init(&tmpl);
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
|
||||
/* A key must at least have a public part */
|
||||
if (!ossl_param_bld_push_octet_string(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
|
||||
key->pubkey, key->keylen))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
|
||||
|
||||
if (key->privkey != NULL) {
|
||||
if (!ossl_param_bld_push_octet_string(&tmpl,
|
||||
if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
|
||||
OSSL_PKEY_PARAM_PRIV_KEY,
|
||||
key->privkey, key->keylen))
|
||||
goto err;
|
||||
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
|
||||
}
|
||||
|
||||
params = ossl_param_bld_to_param(&tmpl);
|
||||
params = OSSL_PARAM_BLD_to_param(tmpl);
|
||||
|
||||
/* We export, the provider imports */
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
|
||||
params);
|
||||
rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
|
||||
|
||||
err:
|
||||
ossl_param_bld_free(params);
|
||||
OSSL_PARAM_BLD_free(tmpl);
|
||||
OSSL_PARAM_BLD_free_params(params);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
|
||||
int keytype)
|
||||
{
|
||||
EVP_PKEY *pkey = key;
|
||||
ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
|
||||
|
||||
if (ecx == NULL) {
|
||||
ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ecx_key_fromdata(ecx, params, 1)
|
||||
|| !EVP_PKEY_assign(pkey, keytype, ecx)) {
|
||||
ecx_key_free(ecx);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int x25519_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
EVP_PKEY_X25519,
|
||||
EVP_PKEY_X25519,
|
||||
@@ -487,9 +509,15 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to
|
||||
ecx_pkey_export_to,
|
||||
x25519_import_from
|
||||
};
|
||||
|
||||
static int x448_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_X448);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
EVP_PKEY_X448,
|
||||
EVP_PKEY_X448,
|
||||
@@ -532,7 +560,8 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to
|
||||
ecx_pkey_export_to,
|
||||
x448_import_from
|
||||
};
|
||||
|
||||
static int ecd_size25519(const EVP_PKEY *pkey)
|
||||
@@ -607,6 +636,10 @@ static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ed25519_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
EVP_PKEY_ED25519,
|
||||
@@ -648,8 +681,16 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to,
|
||||
ed25519_import_from
|
||||
};
|
||||
|
||||
static int ed448_import_from(const OSSL_PARAM params[], void *key)
|
||||
{
|
||||
return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
EVP_PKEY_ED448,
|
||||
EVP_PKEY_ED448,
|
||||
@@ -690,6 +731,9 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
|
||||
ecx_set_pub_key,
|
||||
ecx_get_priv_key,
|
||||
ecx_get_pub_key,
|
||||
ecx_pkey_dirty_cnt,
|
||||
ecx_pkey_export_to,
|
||||
ed448_import_from
|
||||
};
|
||||
|
||||
static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
@@ -793,7 +837,8 @@ static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
|
||||
if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
|
||||
NULL) == 0)
|
||||
return 0;
|
||||
*siglen = ED25519_SIGSIZE;
|
||||
return 1;
|
||||
@@ -834,7 +879,7 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
if (siglen != ED25519_SIGSIZE)
|
||||
return 0;
|
||||
|
||||
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
|
||||
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL);
|
||||
}
|
||||
|
||||
static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
|
||||
@@ -1100,7 +1145,7 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
ECX_KEY *key = ecx_key_new(X25519_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
|
||||
if (key == NULL) {
|
||||
@@ -1142,7 +1187,7 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
ECX_KEY *key = ecx_key_new(X448_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
|
||||
if (key == NULL) {
|
||||
@@ -1187,7 +1232,7 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
};
|
||||
unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
|
||||
ECX_KEY *key = ecx_key_new(ED25519_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
unsigned int sz;
|
||||
|
||||
@@ -1244,7 +1289,7 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
|
||||
};
|
||||
unsigned char x_dst[57], buff[114];
|
||||
ECX_KEY *key = ecx_key_new(ED448_KEYLEN, 1);
|
||||
ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
|
||||
unsigned char *privkey = NULL, *pubkey;
|
||||
EVP_MD_CTX *hashctx = NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user