diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_gf2m.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_gf2m.c | 114 |
1 files changed, 96 insertions, 18 deletions
diff --git a/src/lib/libcrypto/bn/bn_gf2m.c b/src/lib/libcrypto/bn/bn_gf2m.c index 432a3aa338..8a4dc20ad9 100644 --- a/src/lib/libcrypto/bn/bn_gf2m.c +++ b/src/lib/libcrypto/bn/bn_gf2m.c | |||
@@ -94,6 +94,8 @@ | |||
94 | #include "cryptlib.h" | 94 | #include "cryptlib.h" |
95 | #include "bn_lcl.h" | 95 | #include "bn_lcl.h" |
96 | 96 | ||
97 | #ifndef OPENSSL_NO_EC2M | ||
98 | |||
97 | /* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */ | 99 | /* Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should fail. */ |
98 | #define MAX_ITERATIONS 50 | 100 | #define MAX_ITERATIONS 50 |
99 | 101 | ||
@@ -122,6 +124,7 @@ static const BN_ULONG SQR_tb[16] = | |||
122 | SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] | 124 | SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] |
123 | #endif | 125 | #endif |
124 | 126 | ||
127 | #if !defined(OPENSSL_BN_ASM_GF2m) | ||
125 | /* Product of two polynomials a, b each with degree < BN_BITS2 - 1, | 128 | /* Product of two polynomials a, b each with degree < BN_BITS2 - 1, |
126 | * result is a polynomial r with degree < 2 * BN_BITS - 1 | 129 | * result is a polynomial r with degree < 2 * BN_BITS - 1 |
127 | * The caller MUST ensure that the variables have the right amount | 130 | * The caller MUST ensure that the variables have the right amount |
@@ -216,7 +219,9 @@ static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, c | |||
216 | r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ | 219 | r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ |
217 | r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ | 220 | r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ |
218 | } | 221 | } |
219 | 222 | #else | |
223 | void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0); | ||
224 | #endif | ||
220 | 225 | ||
221 | /* Add polynomials a and b and store result in r; r could be a or b, a and b | 226 | /* Add polynomials a and b and store result in r; r could be a or b, a and b |
222 | * could be equal; r is the bitwise XOR of a and b. | 227 | * could be equal; r is the bitwise XOR of a and b. |
@@ -360,21 +365,17 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]) | |||
360 | int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) | 365 | int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) |
361 | { | 366 | { |
362 | int ret = 0; | 367 | int ret = 0; |
363 | const int max = BN_num_bits(p) + 1; | 368 | int arr[6]; |
364 | int *arr=NULL; | ||
365 | bn_check_top(a); | 369 | bn_check_top(a); |
366 | bn_check_top(p); | 370 | bn_check_top(p); |
367 | if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) goto err; | 371 | ret = BN_GF2m_poly2arr(p, arr, sizeof(arr)/sizeof(arr[0])); |
368 | ret = BN_GF2m_poly2arr(p, arr, max); | 372 | if (!ret || ret > (int)(sizeof(arr)/sizeof(arr[0]))) |
369 | if (!ret || ret > max) | ||
370 | { | 373 | { |
371 | BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH); | 374 | BNerr(BN_F_BN_GF2M_MOD,BN_R_INVALID_LENGTH); |
372 | goto err; | 375 | return 0; |
373 | } | 376 | } |
374 | ret = BN_GF2m_mod_arr(r, a, arr); | 377 | ret = BN_GF2m_mod_arr(r, a, arr); |
375 | bn_check_top(r); | 378 | bn_check_top(r); |
376 | err: | ||
377 | if (arr) OPENSSL_free(arr); | ||
378 | return ret; | 379 | return ret; |
379 | } | 380 | } |
380 | 381 | ||
@@ -521,7 +522,7 @@ err: | |||
521 | */ | 522 | */ |
522 | int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | 523 | int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) |
523 | { | 524 | { |
524 | BIGNUM *b, *c, *u, *v, *tmp; | 525 | BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp; |
525 | int ret = 0; | 526 | int ret = 0; |
526 | 527 | ||
527 | bn_check_top(a); | 528 | bn_check_top(a); |
@@ -529,18 +530,18 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
529 | 530 | ||
530 | BN_CTX_start(ctx); | 531 | BN_CTX_start(ctx); |
531 | 532 | ||
532 | b = BN_CTX_get(ctx); | 533 | if ((b = BN_CTX_get(ctx))==NULL) goto err; |
533 | c = BN_CTX_get(ctx); | 534 | if ((c = BN_CTX_get(ctx))==NULL) goto err; |
534 | u = BN_CTX_get(ctx); | 535 | if ((u = BN_CTX_get(ctx))==NULL) goto err; |
535 | v = BN_CTX_get(ctx); | 536 | if ((v = BN_CTX_get(ctx))==NULL) goto err; |
536 | if (v == NULL) goto err; | ||
537 | 537 | ||
538 | if (!BN_one(b)) goto err; | ||
539 | if (!BN_GF2m_mod(u, a, p)) goto err; | 538 | if (!BN_GF2m_mod(u, a, p)) goto err; |
540 | if (!BN_copy(v, p)) goto err; | ||
541 | |||
542 | if (BN_is_zero(u)) goto err; | 539 | if (BN_is_zero(u)) goto err; |
543 | 540 | ||
541 | if (!BN_copy(v, p)) goto err; | ||
542 | #if 0 | ||
543 | if (!BN_one(b)) goto err; | ||
544 | |||
544 | while (1) | 545 | while (1) |
545 | { | 546 | { |
546 | while (!BN_is_odd(u)) | 547 | while (!BN_is_odd(u)) |
@@ -565,13 +566,89 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) | |||
565 | if (!BN_GF2m_add(u, u, v)) goto err; | 566 | if (!BN_GF2m_add(u, u, v)) goto err; |
566 | if (!BN_GF2m_add(b, b, c)) goto err; | 567 | if (!BN_GF2m_add(b, b, c)) goto err; |
567 | } | 568 | } |
569 | #else | ||
570 | { | ||
571 | int i, ubits = BN_num_bits(u), | ||
572 | vbits = BN_num_bits(v), /* v is copy of p */ | ||
573 | top = p->top; | ||
574 | BN_ULONG *udp,*bdp,*vdp,*cdp; | ||
575 | |||
576 | bn_wexpand(u,top); udp = u->d; | ||
577 | for (i=u->top;i<top;i++) udp[i] = 0; | ||
578 | u->top = top; | ||
579 | bn_wexpand(b,top); bdp = b->d; | ||
580 | bdp[0] = 1; | ||
581 | for (i=1;i<top;i++) bdp[i] = 0; | ||
582 | b->top = top; | ||
583 | bn_wexpand(c,top); cdp = c->d; | ||
584 | for (i=0;i<top;i++) cdp[i] = 0; | ||
585 | c->top = top; | ||
586 | vdp = v->d; /* It pays off to "cache" *->d pointers, because | ||
587 | * it allows optimizer to be more aggressive. | ||
588 | * But we don't have to "cache" p->d, because *p | ||
589 | * is declared 'const'... */ | ||
590 | while (1) | ||
591 | { | ||
592 | while (ubits && !(udp[0]&1)) | ||
593 | { | ||
594 | BN_ULONG u0,u1,b0,b1,mask; | ||
595 | |||
596 | u0 = udp[0]; | ||
597 | b0 = bdp[0]; | ||
598 | mask = (BN_ULONG)0-(b0&1); | ||
599 | b0 ^= p->d[0]&mask; | ||
600 | for (i=0;i<top-1;i++) | ||
601 | { | ||
602 | u1 = udp[i+1]; | ||
603 | udp[i] = ((u0>>1)|(u1<<(BN_BITS2-1)))&BN_MASK2; | ||
604 | u0 = u1; | ||
605 | b1 = bdp[i+1]^(p->d[i+1]&mask); | ||
606 | bdp[i] = ((b0>>1)|(b1<<(BN_BITS2-1)))&BN_MASK2; | ||
607 | b0 = b1; | ||
608 | } | ||
609 | udp[i] = u0>>1; | ||
610 | bdp[i] = b0>>1; | ||
611 | ubits--; | ||
612 | } | ||
568 | 613 | ||
614 | if (ubits<=BN_BITS2 && udp[0]==1) break; | ||
615 | |||
616 | if (ubits<vbits) | ||
617 | { | ||
618 | i = ubits; ubits = vbits; vbits = i; | ||
619 | tmp = u; u = v; v = tmp; | ||
620 | tmp = b; b = c; c = tmp; | ||
621 | udp = vdp; vdp = v->d; | ||
622 | bdp = cdp; cdp = c->d; | ||
623 | } | ||
624 | for(i=0;i<top;i++) | ||
625 | { | ||
626 | udp[i] ^= vdp[i]; | ||
627 | bdp[i] ^= cdp[i]; | ||
628 | } | ||
629 | if (ubits==vbits) | ||
630 | { | ||
631 | BN_ULONG ul; | ||
632 | int utop = (ubits-1)/BN_BITS2; | ||
633 | |||
634 | while ((ul=udp[utop])==0 && utop) utop--; | ||
635 | ubits = utop*BN_BITS2 + BN_num_bits_word(ul); | ||
636 | } | ||
637 | } | ||
638 | bn_correct_top(b); | ||
639 | } | ||
640 | #endif | ||
569 | 641 | ||
570 | if (!BN_copy(r, b)) goto err; | 642 | if (!BN_copy(r, b)) goto err; |
571 | bn_check_top(r); | 643 | bn_check_top(r); |
572 | ret = 1; | 644 | ret = 1; |
573 | 645 | ||
574 | err: | 646 | err: |
647 | #ifdef BN_DEBUG /* BN_CTX_end would complain about the expanded form */ | ||
648 | bn_correct_top(c); | ||
649 | bn_correct_top(u); | ||
650 | bn_correct_top(v); | ||
651 | #endif | ||
575 | BN_CTX_end(ctx); | 652 | BN_CTX_end(ctx); |
576 | return ret; | 653 | return ret; |
577 | } | 654 | } |
@@ -1033,3 +1110,4 @@ int BN_GF2m_arr2poly(const int p[], BIGNUM *a) | |||
1033 | return 1; | 1110 | return 1; |
1034 | } | 1111 | } |
1035 | 1112 | ||
1113 | #endif | ||