aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/ec
diff options
context:
space:
mode:
authorBodo Möller <bodo@openssl.org>2002-03-18 13:10:45 +0000
committerBodo Möller <bodo@openssl.org>2002-03-18 13:10:45 +0000
commitaf28dd6c75cc7abaec8b5df7555f07d143d3a6d1 (patch)
treefc317b4c33a4814c735d3f6f64e8a9a54c86486a /crypto/ec
parente79ec456beacdc1d8b463d90661fc872e7cf836a (diff)
downloadopenssl-af28dd6c75cc7abaec8b5df7555f07d143d3a6d1.tar.gz
Fix bugs and typos.
Add some WTLS curves. New function EC_GROUP_check() (this will probably be implemented differently soon). Submitted by: Nils Larsch Reviewed by: Bodo Moeller
Diffstat (limited to 'crypto/ec')
-rw-r--r--crypto/ec/ec.h15
-rw-r--r--crypto/ec/ec_curve.c31
-rw-r--r--crypto/ec/ec_err.c8
-rw-r--r--crypto/ec/ec_lcl.h4
-rw-r--r--crypto/ec/ec_lib.c34
-rw-r--r--crypto/ec/ecp_mont.c1
-rw-r--r--crypto/ec/ecp_nist.c1
-rw-r--r--crypto/ec/ecp_recp.c1
-rw-r--r--crypto/ec/ecp_smpl.c109
9 files changed, 187 insertions, 17 deletions
diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h
index 192ef13f01..f83bacc89b 100644
--- a/crypto/ec/ec.h
+++ b/crypto/ec/ec.h
@@ -1,6 +1,6 @@
/* crypto/ec/ec.h */
/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
+ * 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
@@ -125,6 +125,8 @@ 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 *);
+/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
/* EC_GROUP_new_GFp() calls EC_GROUP_new() and EC_GROUP_set_GFp()
* after choosing an appropriate EC_METHOD */
@@ -163,6 +165,11 @@ EC_GROUP *EC_GROUP_new_by_name(int name);
#define EC_GROUP_SECG_PRIME_256R1 NID_secp256r1
#define EC_GROUP_SECG_PRIME_384R1 NID_secp384r1
#define EC_GROUP_SECG_PRIME_521R1 NID_secp521r1
+#define EC_GROUP_WTLS_6 NID_wap_wsg_idm_ecid_wtls6
+#define EC_GROUP_WTLS_7 NID_secp160r1
+#define EC_GROUP_WTLS_8 NID_wap_wsg_idm_ecid_wtls8
+#define EC_GROUP_WTLS_9 NID_wap_wsg_idm_ecid_wtls9
+#define EC_GROUP_WTLS_12 NID_secp224r1
EC_POINT *EC_POINT_new(const EC_GROUP *);
void EC_POINT_free(EC_POINT *);
@@ -220,6 +227,7 @@ void ERR_load_EC_strings(void);
#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134
#define EC_F_EC_GFP_MONT_FIELD_MUL 131
#define EC_F_EC_GFP_MONT_FIELD_SQR 132
+#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK 151
#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100
#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101
#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102
@@ -229,6 +237,7 @@ void ERR_load_EC_strings(void);
#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
+#define EC_F_EC_GROUP_CHECK 150
#define EC_F_EC_GROUP_COPY 106
#define EC_F_EC_GROUP_GET0_GENERATOR 139
#define EC_F_EC_GROUP_GET_COFACTOR 140
@@ -266,6 +275,7 @@ void ERR_load_EC_strings(void);
/* Reason codes. */
#define EC_R_BUFFER_TOO_SMALL 100
+#define EC_R_DISCRIMINANT_IS_ZERO 118
#define EC_R_INCOMPATIBLE_OBJECTS 101
#define EC_R_INVALID_ARGUMENT 112
#define EC_R_INVALID_COMPRESSED_POINT 110
@@ -273,13 +283,14 @@ void ERR_load_EC_strings(void);
#define EC_R_INVALID_ENCODING 102
#define EC_R_INVALID_FIELD 103
#define EC_R_INVALID_FORM 104
-#define EC_R_MISSING_PARAMETERS 115
+#define EC_R_INVALID_GROUP_ORDER 119
#define EC_R_NOT_INITIALIZED 111
#define EC_R_NO_SUCH_EXTRA_DATA 105
#define EC_R_POINT_AT_INFINITY 106
#define EC_R_POINT_IS_NOT_ON_CURVE 107
#define EC_R_SLOT_FULL 108
#define EC_R_UNDEFINED_GENERATOR 113
+#define EC_R_UNDEFINED_ORDER 122
#define EC_R_UNKNOWN_GROUP 116
#define EC_R_UNKNOWN_NID 117
#define EC_R_UNKNOWN_ORDER 114
diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c
index 8e1f038c3d..132e631a4e 100644
--- a/crypto/ec/ec_curve.c
+++ b/crypto/ec/ec_curve.c
@@ -60,7 +60,7 @@
#include <openssl/asn1t.h>
/* #define _EC_GROUP_EXAMPLE_PRIME_CURVE \
- * "the prime number p", "a", "b", "the compressed base point", "y-bit", "order", "cofacor"
+ * "the prime number p", "a", "b", "the compressed base point", "y-bit", "order", "cofactor"
*/
/* the nist prime curves */
#define _EC_GROUP_NIST_PRIME_192 \
@@ -190,6 +190,25 @@
"7",\
"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",0,\
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1
+/* some wap/wtls curves */
+#define _EC_GROUP_WTLS_6 \
+ "DB7C2ABF62E35E668076BEAD208B",\
+ "DB7C2ABF62E35E668076BEAD2088",\
+ "659EF8BA043916EEDE8911702B22",\
+ "09487239995A5EE76B55F9C2F098",0,\
+ "DB7C2ABF62E35E7628DFAC6561C5",1
+#define _EC_GROUP_WTLS_8 \
+ "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",\
+ "0",\
+ "3",\
+ "1",0,\
+ "0100000000000001ECEA551AD837E9",1
+#define _EC_GROUP_WTLS_9 \
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",\
+ "0",\
+ "3",\
+ "1",0,\
+ "0100000000000000000001CDC98AE0E2DE574ABF33",1
static EC_GROUP *ec_group_new_GFp_from_hex(const char *prime_in,
const char *a_in, const char *b_in,
@@ -317,6 +336,16 @@ EC_GROUP *EC_GROUP_new_by_name(int name)
case EC_GROUP_SECG_PRIME_256K1:
ret = ec_group_new_GFp_from_hex(_EC_GROUP_SECG_PRIME_256K1);
break;
+ /* some wap/wtls curves */
+ case EC_GROUP_WTLS_6:
+ ret = ec_group_new_GFp_from_hex(_EC_GROUP_WTLS_6);
+ break;
+ case EC_GROUP_WTLS_8:
+ ret = ec_group_new_GFp_from_hex(_EC_GROUP_WTLS_8);
+ break;
+ case EC_GROUP_WTLS_9:
+ ret = ec_group_new_GFp_from_hex(_EC_GROUP_WTLS_9);
+ break;
}
if (ret == NULL)
diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
index 2199d92539..e78713bd0b 100644
--- a/crypto/ec/ec_err.c
+++ b/crypto/ec/ec_err.c
@@ -1,6 +1,6 @@
/* crypto/ec/ec_err.c */
/* ====================================================================
- * Copyright (c) 2001 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-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
@@ -71,6 +71,7 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_ENCODE,0), "ec_GFp_mont_field_encode"},
{ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_MUL,0), "ec_GFp_mont_field_mul"},
{ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_SQR,0), "ec_GFp_mont_field_sqr"},
+{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_CHECK,0), "ec_GFp_simple_group_check"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP,0), "ec_GFp_simple_group_set_curve_GFp"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR,0), "ec_GFp_simple_group_set_generator"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_MAKE_AFFINE,0), "ec_GFp_simple_make_affine"},
@@ -80,6 +81,7 @@ static ERR_STRING_DATA EC_str_functs[]=
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP,0), "ec_GFp_simple_point_get_affine_coordinates_GFp"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP,0), "ec_GFp_simple_point_set_affine_coordinates_GFp"},
{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP,0), "ec_GFp_simple_set_compressed_coordinates_GFp"},
+{ERR_PACK(0,EC_F_EC_GROUP_CHECK,0), "EC_GROUP_check"},
{ERR_PACK(0,EC_F_EC_GROUP_COPY,0), "EC_GROUP_copy"},
{ERR_PACK(0,EC_F_EC_GROUP_GET0_GENERATOR,0), "EC_GROUP_get0_generator"},
{ERR_PACK(0,EC_F_EC_GROUP_GET_COFACTOR,0), "EC_GROUP_get_cofactor"},
@@ -120,6 +122,7 @@ static ERR_STRING_DATA EC_str_functs[]=
static ERR_STRING_DATA EC_str_reasons[]=
{
{EC_R_BUFFER_TOO_SMALL ,"buffer too small"},
+{EC_R_DISCRIMINANT_IS_ZERO ,"discriminant is zero"},
{EC_R_INCOMPATIBLE_OBJECTS ,"incompatible objects"},
{EC_R_INVALID_ARGUMENT ,"invalid argument"},
{EC_R_INVALID_COMPRESSED_POINT ,"invalid compressed point"},
@@ -127,13 +130,14 @@ static ERR_STRING_DATA EC_str_reasons[]=
{EC_R_INVALID_ENCODING ,"invalid encoding"},
{EC_R_INVALID_FIELD ,"invalid field"},
{EC_R_INVALID_FORM ,"invalid form"},
-{EC_R_MISSING_PARAMETERS ,"missing parameters"},
+{EC_R_INVALID_GROUP_ORDER ,"invalid group order"},
{EC_R_NOT_INITIALIZED ,"not initialized"},
{EC_R_NO_SUCH_EXTRA_DATA ,"no such extra data"},
{EC_R_POINT_AT_INFINITY ,"point at infinity"},
{EC_R_POINT_IS_NOT_ON_CURVE ,"point is not on curve"},
{EC_R_SLOT_FULL ,"slot full"},
{EC_R_UNDEFINED_GENERATOR ,"undefined generator"},
+{EC_R_UNDEFINED_ORDER ,"undefined order"},
{EC_R_UNKNOWN_GROUP ,"unknown group"},
{EC_R_UNKNOWN_NID ,"unknown nid"},
{EC_R_UNKNOWN_ORDER ,"unknown order"},
diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h
index b93825524f..87feb39dea 100644
--- a/crypto/ec/ec_lcl.h
+++ b/crypto/ec/ec_lcl.h
@@ -82,6 +82,9 @@ struct ec_method_st {
int (*group_get_order)(const EC_GROUP *, BIGNUM *order, BN_CTX *);
int (*group_get_cofactor)(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
+ /* used by EC_GROUP_check: */
+ int (*group_check)(const EC_GROUP *, BN_CTX *);
+
/* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
int (*point_init)(EC_POINT *);
void (*point_finish)(EC_POINT *);
@@ -215,6 +218,7 @@ int ec_GFp_simple_group_set_generator(EC_GROUP *, const EC_POINT *generator,
EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *);
int ec_GFp_simple_group_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
int ec_GFp_simple_group_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
+int ec_GFp_simple_group_check(const EC_GROUP *, BN_CTX *);
int ec_GFp_simple_point_init(EC_POINT *);
void ec_GFp_simple_point_finish(EC_POINT *);
void ec_GFp_simple_point_clear_finish(EC_POINT *);
diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
index 3e372dbed3..1a6aceed82 100644
--- a/crypto/ec/ec_lib.c
+++ b/crypto/ec/ec_lib.c
@@ -237,6 +237,29 @@ int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
}
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
+ {
+ if (group->meth->group_check == 0)
+ {
+ ECerr(EC_F_EC_GROUP_CHECK, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ return 0;
+ }
+ return group->meth->group_check(group, ctx);
+ }
+
+
+void EC_GROUP_set_nid(EC_GROUP *group, int nid)
+ {
+ group->nid = nid;
+ }
+
+
+int EC_GROUP_get_nid(const EC_GROUP *group)
+ {
+ return group->nid;
+ }
+
+
/* this has 'package' visibility */
int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *),
void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
@@ -299,17 +322,6 @@ void EC_GROUP_clear_free_extra_data(EC_GROUP *group)
group->extra_data_clear_free_func = 0;
}
-void EC_GROUP_set_nid(EC_GROUP *group, int nid)
- {
- group->nid = nid;
- }
-
-int EC_GROUP_get_nid(const EC_GROUP *group)
- {
- return group->nid;
- }
-
-
/* functions for EC_POINT objects */
diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c
index 7b30d4c38a..1d02661555 100644
--- a/crypto/ec/ecp_mont.c
+++ b/crypto/ec/ecp_mont.c
@@ -71,6 +71,7 @@ const EC_METHOD *EC_GFp_mont_method(void)
ec_GFp_simple_group_get0_generator,
ec_GFp_simple_group_get_order,
ec_GFp_simple_group_get_cofactor,
+ ec_GFp_simple_group_check,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c
index ed07748675..4d92220670 100644
--- a/crypto/ec/ecp_nist.c
+++ b/crypto/ec/ecp_nist.c
@@ -69,6 +69,7 @@ const EC_METHOD *EC_GFp_nist_method(void)
ec_GFp_simple_group_get0_generator,
ec_GFp_simple_group_get_order,
ec_GFp_simple_group_get_cofactor,
+ ec_GFp_simple_group_check,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
diff --git a/crypto/ec/ecp_recp.c b/crypto/ec/ecp_recp.c
index fec843b5c8..b251c921ce 100644
--- a/crypto/ec/ecp_recp.c
+++ b/crypto/ec/ecp_recp.c
@@ -69,6 +69,7 @@ const EC_METHOD *EC_GFp_recp_method(void)
ec_GFp_simple_group_get0_generator,
ec_GFp_simple_group_get_order,
ec_GFp_simple_group_get_cofactor,
+ ec_GFp_simple_group_check,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c
index 4666a052bf..8e062dc951 100644
--- a/crypto/ec/ecp_smpl.c
+++ b/crypto/ec/ecp_smpl.c
@@ -2,7 +2,7 @@
/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
* for the OpenSSL project. */
/* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
+ * 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
@@ -73,6 +73,7 @@ const EC_METHOD *EC_GFp_simple_method(void)
ec_GFp_simple_group_get0_generator,
ec_GFp_simple_group_get_order,
ec_GFp_simple_group_get_cofactor,
+ ec_GFp_simple_group_check,
ec_GFp_simple_point_init,
ec_GFp_simple_point_finish,
ec_GFp_simple_point_clear_finish,
@@ -338,6 +339,112 @@ int ec_GFp_simple_group_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN
}
+int ec_GFp_simple_group_check(const EC_GROUP *group, BN_CTX *ctx)
+ {
+ int ret = 0;
+ BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
+ const BIGNUM *p = &group->field;
+ BN_CTX *new_ctx = NULL;
+ EC_POINT *point = NULL;
+
+ if (ctx == NULL)
+ {
+ ctx = new_ctx = BN_CTX_new();
+ if (ctx == NULL)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ BN_CTX_start(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ tmp_1 = BN_CTX_get(ctx);
+ tmp_2 = BN_CTX_get(ctx);
+ order = BN_CTX_get(ctx);
+ if (order == NULL) goto err;
+
+ if (group->meth->field_decode)
+ {
+ if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
+ if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
+ }
+ else
+ {
+ if (!BN_copy(a, &group->a)) goto err;
+ if (!BN_copy(b, &group->b)) goto err;
+ }
+
+ /* check the discriminant:
+ * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
+ * 0 =< a, b < p */
+ if (BN_is_zero(a))
+ {
+ if (BN_is_zero(b))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+ goto err;
+ }
+ }
+ else if (!BN_is_zero(b))
+ {
+ if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
+ if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
+ if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
+ /* tmp_1 = 4*a^3 */
+
+ if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
+ if (!BN_mul_word(tmp_2, 27)) goto err;
+ /* tmp_2 = 27*b^2 */
+
+ if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
+ if (BN_is_zero(a))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+ goto err;
+ }
+ }
+
+ /* check the generator */
+ if (group->generator == NULL)
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+ goto err;
+ }
+ if (!ec_GFp_simple_is_on_curve(group, group->generator, ctx))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+ goto err;
+ }
+
+ /* check the order of the generator */
+ if ((point = EC_POINT_new(group)) == NULL) goto err;
+ if (!EC_GROUP_get_order(group, order, ctx)) goto err;
+ if (BN_is_zero(order))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
+ goto err;
+ }
+
+ if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err;
+ if (!EC_POINT_is_at_infinity(group, point))
+ {
+ ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ BN_CTX_end(ctx);
+ if (new_ctx != NULL)
+ BN_CTX_free(new_ctx);
+ if (point)
+ EC_POINT_free(point);
+ return ret;
+ }
+
+
int ec_GFp_simple_point_init(EC_POINT *point)
{
BN_init(&point->X);