diff options
Diffstat (limited to 'src/lib/libcrypto/bn/bn_nist.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_nist.c | 184 |
1 files changed, 134 insertions, 50 deletions
diff --git a/src/lib/libcrypto/bn/bn_nist.c b/src/lib/libcrypto/bn/bn_nist.c index e14232fdbb..1fc94f55c3 100644 --- a/src/lib/libcrypto/bn/bn_nist.c +++ b/src/lib/libcrypto/bn/bn_nist.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include "bn_lcl.h" | 59 | #include "bn_lcl.h" |
60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
61 | 61 | ||
62 | |||
62 | #define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 | 63 | #define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 |
63 | #define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 | 64 | #define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 |
64 | #define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 | 65 | #define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 |
@@ -101,60 +102,98 @@ static const BN_ULONG _nist_p_521[] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, | |||
101 | 0xFFFFFFFF,0x000001FF}; | 102 | 0xFFFFFFFF,0x000001FF}; |
102 | #endif | 103 | #endif |
103 | 104 | ||
105 | |||
106 | static const BIGNUM _bignum_nist_p_192 = | ||
107 | { | ||
108 | (BN_ULONG *)_nist_p_192, | ||
109 | BN_NIST_192_TOP, | ||
110 | BN_NIST_192_TOP, | ||
111 | 0, | ||
112 | BN_FLG_STATIC_DATA | ||
113 | }; | ||
114 | |||
115 | static const BIGNUM _bignum_nist_p_224 = | ||
116 | { | ||
117 | (BN_ULONG *)_nist_p_224, | ||
118 | BN_NIST_224_TOP, | ||
119 | BN_NIST_224_TOP, | ||
120 | 0, | ||
121 | BN_FLG_STATIC_DATA | ||
122 | }; | ||
123 | |||
124 | static const BIGNUM _bignum_nist_p_256 = | ||
125 | { | ||
126 | (BN_ULONG *)_nist_p_256, | ||
127 | BN_NIST_256_TOP, | ||
128 | BN_NIST_256_TOP, | ||
129 | 0, | ||
130 | BN_FLG_STATIC_DATA | ||
131 | }; | ||
132 | |||
133 | static const BIGNUM _bignum_nist_p_384 = | ||
134 | { | ||
135 | (BN_ULONG *)_nist_p_384, | ||
136 | BN_NIST_384_TOP, | ||
137 | BN_NIST_384_TOP, | ||
138 | 0, | ||
139 | BN_FLG_STATIC_DATA | ||
140 | }; | ||
141 | |||
142 | static const BIGNUM _bignum_nist_p_521 = | ||
143 | { | ||
144 | (BN_ULONG *)_nist_p_521, | ||
145 | BN_NIST_521_TOP, | ||
146 | BN_NIST_521_TOP, | ||
147 | 0, | ||
148 | BN_FLG_STATIC_DATA | ||
149 | }; | ||
150 | |||
151 | |||
104 | const BIGNUM *BN_get0_nist_prime_192(void) | 152 | const BIGNUM *BN_get0_nist_prime_192(void) |
105 | { | 153 | { |
106 | static BIGNUM const_nist_192 = { (BN_ULONG *)_nist_p_192, | 154 | return &_bignum_nist_p_192; |
107 | BN_NIST_192_TOP, BN_NIST_192_TOP, 0, BN_FLG_STATIC_DATA }; | ||
108 | return &const_nist_192; | ||
109 | } | 155 | } |
110 | 156 | ||
111 | const BIGNUM *BN_get0_nist_prime_224(void) | 157 | const BIGNUM *BN_get0_nist_prime_224(void) |
112 | { | 158 | { |
113 | static BIGNUM const_nist_224 = { (BN_ULONG *)_nist_p_224, | 159 | return &_bignum_nist_p_224; |
114 | BN_NIST_224_TOP, BN_NIST_224_TOP, 0, BN_FLG_STATIC_DATA }; | ||
115 | return &const_nist_224; | ||
116 | } | 160 | } |
117 | 161 | ||
118 | const BIGNUM *BN_get0_nist_prime_256(void) | 162 | const BIGNUM *BN_get0_nist_prime_256(void) |
119 | { | 163 | { |
120 | static BIGNUM const_nist_256 = { (BN_ULONG *)_nist_p_256, | 164 | return &_bignum_nist_p_256; |
121 | BN_NIST_256_TOP, BN_NIST_256_TOP, 0, BN_FLG_STATIC_DATA }; | ||
122 | return &const_nist_256; | ||
123 | } | 165 | } |
124 | 166 | ||
125 | const BIGNUM *BN_get0_nist_prime_384(void) | 167 | const BIGNUM *BN_get0_nist_prime_384(void) |
126 | { | 168 | { |
127 | static BIGNUM const_nist_384 = { (BN_ULONG *)_nist_p_384, | 169 | return &_bignum_nist_p_384; |
128 | BN_NIST_384_TOP, BN_NIST_384_TOP, 0, BN_FLG_STATIC_DATA }; | ||
129 | return &const_nist_384; | ||
130 | } | 170 | } |
131 | 171 | ||
132 | const BIGNUM *BN_get0_nist_prime_521(void) | 172 | const BIGNUM *BN_get0_nist_prime_521(void) |
133 | { | 173 | { |
134 | static BIGNUM const_nist_521 = { (BN_ULONG *)_nist_p_521, | 174 | return &_bignum_nist_p_521; |
135 | BN_NIST_521_TOP, BN_NIST_521_TOP, 0, BN_FLG_STATIC_DATA }; | ||
136 | return &const_nist_521; | ||
137 | } | 175 | } |
138 | 176 | ||
139 | #define BN_NIST_ADD_ONE(a) while (!(*(a)=(*(a)+1)&BN_MASK2)) ++(a); | ||
140 | 177 | ||
141 | static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max) | 178 | static void nist_cp_bn_0(BN_ULONG *buf, BN_ULONG *a, int top, int max) |
142 | { | 179 | { |
143 | int i; | 180 | int i; |
144 | BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); | 181 | BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); |
145 | for (i = (top); i != 0; i--) | 182 | |
146 | *_tmp1++ = *_tmp2++; | 183 | OPENSSL_assert(top <= max); |
147 | for (i = (max) - (top); i != 0; i--) | 184 | for (i = (top); i != 0; i--) |
148 | *_tmp1++ = (BN_ULONG) 0; | 185 | *_tmp1++ = *_tmp2++; |
149 | } | 186 | for (i = (max) - (top); i != 0; i--) |
187 | *_tmp1++ = (BN_ULONG) 0; | ||
188 | } | ||
150 | 189 | ||
151 | static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top) | 190 | static void nist_cp_bn(BN_ULONG *buf, BN_ULONG *a, int top) |
152 | { | 191 | { |
153 | int i; | 192 | int i; |
154 | BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); | 193 | BN_ULONG *_tmp1 = (buf), *_tmp2 = (a); |
155 | for (i = (top); i != 0; i--) | 194 | for (i = (top); i != 0; i--) |
156 | *_tmp1++ = *_tmp2++; | 195 | *_tmp1++ = *_tmp2++; |
157 | } | 196 | } |
158 | 197 | ||
159 | #if BN_BITS2 == 64 | 198 | #if BN_BITS2 == 64 |
160 | #define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; | 199 | #define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; |
@@ -199,6 +238,11 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
199 | *res; | 238 | *res; |
200 | size_t mask; | 239 | size_t mask; |
201 | 240 | ||
241 | field = &_bignum_nist_p_192; /* just to make sure */ | ||
242 | |||
243 | if (BN_is_negative(a) || a->top > 2*BN_NIST_192_TOP) | ||
244 | return BN_nnmod(r, field, a, ctx); | ||
245 | |||
202 | i = BN_ucmp(field, a); | 246 | i = BN_ucmp(field, a); |
203 | if (i == 0) | 247 | if (i == 0) |
204 | { | 248 | { |
@@ -208,9 +252,6 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
208 | else if (i > 0) | 252 | else if (i > 0) |
209 | return (r == a) ? 1 : (BN_copy(r ,a) != NULL); | 253 | return (r == a) ? 1 : (BN_copy(r ,a) != NULL); |
210 | 254 | ||
211 | if (top == BN_NIST_192_TOP) | ||
212 | return BN_usub(r, a, field); | ||
213 | |||
214 | if (r != a) | 255 | if (r != a) |
215 | { | 256 | { |
216 | if (!bn_wexpand(r, BN_NIST_192_TOP)) | 257 | if (!bn_wexpand(r, BN_NIST_192_TOP)) |
@@ -245,6 +286,11 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
245 | r->top = BN_NIST_192_TOP; | 286 | r->top = BN_NIST_192_TOP; |
246 | bn_correct_top(r); | 287 | bn_correct_top(r); |
247 | 288 | ||
289 | if (BN_ucmp(field, r) <= 0) | ||
290 | { | ||
291 | if (!BN_usub(r, r, field)) return 0; | ||
292 | } | ||
293 | |||
248 | return 1; | 294 | return 1; |
249 | } | 295 | } |
250 | 296 | ||
@@ -272,6 +318,11 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
272 | *res; | 318 | *res; |
273 | size_t mask; | 319 | size_t mask; |
274 | 320 | ||
321 | field = &_bignum_nist_p_224; /* just to make sure */ | ||
322 | |||
323 | if (BN_is_negative(a) || a->top > 2*BN_NIST_224_TOP) | ||
324 | return BN_nnmod(r, field, a, ctx); | ||
325 | |||
275 | i = BN_ucmp(field, a); | 326 | i = BN_ucmp(field, a); |
276 | if (i == 0) | 327 | if (i == 0) |
277 | { | 328 | { |
@@ -281,9 +332,6 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
281 | else if (i > 0) | 332 | else if (i > 0) |
282 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | 333 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); |
283 | 334 | ||
284 | if (top == BN_NIST_224_TOP) | ||
285 | return BN_usub(r, a, field); | ||
286 | |||
287 | if (r != a) | 335 | if (r != a) |
288 | { | 336 | { |
289 | if (!bn_wexpand(r, BN_NIST_224_TOP)) | 337 | if (!bn_wexpand(r, BN_NIST_224_TOP)) |
@@ -333,6 +381,11 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
333 | r->top = BN_NIST_224_TOP; | 381 | r->top = BN_NIST_224_TOP; |
334 | bn_correct_top(r); | 382 | bn_correct_top(r); |
335 | 383 | ||
384 | if (BN_ucmp(field, r) <= 0) | ||
385 | { | ||
386 | if (!BN_usub(r, r, field)) return 0; | ||
387 | } | ||
388 | |||
336 | return 1; | 389 | return 1; |
337 | #else /* BN_BITS!=32 */ | 390 | #else /* BN_BITS!=32 */ |
338 | return 0; | 391 | return 0; |
@@ -364,6 +417,11 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
364 | *res; | 417 | *res; |
365 | size_t mask; | 418 | size_t mask; |
366 | 419 | ||
420 | field = &_bignum_nist_p_256; /* just to make sure */ | ||
421 | |||
422 | if (BN_is_negative(a) || a->top > 2*BN_NIST_256_TOP) | ||
423 | return BN_nnmod(r, field, a, ctx); | ||
424 | |||
367 | i = BN_ucmp(field, a); | 425 | i = BN_ucmp(field, a); |
368 | if (i == 0) | 426 | if (i == 0) |
369 | { | 427 | { |
@@ -373,9 +431,6 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
373 | else if (i > 0) | 431 | else if (i > 0) |
374 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | 432 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); |
375 | 433 | ||
376 | if (top == BN_NIST_256_TOP) | ||
377 | return BN_usub(r, a, field); | ||
378 | |||
379 | if (r != a) | 434 | if (r != a) |
380 | { | 435 | { |
381 | if (!bn_wexpand(r, BN_NIST_256_TOP)) | 436 | if (!bn_wexpand(r, BN_NIST_256_TOP)) |
@@ -470,6 +525,11 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
470 | r->top = BN_NIST_256_TOP; | 525 | r->top = BN_NIST_256_TOP; |
471 | bn_correct_top(r); | 526 | bn_correct_top(r); |
472 | 527 | ||
528 | if (BN_ucmp(field, r) <= 0) | ||
529 | { | ||
530 | if (!BN_usub(r, r, field)) return 0; | ||
531 | } | ||
532 | |||
473 | return 1; | 533 | return 1; |
474 | #else /* BN_BITS!=32 */ | 534 | #else /* BN_BITS!=32 */ |
475 | return 0; | 535 | return 0; |
@@ -505,6 +565,11 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
505 | *res; | 565 | *res; |
506 | size_t mask; | 566 | size_t mask; |
507 | 567 | ||
568 | field = &_bignum_nist_p_384; /* just to make sure */ | ||
569 | |||
570 | if (BN_is_negative(a) || a->top > 2*BN_NIST_384_TOP) | ||
571 | return BN_nnmod(r, field, a, ctx); | ||
572 | |||
508 | i = BN_ucmp(field, a); | 573 | i = BN_ucmp(field, a); |
509 | if (i == 0) | 574 | if (i == 0) |
510 | { | 575 | { |
@@ -514,9 +579,6 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
514 | else if (i > 0) | 579 | else if (i > 0) |
515 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | 580 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); |
516 | 581 | ||
517 | if (top == BN_NIST_384_TOP) | ||
518 | return BN_usub(r, a, field); | ||
519 | |||
520 | if (r != a) | 582 | if (r != a) |
521 | { | 583 | { |
522 | if (!bn_wexpand(r, BN_NIST_384_TOP)) | 584 | if (!bn_wexpand(r, BN_NIST_384_TOP)) |
@@ -631,6 +693,11 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
631 | r->top = BN_NIST_384_TOP; | 693 | r->top = BN_NIST_384_TOP; |
632 | bn_correct_top(r); | 694 | bn_correct_top(r); |
633 | 695 | ||
696 | if (BN_ucmp(field, r) <= 0) | ||
697 | { | ||
698 | if (!BN_usub(r, r, field)) return 0; | ||
699 | } | ||
700 | |||
634 | return 1; | 701 | return 1; |
635 | #else /* BN_BITS!=32 */ | 702 | #else /* BN_BITS!=32 */ |
636 | return 0; | 703 | return 0; |
@@ -646,14 +713,35 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
646 | #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF | 713 | #define BN_NIST_521_TOP_MASK (BN_ULONG)0x1FF |
647 | #endif | 714 | #endif |
648 | int top, ret = 0; | 715 | int top, ret = 0; |
649 | BN_ULONG *r_d; | ||
650 | BIGNUM *tmp; | 716 | BIGNUM *tmp; |
651 | 717 | ||
718 | field = &_bignum_nist_p_521; /* just to make sure */ | ||
719 | |||
720 | if (BN_is_negative(a)) | ||
721 | return BN_nnmod(r, field, a, ctx); | ||
722 | |||
652 | /* check whether a reduction is necessary */ | 723 | /* check whether a reduction is necessary */ |
653 | top = a->top; | 724 | top = a->top; |
654 | if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP && | 725 | if (top < BN_NIST_521_TOP || ( top == BN_NIST_521_TOP && |
655 | (!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK))))) | 726 | (!(a->d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK))))) |
656 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | 727 | { |
728 | int i = BN_ucmp(field, a); | ||
729 | if (i == 0) | ||
730 | { | ||
731 | BN_zero(r); | ||
732 | return 1; | ||
733 | } | ||
734 | else | ||
735 | { | ||
736 | #ifdef BN_DEBUG | ||
737 | OPENSSL_assert(i > 0); /* because 'field' is 1111...1111 */ | ||
738 | #endif | ||
739 | return (r == a)? 1 : (BN_copy(r ,a) != NULL); | ||
740 | } | ||
741 | } | ||
742 | |||
743 | if (BN_num_bits(a) > 2*521) | ||
744 | return BN_nnmod(r, field, a, ctx); | ||
657 | 745 | ||
658 | BN_CTX_start(ctx); | 746 | BN_CTX_start(ctx); |
659 | tmp = BN_CTX_get(ctx); | 747 | tmp = BN_CTX_get(ctx); |
@@ -673,15 +761,11 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, | |||
673 | 761 | ||
674 | if (!BN_uadd(r, tmp, r)) | 762 | if (!BN_uadd(r, tmp, r)) |
675 | goto err; | 763 | goto err; |
676 | top = r->top; | 764 | |
677 | r_d = r->d; | 765 | if (BN_ucmp(field, r) <= 0) |
678 | if (top == BN_NIST_521_TOP && | ||
679 | (r_d[BN_NIST_521_TOP-1] & ~(BN_NIST_521_TOP_MASK))) | ||
680 | { | 766 | { |
681 | BN_NIST_ADD_ONE(r_d) | 767 | if (!BN_usub(r, r, field)) goto err; |
682 | r->d[BN_NIST_521_TOP-1] &= BN_NIST_521_TOP_MASK; | ||
683 | } | 768 | } |
684 | bn_correct_top(r); | ||
685 | 769 | ||
686 | ret = 1; | 770 | ret = 1; |
687 | err: | 771 | err: |