diff options
author | Nils Larsch <nils@openssl.org> | 2005-05-16 10:11:04 +0000 |
---|---|---|
committer | Nils Larsch <nils@openssl.org> | 2005-05-16 10:11:04 +0000 |
commit | 9dd84053419aa220b5e66a5f9fcf809dbd6d9369 (patch) | |
tree | 7818c598a88a5b457333fd9f5951836fe96834b6 /crypto | |
parent | 46a643763de6d8e39ecf6f76fa79b4d04885aa59 (diff) |
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.c | 2 | ||||
-rw-r--r-- | crypto/asn1/d2i_pu.c | 2 | ||||
-rw-r--r-- | crypto/asn1/i2d_pr.c | 2 | ||||
-rw-r--r-- | crypto/asn1/i2d_pu.c | 2 | ||||
-rw-r--r-- | crypto/asn1/t_pkey.c | 36 | ||||
-rw-r--r-- | crypto/asn1/t_req.c | 2 | ||||
-rw-r--r-- | crypto/asn1/t_spki.c | 2 | ||||
-rw-r--r-- | crypto/asn1/t_x509.c | 2 | ||||
-rw-r--r-- | crypto/asn1/x_pubkey.c | 42 | ||||
-rw-r--r-- | crypto/ec/ec.h | 43 | ||||
-rw-r--r-- | crypto/ec/ec_key.c | 126 | ||||
-rw-r--r-- | crypto/ec/ec_lcl.h | 29 | ||||
-rw-r--r-- | crypto/ec/ec_lib.c | 57 | ||||
-rw-r--r-- | crypto/ec/ec_mult.c | 10 | ||||
-rw-r--r-- | crypto/ecdh/ecdh.h | 7 | ||||
-rw-r--r-- | crypto/ecdh/ecdhtest.c | 40 | ||||
-rw-r--r-- | crypto/ecdh/ech_lib.c | 68 | ||||
-rw-r--r-- | crypto/ecdh/ech_locl.h | 5 | ||||
-rw-r--r-- | crypto/ecdh/ech_ossl.c | 18 | ||||
-rw-r--r-- | crypto/ecdsa/ecdsa.h | 59 | ||||
-rw-r--r-- | crypto/ecdsa/ecdsatest.c | 21 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_lib.c | 86 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_locl.h | 9 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_ossl.c | 56 | ||||
-rw-r--r-- | crypto/ecdsa/ecs_sign.c | 25 | ||||
-rw-r--r-- | crypto/evp/evp.h | 2 | ||||
-rw-r--r-- | crypto/evp/evp_pkey.c | 71 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 41 | ||||
-rw-r--r-- | crypto/pem/pem_info.c | 2 |
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) |