This commit is contained in:
purplerain 2023-06-25 21:25:02 +00:00
parent 82bafdd0b3
commit ae25582c29
Signed by: purplerain
GPG key ID: F42C07F07E2E35B7
37 changed files with 421 additions and 1406 deletions

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ecs_lib.c,v 1.17 2023/04/25 19:26:45 tb Exp $ */
/* $OpenBSD: ecs_lib.c,v 1.22 2023/06/25 19:33:39 tb Exp $ */
/* ====================================================================
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
*
@ -68,9 +68,18 @@
static const ECDSA_METHOD *default_ECDSA_method = NULL;
static void *ecdsa_data_new(void);
static void *ecdsa_data_dup(void *);
static void ecdsa_data_free(void *);
static const ECDSA_METHOD openssl_ecdsa_meth = {
.name = "OpenSSL ECDSA method",
.ecdsa_do_sign = ossl_ecdsa_sign_sig,
.ecdsa_sign_setup = ossl_ecdsa_sign_setup,
.ecdsa_do_verify = ossl_ecdsa_verify_sig,
};
const ECDSA_METHOD *
ECDSA_OpenSSL(void)
{
return &openssl_ecdsa_meth;
}
void
ECDSA_set_default_method(const ECDSA_METHOD *meth)
@ -90,168 +99,24 @@ ECDSA_get_default_method(void)
int
ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
{
ECDSA_DATA *ecdsa;
ecdsa = ecdsa_check(eckey);
if (ecdsa == NULL)
return 0;
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(ecdsa->engine);
ecdsa->engine = NULL;
#endif
ecdsa->meth = meth;
return 1;
}
static ECDSA_DATA *
ECDSA_DATA_new_method(ENGINE *engine)
{
ECDSA_DATA *ret;
ret = malloc(sizeof(ECDSA_DATA));
if (ret == NULL) {
ECDSAerror(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->init = NULL;
ret->meth = ECDSA_get_default_method();
ret->engine = engine;
#ifndef OPENSSL_NO_ENGINE
if (!ret->engine)
ret->engine = ENGINE_get_default_ECDSA();
if (ret->engine) {
ret->meth = ENGINE_get_ECDSA(ret->engine);
if (ret->meth == NULL) {
ECDSAerror(ERR_R_ENGINE_LIB);
ENGINE_finish(ret->engine);
free(ret);
return NULL;
}
}
#endif
ret->flags = ret->meth->flags;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data);
return (ret);
}
static void *
ecdsa_data_new(void)
{
return (void *)ECDSA_DATA_new_method(NULL);
}
static void *
ecdsa_data_dup(void *data)
{
ECDSA_DATA *r = (ECDSA_DATA *)data;
/* XXX: dummy operation */
if (r == NULL)
return NULL;
return ecdsa_data_new();
}
static void
ecdsa_data_free(void *data)
{
ECDSA_DATA *r = (ECDSA_DATA *)data;
#ifndef OPENSSL_NO_ENGINE
ENGINE_finish(r->engine);
#endif
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
freezero(r, sizeof(ECDSA_DATA));
}
ECDSA_DATA *
ecdsa_check(EC_KEY *key)
{
ECDSA_DATA *ecdsa_data;
void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup,
ecdsa_data_free, ecdsa_data_free);
if (data == NULL) {
ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
if (ecdsa_data == NULL)
return NULL;
data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
if (data != NULL) {
/* Another thread raced us to install the key_method
* data and won. */
ecdsa_data_free(ecdsa_data);
ecdsa_data = (ECDSA_DATA *)data;
}
} else
ecdsa_data = (ECDSA_DATA *)data;
return ecdsa_data;
}
int
ECDSA_size(const EC_KEY *r)
{
BIGNUM *order = NULL;
const EC_GROUP *group;
ECDSA_SIG signature;
int ret = 0;
if (r == NULL)
goto err;
if ((group = EC_KEY_get0_group(r)) == NULL)
goto err;
if ((order = BN_new()) == NULL)
goto err;
if (!EC_GROUP_get_order(group, order, NULL))
goto err;
signature.r = order;
signature.s = order;
if ((ret = i2d_ECDSA_SIG(&signature, NULL)) < 0)
ret = 0;
err:
BN_free(order);
return ret;
return 0;
}
int
ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp,
new_func, dup_func, free_func);
return -1;
}
int
ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg)
{
ECDSA_DATA *ecdsa;
ecdsa = ecdsa_check(d);
if (ecdsa == NULL)
return 0;
return (CRYPTO_set_ex_data(&ecdsa->ex_data, idx, arg));
return 0;
}
void *
ECDSA_get_ex_data(EC_KEY *d, int idx)
{
ECDSA_DATA *ecdsa;
ecdsa = ecdsa_check(d);
if (ecdsa == NULL)
return NULL;
return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx));
return NULL;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ecs_local.h,v 1.2 2022/11/26 17:23:17 tb Exp $ */
/* $OpenBSD: ecs_local.h,v 1.3 2023/06/25 18:45:56 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project
*/
@ -63,29 +63,11 @@
__BEGIN_HIDDEN_DECLS
typedef struct ecdsa_data_st {
/* EC_KEY_METH_DATA part */
int (*init)(EC_KEY *);
/* method (ECDSA) specific part */
ENGINE *engine;
int flags;
const ECDSA_METHOD *meth;
CRYPTO_EX_DATA ex_data;
} ECDSA_DATA;
struct ECDSA_SIG_st {
BIGNUM *r;
BIGNUM *s;
};
/** ecdsa_check
* checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure
* and if not it removes the old meth_data and creates a ECDSA_DATA structure.
* \param eckey pointer to a EC_KEY object
* \return pointer to a ECDSA_DATA structure
*/
ECDSA_DATA *ecdsa_check(EC_KEY *eckey);
int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp);
int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ecs_ossl.c,v 1.33 2023/04/13 15:00:24 tb Exp $ */
/* $OpenBSD: ecs_ossl.c,v 1.37 2023/06/25 19:33:39 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project
*/
@ -71,25 +71,6 @@
static int ecdsa_prepare_digest(const unsigned char *dgst, int dgst_len,
BIGNUM *order, BIGNUM *ret);
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp);
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey);
static ECDSA_METHOD openssl_ecdsa_meth = {
.name = "OpenSSL ECDSA method",
.ecdsa_do_sign = ecdsa_do_sign,
.ecdsa_sign_setup = ecdsa_sign_setup,
.ecdsa_do_verify = ecdsa_do_verify
};
const ECDSA_METHOD *
ECDSA_OpenSSL(void)
{
return &openssl_ecdsa_meth;
}
static int
ecdsa_prepare_digest(const unsigned char *dgst, int dgst_len, BIGNUM *order,
@ -139,8 +120,8 @@ ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen, unsigned char *si
return ret;
}
static int
ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
int
ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
BN_CTX *ctx = ctx_in;
BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
@ -260,18 +241,6 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
return (ret);
}
/* replace w/ ecdsa_sign_setup() when ECDSA_METHOD gets removed */
int
ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
{
ECDSA_DATA *ecdsa;
if ((ecdsa = ecdsa_check(eckey)) == NULL)
return 0;
return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp);
}
/*
* It is too expensive to check curve parameters on every sign operation.
* Instead, cap the number of retries. A single retry is very unlikely, so
@ -279,8 +248,8 @@ ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp
*/
#define ECDSA_MAX_SIGN_ITERATIONS 32
static ECDSA_SIG *
ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
ECDSA_SIG *
ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
{
BIGNUM *b = NULL, *binv = NULL, *bm = NULL, *bxr = NULL;
@ -289,15 +258,13 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
BN_CTX *ctx = NULL;
const EC_GROUP *group;
ECDSA_SIG *ret;
ECDSA_DATA *ecdsa;
int attempts = 0;
int ok = 0;
ecdsa = ecdsa_check(eckey);
group = EC_KEY_get0_group(eckey);
priv_key = EC_KEY_get0_private_key(eckey);
if (group == NULL || priv_key == NULL || ecdsa == NULL) {
if (group == NULL || priv_key == NULL) {
ECDSAerror(ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
@ -434,18 +401,6 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
return ret;
}
/* replace w/ ecdsa_do_sign() when ECDSA_METHOD gets removed */
ECDSA_SIG *
ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
{
ECDSA_DATA *ecdsa;
if ((ecdsa = ecdsa_check(eckey)) == NULL)
return NULL;
return ecdsa->meth->ecdsa_do_sign(dgst, dgst_len, in_kinv, in_r, eckey);
}
int
ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
const unsigned char *sigbuf, int sig_len, EC_KEY *eckey)
@ -472,8 +427,8 @@ ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len,
return (ret);
}
static int
ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
int
ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
EC_KEY *eckey)
{
BN_CTX *ctx;
@ -563,18 +518,6 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
return ret;
}
/* replace w/ ecdsa_do_verify() when ECDSA_METHOD gets removed */
int
ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey)
{
ECDSA_DATA *ecdsa;
if ((ecdsa = ecdsa_check(eckey)) == NULL)
return 0;
return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey);
}
ECDSA_SIG *
ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
{
@ -637,3 +580,35 @@ ECDSA_verify(int type, const unsigned char *dgst, int dgst_len,
ECDSAerror(EVP_R_METHOD_NOT_SUPPORTED);
return 0;
}
int
ECDSA_size(const EC_KEY *r)
{
BIGNUM *order = NULL;
const EC_GROUP *group;
ECDSA_SIG signature;
int ret = 0;
if (r == NULL)
goto err;
if ((group = EC_KEY_get0_group(r)) == NULL)
goto err;
if ((order = BN_new()) == NULL)
goto err;
if (!EC_GROUP_get_order(group, order, NULL))
goto err;
signature.r = order;
signature.s = order;
if ((ret = i2d_ECDSA_SIG(&signature, NULL)) < 0)
ret = 0;
err:
BN_free(order);
return ret;
}