diff options
Diffstat (limited to 'src/lib/libcrypto/ec/ec2_smpl.c')
-rw-r--r-- | src/lib/libcrypto/ec/ec2_smpl.c | 112 |
1 files changed, 89 insertions, 23 deletions
diff --git a/src/lib/libcrypto/ec/ec2_smpl.c b/src/lib/libcrypto/ec/ec2_smpl.c index 522d036ca1..cf357b462a 100644 --- a/src/lib/libcrypto/ec/ec2_smpl.c +++ b/src/lib/libcrypto/ec/ec2_smpl.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * | 14 | * |
15 | */ | 15 | */ |
16 | /* ==================================================================== | 16 | /* ==================================================================== |
17 | * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. | 17 | * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. |
18 | * | 18 | * |
19 | * Redistribution and use in source and binary forms, with or without | 19 | * Redistribution and use in source and binary forms, with or without |
20 | * modification, are permitted provided that the following conditions | 20 | * modification, are permitted provided that the following conditions |
@@ -157,6 +157,7 @@ void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) | |||
157 | group->poly[2] = 0; | 157 | group->poly[2] = 0; |
158 | group->poly[3] = 0; | 158 | group->poly[3] = 0; |
159 | group->poly[4] = 0; | 159 | group->poly[4] = 0; |
160 | group->poly[5] = -1; | ||
160 | } | 161 | } |
161 | 162 | ||
162 | 163 | ||
@@ -174,10 +175,9 @@ int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) | |||
174 | dest->poly[2] = src->poly[2]; | 175 | dest->poly[2] = src->poly[2]; |
175 | dest->poly[3] = src->poly[3]; | 176 | dest->poly[3] = src->poly[3]; |
176 | dest->poly[4] = src->poly[4]; | 177 | dest->poly[4] = src->poly[4]; |
177 | if(bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) | 178 | dest->poly[5] = src->poly[5]; |
178 | return 0; | 179 | if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0; |
179 | if(bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) | 180 | if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) == NULL) return 0; |
180 | return 0; | ||
181 | for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0; | 181 | for (i = dest->a.top; i < dest->a.dmax; i++) dest->a.d[i] = 0; |
182 | for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0; | 182 | for (i = dest->b.top; i < dest->b.dmax; i++) dest->b.d[i] = 0; |
183 | return 1; | 183 | return 1; |
@@ -192,7 +192,7 @@ int ec_GF2m_simple_group_set_curve(EC_GROUP *group, | |||
192 | 192 | ||
193 | /* group->field */ | 193 | /* group->field */ |
194 | if (!BN_copy(&group->field, p)) goto err; | 194 | if (!BN_copy(&group->field, p)) goto err; |
195 | i = BN_GF2m_poly2arr(&group->field, group->poly, 5); | 195 | i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1; |
196 | if ((i != 5) && (i != 3)) | 196 | if ((i != 5) && (i != 3)) |
197 | { | 197 | { |
198 | ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); | 198 | ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); |
@@ -406,18 +406,94 @@ int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, const EC_ | |||
406 | } | 406 | } |
407 | 407 | ||
408 | 408 | ||
409 | /* Include patented algorithms. */ | 409 | /* Calculates and sets the affine coordinates of an EC_POINT from the given |
410 | #include "ec2_smpt.c" | 410 | * compressed coordinates. Uses algorithm 2.3.4 of SEC 1. |
411 | * Note that the simple implementation only uses affine coordinates. | ||
412 | * | ||
413 | * The method is from the following publication: | ||
414 | * | ||
415 | * Harper, Menezes, Vanstone: | ||
416 | * "Public-Key Cryptosystems with Very Small Key Lengths", | ||
417 | * EUROCRYPT '92, Springer-Verlag LNCS 658, | ||
418 | * published February 1993 | ||
419 | * | ||
420 | * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe | ||
421 | * the same method, but claim no priority date earlier than July 29, 1994 | ||
422 | * (and additionally fail to cite the EUROCRYPT '92 publication as prior art). | ||
423 | */ | ||
424 | int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, EC_POINT *point, | ||
425 | const BIGNUM *x_, int y_bit, BN_CTX *ctx) | ||
426 | { | ||
427 | BN_CTX *new_ctx = NULL; | ||
428 | BIGNUM *tmp, *x, *y, *z; | ||
429 | int ret = 0, z0; | ||
430 | |||
431 | /* clear error queue */ | ||
432 | ERR_clear_error(); | ||
433 | |||
434 | if (ctx == NULL) | ||
435 | { | ||
436 | ctx = new_ctx = BN_CTX_new(); | ||
437 | if (ctx == NULL) | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | y_bit = (y_bit != 0) ? 1 : 0; | ||
442 | |||
443 | BN_CTX_start(ctx); | ||
444 | tmp = BN_CTX_get(ctx); | ||
445 | x = BN_CTX_get(ctx); | ||
446 | y = BN_CTX_get(ctx); | ||
447 | z = BN_CTX_get(ctx); | ||
448 | if (z == NULL) goto err; | ||
449 | |||
450 | if (!BN_GF2m_mod_arr(x, x_, group->poly)) goto err; | ||
451 | if (BN_is_zero(x)) | ||
452 | { | ||
453 | if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) goto err; | ||
454 | } | ||
455 | else | ||
456 | { | ||
457 | if (!group->meth->field_sqr(group, tmp, x, ctx)) goto err; | ||
458 | if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) goto err; | ||
459 | if (!BN_GF2m_add(tmp, &group->a, tmp)) goto err; | ||
460 | if (!BN_GF2m_add(tmp, x, tmp)) goto err; | ||
461 | if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) | ||
462 | { | ||
463 | unsigned long err = ERR_peek_last_error(); | ||
464 | |||
465 | if (ERR_GET_LIB(err) == ERR_LIB_BN && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) | ||
466 | { | ||
467 | ERR_clear_error(); | ||
468 | ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, EC_R_INVALID_COMPRESSED_POINT); | ||
469 | } | ||
470 | else | ||
471 | ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, ERR_R_BN_LIB); | ||
472 | goto err; | ||
473 | } | ||
474 | z0 = (BN_is_odd(z)) ? 1 : 0; | ||
475 | if (!group->meth->field_mul(group, y, x, z, ctx)) goto err; | ||
476 | if (z0 != y_bit) | ||
477 | { | ||
478 | if (!BN_GF2m_add(y, y, x)) goto err; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; | ||
483 | |||
484 | ret = 1; | ||
485 | |||
486 | err: | ||
487 | BN_CTX_end(ctx); | ||
488 | if (new_ctx != NULL) | ||
489 | BN_CTX_free(new_ctx); | ||
490 | return ret; | ||
491 | } | ||
411 | 492 | ||
412 | 493 | ||
413 | /* Converts an EC_POINT to an octet string. | 494 | /* Converts an EC_POINT to an octet string. |
414 | * If buf is NULL, the encoded length will be returned. | 495 | * If buf is NULL, the encoded length will be returned. |
415 | * If the length len of buf is smaller than required an error will be returned. | 496 | * If the length len of buf is smaller than required an error will be returned. |
416 | * | ||
417 | * The point compression section of this function is patented by Certicom Corp. | ||
418 | * under US Patent 6,141,420. Point compression is disabled by default and can | ||
419 | * be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at | ||
420 | * Configure-time. | ||
421 | */ | 497 | */ |
422 | size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, | 498 | size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, |
423 | unsigned char *buf, size_t len, BN_CTX *ctx) | 499 | unsigned char *buf, size_t len, BN_CTX *ctx) |
@@ -428,14 +504,6 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po | |||
428 | BIGNUM *x, *y, *yxi; | 504 | BIGNUM *x, *y, *yxi; |
429 | size_t field_len, i, skip; | 505 | size_t field_len, i, skip; |
430 | 506 | ||
431 | #ifndef OPENSSL_EC_BIN_PT_COMP | ||
432 | if ((form == POINT_CONVERSION_COMPRESSED) || (form == POINT_CONVERSION_HYBRID)) | ||
433 | { | ||
434 | ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_DISABLED); | ||
435 | goto err; | ||
436 | } | ||
437 | #endif | ||
438 | |||
439 | if ((form != POINT_CONVERSION_COMPRESSED) | 507 | if ((form != POINT_CONVERSION_COMPRESSED) |
440 | && (form != POINT_CONVERSION_UNCOMPRESSED) | 508 | && (form != POINT_CONVERSION_UNCOMPRESSED) |
441 | && (form != POINT_CONVERSION_HYBRID)) | 509 | && (form != POINT_CONVERSION_HYBRID)) |
@@ -490,13 +558,11 @@ size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, po | |||
490 | if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; | 558 | if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; |
491 | 559 | ||
492 | buf[0] = form; | 560 | buf[0] = form; |
493 | #ifdef OPENSSL_EC_BIN_PT_COMP | ||
494 | if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) | 561 | if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) |
495 | { | 562 | { |
496 | if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; | 563 | if (!group->meth->field_div(group, yxi, y, x, ctx)) goto err; |
497 | if (BN_is_odd(yxi)) buf[0]++; | 564 | if (BN_is_odd(yxi)) buf[0]++; |
498 | } | 565 | } |
499 | #endif | ||
500 | 566 | ||
501 | i = 1; | 567 | i = 1; |
502 | 568 | ||