summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec')
-rw-r--r--src/lib/libcrypto/ec/ec.h28
-rw-r--r--src/lib/libcrypto/ec/ec2_mult.c27
-rw-r--r--src/lib/libcrypto/ec/ec_ameth.c2
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c6
-rw-r--r--src/lib/libcrypto/ec/ec_key.c13
-rw-r--r--src/lib/libcrypto/ec/ec_lib.c10
-rw-r--r--src/lib/libcrypto/ec/ec_pmeth.c2
-rw-r--r--src/lib/libcrypto/ec/ecp_mont.c1
8 files changed, 56 insertions, 33 deletions
diff --git a/src/lib/libcrypto/ec/ec.h b/src/lib/libcrypto/ec/ec.h
index 9d01325af3..dfe8710d33 100644
--- a/src/lib/libcrypto/ec/ec.h
+++ b/src/lib/libcrypto/ec/ec.h
@@ -274,10 +274,10 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group);
274void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); 274void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
275int EC_GROUP_get_asn1_flag(const EC_GROUP *group); 275int EC_GROUP_get_asn1_flag(const EC_GROUP *group);
276 276
277void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t); 277void EC_GROUP_set_point_conversion_form(EC_GROUP *group, point_conversion_form_t form);
278point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); 278point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
279 279
280unsigned char *EC_GROUP_get0_seed(const EC_GROUP *); 280unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x);
281size_t EC_GROUP_get_seed_len(const EC_GROUP *); 281size_t EC_GROUP_get_seed_len(const EC_GROUP *);
282size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); 282size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
283 283
@@ -626,8 +626,8 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *c
626 */ 626 */
627int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); 627int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx);
628 628
629int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); 629int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx);
630int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); 630int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx);
631 631
632/** Computes r = generator * n sum_{i=0}^num p[i] * m[i] 632/** Computes r = generator * n sum_{i=0}^num p[i] * m[i]
633 * \param group underlying EC_GROUP object 633 * \param group underlying EC_GROUP object
@@ -800,16 +800,24 @@ const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key);
800int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); 800int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
801 801
802unsigned EC_KEY_get_enc_flags(const EC_KEY *key); 802unsigned EC_KEY_get_enc_flags(const EC_KEY *key);
803void EC_KEY_set_enc_flags(EC_KEY *, unsigned int); 803void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags);
804point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *); 804point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key);
805void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t); 805void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform);
806/* functions to set/get method specific data */ 806/* functions to set/get method specific data */
807void *EC_KEY_get_key_method_data(EC_KEY *, 807void *EC_KEY_get_key_method_data(EC_KEY *key,
808 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); 808 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
809void EC_KEY_insert_key_method_data(EC_KEY *, void *data, 809/** Sets the key method data of an EC_KEY object, if none has yet been set.
810 * \param key EC_KEY object
811 * \param data opaque data to install.
812 * \param dup_func a function that duplicates |data|.
813 * \param free_func a function that frees |data|.
814 * \param clear_free_func a function that wipes and frees |data|.
815 * \return the previously set data pointer, or NULL if |data| was inserted.
816 */
817void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
810 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); 818 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
811/* wrapper functions for the underlying EC_GROUP object */ 819/* wrapper functions for the underlying EC_GROUP object */
812void EC_KEY_set_asn1_flag(EC_KEY *, int); 820void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag);
813 821
814/** Creates a table of pre-computed multiples of the generator to 822/** Creates a table of pre-computed multiples of the generator to
815 * accelerate further EC_KEY operations. 823 * accelerate further EC_KEY operations.
diff --git a/src/lib/libcrypto/ec/ec2_mult.c b/src/lib/libcrypto/ec/ec2_mult.c
index 26f4a783fc..1c575dc47a 100644
--- a/src/lib/libcrypto/ec/ec2_mult.c
+++ b/src/lib/libcrypto/ec/ec2_mult.c
@@ -208,11 +208,15 @@ static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, BIG
208 return ret; 208 return ret;
209 } 209 }
210 210
211
211/* Computes scalar*point and stores the result in r. 212/* Computes scalar*point and stores the result in r.
212 * point can not equal r. 213 * point can not equal r.
213 * Uses algorithm 2P of 214 * Uses a modified algorithm 2P of
214 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over 215 * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
215 * GF(2^m) without precomputation" (CHES '99, LNCS 1717). 216 * GF(2^m) without precomputation" (CHES '99, LNCS 1717).
217 *
218 * To protect against side-channel attack the function uses constant time swap,
219 * avoiding conditional branches.
216 */ 220 */
217static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, 221static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
218 const EC_POINT *point, BN_CTX *ctx) 222 const EC_POINT *point, BN_CTX *ctx)
@@ -246,6 +250,11 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
246 x2 = &r->X; 250 x2 = &r->X;
247 z2 = &r->Y; 251 z2 = &r->Y;
248 252
253 bn_wexpand(x1, group->field.top);
254 bn_wexpand(z1, group->field.top);
255 bn_wexpand(x2, group->field.top);
256 bn_wexpand(z2, group->field.top);
257
249 if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ 258 if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
250 if (!BN_one(z1)) goto err; /* z1 = 1 */ 259 if (!BN_one(z1)) goto err; /* z1 = 1 */
251 if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ 260 if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
@@ -270,16 +279,12 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r,
270 word = scalar->d[i]; 279 word = scalar->d[i];
271 while (mask) 280 while (mask)
272 { 281 {
273 if (word & mask) 282 BN_consttime_swap(word & mask, x1, x2, group->field.top);
274 { 283 BN_consttime_swap(word & mask, z1, z2, group->field.top);
275 if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; 284 if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
276 if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; 285 if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
277 } 286 BN_consttime_swap(word & mask, x1, x2, group->field.top);
278 else 287 BN_consttime_swap(word & mask, z1, z2, group->field.top);
279 {
280 if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
281 if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
282 }
283 mask >>= 1; 288 mask >>= 1;
284 } 289 }
285 mask = BN_TBIT; 290 mask = BN_TBIT;
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c
index 83909c1853..0ce4524076 100644
--- a/src/lib/libcrypto/ec/ec_ameth.c
+++ b/src/lib/libcrypto/ec/ec_ameth.c
@@ -88,7 +88,7 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
88 if (!pstr) 88 if (!pstr)
89 return 0; 89 return 0;
90 pstr->length = i2d_ECParameters(ec_key, &pstr->data); 90 pstr->length = i2d_ECParameters(ec_key, &pstr->data);
91 if (pstr->length < 0) 91 if (pstr->length <= 0)
92 { 92 {
93 ASN1_STRING_free(pstr); 93 ASN1_STRING_free(pstr);
94 ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); 94 ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB);
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c
index 175eec5342..145807b611 100644
--- a/src/lib/libcrypto/ec/ec_asn1.c
+++ b/src/lib/libcrypto/ec/ec_asn1.c
@@ -89,7 +89,8 @@ int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k)
89 if (group == NULL) 89 if (group == NULL)
90 return 0; 90 return 0;
91 91
92 if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve 92 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
93 NID_X9_62_characteristic_two_field
93 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) 94 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0)))
94 { 95 {
95 ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 96 ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
@@ -107,7 +108,8 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
107 if (group == NULL) 108 if (group == NULL)
108 return 0; 109 return 0;
109 110
110 if (EC_GROUP_method_of(group)->group_set_curve != ec_GF2m_simple_group_set_curve 111 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
112 NID_X9_62_characteristic_two_field
111 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) 113 || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0)))
112 { 114 {
113 ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 115 ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
diff --git a/src/lib/libcrypto/ec/ec_key.c b/src/lib/libcrypto/ec/ec_key.c
index bf9fd2dc2c..7fa247593d 100644
--- a/src/lib/libcrypto/ec/ec_key.c
+++ b/src/lib/libcrypto/ec/ec_key.c
@@ -520,18 +520,27 @@ void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform)
520void *EC_KEY_get_key_method_data(EC_KEY *key, 520void *EC_KEY_get_key_method_data(EC_KEY *key,
521 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 521 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
522 { 522 {
523 return EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 523 void *ret;
524
525 CRYPTO_r_lock(CRYPTO_LOCK_EC);
526 ret = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
527 CRYPTO_r_unlock(CRYPTO_LOCK_EC);
528
529 return ret;
524 } 530 }
525 531
526void EC_KEY_insert_key_method_data(EC_KEY *key, void *data, 532void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data,
527 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)) 533 void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *))
528 { 534 {
529 EC_EXTRA_DATA *ex_data; 535 EC_EXTRA_DATA *ex_data;
536
530 CRYPTO_w_lock(CRYPTO_LOCK_EC); 537 CRYPTO_w_lock(CRYPTO_LOCK_EC);
531 ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func); 538 ex_data = EC_EX_DATA_get_data(key->method_data, dup_func, free_func, clear_free_func);
532 if (ex_data == NULL) 539 if (ex_data == NULL)
533 EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func); 540 EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, clear_free_func);
534 CRYPTO_w_unlock(CRYPTO_LOCK_EC); 541 CRYPTO_w_unlock(CRYPTO_LOCK_EC);
542
543 return ex_data;
535 } 544 }
536 545
537void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) 546void EC_KEY_set_asn1_flag(EC_KEY *key, int flag)
diff --git a/src/lib/libcrypto/ec/ec_lib.c b/src/lib/libcrypto/ec/ec_lib.c
index 25247b5803..de9a0cc2b3 100644
--- a/src/lib/libcrypto/ec/ec_lib.c
+++ b/src/lib/libcrypto/ec/ec_lib.c
@@ -480,10 +480,10 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx)
480 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != 480 if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) !=
481 EC_METHOD_get_field_type(EC_GROUP_method_of(b))) 481 EC_METHOD_get_field_type(EC_GROUP_method_of(b)))
482 return 1; 482 return 1;
483 /* compare the curve name (if present) */ 483 /* compare the curve name (if present in both) */
484 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && 484 if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) &&
485 EC_GROUP_get_curve_name(a) == EC_GROUP_get_curve_name(b)) 485 EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b))
486 return 0; 486 return 1;
487 487
488 if (!ctx) 488 if (!ctx)
489 ctx_new = ctx = BN_CTX_new(); 489 ctx_new = ctx = BN_CTX_new();
@@ -993,12 +993,12 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN
993 if (group->meth->point_cmp == 0) 993 if (group->meth->point_cmp == 0)
994 { 994 {
995 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 995 ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
996 return 0; 996 return -1;
997 } 997 }
998 if ((group->meth != a->meth) || (a->meth != b->meth)) 998 if ((group->meth != a->meth) || (a->meth != b->meth))
999 { 999 {
1000 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); 1000 ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS);
1001 return 0; 1001 return -1;
1002 } 1002 }
1003 return group->meth->point_cmp(group, a, b, ctx); 1003 return group->meth->point_cmp(group, a, b, ctx);
1004 } 1004 }
diff --git a/src/lib/libcrypto/ec/ec_pmeth.c b/src/lib/libcrypto/ec/ec_pmeth.c
index d1ed66c37e..66ee397d86 100644
--- a/src/lib/libcrypto/ec/ec_pmeth.c
+++ b/src/lib/libcrypto/ec/ec_pmeth.c
@@ -188,7 +188,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
188 188
189 pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); 189 pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec);
190 190
191 /* NB: unlike PKS#3 DH, if *outlen is less than maximum size this is 191 /* NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is
192 * not an error, the result is truncated. 192 * not an error, the result is truncated.
193 */ 193 */
194 194
diff --git a/src/lib/libcrypto/ec/ecp_mont.c b/src/lib/libcrypto/ec/ecp_mont.c
index 079e47431b..f04f132c7a 100644
--- a/src/lib/libcrypto/ec/ecp_mont.c
+++ b/src/lib/libcrypto/ec/ecp_mont.c
@@ -114,7 +114,6 @@ const EC_METHOD *EC_GFp_mont_method(void)
114 ec_GFp_mont_field_decode, 114 ec_GFp_mont_field_decode,
115 ec_GFp_mont_field_set_to_one }; 115 ec_GFp_mont_field_set_to_one };
116 116
117
118 return &ret; 117 return &ret;
119#endif 118#endif
120 } 119 }