aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorNils Larsch <nils@openssl.org>2005-05-16 10:11:04 +0000
committerNils Larsch <nils@openssl.org>2005-05-16 10:11:04 +0000
commit9dd84053419aa220b5e66a5f9fcf809dbd6d9369 (patch)
tree7818c598a88a5b457333fd9f5951836fe96834b6 /crypto
parent46a643763de6d8e39ecf6f76fa79b4d04885aa59 (diff)
downloadopenssl-9dd84053419aa220b5e66a5f9fcf809dbd6d9369.tar.gz
ecc api cleanup; summary:
- hide the EC_KEY structure definition in ec_lcl.c + add some functions to use/access the EC_KEY fields - change the way how method specific data (ecdsa/ecdh) is attached to a EC_KEY - add ECDSA_sign_ex and ECDSA_do_sign_ex functions with additional parameters for pre-computed values - rebuild libeay.num from 0.9.7
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asn1/d2i_pr.c2
-rw-r--r--crypto/asn1/d2i_pu.c2
-rw-r--r--crypto/asn1/i2d_pr.c2
-rw-r--r--crypto/asn1/i2d_pu.c2
-rw-r--r--crypto/asn1/t_pkey.c36
-rw-r--r--crypto/asn1/t_req.c2
-rw-r--r--crypto/asn1/t_spki.c2
-rw-r--r--crypto/asn1/t_x509.c2
-rw-r--r--crypto/asn1/x_pubkey.c42
-rw-r--r--crypto/ec/ec.h43
-rw-r--r--crypto/ec/ec_key.c126
-rw-r--r--crypto/ec/ec_lcl.h29
-rw-r--r--crypto/ec/ec_lib.c57
-rw-r--r--crypto/ec/ec_mult.c10
-rw-r--r--crypto/ecdh/ecdh.h7
-rw-r--r--crypto/ecdh/ecdhtest.c40
-rw-r--r--crypto/ecdh/ech_lib.c68
-rw-r--r--crypto/ecdh/ech_locl.h5
-rw-r--r--crypto/ecdh/ech_ossl.c18
-rw-r--r--crypto/ecdsa/ecdsa.h59
-rw-r--r--crypto/ecdsa/ecdsatest.c21
-rw-r--r--crypto/ecdsa/ecs_lib.c86
-rw-r--r--crypto/ecdsa/ecs_locl.h9
-rw-r--r--crypto/ecdsa/ecs_ossl.c56
-rw-r--r--crypto/ecdsa/ecs_sign.c25
-rw-r--r--crypto/evp/evp.h2
-rw-r--r--crypto/evp/evp_pkey.c71
-rw-r--r--crypto/evp/p_lib.c41
-rw-r--r--crypto/pem/pem_info.c2
29 files changed, 532 insertions, 335 deletions
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index 5f30585142..207ccda5ac 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -113,7 +113,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
- if ((ret->pkey.eckey = d2i_ECPrivateKey(NULL,
+ if ((ret->pkey.ec = d2i_ECPrivateKey(NULL,
(const unsigned char **)pp, length)) == NULL)
{
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
diff --git a/crypto/asn1/d2i_pu.c b/crypto/asn1/d2i_pu.c
index 8a05810eda..3694f51a8c 100644
--- a/crypto/asn1/d2i_pu.c
+++ b/crypto/asn1/d2i_pu.c
@@ -113,7 +113,7 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
- if (!o2i_ECPublicKey(&(ret->pkey.eckey),
+ if (!o2i_ECPublicKey(&(ret->pkey.ec),
(const unsigned char **)pp, length))
{
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
diff --git a/crypto/asn1/i2d_pr.c b/crypto/asn1/i2d_pr.c
index bbf2a0d2d6..0be52c5b76 100644
--- a/crypto/asn1/i2d_pr.c
+++ b/crypto/asn1/i2d_pr.c
@@ -89,7 +89,7 @@ int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
#ifndef OPENSSL_NO_EC
if (a->type == EVP_PKEY_EC)
{
- return(i2d_ECPrivateKey(a->pkey.eckey, pp));
+ return(i2d_ECPrivateKey(a->pkey.ec, pp));
}
#endif
diff --git a/crypto/asn1/i2d_pu.c b/crypto/asn1/i2d_pu.c
index 44f186442e..34286dbd35 100644
--- a/crypto/asn1/i2d_pu.c
+++ b/crypto/asn1/i2d_pu.c
@@ -85,7 +85,7 @@ int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
- return(i2o_ECPublicKey(a->pkey.eckey, pp));
+ return(i2o_ECPublicKey(a->pkey.ec, pp));
#endif
default:
ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
diff --git a/crypto/asn1/t_pkey.c b/crypto/asn1/t_pkey.c
index 687a2bd6f5..7dd4ae3787 100644
--- a/crypto/asn1/t_pkey.c
+++ b/crypto/asn1/t_pkey.c
@@ -79,7 +79,7 @@
#include <openssl/ec.h>
#endif
-static int print(BIO *fp,const char *str,BIGNUM *num,
+static int print(BIO *fp,const char *str, const BIGNUM *num,
unsigned char *buf,int off);
static int print_bin(BIO *fp, const char *str, const unsigned char *num,
size_t len, int off);
@@ -279,7 +279,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off)
size_t buf_len=0, i;
int ret=0, reason=ERR_R_BIO_LIB;
BN_CTX *ctx=NULL;
- EC_POINT *point=NULL;
+ const EC_POINT *point=NULL;
BIGNUM *p=NULL, *a=NULL, *b=NULL, *gen=NULL,
*order=NULL, *cofactor=NULL;
const unsigned char *seed;
@@ -481,24 +481,29 @@ int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
int ret=0, reason=ERR_R_BIO_LIB;
BIGNUM *pub_key=NULL, *order=NULL;
BN_CTX *ctx=NULL;
+ const EC_GROUP *group;
+ const EC_POINT *public_key;
+ const BIGNUM *priv_key;
- if (!x || !x->group)
+ if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
{
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
- if ((pub_key = EC_POINT_point2bn(x->group, x->pub_key,
- x->conv_form, NULL, ctx)) == NULL)
+ public_key = EC_KEY_get0_public_key(x);
+ if ((pub_key = EC_POINT_point2bn(group, public_key,
+ EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
{
reason = ERR_R_EC_LIB;
goto err;
}
buf_len = (size_t)BN_num_bytes(pub_key);
- if (x->priv_key)
+ priv_key = EC_KEY_get0_private_key(x);
+ if (priv_key != NULL)
{
- if ((i = (size_t)BN_num_bytes(x->priv_key)) > buf_len)
+ if ((i = (size_t)BN_num_bytes(priv_key)) > buf_len)
buf_len = i;
}
@@ -509,25 +514,25 @@ int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
goto err;
}
- if (x->priv_key != NULL)
+ if (priv_key != NULL)
{
if (!BIO_indent(bp, off, 128))
goto err;
if ((order = BN_new()) == NULL)
goto err;
- if (!EC_GROUP_get_order(x->group, order, NULL))
+ if (!EC_GROUP_get_order(group, order, NULL))
goto err;
if (BIO_printf(bp, "Private-Key: (%d bit)\n",
BN_num_bits(order)) <= 0) goto err;
}
- if ((x->priv_key != NULL) && !print(bp, "priv:", x->priv_key,
+ if ((priv_key != NULL) && !print(bp, "priv:", priv_key,
buffer, off))
goto err;
if ((pub_key != NULL) && !print(bp, "pub: ", pub_key,
buffer, off))
goto err;
- if (!ECPKParameters_print(bp, x->group, off))
+ if (!ECPKParameters_print(bp, group, off))
goto err;
ret=1;
err:
@@ -545,7 +550,7 @@ err:
}
#endif /* OPENSSL_NO_EC */
-static int print(BIO *bp, const char *number, BIGNUM *num, unsigned char *buf,
+static int print(BIO *bp, const char *number, const BIGNUM *num, unsigned char *buf,
int off)
{
int n,i;
@@ -770,8 +775,9 @@ int ECParameters_print(BIO *bp, const EC_KEY *x)
{
int reason=ERR_R_EC_LIB, ret=0;
BIGNUM *order=NULL;
+ const EC_GROUP *group;
- if (!x || !x->group)
+ if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL)
{
reason = ERR_R_PASSED_NULL_PARAMETER;;
goto err;
@@ -783,7 +789,7 @@ int ECParameters_print(BIO *bp, const EC_KEY *x)
goto err;
}
- if (!EC_GROUP_get_order(x->group, order, NULL))
+ if (!EC_GROUP_get_order(group, order, NULL))
{
reason = ERR_R_EC_LIB;
goto err;
@@ -792,7 +798,7 @@ int ECParameters_print(BIO *bp, const EC_KEY *x)
if (BIO_printf(bp, "ECDSA-Parameters: (%d bit)\n",
BN_num_bits(order)) <= 0)
goto err;
- if (!ECPKParameters_print(bp, x->group, 4))
+ if (!ECPKParameters_print(bp, group, 4))
goto err;
ret=1;
err:
diff --git a/crypto/asn1/t_req.c b/crypto/asn1/t_req.c
index 4056cf6ea4..204ca105e3 100644
--- a/crypto/asn1/t_req.c
+++ b/crypto/asn1/t_req.c
@@ -166,7 +166,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long
if (pkey->type == EVP_PKEY_EC)
{
BIO_printf(bp, "%12sEC Public Key: \n","");
- EC_KEY_print(bp, pkey->pkey.eckey, 16);
+ EC_KEY_print(bp, pkey->pkey.ec, 16);
}
else
#endif
diff --git a/crypto/asn1/t_spki.c b/crypto/asn1/t_spki.c
index e84bae6438..23ab3b94e0 100644
--- a/crypto/asn1/t_spki.c
+++ b/crypto/asn1/t_spki.c
@@ -100,7 +100,7 @@ int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
if (pkey->type == EVP_PKEY_EC)
{
BIO_printf(out, " EC Public Key:\n");
- EC_KEY_print(out, pkey->pkey.eckey,2);
+ EC_KEY_print(out, pkey->pkey.ec,2);
}
else
#endif
diff --git a/crypto/asn1/t_x509.c b/crypto/asn1/t_x509.c
index 4bf5c893e7..61f48d14d7 100644
--- a/crypto/asn1/t_x509.c
+++ b/crypto/asn1/t_x509.c
@@ -236,7 +236,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
if (pkey->type == EVP_PKEY_EC)
{
BIO_printf(bp, "%12sEC Public Key:\n","");
- EC_KEY_print(bp, pkey->pkey.eckey, 16);
+ EC_KEY_print(bp, pkey->pkey.ec, 16);
}
else
#endif
diff --git a/crypto/asn1/x_pubkey.c b/crypto/asn1/x_pubkey.c
index c371e4c4cd..50faa4af20 100644
--- a/crypto/asn1/x_pubkey.c
+++ b/crypto/asn1/x_pubkey.c
@@ -159,9 +159,10 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
int nid=0;
unsigned char *pp;
- EC_KEY *eckey;
+ EC_KEY *ec_key;
+ const EC_GROUP *group;
- eckey = pkey->pkey.eckey;
+ ec_key = pkey->pkey.ec;
ASN1_TYPE_free(a->parameter);
if ((a->parameter = ASN1_TYPE_new()) == NULL)
@@ -170,8 +171,9 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
goto err;
}
- if (EC_GROUP_get_asn1_flag(eckey->group)
- && (nid = EC_GROUP_get_curve_name(eckey->group)))
+ group = EC_KEY_get0_group(ec_key);
+ if (EC_GROUP_get_asn1_flag(group)
+ && (nid = EC_GROUP_get_curve_name(group)))
{
/* just set the OID */
a->parameter->type = V_ASN1_OBJECT;
@@ -179,7 +181,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
}
else /* explicit parameters */
{
- if ((i = i2d_ECParameters(eckey, NULL)) == 0)
+ if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
{
X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
goto err;
@@ -190,7 +192,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
goto err;
}
pp = p;
- if (!i2d_ECParameters(eckey, &pp))
+ if (!i2d_ECParameters(ec_key, &pp))
{
X509err(X509_F_X509_PUBKEY_SET, ERR_R_EC_LIB);
OPENSSL_free(p);
@@ -313,7 +315,7 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
/* type == V_ASN1_SEQUENCE => we have explicit parameters
* (e.g. parameters in the X9_62_EC_PARAMETERS-structure )
*/
- if ((ret->pkey.eckey= EC_KEY_new()) == NULL)
+ if ((ret->pkey.ec= EC_KEY_new()) == NULL)
{
X509err(X509_F_X509_PUBKEY_GET,
ERR_R_MALLOC_FAILURE);
@@ -321,7 +323,7 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
}
cp = p = a->parameter->value.sequence->data;
j = a->parameter->value.sequence->length;
- if (!d2i_ECParameters(&ret->pkey.eckey, &cp, (long)j))
+ if (!d2i_ECParameters(&ret->pkey.ec, &cp, (long)j))
{
X509err(X509_F_X509_PUBKEY_GET, ERR_R_EC_LIB);
goto err;
@@ -332,17 +334,21 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
/* type == V_ASN1_OBJECT => the parameters are given
* by an asn1 OID
*/
- EC_KEY *eckey;
- if (ret->pkey.eckey == NULL)
- ret->pkey.eckey = EC_KEY_new();
- eckey = ret->pkey.eckey;
- if (eckey->group)
- EC_GROUP_free(eckey->group);
- if ((eckey->group = EC_GROUP_new_by_curve_name(
- OBJ_obj2nid(a->parameter->value.object))) == NULL)
+ EC_KEY *ec_key;
+ EC_GROUP *group;
+
+ if (ret->pkey.ec == NULL)
+ ret->pkey.ec = EC_KEY_new();
+ ec_key = ret->pkey.ec;
+ if (ec_key == NULL)
+ goto err;
+ group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
+ if (group == NULL)
+ goto err;
+ EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+ if (EC_KEY_set_group(ec_key, group) == 0)
goto err;
- EC_GROUP_set_asn1_flag(eckey->group,
- OPENSSL_EC_NAMED_CURVE);
+ EC_GROUP_free(group);
}
/* the case implicitlyCA is currently not implemented */
ret->save_parameters = 1;
diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h
index c706669a7a..a19a075b0d 100644
--- a/crypto/ec/ec.h
+++ b/crypto/ec/ec.h
@@ -139,7 +139,7 @@ const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
int EC_METHOD_get_field_type(const EC_METHOD *);
int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
-EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
@@ -292,36 +292,37 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
/* the EC_KEY stuff */
typedef struct ec_key_st EC_KEY;
-typedef struct ec_key_meth_data_st {
- int (*init)(EC_KEY *);
- void (*finish)(EC_KEY *);
- } EC_KEY_METH_DATA;
-
-struct ec_key_st {
- int version;
-
- EC_GROUP *group;
-
- EC_POINT *pub_key;
- BIGNUM *priv_key;
-
- unsigned int enc_flag;
- point_conversion_form_t conv_form;
-
- int references;
-
- EC_KEY_METH_DATA *meth_data;
- }/* EC_KEY */;
/* some values for the encoding_flag */
#define EC_PKEY_NO_PARAMETERS 0x001
#define EC_PKEY_NO_PUBKEY 0x002
EC_KEY *EC_KEY_new(void);
+EC_KEY *EC_KEY_new_by_curve_name(int nid);
void EC_KEY_free(EC_KEY *);
EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
EC_KEY *EC_KEY_dup(const EC_KEY *);
+
int EC_KEY_up_ref(EC_KEY *);
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *);
+int EC_KEY_set_group(EC_KEY *, const EC_GROUP *);
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *);
+int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *);
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
+int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
+unsigned EC_KEY_get_enc_flags(const EC_KEY *);
+void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
+void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
+/* functions to set/get method specific data */
+void *EC_KEY_get_key_method_data(EC_KEY *,
+ void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
+ void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+/* wrapper functions for the underlying EC_GROUP object */
+void EC_KEY_set_asn1_flag(EC_KEY *, int);
+int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx);
+
/* EC_KEY_generate_key() creates a ec private (public) key */
int EC_KEY_generate_key(EC_KEY *);
/* EC_KEY_check_key() */
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 68aba4348b..66d9c8dd82 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -3,7 +3,7 @@
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -84,10 +84,23 @@ EC_KEY *EC_KEY_new(void)
ret->enc_flag= 0;
ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
ret->references= 1;
- ret->meth_data = NULL;
+ ret->method_data = NULL;
return(ret);
}
+EC_KEY *EC_KEY_new_by_curve_name(int nid)
+ {
+ EC_KEY *ret = EC_KEY_new();
+ if (ret == NULL)
+ return NULL;
+ ret->group = EC_GROUP_new_by_curve_name(nid);
+ if (ret->group == NULL)
+ {
+ EC_KEY_free(ret);
+ return NULL;
+ }
+ return ret;
+ }
void EC_KEY_free(EC_KEY *r)
{
@@ -115,8 +128,7 @@ void EC_KEY_free(EC_KEY *r)
if (r->priv_key != NULL)
BN_clear_free(r->priv_key);
- if (r->meth_data && r->meth_data->finish)
- r->meth_data->finish(r);
+ EC_EX_DATA_free_all_data(&r->method_data);
OPENSSL_cleanse((void *)r, sizeof(EC_KEY));
@@ -125,6 +137,8 @@ void EC_KEY_free(EC_KEY *r)
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
{
+ EC_EXTRA_DATA *d;
+
if (dest == NULL || src == NULL)
{
ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
@@ -166,6 +180,19 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
if (!BN_copy(dest->priv_key, src->priv_key))
return NULL;
}
+ /* copy method/extra data */
+ EC_EX_DATA_free_all_data(&dest->method_data);
+
+ for (d = src->method_data; d != NULL; d = d->next)
+ {
+ void *t = d->dup_func(d->data);
+
+ if (t == NULL)
+ return 0;
+ if (!EC_EX_DATA_set_data(&dest->method_data, t, d->dup_func, d->free_func, d->clear_free_func))
+ return 0;
+ }
+
/* copy the rest */
dest->enc_flag = src->enc_flag;
dest->conv_form = src->conv_form;
@@ -375,3 +402,94 @@ err:
EC_POINT_free(point);
return(ok);
}
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key)
+ {
+ return key->group;
+ }
+
+int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group)
+ {
+ if (key->group != NULL)
+ EC_GROUP_free(key->group);
+ key->group = EC_GROUP_dup(group);
+ return (key->group == NULL) ? 0 : 1;
+ }
+
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key)
+ {
+ return key->priv_key;
+ }
+
+int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key)
+ {
+ if (key->priv_key)
+ BN_clear_free(key->priv_key);
+ key->priv_key = BN_dup(priv_key);
+ return (key->priv_key == NULL) ? 0 : 1;
+ }
+
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key)
+ {
+ return key->pub_key;
+ }
+
+int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key)
+ {
+ if (key->pub_key != NULL)
+ EC_POINT_free(key->pub_key);
+ key->pub_key = EC_POINT_dup(pub_key, key->group);
+ return (key->pub_key == NULL) ? 0 : 1;
+ }
+
+unsigned int EC_KEY_get_enc_flags(const EC_KEY *key)
+ {
+ return key->enc_flag;
+ }
+
+void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags)
+ {
+ key->enc_flag = flags;
+ }
+
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key)
+ {
+ return key->conv_form;
+ }
+
+void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
+ {
+ key->conv_form = cform;
+ if (key->group != NULL)
+ EC_GROUP_set_point_conversion_form(key->group, cform);
+ }
+
+void *EC_KEY_get_key_method_data(EC_KEY *key,
+ void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+ {
+ return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+ }
+
+void EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
+ void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
+ {
+ EC_EXTRA_DATA *ex_data;
+ CRYPTO_w_lock(CRYPTO_LOCK_EC);
+ ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
+ if (ex_data == NULL)
+ EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
+ CRYPTO_w_unlock(CRYPTO_LOCK_EC);
+ }
+
+void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
+ {
+ if (key->group != NULL)
+ EC_GROUP_set_asn1_flag(key->group, flag);
+ }
+
+int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)
+ {
+ if (key->group == NULL)
+ return 0;
+ return EC_GROUP_precompute_mult(key->group, ctx);
+ }
diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h
index c878081942..fdd7aa2755 100644
--- a/crypto/ec/ec_lcl.h
+++ b/crypto/ec/ec_lcl.h
@@ -229,22 +229,37 @@ struct ec_group_st {
int (*field_mod_func)(BIGNUM *, const BIGNUM *, const BIGNUM *, BN_CTX *); /* method-specific */
} /* EC_GROUP */;
+struct ec_key_st {
+ int version;
-/* Basically a 'mixin' for extra data, but available for EC_GROUPs only
+ EC_GROUP *group;
+
+ EC_POINT *pub_key;
+ BIGNUM *priv_key;
+
+ unsigned int enc_flag;
+ point_conversion_form_t conv_form;
+
+ int references;
+
+ EC_EXTRA_DATA *method_data;
+} /* EC_KEY */;
+
+/* Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs only
* (with visibility limited to 'package' level for now).
* We use the function pointers as index for retrieval; this obviates
* global ex_data-style index tables.
*/
-int EC_GROUP_set_extra_data(EC_GROUP *, void *data,
+int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
-void *EC_GROUP_get_extra_data(const EC_GROUP *,
+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
-void EC_GROUP_free_extra_data(EC_GROUP*,
+void EC_EX_DATA_free_data(EC_EXTRA_DATA **,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
-void EC_GROUP_clear_free_extra_data(EC_GROUP*,
+void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
-void EC_GROUP_free_all_extra_data(EC_GROUP *);
-void EC_GROUP_clear_free_all_extra_data(EC_GROUP *);
+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **);
+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **);
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index ae9ee08660..6d3a562690 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -127,7 +127,7 @@ void EC_GROUP_free(EC_GROUP *group)
if (group->meth->group_finish != 0)
group->meth->group_finish(group);
- EC_GROUP_free_all_extra_data(group);
+ EC_EX_DATA_free_all_data(&group->extra_data);
if (group->generator != NULL)
EC_POINT_free(group->generator);
@@ -150,7 +150,7 @@ void EC_GROUP_clear_free(EC_GROUP *group)
else if (group->meth != NULL && group->meth->group_finish != 0)
group->meth->group_finish(group);
- EC_GROUP_clear_free_all_extra_data(group);
+ EC_EX_DATA_clear_free_all_data(&group->extra_data);
if (group->generator != NULL)
EC_POINT_clear_free(group->generator);
@@ -185,7 +185,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
if (dest == src)
return 1;
- EC_GROUP_free_all_extra_data(dest);
+ EC_EX_DATA_free_all_data(&dest->extra_data);
for (d = src->extra_data; d != NULL; d = d->next)
{
@@ -193,7 +193,7 @@ int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src)
if (t == NULL)
return 0;
- if (!EC_GROUP_set_extra_data(dest, t, d->dup_func, d->free_func, d->clear_free_func))
+ if (!EC_EX_DATA_set_data(&dest->extra_data, t, d->dup_func, d->free_func, d->clear_free_func))
return 0;
}
@@ -310,7 +310,7 @@ int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIG
}
-EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group)
{
return group->generator;
}
@@ -546,15 +546,15 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
/* this has 'package' visibility */
-int EC_GROUP_set_extra_data(EC_GROUP *group, void *data,
+int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
{
EC_EXTRA_DATA *d;
- if (group == NULL)
+ if (ex_data == NULL)
return 0;
- for (d = group->extra_data; d != NULL; d = d->next)
+ for (d = *ex_data; d != NULL; d = d->next)
{
if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
{
@@ -576,22 +576,19 @@ int EC_GROUP_set_extra_data(EC_GROUP *group, void *data,
d->free_func = free_func;
d->clear_free_func = clear_free_func;
- d->next = group->extra_data;
- group->extra_data = d;
+ d->next = *ex_data;
+ *ex_data = d;
return 1;
}
/* this has 'package' visibility */
-void *EC_GROUP_get_extra_data(const EC_GROUP *group,
+void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
{
- EC_EXTRA_DATA *d;
-
- if (group == NULL)
- return NULL;
+ const EC_EXTRA_DATA *d;
- for (d = group->extra_data; d != NULL; d = d->next)
+ for (d = ex_data; d != NULL; d = d->next)
{
if (d->dup_func == dup_func && d->free_func == free_func && d->clear_free_func == clear_free_func)
return d->data;
@@ -601,15 +598,15 @@ void *EC_GROUP_get_extra_data(const EC_GROUP *group,
}
/* this has 'package' visibility */
-void EC_GROUP_free_extra_data(EC_GROUP *group,
+void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
{
EC_EXTRA_DATA **p;
- if (group == NULL)
+ if (ex_data == NULL)
return;
- for (p = &group->extra_data; *p != NULL; p = &((*p)->next))
+ for (p = ex_data; *p != NULL; p = &((*p)->next))
{
if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
{
@@ -625,15 +622,15 @@ void EC_GROUP_free_extra_data(EC_GROUP *group,
}
/* this has 'package' visibility */
-void EC_GROUP_clear_free_extra_data(EC_GROUP *group,
+void EC_EX_DATA_clear_free_extra_data(EC_EXTRA_DATA **ex_data,
void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
{
EC_EXTRA_DATA **p;
- if (group == NULL)
+ if (ex_data == NULL)
return;
- for (p = &group->extra_data; *p != NULL; p = &((*p)->next))
+ for (p = ex_data; *p != NULL; p = &((*p)->next))
{
if ((*p)->dup_func == dup_func && (*p)->free_func == free_func && (*p)->clear_free_func == clear_free_func)
{
@@ -649,14 +646,14 @@ void EC_GROUP_clear_free_extra_data(EC_GROUP *group,
}
/* this has 'package' visibility */
-void EC_GROUP_free_all_extra_data(EC_GROUP *group)
+void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data)
{
EC_EXTRA_DATA *d;
- if (group == NULL)
+ if (ex_data == NULL)
return;
- d = group->extra_data;
+ d = *ex_data;
while (d)
{
EC_EXTRA_DATA *next = d->next;
@@ -666,18 +663,18 @@ void EC_GROUP_free_all_extra_data(EC_GROUP *group)
d = next;
}
- group->extra_data = NULL;
+ *ex_data = NULL;
}
/* this has 'package' visibility */
-void EC_GROUP_clear_free_all_extra_data(EC_GROUP *group)
+void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data)
{
EC_EXTRA_DATA *d;
- if (group == NULL)
+ if (ex_data == NULL)
return;
- d = group->extra_data;
+ d = *ex_data;
while (d)
{
EC_EXTRA_DATA *next = d->next;
@@ -687,7 +684,7 @@ void EC_GROUP_clear_free_all_extra_data(EC_GROUP *group)
d = next;
}
- group->extra_data = NULL;
+ *ex_data = NULL;
}
diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c
index 101f44a2e0..7320e31c5c 100644
--- a/crypto/ec/ec_mult.c
+++ b/crypto/ec/ec_mult.c
@@ -325,7 +325,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t num, const EC_POINT *points[], const BIGNUM *scalars[], BN_CTX *ctx)
{
BN_CTX *new_ctx = NULL;
- EC_POINT *generator = NULL;
+ const EC_POINT *generator = NULL;
EC_POINT *tmp = NULL;
size_t totalnum;
size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
@@ -385,7 +385,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* look if we can use precomputed multiples of generator */
- pre_comp = EC_GROUP_get_extra_data(group, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
+ pre_comp = EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
if (pre_comp && pre_comp->numblocks && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0))
{
@@ -744,7 +744,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
int ret = 0;
/* if there is an old EC_PRE_COMP object, throw it away */
- EC_GROUP_free_extra_data(group, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
+ EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free);
if ((pre_comp = ec_pre_comp_new(group)) == NULL)
return 0;
@@ -872,7 +872,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
points = NULL;
pre_comp->num = num;
- if (!EC_GROUP_set_extra_data(group, pre_comp,
+ if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp,
ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free))
goto err;
pre_comp = NULL;
@@ -902,7 +902,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
int ec_wNAF_have_precompute_mult(const EC_GROUP *group)
{
- if (EC_GROUP_get_extra_data(group, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
+ if (EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, ec_pre_comp_clear_free) != NULL)
return 1;
else
return 0;
diff --git a/crypto/ecdh/ecdh.h b/crypto/ecdh/ecdh.h
index 98b8bb253c..b4b58ee65b 100644
--- a/crypto/ecdh/ecdh.h
+++ b/crypto/ecdh/ecdh.h
@@ -85,13 +85,6 @@
extern "C" {
#endif
-typedef struct ecdh_data_st ECDH_DATA;
-
-/* ECDH_DATA functions */
-ECDH_DATA *ECDH_DATA_new(void);
-ECDH_DATA *ECDH_DATA_new_method(ENGINE *);
-void ECDH_DATA_free(ECDH_DATA *);
-
const ECDH_METHOD *ECDH_OpenSSL(void);
void ECDH_set_default_method(const ECDH_METHOD *);
diff --git a/crypto/ecdh/ecdhtest.c b/crypto/ecdh/ecdhtest.c
index f4e02966e2..c0414b92d3 100644
--- a/crypto/ecdh/ecdhtest.c
+++ b/crypto/ecdh/ecdhtest.c
@@ -119,9 +119,7 @@ static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen)
}
-int test_ecdh_curve(int , char *, BN_CTX *, BIO *);
-
-int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
+static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out)
{
EC_KEY *a=NULL;
EC_KEY *b=NULL;
@@ -130,12 +128,14 @@ int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
char buf[12];
unsigned char *abuf=NULL,*bbuf=NULL;
int i,alen,blen,aout,bout,ret=0;
+ const EC_GROUP *group;
- if ((a=EC_KEY_new()) == NULL) goto err;
- if ((a->group=EC_GROUP_new_by_curve_name(nid)) == NULL) goto err;
+ a = EC_KEY_new_by_curve_name(nid);
+ b = EC_KEY_new_by_curve_name(nid);
+ if (a == NULL || b == NULL)
+ goto err;
- if ((b=EC_KEY_new()) == NULL) goto err;
- b->group = a->group;
+ group = EC_KEY_get0_group(a);
if ((x_a=BN_new()) == NULL) goto err;
if ((y_a=BN_new()) == NULL) goto err;
@@ -152,13 +152,15 @@ int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
if (!EC_KEY_generate_key(a)) goto err;
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(a->group)) == NID_X9_62_prime_field)
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
{
- if (!EC_POINT_get_affine_coordinates_GFp(a->group, a->pub_key, x_a, y_a, ctx)) goto err;
+ if (!EC_POINT_get_affine_coordinates_GFp(group,
+ EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
}
else
{
- if (!EC_POINT_get_affine_coordinates_GF2m(a->group, a->pub_key, x_a, y_a, ctx)) goto err;
+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
+ EC_KEY_get0_public_key(a), x_a, y_a, ctx)) goto err;
}
#ifdef NOISY
BIO_puts(out," pri 1=");
@@ -175,13 +177,15 @@ int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
if (!EC_KEY_generate_key(b)) goto err;
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(b->group)) == NID_X9_62_prime_field)
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
{
- if (!EC_POINT_get_affine_coordinates_GFp(b->group, b->pub_key, x_b, y_b, ctx)) goto err;
+ if (!EC_POINT_get_affine_coordinates_GFp(group,
+ EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
}
else
{
- if (!EC_POINT_get_affine_coordinates_GF2m(a->group, b->pub_key, x_b, y_b, ctx)) goto err;
+ if (!EC_POINT_get_affine_coordinates_GF2m(group,
+ EC_KEY_get0_public_key(b), x_b, y_b, ctx)) goto err;
}
#ifdef NOISY
@@ -199,7 +203,7 @@ int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
alen=KDF1_SHA1_len;
abuf=(unsigned char *)OPENSSL_malloc(alen);
- aout=ECDH_compute_key(abuf,alen,b->pub_key,a,KDF1_SHA1);
+ aout=ECDH_compute_key(abuf,alen,EC_KEY_get0_public_key(b),a,KDF1_SHA1);
#ifdef NOISY
BIO_puts(out," key1 =");
@@ -216,7 +220,7 @@ int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
blen=KDF1_SHA1_len;
bbuf=(unsigned char *)OPENSSL_malloc(blen);
- bout=ECDH_compute_key(bbuf,blen,a->pub_key,b,KDF1_SHA1);
+ bout=ECDH_compute_key(bbuf,blen,EC_KEY_get0_public_key(a),b,KDF1_SHA1);
#ifdef NOISY
BIO_puts(out," key2 =");
@@ -237,7 +241,7 @@ int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
BIO_printf(out, " failed\n\n");
BIO_printf(out, "key a:\n");
BIO_printf(out, "private key: ");
- BN_print(out, a->priv_key);
+ BN_print(out, EC_KEY_get0_private_key(a));
BIO_printf(out, "\n");
BIO_printf(out, "public key (x,y): ");
BN_print(out, x_a);
@@ -245,7 +249,7 @@ int test_ecdh_curve(int nid, char *text, BN_CTX *ctx, BIO *out)
BN_print(out, y_a);
BIO_printf(out, "\nkey b:\n");
BIO_printf(out, "private key: ");
- BN_print(out, b->priv_key);
+ BN_print(out, EC_KEY_get0_private_key(b));
BIO_printf(out, "\n");
BIO_printf(out, "public key (x,y): ");
BN_print(out, x_b);
@@ -286,8 +290,6 @@ err:
if (y_a) BN_free(y_a);
if (x_b) BN_free(x_b);
if (y_b) BN_free(y_b);
- if (a->group) EC_GROUP_free(a->group);
- a->group = b->group = NULL;
if (b) EC_KEY_free(b);
if (a) EC_KEY_free(a);
return(ret);
diff --git a/crypto/ecdh/ech_lib.c b/crypto/ecdh/ech_lib.c
index a6392bcb3d..85fbfc5cac 100644
--- a/crypto/ecdh/ech_lib.c
+++ b/crypto/ecdh/ech_lib.c
@@ -76,10 +76,11 @@
const char *ECDH_version="ECDH" OPENSSL_VERSION_PTEXT;
-static void ecdh_finish(EC_KEY *);
-
static const ECDH_METHOD *default_ECDH_method = NULL;
+static void *ecdh_data_dup(void *);
+static void ecdh_data_free(void *);
+
void ECDH_set_default_method(const ECDH_METHOD *meth)
{
default_ECDH_method = meth;
@@ -122,12 +123,7 @@ int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth)
return 1;
}
-ECDH_DATA *ECDH_DATA_new(void)
- {
- return ECDH_DATA_new_method(NULL);
- }
-
-ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
+static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
{
ECDH_DATA *ret;
@@ -139,7 +135,6 @@ ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
}
ret->init = NULL;
- ret->finish = ecdh_finish;
ret->meth = ECDH_get_default_method();
ret->engine = engine;
@@ -172,12 +167,26 @@ ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine)
return(ret);
}
-void ECDH_DATA_free(ECDH_DATA *r)
+void *ecdh_data_new(void)
{
-#if 0
- if (r->meth->finish)
- r->meth->finish(r);
-#endif
+ return (void *)ECDH_DATA_new_method(NULL);
+ }
+
+static void *ecdh_data_dup(void *data)
+{
+ ECDH_DATA *r = (ECDH_DATA *)data;
+
+ /* XXX: dummy operation */
+ if (r == NULL)
+ return NULL;
+
+ return (void *)ecdh_data_new();
+}
+
+void ecdh_data_free(void *data)
+ {
+ ECDH_DATA *r = (ECDH_DATA *)data;
+
#ifndef OPENSSL_NO_ENGINE
if (r->engine)
ENGINE_finish(r->engine);
@@ -192,25 +201,24 @@ void ECDH_DATA_free(ECDH_DATA *r)
ECDH_DATA *ecdh_check(EC_KEY *key)
{
- if (key->meth_data)
- {
- if (key->meth_data->finish != ecdh_finish)
- {
- key->meth_data->finish(key);
- key->meth_data = (EC_KEY_METH_DATA *)ECDH_DATA_new();
- }
- }
- else
- key->meth_data = (EC_KEY_METH_DATA *)ECDH_DATA_new();
- return (ECDH_DATA *)key->meth_data;
- }
-
-static void ecdh_finish(EC_KEY *key)
+ ECDH_DATA *ecdh_data;
+
+ void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup,
+ ecdh_data_free, ecdh_data_free);
+ if (data == NULL)
{
- if (key->meth_data && key->meth_data->finish == ecdh_finish)
- ECDH_DATA_free((ECDH_DATA *)key->meth_data);
+ ecdh_data = (ECDH_DATA *)ecdh_data_new();
+ if (ecdh_data == NULL)
+ return NULL;
+ EC_KEY_insert_key_method_data(key, (void *)ecdh_data,
+ ecdh_data_dup, ecdh_data_free, ecdh_data_free);
}
+ else
+ ecdh_data = (ECDH_DATA *)data;
+
+ return ecdh_data;
+ }
int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
diff --git a/crypto/ecdh/ech_locl.h b/crypto/ecdh/ech_locl.h
index 1a2db43b8a..f658526a7e 100644
--- a/crypto/ecdh/ech_locl.h
+++ b/crypto/ecdh/ech_locl.h
@@ -75,16 +75,15 @@ struct ecdh_method
char *app_data;
};
-struct ecdh_data_st {
+typedef struct ecdh_data_st {
/* EC_KEY_METH_DATA part */
int (*init)(EC_KEY *);
- void (*finish)(EC_KEY *);
/* method specific part */
ENGINE *engine;
int flags;
const ECDH_METHOD *meth;
CRYPTO_EX_DATA ex_data;
-};
+} ECDH_DATA;
ECDH_DATA *ecdh_check(EC_KEY *);
diff --git a/crypto/ecdh/ech_ossl.c b/crypto/ecdh/ech_ossl.c
index dab7e8eab8..2a40ff12df 100644
--- a/crypto/ecdh/ech_ossl.c
+++ b/crypto/ecdh/ech_ossl.c
@@ -112,6 +112,8 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
BN_CTX *ctx;
EC_POINT *tmp=NULL;
BIGNUM *x=NULL, *y=NULL;
+ const BIGNUM *priv_key;
+ const EC_GROUP* group;
int ret= -1;
size_t buflen, len;
unsigned char *buf=NULL;
@@ -127,27 +129,29 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
- if (ecdh->priv_key == NULL)
+ priv_key = EC_KEY_get0_private_key(ecdh);
+ if (priv_key == NULL)
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
goto err;
}
- if ((tmp=EC_POINT_new(ecdh->group)) == NULL)
+ group = EC_KEY_get0_group(ecdh);
+ if ((tmp=EC_POINT_new(group)) == NULL)
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!EC_POINT_mul(ecdh->group, tmp, NULL, pub_key, ecdh->priv_key, ctx))
+ if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx))
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecdh->group)) == NID_X9_62_prime_field)
+ if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
{
- if (!EC_POINT_get_affine_coordinates_GFp(ecdh->group, tmp, x, y, ctx))
+ if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx))
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
@@ -155,14 +159,14 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
}
else
{
- if (!EC_POINT_get_affine_coordinates_GF2m(ecdh->group, tmp, x, y, ctx))
+ if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx))
{
ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
}
- buflen = (EC_GROUP_get_degree(ecdh->group) + 7)/8;
+ buflen = (EC_GROUP_get_degree(group) + 7)/8;
len = BN_num_bytes(x);
if (len > buflen)
{
diff --git a/crypto/ecdsa/ecdsa.h b/crypto/ecdsa/ecdsa.h
index 14bb363389..76c5a4aa2a 100644
--- a/crypto/ecdsa/ecdsa.h
+++ b/crypto/ecdsa/ecdsa.h
@@ -81,9 +81,6 @@ typedef struct ECDSA_SIG_st
BIGNUM *s;
} ECDSA_SIG;
-/* ecdsa_data_st is defined in ecs_locl.h */
-typedef struct ecdsa_data_st ECDSA_DATA;
-
/** ECDSA_SIG *ECDSA_SIG_new(void)
* allocates and initialize a ECDSA_SIG structure
* \return pointer to a ECDSA_SIG structure or NULL if an error occurred
@@ -115,25 +112,6 @@ int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp);
*/
ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len);
-/** ECDSA_DATA_new
- * creates a new ECDSA_DATA object
- * \return pointer to a newly allocated (and initialized) ECDSA_DATA object
- */
-ECDSA_DATA *ECDSA_DATA_new(void);
-
-/** ECDSA_DATA_new_method
- * creates a new ECDSA_DATA object using a specified ENGINE
- * \param eng pointer to a ENGINE structure
- * \return pointer to a newly allocated (and initialized) ECDSA_DATA object
- */
-ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *eng);
-
-/** ECDSA_DATA_free
- * frees ECDSA_DATA structure
- * \param data pointer to a ECDSA_DATA structure
- */
-void ECDSA_DATA_free(ECDSA_DATA *data);
-
/** ECDSA_do_sign
* computes the ECDSA signature of the given hash value using
* the supplied private key and returns the created signature.
@@ -144,6 +122,20 @@ void ECDSA_DATA_free(ECDSA_DATA *data);
*/
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
+/** ECDSA_do_sign_ex
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param kinv optional pointer to a pre-computed inverse k
+ * \param rp optional pointer to the pre-computed rp value (see
+ * ECDSA_sign_setup
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL
+ */
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen,
+ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
+
/** ECDSA_do_verify
* verifies that the supplied signature is a valid ECDSA
* signature of the supplied hash value using the supplied public key.
@@ -186,9 +178,7 @@ int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
int ECDSA_size(const EC_KEY *eckey);
/** ECDSA_sign_setup
- * precompute parts of the signing operation (the computed values may be
- * passed to ECDSA_DATA->kinv and ECDSA_DATA->r for a later signature
- * computation).
+ * precompute parts of the signing operation.
* \param eckey pointer to the EC_KEY object containing a private EC key
* \param ctx pointer to a BN_CTX object (may be NULL)
* \param kinv pointer to a BIGNUM pointer for the inverse of k
@@ -212,6 +202,25 @@ int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen,
unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
+
+/** ECDSA_sign_ex
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param sig buffer to hold the DER encoded signature
+ * \param siglen pointer to the length of the returned signature
+ * \param kinv optional pointer to a pre-computed inverse k
+ * \param rp optional pointer to the pre-computed rp value (see
+ * ECDSA_sign_setup
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return 1 on success and 0 otherwise
+ */
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen,
+ unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
+ const BIGNUM *rp, EC_KEY *eckey);
+
/** ECDSA_verify
* verifies that the given signature is valid ECDSA signature
* of the supplied hash value using the specified public key.
diff --git a/crypto/ecdsa/ecdsatest.c b/crypto/ecdsa/ecdsatest.c
index 5315d90dd2..70f2cc4e8e 100644
--- a/crypto/ecdsa/ecdsatest.c
+++ b/crypto/ecdsa/ecdsatest.c
@@ -3,7 +3,7 @@
* Written by Nils Larsch for the OpenSSL project.
*/
/* ====================================================================
- * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -201,9 +201,7 @@ int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in)
BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid));
/* create the key */
- if ((key = EC_KEY_new()) == NULL)
- goto x962_int_err;
- if ((key->group = EC_GROUP_new_by_curve_name(nid)) == NULL)
+ if ((key = EC_KEY_new_by_curve_name(nid)) == NULL)
goto x962_int_err;
if (!EC_KEY_generate_key(key))
goto x962_int_err;
@@ -291,6 +289,7 @@ int test_builtin(BIO *out)
EC_builtin_curve *curves = NULL;
size_t crv_len = 0, n = 0;
EC_KEY *eckey = NULL, *wrong_eckey = NULL;
+ EC_GROUP *group;
unsigned char digest[20], wrong_digest[20];
unsigned char *signature = NULL;
unsigned int sig_len;
@@ -337,9 +336,13 @@ int test_builtin(BIO *out)
/* create new ecdsa key (== EC_KEY) */
if ((eckey = EC_KEY_new()) == NULL)
goto builtin_err;
- if ((eckey->group = EC_GROUP_new_by_curve_name(nid)) == NULL)
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (group == NULL)
+ goto builtin_err;
+ if (EC_KEY_set_group(eckey, group) == 0)
goto builtin_err;
- if (EC_GROUP_get_degree(eckey->group) < 160)
+ EC_GROUP_free(group);
+ if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160)
/* drop the curve */
{
EC_KEY_free(eckey);
@@ -356,8 +359,12 @@ int test_builtin(BIO *out)
/* create second key */
if ((wrong_eckey = EC_KEY_new()) == NULL)
goto builtin_err;
- if ((wrong_eckey->group = EC_GROUP_new_by_curve_name(nid)) == NULL)
+ group = EC_GROUP_new_by_curve_name(nid);
+ if (group == NULL)
+ goto builtin_err;
+ if (EC_KEY_set_group(wrong_eckey, group) == 0)
goto builtin_err;
+ EC_GROUP_free(group);
if (!EC_KEY_generate_key(wrong_eckey))
{
BIO_printf(out, " failed\n");
diff --git a/crypto/ecdsa/ecs_lib.c b/crypto/ecdsa/ecs_lib.c
index 645a7087c8..8a6d4ad45d 100644
--- a/crypto/ecdsa/ecs_lib.c
+++ b/crypto/ecdsa/ecs_lib.c
@@ -1,6 +1,6 @@
/* crypto/ecdsa/ecs_lib.c */
/* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -63,10 +63,11 @@
const char *ECDSA_version="ECDSA" OPENSSL_VERSION_PTEXT;
-static void ecdsa_finish(EC_KEY *);
-
static const ECDSA_METHOD *default_ECDSA_method = NULL;
+static void *ecdsa_data_dup(void *);
+static void ecdsa_data_free(void *);
+
void ECDSA_set_default_method(const ECDSA_METHOD *meth)
{
default_ECDSA_method = meth;
@@ -90,10 +91,6 @@ int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
return 0;
mtmp = ecdsa->meth;
-#if 0
- if (mtmp->finish)
- mtmp->finish(eckey);
-#endif
#ifndef OPENSSL_NO_ENGINE
if (ecdsa->engine)
{
@@ -102,19 +99,11 @@ int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth)
}
#endif
ecdsa->meth = meth;
-#if 0
- if (meth->init)
- meth->init(eckey);
-#endif
- return 1;
-}
-ECDSA_DATA *ECDSA_DATA_new(void)
-{
- return ECDSA_DATA_new_method(NULL);
+ return 1;
}
-ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
+static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
{
ECDSA_DATA *ret;
@@ -126,10 +115,6 @@ ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
}
ret->init = NULL;
- ret->finish = ecdsa_finish;
-
- ret->kinv = NULL;
- ret->r = NULL;
ret->meth = ECDSA_get_default_method();
ret->engine = engine;
@@ -162,22 +147,30 @@ ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine)
return(ret);
}
-void ECDSA_DATA_free(ECDSA_DATA *r)
+void *ecdsa_data_new(void)
{
- if (r->kinv)
- BN_clear_free(r->kinv);
- if (r->r)
- BN_clear_free(r->r);
+ 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;
-#if 0
- if (r->meth->finish)
- r->meth->finish(r);
-#endif
#ifndef OPENSSL_NO_ENGINE
if (r->engine)
ENGINE_finish(r->engine);
#endif
-
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data);
OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA));
@@ -187,23 +180,23 @@ void ECDSA_DATA_free(ECDSA_DATA *r)
ECDSA_DATA *ecdsa_check(EC_KEY *key)
{
- if (key->meth_data)
+ 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)
{
- if (key->meth_data->finish != ecdsa_finish)
- {
- key->meth_data->finish(key);
- key->meth_data = (EC_KEY_METH_DATA *)ECDSA_DATA_new();
- }
+ ecdsa_data = (ECDSA_DATA *)ecdsa_data_new();
+ if (ecdsa_data == NULL)
+ return NULL;
+ EC_KEY_insert_key_method_data(key, (void *)ecdsa_data,
+ ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free);
}
else
- key->meth_data = (EC_KEY_METH_DATA *)ECDSA_DATA_new();
- return (ECDSA_DATA *)key->meth_data;
-}
+ ecdsa_data = (ECDSA_DATA *)data;
+
-static void ecdsa_finish(EC_KEY *key)
-{
- if (key->meth_data && key->meth_data->finish == ecdsa_finish)
- ECDSA_DATA_free((ECDSA_DATA *)key->meth_data);
+ return ecdsa_data;
}
int ECDSA_size(const EC_KEY *r)
@@ -212,11 +205,12 @@ int ECDSA_size(const EC_KEY *r)
ASN1_INTEGER bs;
BIGNUM *order=NULL;
unsigned char buf[4];
+ const EC_GROUP *group = EC_KEY_get0_group(r);
- if (r == NULL || r->group == NULL)
+ if (r == NULL || group == NULL)
return 0;
if ((order = BN_new()) == NULL) return 0;
- if (!EC_GROUP_get_order(r->group,order,NULL))
+ if (!EC_GROUP_get_order(group,order,NULL))
{
BN_clear_free(order);
return 0;
diff --git a/crypto/ecdsa/ecs_locl.h b/crypto/ecdsa/ecs_locl.h
index 343b866249..3a69a840e2 100644
--- a/crypto/ecdsa/ecs_locl.h
+++ b/crypto/ecdsa/ecs_locl.h
@@ -69,7 +69,7 @@ struct ecdsa_method
{
const char *name;
ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len,
- EC_KEY *eckey);
+ const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey);
int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv,
BIGNUM **r);
int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len,
@@ -82,18 +82,15 @@ struct ecdsa_method
char *app_data;
};
-struct ecdsa_data_st {
+typedef struct ecdsa_data_st {
/* EC_KEY_METH_DATA part */
int (*init)(EC_KEY *);
- void (*finish)(EC_KEY *);
/* method (ECDSA) specific part */
- BIGNUM *kinv; /* signing pre-calc */
- BIGNUM *r; /* signing pre-calc */
ENGINE *engine;
int flags;
const ECDSA_METHOD *meth;
CRYPTO_EX_DATA ex_data;
-};
+} ECDSA_DATA;
/** ecdsa_check
* checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure
diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c
index ea776db8d8..8be45ddc93 100644
--- a/crypto/ecdsa/ecs_ossl.c
+++ b/crypto/ecdsa/ecs_ossl.c
@@ -62,7 +62,7 @@
#include <openssl/bn.h>
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
- EC_KEY *eckey);
+ 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,
@@ -92,14 +92,14 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BN_CTX *ctx = NULL;
BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
EC_POINT *tmp_point=NULL;
- EC_GROUP *group;
+ const EC_GROUP *group;
int ret = 0;
- if (!eckey || !eckey->group || !eckey->pub_key || !eckey->priv_key)
+
+ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- group = eckey->group;
if (ctx_in == NULL)
{
@@ -210,24 +210,27 @@ err:
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
- EC_KEY *eckey)
+ const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
{
int ok = 0;
- BIGNUM *kinv=NULL, *r, *s, *m=NULL,*tmp=NULL,*order=NULL;
+ BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
+ const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
- EC_GROUP *group;
+ const EC_GROUP *group;
ECDSA_SIG *ret;
ECDSA_DATA *ecdsa;
+ const BIGNUM *priv_key;
- ecdsa = ecdsa_check(eckey);
-
- if (!eckey->group || !eckey->pub_key || !eckey->priv_key || !ecdsa)
+ 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)
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
- group = eckey->group;
ret = ECDSA_SIG_new();
if (!ret)
{
@@ -262,26 +265,26 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
}
do
{
- if (ecdsa->kinv == NULL || ecdsa->r == NULL)
+ if (in_kinv == NULL || in_r == NULL)
{
if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
goto err;
}
- r = ret->r;
+ ckinv = kinv;
}
else
{
- BN_free(ret->r);
- kinv = ecdsa->kinv;
- r = ecdsa->r;
- ret->r = r;
- ecdsa->kinv = NULL;
- ecdsa->r = NULL;
+ ckinv = in_kinv;
+ if (BN_copy(ret->r, in_r) == NULL)
+ {
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
}
- if (!BN_mod_mul(tmp, eckey->priv_key, r, order, ctx))
+ if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
@@ -291,7 +294,7 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
- if (!BN_mod_mul(s, s, kinv, order, ctx))
+ if (!BN_mod_mul(s, s, ckinv, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
@@ -326,16 +329,17 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
BN_CTX *ctx;
BIGNUM *order, *u1, *u2, *m, *X;
EC_POINT *point = NULL;
- EC_GROUP *group;
+ const EC_GROUP *group;
+ const EC_POINT *pub_key;
+
/* check input values */
- if (!eckey || !eckey->group || !eckey->pub_key || !sig)
+ if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
+ (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
return -1;
}
- group = eckey->group;
-
ctx = BN_CTX_new();
if (!ctx)
{
@@ -398,7 +402,7 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (!EC_POINT_mul(group, point, u1, eckey->pub_key, u2, ctx))
+ if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
diff --git a/crypto/ecdsa/ecs_sign.c b/crypto/ecdsa/ecs_sign.c
index ee6aef8010..5143923050 100644
--- a/crypto/ecdsa/ecs_sign.c
+++ b/crypto/ecdsa/ecs_sign.c
@@ -58,27 +58,40 @@
#include <openssl/engine.h>
#endif
-ECDSA_SIG * ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
+{
+ return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey);
+}
+
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen,
+ const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey)
{
ECDSA_DATA *ecdsa = ecdsa_check(eckey);
if (ecdsa == NULL)
return NULL;
- return ecdsa->meth->ecdsa_do_sign(dgst, dlen, eckey);
+ return ecdsa->meth->ecdsa_do_sign(dgst, dlen, NULL, NULL, eckey);
}
int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char
*sig, unsigned int *siglen, EC_KEY *eckey)
{
+ return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey);
+}
+
+int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
+ *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r,
+ EC_KEY *eckey)
+{
ECDSA_SIG *s;
- s=ECDSA_do_sign(dgst,dlen,eckey);
+ s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
if (s == NULL)
{
*siglen=0;
- return(0);
+ return 0;
}
- *siglen=i2d_ECDSA_SIG(s,&sig);
+ *siglen = i2d_ECDSA_SIG(s, &sig);
ECDSA_SIG_free(s);
- return(1);
+ return 1;
}
int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index 4d38425b03..e35d472c70 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -140,7 +140,7 @@ struct evp_pkey_st
struct dh_st *dh; /* DH */
#endif
#ifndef OPENSSL_NO_EC
- struct ec_key_st *eckey;/* ECC */
+ struct ec_key_st *ec; /* ECC */
#endif
} pkey;
int save_parameters;
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index 6510ed54dc..b71555e712 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -250,6 +250,7 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
}
else
{
+ EC_GROUP *group;
cp = p = param->value.object->data;
plen = param->value.object->length;
@@ -262,11 +263,13 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
ERR_R_MALLOC_FAILURE);
goto ecerr;
}
- if ((eckey->group = EC_GROUP_new_by_curve_name(
- OBJ_obj2nid(a->parameter->value.object))) == NULL)
+ group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(a->parameter->value.object));
+ if (group == NULL)
goto ecerr;
- EC_GROUP_set_asn1_flag(eckey->group,
- OPENSSL_EC_NAMED_CURVE);
+ EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+ if (EC_KEY_set_group(eckey, group) == 0)
+ goto ecerr;
+ EC_GROUP_free(group);
}
/* We have parameters now set private key */
@@ -277,28 +280,40 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
}
/* calculate public key (if necessary) */
- if (!eckey->pub_key)
+ if (EC_KEY_get0_public_key(eckey) == NULL)
{
+ const BIGNUM *priv_key;
+ const EC_GROUP *group;
+ EC_POINT *pub_key;
/* the public key was not included in the SEC1 private
* key => calculate the public key */
- eckey->pub_key = EC_POINT_new(eckey->group);
- if (!eckey->pub_key)
+ group = EC_KEY_get0_group(eckey);
+ pub_key = EC_POINT_new(group);
+ if (pub_key == NULL)
+ {
+ EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
+ goto ecerr;
+ }
+ if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group)))
{
+ EC_POINT_free(pub_key);
EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
goto ecerr;
}
- if (!EC_POINT_copy(eckey->pub_key,
- EC_GROUP_get0_generator(eckey->group)))
+ priv_key = EC_KEY_get0_private_key(eckey);
+ if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
{
+ EC_POINT_free(pub_key);
EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
goto ecerr;
}
- if (!EC_POINT_mul(eckey->group, eckey->pub_key,
- eckey->priv_key, NULL, NULL, ctx))
+ if (EC_KEY_set_public_key(eckey, pub_key) == 0)
{
+ EC_POINT_free(pub_key);
EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_EC_LIB);
goto ecerr;
}
+ EC_POINT_free(pub_key);
}
EVP_PKEY_assign_EC_KEY(pkey, eckey);
@@ -583,17 +598,18 @@ err:
#ifndef OPENSSL_NO_EC
static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
- EC_KEY *eckey;
+ EC_KEY *ec_key;
+ const EC_GROUP *group;
unsigned char *p, *pp;
int nid, i, ret = 0;
- unsigned int tmp_flags;
+ unsigned int tmp_flags, old_flags;
- if (pkey->pkey.eckey == NULL || pkey->pkey.eckey->group == NULL)
+ ec_key = pkey->pkey.ec;
+ if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL)
{
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, EVP_R_MISSING_PARAMETERS);
return 0;
}
- eckey = pkey->pkey.eckey;
/* set the ec parameters OID */
if (p8->pkeyalg->algorithm)
@@ -615,8 +631,8 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
return 0;
}
- if (EC_GROUP_get_asn1_flag(eckey->group)
- && (nid = EC_GROUP_get_curve_name(eckey->group)))
+ if (EC_GROUP_get_asn1_flag(group)
+ && (nid = EC_GROUP_get_curve_name(group)))
{
/* we have a 'named curve' => just set the OID */
p8->pkeyalg->parameter->type = V_ASN1_OBJECT;
@@ -624,7 +640,7 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
}
else /* explicit parameters */
{
- if ((i = i2d_ECParameters(eckey, NULL)) == 0)
+ if ((i = i2d_ECParameters(ec_key, NULL)) == 0)
{
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
return 0;
@@ -635,7 +651,7 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
return 0;
}
pp = p;
- if (!i2d_ECParameters(eckey, &pp))
+ if (!i2d_ECParameters(ec_key, &pp))
{
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
OPENSSL_free(p);
@@ -657,32 +673,33 @@ static int eckey_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
/* do not include the parameters in the SEC1 private key
* see PKCS#11 12.11 */
- tmp_flags = pkey->pkey.eckey->enc_flag;
- pkey->pkey.eckey->enc_flag |= EC_PKEY_NO_PARAMETERS;
- i = i2d_ECPrivateKey(pkey->pkey.eckey, NULL);
+ old_flags = EC_KEY_get_enc_flags(pkey->pkey.ec);
+ tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
+ EC_KEY_set_enc_flags(pkey->pkey.ec, tmp_flags);
+ i = i2d_ECPrivateKey(pkey->pkey.ec, NULL);
if (!i)
{
- pkey->pkey.eckey->enc_flag = tmp_flags;
+ EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
return 0;
}
p = (unsigned char *) OPENSSL_malloc(i);
if (!p)
{
- pkey->pkey.eckey->enc_flag = tmp_flags;
+ EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
return 0;
}
pp = p;
- if (!i2d_ECPrivateKey(pkey->pkey.eckey, &pp))
+ if (!i2d_ECPrivateKey(pkey->pkey.ec, &pp))
{
- pkey->pkey.eckey->enc_flag = tmp_flags;
+ EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
EVPerr(EVP_F_ECKEY_PKEY2PKCS8, ERR_R_EC_LIB);
OPENSSL_free(p);
return 0;
}
/* restore old encoding flags */
- pkey->pkey.eckey->enc_flag = tmp_flags;
+ EC_KEY_set_enc_flags(pkey->pkey.ec, old_flags);
switch(p8->broken) {
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 85caa478ca..04b57e8251 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -86,6 +86,7 @@ int EVP_PKEY_bits(EVP_PKEY *pkey)
else if (pkey->type == EVP_PKEY_EC)
{
BIGNUM *order = BN_new();
+ const EC_GROUP *group;
int ret;
if (!order)
@@ -93,7 +94,8 @@ int EVP_PKEY_bits(EVP_PKEY *pkey)
ERR_clear_error();
return 0;
}
- if (!EC_GROUP_get_order(pkey->pkey.eckey->group, order, NULL))
+ group = EC_KEY_get0_group(pkey->pkey.ec);
+ if (!EC_GROUP_get_order(group, order, NULL))
{
ERR_clear_error();
return 0;
@@ -122,7 +124,7 @@ int EVP_PKEY_size(EVP_PKEY *pkey)
#endif
#ifndef OPENSSL_NO_ECDSA
if (pkey->type == EVP_PKEY_EC)
- return(ECDSA_size(pkey->pkey.eckey));
+ return(ECDSA_size(pkey->pkey.ec));
#endif
return(0);
@@ -187,13 +189,12 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
#ifndef OPENSSL_NO_EC
if (to->type == EVP_PKEY_EC)
{
- if (to->pkey.eckey->group != NULL)
- EC_GROUP_free(to->pkey.eckey->group);
- if ((to->pkey.eckey->group = EC_GROUP_new(
- EC_GROUP_method_of(from->pkey.eckey->group))) == NULL)
+ EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec));
+ if (group == NULL)
goto err;
- if (!EC_GROUP_copy(to->pkey.eckey->group,
- from->pkey.eckey->group)) goto err;
+ if (EC_KEY_set_group(to->pkey.ec, group) == 0)
+ goto err;
+ EC_GROUP_free(group);
}
#endif
return(1);
@@ -216,7 +217,7 @@ int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey)
#ifndef OPENSSL_NO_EC
if (pkey->type == EVP_PKEY_EC)
{
- if (pkey->pkey.eckey->group == NULL)
+ if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
return(1);
}
#endif
@@ -240,7 +241,9 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
#ifndef OPENSSL_NO_EC
if (a->type == EVP_PKEY_EC && b->type == EVP_PKEY_EC)
{
- if (EC_GROUP_cmp(a->pkey.eckey->group, b->pkey.eckey->group, NULL))
+ const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
+ *group_b = EC_KEY_get0_group(b->pkey.ec);
+ if (EC_GROUP_cmp(group_a, group_b, NULL))
return 0;
else
return 1;
@@ -275,8 +278,11 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
{
- int r = EC_POINT_cmp(b->pkey.eckey->group,
- b->pkey.eckey->pub_key,a->pkey.eckey->pub_key,NULL);
+ int r;
+ const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
+ const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
+ *pb = EC_KEY_get0_public_key(b->pkey.ec);
+ r = EC_POINT_cmp(group, pa, pb, NULL);
if (r != 0)
{
if (r == 1)
@@ -372,8 +378,9 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
{
int ret = EVP_PKEY_assign_EC_KEY(pkey,key);
- if (ret) CRYPTO_add(&key->references, 1, CRYPTO_LOCK_EC);
- return ret;
+ if (ret)
+ EC_KEY_up_ref(key);
+ return ret;
}
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
@@ -383,8 +390,8 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey)
EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
return NULL;
}
- CRYPTO_add(&pkey->pkey.eckey->references, 1, CRYPTO_LOCK_EC);
- return pkey->pkey.eckey;
+ EC_KEY_up_ref(pkey->pkey.ec);
+ return pkey->pkey.ec;
}
#endif
@@ -476,7 +483,7 @@ static void EVP_PKEY_free_it(EVP_PKEY *x)
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
- EC_KEY_free(x->pkey.eckey);
+ EC_KEY_free(x->pkey.ec);
break;
#endif
#ifndef OPENSSL_NO_DH
diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c
index c8980bb56f..489e71a892 100644
--- a/crypto/pem/pem_info.c
+++ b/crypto/pem/pem_info.c
@@ -225,7 +225,7 @@ start:
if ((xi->x_pkey->dec_pkey=EVP_PKEY_new()) == NULL)
goto err;
xi->x_pkey->dec_pkey->type=EVP_PKEY_EC;
- pp=&(xi->x_pkey->dec_pkey->pkey.eckey);
+ pp=&(xi->x_pkey->dec_pkey->pkey.ec);
if ((int)strlen(header) > 10) /* assume encrypted */
raw=1;
}