summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec/ec2_smpl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec/ec2_smpl.c')
-rw-r--r--src/lib/libcrypto/ec/ec2_smpl.c112
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 */
424int 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 */
422size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, 498size_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