summaryrefslogtreecommitdiffstats
path: root/crypto/ec
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2002-08-07 10:49:54 +0000
committerBodo Möller <bodo@openssl.org>2002-08-07 10:49:54 +0000
commit14a7cfb32a0347a4bc620ae1b552b21c4c1e270b (patch)
tree13c4bcc3d58ba7db5e598cd668670873b51e8ce3 /crypto/ec
parent7a8645d1716d7f84435b0f3d8d2fd122d6f75113 (diff)
use a generic EC_KEY structure (EC keys are not ECDSA specific)
Submitted by: Nils Larsch
Diffstat (limited to 'crypto/ec')
-rw-r--r--crypto/ec/Makefile.ssl16
-rw-r--r--crypto/ec/ec.h102
-rw-r--r--crypto/ec/ec_asn1.c393
-rw-r--r--crypto/ec/ec_err.c23
-rw-r--r--crypto/ec/ec_key.c354
5 files changed, 803 insertions, 85 deletions
diff --git a/crypto/ec/Makefile.ssl b/crypto/ec/Makefile.ssl
index fbc80ff05e..d183f679c4 100644
--- a/crypto/ec/Makefile.ssl
+++ b/crypto/ec/Makefile.ssl
@@ -23,12 +23,12 @@ TEST=ectest.c
APPS=
LIB=$(TOP)/libcrypto.a
-LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_recp.c ecp_nist.c ec_cvt.c ec_mult.c \
- ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c \
+LIBSRC= ec_lib.c ecp_smpl.c ecp_mont.c ecp_recp.c ecp_nist.c ec_cvt.c ec_mult.c\
+ ec_err.c ec_curve.c ec_check.c ec_print.c ec_asn1.c ec_key.c\
ec2_smpl.c ec2_smpt.c ec2_mult.c
-LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_recp.o ecp_nist.o ec_cvt.o ec_mult.o \
- ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o \
+LIBOBJ= ec_lib.o ecp_smpl.o ecp_mont.o ecp_recp.o ecp_nist.o ec_cvt.o ec_mult.o\
+ ec_err.o ec_curve.o ec_check.o ec_print.o ec_asn1.o ec_key.o\
ec2_smpl.o ec2_mult.o
SRC= $(LIBSRC)
@@ -142,6 +142,14 @@ ec_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
ec_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h
ec_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
ec_err.o: ec_err.c
+ec_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+ec_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+ec_key.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
+ec_key.o: ../../include/openssl/err.h ../../include/openssl/lhash.h
+ec_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/opensslconf.h
+ec_key.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+ec_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+ec_key.o: ../../include/openssl/symhacks.h ec_key.c ec_lcl.h
ec_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
ec_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
ec_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h
index ff9af9f8e4..4a1787f0b7 100644
--- a/crypto/ec/ec.h
+++ b/crypto/ec/ec.h
@@ -334,21 +334,8 @@ int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
/* ASN1 stuff */
#define OPENSSL_EC_NAMED_CURVE 0x001
-typedef struct ec_parameters_st ECPARAMETERS;
typedef struct ecpk_parameters_st ECPKPARAMETERS;
-DECLARE_ASN1_ITEM(ECPARAMETERS)
-DECLARE_ASN1_ITEM(ECPKPARAMETERS)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPARAMETERS, ECPARAMETERS)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
-
-EC_GROUP *EC_ASN1_pkparameters2group(const ECPKPARAMETERS *);
-ECPKPARAMETERS *EC_ASN1_group2pkparameters(const EC_GROUP *, ECPKPARAMETERS *);
-
-
-EC_GROUP *d2i_ECParameters(EC_GROUP **, const unsigned char **in, long len);
-int i2d_ECParameters(const EC_GROUP *, unsigned char **out);
-
EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
@@ -368,18 +355,65 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
#endif
-/* SEC1 ECPrivateKey */
-typedef struct ec_privatekey_st {
- int version;
- ASN1_OCTET_STRING *privateKey;
- ECPKPARAMETERS *parameters;
- ASN1_BIT_STRING *publicKey;
- } EC_PRIVATEKEY;
+/* 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;
-DECLARE_ASN1_ITEM(EC_PRIVATEKEY)
-DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
+ 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);
+void EC_KEY_free(EC_KEY *);
+EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
+EC_KEY *EC_KEY_dup(const EC_KEY *);
+
+/* EC_KEY_generate_key() creates a ec private (public) key */
+int EC_KEY_generate_key(EC_KEY *);
+/* EC_KEY_check_key() */
+int EC_KEY_check_key(const EC_KEY *);
+
+/* de- and encode functions for the SEC1 ECPrivateKey */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len);
+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out);
+/* de- and encode functions for the elliptic curve parameters */
+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len);
+int i2d_ECParameters(EC_KEY *a, unsigned char **out);
+
+EC_KEY *ECPublicKey_set_octet_string(EC_KEY **a, const unsigned char **in,
+ long len);
+int ECPublicKey_get_octet_string(EC_KEY *a, unsigned char **out);
+
+#ifndef OPENSSL_NO_BIO
+int ECParameters_print(BIO *bp, const EC_KEY *x);
+int EC_KEY_print(BIO *bp, const EC_KEY *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int ECParameters_print_fp(FILE *fp, const EC_KEY *x);
+int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
+#endif
+#define ECParameters_dup(x) (EC_KEY *)ASN1_dup((int (*)())i2d_ECParameters,\
+ (char *(*)())d2i_ECParameters,(char *)(x))
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -391,11 +425,15 @@ void ERR_load_EC_strings(void);
/* Function codes. */
#define EC_F_COMPUTE_WNAF 143
-#define EC_F_D2I_ECDSAPARAMETERS 154
#define EC_F_D2I_ECPARAMETERS 155
#define EC_F_D2I_ECPKPARAMETERS 161
+#define EC_F_D2I_ECPRIVATEKEY 168
+#define EC_F_ECPARAMETERS_PRINT 173
+#define EC_F_ECPARAMETERS_PRINT_FP 174
#define EC_F_ECPKPARAMETERS_PRINT 166
#define EC_F_ECPKPARAMETERS_PRINT_FP 167
+#define EC_F_ECPUBLICKEY_GET_OCTET 170
+#define EC_F_ECPUBLICKEY_SET_OCTET 171
#define EC_F_EC_ASN1_GROUP2CURVE 159
#define EC_F_EC_ASN1_GROUP2FIELDID 156
#define EC_F_EC_ASN1_GROUP2PARAMETERS 160
@@ -419,9 +457,9 @@ void ERR_load_EC_strings(void);
#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103
#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104
#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137
-#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 105
-#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 128
-#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 129
+#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 105
+#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 128
+#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 129
#define EC_F_EC_GROUP_CHECK 150
#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 153
#define EC_F_EC_GROUP_COPY 106
@@ -443,6 +481,12 @@ void ERR_load_EC_strings(void);
#define EC_F_EC_GROUP_SET_CURVE_GFP 109
#define EC_F_EC_GROUP_SET_EXTRA_DATA 110
#define EC_F_EC_GROUP_SET_GENERATOR 111
+#define EC_F_EC_KEY_CHECK_KEY 184
+#define EC_F_EC_KEY_COPY 186
+#define EC_F_EC_KEY_GENERATE_KEY 185
+#define EC_F_EC_KEY_PRINT 175
+#define EC_F_EC_KEY_PRINT_FP 176
+#define EC_F_EC_NEW 172
#define EC_F_EC_POINTS_MAKE_AFFINE 136
#define EC_F_EC_POINTS_MUL 138
#define EC_F_EC_POINT_ADD 112
@@ -471,6 +515,7 @@ void ERR_load_EC_strings(void);
#define EC_F_I2D_ECDSAPARAMETERS 158
#define EC_F_I2D_ECPARAMETERS 164
#define EC_F_I2D_ECPKPARAMETERS 165
+#define EC_F_I2D_ECPRIVATEKEY 169
/* Reason codes. */
#define EC_R_ASN1_ERROR 130
@@ -493,7 +538,9 @@ void ERR_load_EC_strings(void);
#define EC_R_INVALID_FIELD 103
#define EC_R_INVALID_FORM 104
#define EC_R_INVALID_GROUP_ORDER 119
+#define EC_R_INVALID_PRIVATE_KEY 139
#define EC_R_MISSING_PARAMETERS 127
+#define EC_R_MISSING_PRIVATE_KEY 138
#define EC_R_NOT_IMPLEMENTED 136
#define EC_R_NOT_INITIALIZED 111
#define EC_R_NO_SUCH_EXTRA_DATA 105
@@ -508,6 +555,7 @@ void ERR_load_EC_strings(void);
#define EC_R_UNKNOWN_NID 117
#define EC_R_UNKNOWN_ORDER 114
#define EC_R_UNKNOWN_PARAMETERS_TYPE 129
+#define EC_R_WRONG_ORDER 140
#ifdef __cplusplus
}
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c
index 90b64b0e04..bb81cfb3c3 100644
--- a/crypto/ec/ec_asn1.c
+++ b/crypto/ec/ec_asn1.c
@@ -82,14 +82,14 @@ typedef struct x9_62_curve_st {
ASN1_BIT_STRING *seed;
} X9_62_CURVE;
-struct ec_parameters_st {
+typedef struct ec_parameters_st {
ASN1_INTEGER *version;
X9_62_FIELDID *fieldID;
X9_62_CURVE *curve;
ASN1_OCTET_STRING *base;
ASN1_INTEGER *order;
ASN1_INTEGER *cofactor;
- }/* ECPARAMETERS */;
+ } ECPARAMETERS;
struct ecpk_parameters_st {
int type;
@@ -100,6 +100,14 @@ struct ecpk_parameters_st {
} value;
}/* ECPKPARAMETERS */;
+/* SEC1 ECPrivateKey */
+typedef struct ec_privatekey_st {
+ int version;
+ ASN1_OCTET_STRING *privateKey;
+ ECPKPARAMETERS *parameters;
+ ASN1_BIT_STRING *publicKey;
+ } EC_PRIVATEKEY;
+
/* the OpenSSL asn1 definitions */
ASN1_SEQUENCE(X9_62_FIELDID) = {
@@ -151,6 +159,7 @@ ASN1_SEQUENCE(ECPARAMETERS) = {
} ASN1_SEQUENCE_END(ECPARAMETERS)
DECLARE_ASN1_FUNCTIONS_const(ECPARAMETERS)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPARAMETERS, ECPARAMETERS)
IMPLEMENT_ASN1_FUNCTIONS_const(ECPARAMETERS)
ASN1_CHOICE(ECPKPARAMETERS) = {
@@ -160,15 +169,18 @@ ASN1_CHOICE(ECPKPARAMETERS) = {
} ASN1_CHOICE_END(ECPKPARAMETERS)
DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS)
IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS)
ASN1_SEQUENCE(EC_PRIVATEKEY) = {
ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG),
ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING),
- ASN1_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS),
- ASN1_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING)
+ ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0),
+ ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1)
} ASN1_SEQUENCE_END(EC_PRIVATEKEY)
+DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY)
IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY)
/* some internal functions */
@@ -178,6 +190,8 @@ static X9_62_CURVE *ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *);
static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *);
static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *,
ECPARAMETERS *);
+EC_GROUP *EC_ASN1_pkparameters2group(const ECPKPARAMETERS *);
+ECPKPARAMETERS *EC_ASN1_group2pkparameters(const EC_GROUP *, ECPKPARAMETERS *);
static X9_62_FIELDID *ec_asn1_group2field(const EC_GROUP *group,
X9_62_FIELDID *field)
@@ -786,34 +800,7 @@ EC_GROUP *EC_ASN1_pkparameters2group(const ECPKPARAMETERS *params)
return ret;
}
-/* EC_GROUP <-> DER encoding of EC[PK]PARAMETERS */
-
-EC_GROUP *d2i_ECParameters(EC_GROUP **a, const unsigned char **in, long len)
- {
- EC_GROUP *group = NULL;
- ECPARAMETERS *params = NULL;
-
- if ((params = d2i_ECPARAMETERS(NULL, in, len)) == NULL)
- {
- ECerr(EC_F_D2I_ECPARAMETERS, EC_R_D2I_ECPARAMETERS_FAILURE);
- ECPARAMETERS_free(params);
- return NULL;
- }
-
- if ((group = ec_asn1_parameters2group(params)) == NULL)
- {
- ECerr(EC_F_D2I_ECPARAMETERS, EC_R_PARAMETERS2GROUP_FAILURE);
- return NULL;
- }
-
- if (a && *a)
- EC_GROUP_clear_free(*a);
- if (a)
- *a = group;
-
- ECPARAMETERS_free(params);
- return(group);
- }
+/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */
EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
{
@@ -843,40 +830,346 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len)
return(group);
}
-int i2d_ECParameters(const EC_GROUP *a, unsigned char **out)
+int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
{
int ret=0;
- ECPARAMETERS *tmp = ec_asn1_group2parameters(a, NULL);
+ ECPKPARAMETERS *tmp = EC_ASN1_group2pkparameters(a, NULL);
if (tmp == NULL)
{
- ECerr(EC_F_I2D_ECPARAMETERS, EC_R_GROUP2PARAMETERS_FAILURE);
+ ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
return 0;
}
- if ((ret = i2d_ECPARAMETERS(tmp, out)) == 0)
+ if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
{
- ECerr(EC_F_I2D_ECPARAMETERS, EC_R_I2D_EC_PARAMETERS_FAILURE);
- ECPARAMETERS_free(tmp);
+ ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+ ECPKPARAMETERS_free(tmp);
return 0;
}
- ECPARAMETERS_free(tmp);
+ ECPKPARAMETERS_free(tmp);
return(ret);
}
-int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out)
+/* some EC_KEY functions */
+
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
{
- int ret=0;
- ECPKPARAMETERS *tmp = EC_ASN1_group2pkparameters(a, NULL);
- if (tmp == NULL)
+ int ok=0;
+ EC_KEY *ret=NULL;
+ EC_PRIVATEKEY *priv_key=NULL;
+
+ if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
{
- ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE);
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if ((priv_key = d2i_EC_PRIVATEKEY(&priv_key, in, len)) == NULL)
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ EC_PRIVATEKEY_free(priv_key);
+ return NULL;
+ }
+
+ if (a == NULL || *a == NULL)
+ {
+ if ((ret = EC_KEY_new()) == NULL)
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (a)
+ *a = ret;
+ }
+ else
+ ret = *a;
+
+ if (priv_key->parameters)
+ {
+ if (ret->group)
+ EC_GROUP_clear_free(ret->group);
+ ret->group = EC_ASN1_pkparameters2group(priv_key->parameters);
+ }
+
+ if (ret->group == NULL)
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ ret->version = priv_key->version;
+
+ if (priv_key->privateKey)
+ {
+ ret->priv_key = BN_bin2bn(
+ M_ASN1_STRING_data(priv_key->privateKey),
+ M_ASN1_STRING_length(priv_key->privateKey),
+ ret->priv_key);
+ if (ret->priv_key == NULL)
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY,
+ ERR_R_BN_LIB);
+ goto err;
+ }
+ }
+ else
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY,
+ EC_R_MISSING_PRIVATE_KEY);
+ goto err;
+ }
+
+ if (priv_key->publicKey)
+ {
+ if (ret->pub_key)
+ EC_POINT_clear_free(ret->pub_key);
+ ret->pub_key = EC_POINT_new(ret->group);
+ if (ret->pub_key == NULL)
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ if (!EC_POINT_oct2point(ret->group, ret->pub_key,
+ M_ASN1_STRING_data(priv_key->publicKey),
+ M_ASN1_STRING_length(priv_key->publicKey), NULL))
+ {
+ ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+
+ ok = 1;
+err:
+ if (!ok)
+ {
+ if (ret)
+ EC_KEY_free(ret);
+ ret = NULL;
+ }
+
+ if (priv_key)
+ EC_PRIVATEKEY_free(priv_key);
+
+ return(ret);
+ }
+
+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out)
+ {
+ int ret=0, ok=0;
+ unsigned char *buffer=NULL;
+ size_t buf_len=0, tmp_len;
+ EC_PRIVATEKEY *priv_key=NULL;
+
+ if (a == NULL || a->group == NULL || a->priv_key == NULL)
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY,
+ ERR_R_PASSED_NULL_PARAMETER);
+ goto err;
+ }
+
+ if ((priv_key = EC_PRIVATEKEY_new()) == NULL)
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ priv_key->version = a->version;
+
+ buf_len = (size_t)BN_num_bytes(a->priv_key);
+ buffer = OPENSSL_malloc(buf_len);
+ if (buffer == NULL)
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!BN_bn2bin(a->priv_key, buffer))
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB);
+ goto err;
+ }
+
+ if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len))
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+
+ if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS))
+ {
+ if ((priv_key->parameters = EC_ASN1_group2pkparameters(
+ a->group, priv_key->parameters)) == NULL)
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ }
+
+ if (!(a->enc_flag & EC_PKEY_NO_PUBKEY))
+ {
+ priv_key->publicKey = M_ASN1_BIT_STRING_new();
+ if (priv_key->publicKey == NULL)
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ tmp_len = EC_POINT_point2oct(a->group, a->pub_key,
+ a->conv_form, NULL, 0, NULL);
+
+ if (tmp_len > buf_len)
+ buffer = OPENSSL_realloc(buffer, tmp_len);
+ if (buffer == NULL)
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY,
+ ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ buf_len = tmp_len;
+
+ if (!EC_POINT_point2oct(a->group, a->pub_key,
+ a->conv_form, buffer, buf_len, NULL))
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+
+ if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer,
+ buf_len))
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB);
+ goto err;
+ }
+ }
+
+ if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0)
+ {
+ ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB);
+ goto err;
+ }
+ ok=1;
+err:
+ if (buffer)
+ OPENSSL_free(buffer);
+ if (priv_key)
+ EC_PRIVATEKEY_free(priv_key);
+ return(ok?ret:0);
+ }
+
+int i2d_ECParameters(EC_KEY *a, unsigned char **out)
+ {
+ if (a == NULL)
+ {
+ ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0)
+ return i2d_ECPKParameters(a->group, out);
+ }
+
+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len)
+ {
+ EC_GROUP *group;
+ EC_KEY *ret;
+
+ if (in == NULL || *in == NULL)
{
- ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE);
- ECPKPARAMETERS_free(tmp);
+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+
+ group = d2i_ECPKParameters(NULL, in, len);
+
+ if (group == NULL)
+ {
+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB);
+ return NULL;
+ }
+
+ if (a == NULL || *a == NULL)
+ {
+ if ((ret = EC_KEY_new()) == NULL)
+ {
+ ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if (a)
+ *a = ret;
+ }
+ else
+ ret = *a;
+
+ if (ret->group)
+ EC_GROUP_clear_free(ret->group);
+
+ ret->group = group;
+
+ return ret;
+ }
+
+EC_KEY *ECPublicKey_set_octet_string(EC_KEY **a, const unsigned char **in,
+ long len)
+ {
+ EC_KEY *ret=NULL;
+
+ if (a == NULL || (*a) == NULL || (*a)->group == NULL)
+ {
+ /* sorry, but a EC_GROUP-structur is necessary
+ * to set the public key */
+ ECerr(EC_F_ECPUBLICKEY_SET_OCTET, ERR_R_PASSED_NULL_PARAMETER);
return 0;
- }
- ECPKPARAMETERS_free(tmp);
- return(ret);
+ }
+ ret = *a;
+ if (ret->pub_key == NULL &&
+ (ret->pub_key = EC_POINT_new(ret->group)) == NULL)
+ {
+ ECerr(EC_F_ECPUBLICKEY_SET_OCTET, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL))
+ {
+ ECerr(EC_F_ECPUBLICKEY_SET_OCTET, ERR_R_EC_LIB);
+ return 0;
+ }
+ /* save the point conversion form */
+ ret->conv_form = (point_conversion_form_t)(*in[0] & ~0x01);
+ return ret;
+ }
+
+int ECPublicKey_get_octet_string(EC_KEY *a, unsigned char **out)
+ {
+ size_t buf_len=0;
+
+ if (a == NULL)
+ {
+ ECerr(EC_F_ECPUBLICKEY_GET_OCTET, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ buf_len = EC_POINT_point2oct(a->group, a->pub_key,
+ a->conv_form, NULL, 0, NULL);
+
+ if (out == NULL || buf_len == 0)
+ /* out == NULL => just return the length of the octet string */
+ return buf_len;
+
+ if (*out == NULL)
+ if ((*out = OPENSSL_malloc(buf_len)) == NULL)
+ {
+ ECerr(EC_F_ECPUBLICKEY_GET_OCTET,
+ ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
+ *out, buf_len, NULL))
+ {
+ ECerr(EC_F_ECPUBLICKEY_GET_OCTET, ERR_R_EC_LIB);
+ OPENSSL_free(*out);
+ *out = NULL;
+ return 0;
+ }
+ return buf_len;
}
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index c5ff12b366..8626ef0d3a 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -67,17 +67,21 @@
static ERR_STRING_DATA EC_str_functs[]=
{
{ERR_PACK(0,EC_F_COMPUTE_WNAF,0), "COMPUTE_WNAF"},
-{ERR_PACK(0,EC_F_D2I_ECDSAPARAMETERS,0), "d2i_ECDSAParameters"},
{ERR_PACK(0,EC_F_D2I_ECPARAMETERS,0), "d2i_ECParameters"},
{ERR_PACK(0,EC_F_D2I_ECPKPARAMETERS,0), "d2i_ECPKParameters"},
+{ERR_PACK(0,EC_F_D2I_ECPRIVATEKEY,0), "d2i_ECPrivateKey"},
+{ERR_PACK(0,EC_F_ECPARAMETERS_PRINT,0), "ECParameters_print"},
+{ERR_PACK(0,EC_F_ECPARAMETERS_PRINT_FP,0), "ECParameters_print_fp"},
{ERR_PACK(0,EC_F_ECPKPARAMETERS_PRINT,0), "ECPKParameters_print"},
{ERR_PACK(0,EC_F_ECPKPARAMETERS_PRINT_FP,0), "ECPKParameters_print_fp"},
+{ERR_PACK(0,EC_F_ECPUBLICKEY_GET_OCTET,0), "ECPUBLICKEY_GET_OCTET"},
+{ERR_PACK(0,EC_F_ECPUBLICKEY_SET_OCTET,0), "ECPUBLICKEY_SET_OCTET"},
{ERR_PACK(0,EC_F_EC_ASN1_GROUP2CURVE,0), "EC_ASN1_GROUP2CURVE"},
{ERR_PACK(0,EC_F_EC_ASN1_GROUP2FIELDID,0), "EC_ASN1_GROUP2FIELDID"},
{ERR_PACK(0,EC_F_EC_ASN1_GROUP2PARAMETERS,0), "EC_ASN1_GROUP2PARAMETERS"},
-{ERR_PACK(0,EC_F_EC_ASN1_GROUP2PKPARAMETERS,0), "EC_ASN1_group2pkparameters"},
+{ERR_PACK(0,EC_F_EC_ASN1_GROUP2PKPARAMETERS,0), "EC_ASN1_GROUP2PKPARAMETERS"},
{ERR_PACK(0,EC_F_EC_ASN1_PARAMETERS2GROUP,0), "EC_ASN1_PARAMETERS2GROUP"},
-{ERR_PACK(0,EC_F_EC_ASN1_PKPARAMETERS2GROUP,0), "EC_ASN1_pkparameters2group"},
+{ERR_PACK(0,EC_F_EC_ASN1_PKPARAMETERS2GROUP,0), "EC_ASN1_PKPARAMETERS2GROUP"},
{ERR_PACK(0,EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT,0), "ec_GF2m_simple_group_check_discriminant"},
{ERR_PACK(0,EC_F_EC_GF2M_SIMPLE_OCT2POINT,0), "ec_GF2m_simple_oct2point"},
{ERR_PACK(0,EC_F_EC_GF2M_SIMPLE_POINT2OCT,0), "ec_GF2m_simple_point2oct"},
@@ -119,12 +123,19 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_PACK(0,EC_F_EC_GROUP_SET_CURVE_GFP,0), "EC_GROUP_set_curve_GFp"},
{ERR_PACK(0,EC_F_EC_GROUP_SET_EXTRA_DATA,0), "EC_GROUP_set_extra_data"},
{ERR_PACK(0,EC_F_EC_GROUP_SET_GENERATOR,0), "EC_GROUP_set_generator"},
+{ERR_PACK(0,EC_F_EC_KEY_CHECK_KEY,0), "EC_KEY_check_key"},
+{ERR_PACK(0,EC_F_EC_KEY_COPY,0), "EC_KEY_copy"},
+{ERR_PACK(0,EC_F_EC_KEY_GENERATE_KEY,0), "EC_KEY_generate_key"},
+{ERR_PACK(0,EC_F_EC_KEY_PRINT,0), "EC_KEY_print"},
+{ERR_PACK(0,EC_F_EC_KEY_PRINT_FP,0), "EC_KEY_print_fp"},
+{ERR_PACK(0,EC_F_EC_NEW,0), "EC_NEW"},
{ERR_PACK(0,EC_F_EC_POINTS_MAKE_AFFINE,0), "EC_POINTs_make_affine"},
{ERR_PACK(0,EC_F_EC_POINTS_MUL,0), "EC_POINTs_mul"},
{ERR_PACK(0,EC_F_EC_POINT_ADD,0), "EC_POINT_add"},
{ERR_PACK(0,EC_F_EC_POINT_CMP,0), "EC_POINT_cmp"},
{ERR_PACK(0,EC_F_EC_POINT_COPY,0), "EC_POINT_copy"},
{ERR_PACK(0,EC_F_EC_POINT_DBL,0), "EC_POINT_dbl"},
+{ERR_PACK(0,EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M,0), "EC_POINT_get_affine_coordinates_GF2m"},
{ERR_PACK(0,EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP,0), "EC_POINT_get_affine_coordinates_GFp"},
{ERR_PACK(0,EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP,0), "EC_POINT_get_Jprojective_coordinates_GFp"},
{ERR_PACK(0,EC_F_EC_POINT_IS_AT_INFINITY,0), "EC_POINT_is_at_infinity"},
@@ -143,9 +154,10 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_PACK(0,EC_F_EC_WNAF_MUL,0), "ec_wNAF_mul"},
{ERR_PACK(0,EC_F_EC_WNAF_PRECOMPUTE_MULT,0), "ec_wNAF_precompute_mult"},
{ERR_PACK(0,EC_F_GFP_MONT_GROUP_SET_CURVE,0), "GFP_MONT_GROUP_SET_CURVE"},
-{ERR_PACK(0,EC_F_I2D_ECDSAPARAMETERS,0), "i2d_ECDSAParameters"},
+{ERR_PACK(0,EC_F_I2D_ECDSAPARAMETERS,0), "I2D_ECDSAPARAMETERS"},
{ERR_PACK(0,EC_F_I2D_ECPARAMETERS,0), "i2d_ECParameters"},
{ERR_PACK(0,EC_F_I2D_ECPKPARAMETERS,0), "i2d_ECPKParameters"},
+{ERR_PACK(0,EC_F_I2D_ECPRIVATEKEY,0), "i2d_ECPrivateKey"},
{0,NULL}
};
@@ -171,7 +183,9 @@ static ERR_STRING_DATA EC_str_reasons[]=
{EC_R_INVALID_FIELD ,"invalid field"},
{EC_R_INVALID_FORM ,"invalid form"},
{EC_R_INVALID_GROUP_ORDER ,"invalid group order"},
+{EC_R_INVALID_PRIVATE_KEY ,"invalid private key"},
{EC_R_MISSING_PARAMETERS ,"missing parameters"},
+{EC_R_MISSING_PRIVATE_KEY ,"missing private key"},
{EC_R_NOT_IMPLEMENTED ,"not implemented"},
{EC_R_NOT_INITIALIZED ,"not initialized"},
{EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"},
@@ -186,6 +200,7 @@ static ERR_STRING_DATA EC_str_reasons[]=
{EC_R_UNKNOWN_NID ,"unknown nid"},
{EC_R_UNKNOWN_ORDER ,"unknown order"},
{EC_R_UNKNOWN_PARAMETERS_TYPE ,"unknown parameters type"},
+{EC_R_WRONG_ORDER ,"wrong order"},
{0,NULL}
};
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
new file mode 100644
index 0000000000..790d930225
--- /dev/null
+++ b/crypto/ec/ec_key.c
@@ -0,0 +1,354 @@
+/* crypto/ec/ec_key.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "ec_lcl.h"
+#include <openssl/err.h>
+
+EC_KEY *EC_KEY_new(void)
+ {
+ EC_KEY *ret;
+
+ ret=(EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
+ if (ret == NULL)
+ {
+ ECerr(EC_F_EC_NEW, ERR_R_MALLOC_FAILURE);
+ return(NULL);
+ }
+
+ ret->version = 1;
+ ret->group = NULL;
+ ret->pub_key = NULL;
+ ret->priv_key= NULL;
+ ret->enc_flag= 0;
+ ret->conv_form = POINT_CONVERSION_UNCOMPRESSED;
+ ret->references= 1;
+ ret->meth_data = NULL;
+ return(ret);
+ }
+
+
+void EC_KEY_free(EC_KEY *r)
+ {
+ int i;
+
+ if (r == NULL) return;
+
+ i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_EC);
+#ifdef REF_PRINT
+ REF_PRINT("EC_KEY",r);
+#endif
+ if (i > 0) return;
+#ifdef REF_CHECK
+ if (i < 0)
+ {
+ fprintf(stderr,"EC_KEY_free, bad reference count\n");
+ abort();
+ }
+#endif
+
+ if (r->group != NULL)
+ EC_GROUP_free(r->group);
+ if (r->pub_key != NULL)
+ EC_POINT_free(r->pub_key);
+ if (r->priv_key != NULL)
+ BN_clear_free(r->priv_key);
+
+ if (r->meth_data && r->meth_data->finish)
+ r->meth_data->finish(r);
+
+ memset((void *)r, 0x0, sizeof(EC_KEY));
+
+ OPENSSL_free(r);
+ }
+
+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
+ {
+ if (dest == NULL || src == NULL)
+ {
+ ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
+ return NULL;
+ }
+ /* copy the parameters */
+ if (src->group)
+ {
+ const EC_METHOD *meth = EC_GROUP_method_of(src->group);
+ /* clear the old group */
+ if (dest->group)
+ EC_GROUP_free(dest->group);
+ dest->group = EC_GROUP_new(meth);
+ if (dest->group == NULL)
+ return NULL;
+ if (!EC_GROUP_copy(dest->group, src->group))
+ return NULL;
+ }
+ /* copy the public key */
+ if (src->pub_key && src->group)
+ {
+ if (dest->pub_key)
+ EC_POINT_free(dest->pub_key);
+ dest->pub_key = EC_POINT_new(src->group);
+ if (dest->pub_key == NULL)
+ return NULL;
+ if (!EC_POINT_copy(dest->pub_key, src->pub_key))
+ return NULL;
+ }
+ /* copy the private key */
+ if (src->priv_key)
+ {
+ if (dest->priv_key == NULL)
+ {
+ dest->priv_key = BN_new();
+ if (dest->priv_key == NULL)
+ return NULL;
+ }
+ if (!BN_copy(dest->priv_key, src->priv_key))
+ return NULL;
+ }
+ /* copy the rest */
+ dest->enc_flag = src->enc_flag;
+ dest->conv_form = src->conv_form;
+ dest->version = src->version;
+
+ return dest;
+ }
+
+EC_KEY *EC_KEY_dup(const EC_KEY *eckey)
+ {
+ EC_KEY *ret = NULL;
+ int ok = 1;
+
+ ret = EC_KEY_new();
+ if (ret == NULL)
+ return NULL;
+ /* copy the parameters */
+ if (eckey->group)
+ {
+ ret->group = EC_GROUP_dup(eckey->group);
+ if (ret->group == NULL)
+ ok = 0;
+ }
+ /* copy the public key */
+ if (eckey->pub_key && eckey->group)
+ {
+ ret->pub_key = EC_POINT_dup(eckey->pub_key, eckey->group);
+ if (ret->pub_key == NULL)
+ ok = 0;
+ }
+ /* copy the private key */
+ if (eckey->priv_key)
+ {
+ ret->priv_key = BN_dup(ret->priv_key);
+ if (ret->priv_key == NULL)
+ ok = 0;
+ }
+ /* copy the rest */
+ ret->enc_flag = eckey->enc_flag;
+ ret->conv_form = eckey->conv_form;
+ ret->version = eckey->version;
+
+ if (!ok)
+ {
+ EC_KEY_free(ret);
+ ret = NULL;
+ }
+
+ return ret;
+ }
+
+int EC_KEY_generate_key(EC_KEY *eckey)
+ {
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ BIGNUM *priv_key = NULL, *order = NULL;
+ EC_POINT *pub_key = NULL;
+
+ if (!eckey || !eckey->group)
+ {
+ ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if ((order = BN_new()) == NULL) goto err;
+ if ((ctx = BN_CTX_new()) == NULL) goto err;
+
+ if (eckey->priv_key == NULL)
+ {
+ priv_key = BN_new();
+ if (priv_key == NULL)
+ goto err;
+ }
+ else
+ priv_key = eckey->priv_key;
+
+ if (!EC_GROUP_get_order(eckey->group, order, ctx))
+ goto err;
+
+ do
+ if (!BN_rand_range(priv_key, order))
+ goto err;
+ while (BN_is_zero(priv_key));
+
+ if (eckey->pub_key == NULL)
+ {
+ pub_key = EC_POINT_new(eckey->group);
+ if (pub_key == NULL)
+ goto err;
+ }
+ else
+ pub_key = eckey->pub_key;
+