1 /* $OpenBSD: bn_lib.c,v 1.46 2019/03/23 18:48:15 beck Exp $ */ 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59 #ifndef BN_DEBUG 60 # undef NDEBUG /* avoid conflicting definitions */ 61 # define NDEBUG 62 #endif 63 64 #include <assert.h> 65 #include <limits.h> 66 #include <stdio.h> 67 #include <string.h> 68 69 #include <openssl/opensslconf.h> 70 71 #include <openssl/err.h> 72 73 #include "bn_lcl.h" 74 75 /* This stuff appears to be completely unused, so is deprecated */ 76 #ifndef OPENSSL_NO_DEPRECATED 77 /* For a 32 bit machine 78 * 2 - 4 == 128 79 * 3 - 8 == 256 80 * 4 - 16 == 512 81 * 5 - 32 == 1024 82 * 6 - 64 == 2048 83 * 7 - 128 == 4096 84 * 8 - 256 == 8192 85 */ 86 static int bn_limit_bits = 0; 87 static int bn_limit_num = 8; /* (1<<bn_limit_bits) */ 88 static int bn_limit_bits_low = 0; 89 static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */ 90 static int bn_limit_bits_high = 0; 91 static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */ 92 static int bn_limit_bits_mont = 0; 93 static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */ 94 95 void 96 BN_set_params(int mult, int high, int low, int mont) 97 { 98 if (mult >= 0) { 99 if (mult > (int)(sizeof(int) * 8) - 1) 100 mult = sizeof(int) * 8 - 1; 101 bn_limit_bits = mult; 102 bn_limit_num = 1 << mult; 103 } 104 if (high >= 0) { 105 if (high > (int)(sizeof(int) * 8) - 1) 106 high = sizeof(int) * 8 - 1; 107 bn_limit_bits_high = high; 108 bn_limit_num_high = 1 << high; 109 } 110 if (low >= 0) { 111 if (low > (int)(sizeof(int) * 8) - 1) 112 low = sizeof(int) * 8 - 1; 113 bn_limit_bits_low = low; 114 bn_limit_num_low = 1 << low; 115 } 116 if (mont >= 0) { 117 if (mont > (int)(sizeof(int) * 8) - 1) 118 mont = sizeof(int) * 8 - 1; 119 bn_limit_bits_mont = mont; 120 bn_limit_num_mont = 1 << mont; 121 } 122 } 123 124 int 125 BN_get_params(int which) 126 { 127 if (which == 0) 128 return (bn_limit_bits); 129 else if (which == 1) 130 return (bn_limit_bits_high); 131 else if (which == 2) 132 return (bn_limit_bits_low); 133 else if (which == 3) 134 return (bn_limit_bits_mont); 135 else 136 return (0); 137 } 138 #endif 139 140 const BIGNUM * 141 BN_value_one(void) 142 { 143 static const BN_ULONG data_one = 1L; 144 static const BIGNUM const_one = { 145 (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA 146 }; 147 148 return (&const_one); 149 } 150 151 int 152 BN_num_bits_word(BN_ULONG l) 153 { 154 static const unsigned char bits[256] = { 155 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 156 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 157 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 158 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 159 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 160 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 161 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 162 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 163 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 164 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 165 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 166 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 167 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 168 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 169 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 170 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 171 }; 172 173 #ifdef _LP64 174 if (l & 0xffffffff00000000L) { 175 if (l & 0xffff000000000000L) { 176 if (l & 0xff00000000000000L) { 177 return (bits[(int)(l >> 56)] + 56); 178 } else 179 return (bits[(int)(l >> 48)] + 48); 180 } else { 181 if (l & 0x0000ff0000000000L) { 182 return (bits[(int)(l >> 40)] + 40); 183 } else 184 return (bits[(int)(l >> 32)] + 32); 185 } 186 } else 187 #endif 188 { 189 if (l & 0xffff0000L) { 190 if (l & 0xff000000L) 191 return (bits[(int)(l >> 24L)] + 24); 192 else 193 return (bits[(int)(l >> 16L)] + 16); 194 } else { 195 if (l & 0xff00L) 196 return (bits[(int)(l >> 8)] + 8); 197 else 198 return (bits[(int)(l)]); 199 } 200 } 201 } 202 203 int 204 BN_num_bits(const BIGNUM *a) 205 { 206 int i = a->top - 1; 207 208 bn_check_top(a); 209 210 if (BN_is_zero(a)) 211 return 0; 212 return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); 213 } 214 215 void 216 BN_clear_free(BIGNUM *a) 217 { 218 int i; 219 220 if (a == NULL) 221 return; 222 bn_check_top(a); 223 if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) 224 freezero(a->d, a->dmax * sizeof(a->d[0])); 225 i = BN_get_flags(a, BN_FLG_MALLOCED); 226 explicit_bzero(a, sizeof(BIGNUM)); 227 if (i) 228 free(a); 229 } 230 231 void 232 BN_free(BIGNUM *a) 233 { 234 BN_clear_free(a); 235 } 236 237 void 238 BN_init(BIGNUM *a) 239 { 240 memset(a, 0, sizeof(BIGNUM)); 241 bn_check_top(a); 242 } 243 244 BIGNUM * 245 BN_new(void) 246 { 247 BIGNUM *ret; 248 249 if ((ret = malloc(sizeof(BIGNUM))) == NULL) { 250 BNerror(ERR_R_MALLOC_FAILURE); 251 return (NULL); 252 } 253 ret->flags = BN_FLG_MALLOCED; 254 ret->top = 0; 255 ret->neg = 0; 256 ret->dmax = 0; 257 ret->d = NULL; 258 bn_check_top(ret); 259 return (ret); 260 } 261 262 /* This is used both by bn_expand2() and bn_dup_expand() */ 263 /* The caller MUST check that words > b->dmax before calling this */ 264 static BN_ULONG * 265 bn_expand_internal(const BIGNUM *b, int words) 266 { 267 BN_ULONG *A, *a = NULL; 268 const BN_ULONG *B; 269 int i; 270 271 bn_check_top(b); 272 273 if (words > (INT_MAX/(4*BN_BITS2))) { 274 BNerror(BN_R_BIGNUM_TOO_LONG); 275 return NULL; 276 } 277 if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { 278 BNerror(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); 279 return (NULL); 280 } 281 a = A = reallocarray(NULL, words, sizeof(BN_ULONG)); 282 if (A == NULL) { 283 BNerror(ERR_R_MALLOC_FAILURE); 284 return (NULL); 285 } 286 #if 1 287 B = b->d; 288 /* Check if the previous number needs to be copied */ 289 if (B != NULL) { 290 for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { 291 /* 292 * The fact that the loop is unrolled 293 * 4-wise is a tribute to Intel. It's 294 * the one that doesn't have enough 295 * registers to accommodate more data. 296 * I'd unroll it 8-wise otherwise:-) 297 * 298 * <appro@fy.chalmers.se> 299 */ 300 BN_ULONG a0, a1, a2, a3; 301 a0 = B[0]; 302 a1 = B[1]; 303 a2 = B[2]; 304 a3 = B[3]; 305 A[0] = a0; 306 A[1] = a1; 307 A[2] = a2; 308 A[3] = a3; 309 } 310 switch (b->top & 3) { 311 case 3: 312 A[2] = B[2]; 313 case 2: 314 A[1] = B[1]; 315 case 1: 316 A[0] = B[0]; 317 } 318 } 319 320 #else 321 memset(A, 0, sizeof(BN_ULONG) * words); 322 memcpy(A, b->d, sizeof(b->d[0]) * b->top); 323 #endif 324 325 return (a); 326 } 327 328 /* This is an internal function that can be used instead of bn_expand2() 329 * when there is a need to copy BIGNUMs instead of only expanding the 330 * data part, while still expanding them. 331 * Especially useful when needing to expand BIGNUMs that are declared 332 * 'const' and should therefore not be changed. 333 * The reason to use this instead of a BN_dup() followed by a bn_expand2() 334 * is memory allocation overhead. A BN_dup() followed by a bn_expand2() 335 * will allocate new memory for the BIGNUM data twice, and free it once, 336 * while bn_dup_expand() makes sure allocation is made only once. 337 */ 338 339 #ifndef OPENSSL_NO_DEPRECATED 340 BIGNUM * 341 bn_dup_expand(const BIGNUM *b, int words) 342 { 343 BIGNUM *r = NULL; 344 345 bn_check_top(b); 346 347 /* This function does not work if 348 * words <= b->dmax && top < words 349 * because BN_dup() does not preserve 'dmax'! 350 * (But bn_dup_expand() is not used anywhere yet.) 351 */ 352 353 if (words > b->dmax) { 354 BN_ULONG *a = bn_expand_internal(b, words); 355 356 if (a) { 357 r = BN_new(); 358 if (r) { 359 r->top = b->top; 360 r->dmax = words; 361 r->neg = b->neg; 362 r->d = a; 363 } else { 364 /* r == NULL, BN_new failure */ 365 free(a); 366 } 367 } 368 /* If a == NULL, there was an error in allocation in 369 bn_expand_internal(), and NULL should be returned */ 370 } else { 371 r = BN_dup(b); 372 } 373 374 bn_check_top(r); 375 return r; 376 } 377 #endif 378 379 /* This is an internal function that should not be used in applications. 380 * It ensures that 'b' has enough room for a 'words' word number 381 * and initialises any unused part of b->d with leading zeros. 382 * It is mostly used by the various BIGNUM routines. If there is an error, 383 * NULL is returned. If not, 'b' is returned. */ 384 385 BIGNUM * 386 bn_expand2(BIGNUM *b, int words) 387 { 388 bn_check_top(b); 389 390 if (words > b->dmax) { 391 BN_ULONG *a = bn_expand_internal(b, words); 392 if (!a) 393 return NULL; 394 if (b->d) 395 freezero(b->d, b->dmax * sizeof(b->d[0])); 396 b->d = a; 397 b->dmax = words; 398 } 399 400 /* None of this should be necessary because of what b->top means! */ 401 #if 0 402 /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */ 403 if (b->top < b->dmax) { 404 int i; 405 BN_ULONG *A = &(b->d[b->top]); 406 for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) { 407 A[0] = 0; 408 A[1] = 0; 409 A[2] = 0; 410 A[3] = 0; 411 A[4] = 0; 412 A[5] = 0; 413 A[6] = 0; 414 A[7] = 0; 415 } 416 for (i = (b->dmax - b->top)&7; i > 0; i--, A++) 417 A[0] = 0; 418 assert(A == &(b->d[b->dmax])); 419 } 420 #endif 421 bn_check_top(b); 422 return b; 423 } 424 425 BIGNUM * 426 BN_dup(const BIGNUM *a) 427 { 428 BIGNUM *t; 429 430 if (a == NULL) 431 return NULL; 432 bn_check_top(a); 433 434 t = BN_new(); 435 if (t == NULL) 436 return NULL; 437 if (!BN_copy(t, a)) { 438 BN_free(t); 439 return NULL; 440 } 441 bn_check_top(t); 442 return t; 443 } 444 445 BIGNUM * 446 BN_copy(BIGNUM *a, const BIGNUM *b) 447 { 448 int i; 449 BN_ULONG *A; 450 const BN_ULONG *B; 451 452 bn_check_top(b); 453 454 if (a == b) 455 return (a); 456 if (bn_wexpand(a, b->top) == NULL) 457 return (NULL); 458 459 #if 1 460 A = a->d; 461 B = b->d; 462 for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { 463 BN_ULONG a0, a1, a2, a3; 464 a0 = B[0]; 465 a1 = B[1]; 466 a2 = B[2]; 467 a3 = B[3]; 468 A[0] = a0; 469 A[1] = a1; 470 A[2] = a2; 471 A[3] = a3; 472 } 473 switch (b->top & 3) { 474 case 3: 475 A[2] = B[2]; 476 case 2: 477 A[1] = B[1]; 478 case 1: 479 A[0] = B[0]; 480 } 481 #else 482 memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); 483 #endif 484 485 a->top = b->top; 486 a->neg = b->neg; 487 bn_check_top(a); 488 return (a); 489 } 490 491 void 492 BN_swap(BIGNUM *a, BIGNUM *b) 493 { 494 int flags_old_a, flags_old_b; 495 BN_ULONG *tmp_d; 496 int tmp_top, tmp_dmax, tmp_neg; 497 498 bn_check_top(a); 499 bn_check_top(b); 500 501 flags_old_a = a->flags; 502 flags_old_b = b->flags; 503 504 tmp_d = a->d; 505 tmp_top = a->top; 506 tmp_dmax = a->dmax; 507 tmp_neg = a->neg; 508 509 a->d = b->d; 510 a->top = b->top; 511 a->dmax = b->dmax; 512 a->neg = b->neg; 513 514 b->d = tmp_d; 515 b->top = tmp_top; 516 b->dmax = tmp_dmax; 517 b->neg = tmp_neg; 518 519 a->flags = (flags_old_a & BN_FLG_MALLOCED) | 520 (flags_old_b & BN_FLG_STATIC_DATA); 521 b->flags = (flags_old_b & BN_FLG_MALLOCED) | 522 (flags_old_a & BN_FLG_STATIC_DATA); 523 bn_check_top(a); 524 bn_check_top(b); 525 } 526 527 void 528 BN_clear(BIGNUM *a) 529 { 530 bn_check_top(a); 531 if (a->d != NULL) 532 explicit_bzero(a->d, a->dmax * sizeof(a->d[0])); 533 a->top = 0; 534 a->neg = 0; 535 } 536 537 BN_ULONG 538 BN_get_word(const BIGNUM *a) 539 { 540 if (a->top > 1) 541 return BN_MASK2; 542 else if (a->top == 1) 543 return a->d[0]; 544 /* a->top == 0 */ 545 return 0; 546 } 547 548 BIGNUM * 549 bn_expand(BIGNUM *a, int bits) 550 { 551 if (bits > (INT_MAX - BN_BITS2 + 1)) 552 return (NULL); 553 554 if (((bits + BN_BITS2 - 1) / BN_BITS2) <= a->dmax) 555 return (a); 556 557 return bn_expand2(a, (bits + BN_BITS2 - 1) / BN_BITS2); 558 } 559 560 int 561 BN_set_word(BIGNUM *a, BN_ULONG w) 562 { 563 bn_check_top(a); 564 if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL) 565 return (0); 566 a->neg = 0; 567 a->d[0] = w; 568 a->top = (w ? 1 : 0); 569 bn_check_top(a); 570 return (1); 571 } 572 573 BIGNUM * 574 BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) 575 { 576 unsigned int i, m; 577 unsigned int n; 578 BN_ULONG l; 579 BIGNUM *bn = NULL; 580 581 if (len < 0) 582 return (NULL); 583 if (ret == NULL) 584 ret = bn = BN_new(); 585 if (ret == NULL) 586 return (NULL); 587 bn_check_top(ret); 588 l = 0; 589 n = len; 590 if (n == 0) { 591 ret->top = 0; 592 return (ret); 593 } 594 i = ((n - 1) / BN_BYTES) + 1; 595 m = ((n - 1) % (BN_BYTES)); 596 if (bn_wexpand(ret, (int)i) == NULL) { 597 BN_free(bn); 598 return NULL; 599 } 600 ret->top = i; 601 ret->neg = 0; 602 while (n--) { 603 l = (l << 8L) | *(s++); 604 if (m-- == 0) { 605 ret->d[--i] = l; 606 l = 0; 607 m = BN_BYTES - 1; 608 } 609 } 610 /* need to call this due to clear byte at top if avoiding 611 * having the top bit set (-ve number) */ 612 bn_correct_top(ret); 613 return (ret); 614 } 615 616 /* ignore negative */ 617 int 618 BN_bn2bin(const BIGNUM *a, unsigned char *to) 619 { 620 int n, i; 621 BN_ULONG l; 622 623 bn_check_top(a); 624 n = i=BN_num_bytes(a); 625 while (i--) { 626 l = a->d[i / BN_BYTES]; 627 *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; 628 } 629 return (n); 630 } 631 632 int 633 BN_ucmp(const BIGNUM *a, const BIGNUM *b) 634 { 635 int i; 636 BN_ULONG t1, t2, *ap, *bp; 637 638 bn_check_top(a); 639 bn_check_top(b); 640 641 i = a->top - b->top; 642 if (i != 0) 643 return (i); 644 ap = a->d; 645 bp = b->d; 646 for (i = a->top - 1; i >= 0; i--) { 647 t1 = ap[i]; 648 t2 = bp[i]; 649 if (t1 != t2) 650 return ((t1 > t2) ? 1 : -1); 651 } 652 return (0); 653 } 654 655 int 656 BN_cmp(const BIGNUM *a, const BIGNUM *b) 657 { 658 int i; 659 int gt, lt; 660 BN_ULONG t1, t2; 661 662 if ((a == NULL) || (b == NULL)) { 663 if (a != NULL) 664 return (-1); 665 else if (b != NULL) 666 return (1); 667 else 668 return (0); 669 } 670 671 bn_check_top(a); 672 bn_check_top(b); 673 674 if (a->neg != b->neg) { 675 if (a->neg) 676 return (-1); 677 else 678 return (1); 679 } 680 if (a->neg == 0) { 681 gt = 1; 682 lt = -1; 683 } else { 684 gt = -1; 685 lt = 1; 686 } 687 688 if (a->top > b->top) 689 return (gt); 690 if (a->top < b->top) 691 return (lt); 692 for (i = a->top - 1; i >= 0; i--) { 693 t1 = a->d[i]; 694 t2 = b->d[i]; 695 if (t1 > t2) 696 return (gt); 697 if (t1 < t2) 698 return (lt); 699 } 700 return (0); 701 } 702 703 int 704 BN_set_bit(BIGNUM *a, int n) 705 { 706 int i, j, k; 707 708 if (n < 0) 709 return 0; 710 711 i = n / BN_BITS2; 712 j = n % BN_BITS2; 713 if (a->top <= i) { 714 if (bn_wexpand(a, i + 1) == NULL) 715 return (0); 716 for (k = a->top; k < i + 1; k++) 717 a->d[k] = 0; 718 a->top = i + 1; 719 } 720 721 a->d[i] |= (((BN_ULONG)1) << j); 722 bn_check_top(a); 723 return (1); 724 } 725 726 int 727 BN_clear_bit(BIGNUM *a, int n) 728 { 729 int i, j; 730 731 bn_check_top(a); 732 if (n < 0) 733 return 0; 734 735 i = n / BN_BITS2; 736 j = n % BN_BITS2; 737 if (a->top <= i) 738 return (0); 739 740 a->d[i] &= (~(((BN_ULONG)1) << j)); 741 bn_correct_top(a); 742 return (1); 743 } 744 745 int 746 BN_is_bit_set(const BIGNUM *a, int n) 747 { 748 int i, j; 749 750 bn_check_top(a); 751 if (n < 0) 752 return 0; 753 i = n / BN_BITS2; 754 j = n % BN_BITS2; 755 if (a->top <= i) 756 return 0; 757 return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); 758 } 759 760 int 761 BN_mask_bits(BIGNUM *a, int n) 762 { 763 int b, w; 764 765 bn_check_top(a); 766 if (n < 0) 767 return 0; 768 769 w = n / BN_BITS2; 770 b = n % BN_BITS2; 771 if (w >= a->top) 772 return 0; 773 if (b == 0) 774 a->top = w; 775 else { 776 a->top = w + 1; 777 a->d[w] &= ~(BN_MASK2 << b); 778 } 779 bn_correct_top(a); 780 return (1); 781 } 782 783 void 784 BN_set_negative(BIGNUM *a, int b) 785 { 786 if (b && !BN_is_zero(a)) 787 a->neg = 1; 788 else 789 a->neg = 0; 790 } 791 792 int 793 bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) 794 { 795 int i; 796 BN_ULONG aa, bb; 797 798 aa = a[n - 1]; 799 bb = b[n - 1]; 800 if (aa != bb) 801 return ((aa > bb) ? 1 : -1); 802 for (i = n - 2; i >= 0; i--) { 803 aa = a[i]; 804 bb = b[i]; 805 if (aa != bb) 806 return ((aa > bb) ? 1 : -1); 807 } 808 return (0); 809 } 810 811 /* Here follows a specialised variants of bn_cmp_words(). It has the 812 property of performing the operation on arrays of different sizes. 813 The sizes of those arrays is expressed through cl, which is the 814 common length ( basicall, min(len(a),len(b)) ), and dl, which is the 815 delta between the two lengths, calculated as len(a)-len(b). 816 All lengths are the number of BN_ULONGs... */ 817 818 int 819 bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl) 820 { 821 int n, i; 822 823 n = cl - 1; 824 825 if (dl < 0) { 826 for (i = dl; i < 0; i++) { 827 if (b[n - i] != 0) 828 return -1; /* a < b */ 829 } 830 } 831 if (dl > 0) { 832 for (i = dl; i > 0; i--) { 833 if (a[n + i] != 0) 834 return 1; /* a > b */ 835 } 836 } 837 return bn_cmp_words(a, b, cl); 838 } 839 840 /* 841 * Constant-time conditional swap of a and b. 842 * a and b are swapped if condition is not 0. 843 * The code assumes that at most one bit of condition is set. 844 * nwords is the number of words to swap. 845 * The code assumes that at least nwords are allocated in both a and b, 846 * and that no more than nwords are used by either a or b. 847 * a and b cannot be the same number 848 */ 849 void 850 BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) 851 { 852 BN_ULONG t; 853 int i; 854 855 bn_wcheck_size(a, nwords); 856 bn_wcheck_size(b, nwords); 857 858 assert(a != b); 859 assert((condition & (condition - 1)) == 0); 860 assert(sizeof(BN_ULONG) >= sizeof(int)); 861 862 condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; 863 864 t = (a->top^b->top) & condition; 865 a->top ^= t; 866 b->top ^= t; 867 868 #define BN_CONSTTIME_SWAP(ind) \ 869 do { \ 870 t = (a->d[ind] ^ b->d[ind]) & condition; \ 871 a->d[ind] ^= t; \ 872 b->d[ind] ^= t; \ 873 } while (0) 874 875 876 switch (nwords) { 877 default: 878 for (i = 10; i < nwords; i++) 879 BN_CONSTTIME_SWAP(i); 880 /* Fallthrough */ 881 case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ 882 case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ 883 case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ 884 case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ 885 case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ 886 case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ 887 case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ 888 case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ 889 case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ 890 case 1: 891 BN_CONSTTIME_SWAP(0); 892 } 893 #undef BN_CONSTTIME_SWAP 894 } 895 896 /* 897 * Constant-time conditional swap of a and b. 898 * a and b are swapped if condition is not 0. 899 * nwords is the number of words to swap. 900 */ 901 int 902 BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, size_t nwords) 903 { 904 BN_ULONG t; 905 int i, words; 906 907 if (a == b) 908 return 1; 909 if (nwords > INT_MAX) 910 return 0; 911 words = (int)nwords; 912 if (bn_wexpand(a, words) == NULL || bn_wexpand(b, words) == NULL) 913 return 0; 914 if (a->top > words || b->top > words) { 915 BNerror(BN_R_INVALID_LENGTH); 916 return 0; 917 } 918 919 /* Set condition to 0 (if it was zero) or all 1s otherwise. */ 920 condition = ((~condition & (condition - 1)) >> (BN_BITS2 - 1)) - 1; 921 922 /* swap top field */ 923 t = (a->top ^ b->top) & condition; 924 a->top ^= t; 925 b->top ^= t; 926 927 /* swap neg field */ 928 t = (a->neg ^ b->neg) & condition; 929 a->neg ^= t; 930 b->neg ^= t; 931 932 /* swap BN_FLG_CONSTTIME from flag field */ 933 t = ((a->flags ^ b->flags) & BN_FLG_CONSTTIME) & condition; 934 a->flags ^= t; 935 b->flags ^= t; 936 937 /* swap the data */ 938 for (i = 0; i < words; i++) { 939 t = (a->d[i] ^ b->d[i]) & condition; 940 a->d[i] ^= t; 941 b->d[i] ^= t; 942 } 943 944 return 1; 945 } 946 947 BN_GENCB * 948 BN_GENCB_new(void) 949 { 950 BN_GENCB *cb; 951 952 if ((cb = calloc(1, sizeof(*cb))) == NULL) 953 return NULL; 954 955 return cb; 956 } 957 958 void 959 BN_GENCB_free(BN_GENCB *cb) 960 { 961 if (cb == NULL) 962 return; 963 free(cb); 964 } 965 966 void * 967 BN_GENCB_get_arg(BN_GENCB *cb) 968 { 969 return cb->arg; 970 } 971