diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/bn/bn.h | 7 | ||||
| -rw-r--r-- | src/lib/libcrypto/bn/bn_lib.c | 139 |
2 files changed, 137 insertions, 9 deletions
diff --git a/src/lib/libcrypto/bn/bn.h b/src/lib/libcrypto/bn/bn.h index cc1f467523..f03b2c7be7 100644 --- a/src/lib/libcrypto/bn/bn.h +++ b/src/lib/libcrypto/bn/bn.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn.h,v 1.39 2019/08/25 19:23:59 schwarze Exp $ */ | 1 | /* $OpenBSD: bn.h,v 1.40 2021/09/08 12:19:17 tb Exp $ */ |
| 2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -428,6 +428,11 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); | |||
| 428 | void BN_swap(BIGNUM *a, BIGNUM *b); | 428 | void BN_swap(BIGNUM *a, BIGNUM *b); |
| 429 | BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); | 429 | BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); |
| 430 | int BN_bn2bin(const BIGNUM *a, unsigned char *to); | 430 | int BN_bn2bin(const BIGNUM *a, unsigned char *to); |
| 431 | #if defined(LIBRESSL_INTERNAL) | ||
| 432 | int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); | ||
| 433 | BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); | ||
| 434 | int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen); | ||
| 435 | #endif | ||
| 431 | BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); | 436 | BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); |
| 432 | int BN_bn2mpi(const BIGNUM *a, unsigned char *to); | 437 | int BN_bn2mpi(const BIGNUM *a, unsigned char *to); |
| 433 | int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); | 438 | int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); |
diff --git a/src/lib/libcrypto/bn/bn_lib.c b/src/lib/libcrypto/bn/bn_lib.c index 1a91b9e60c..af837eed01 100644 --- a/src/lib/libcrypto/bn/bn_lib.c +++ b/src/lib/libcrypto/bn/bn_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: bn_lib.c,v 1.47 2019/06/17 17:11:48 tb Exp $ */ | 1 | /* $OpenBSD: bn_lib.c,v 1.48 2021/09/08 12:19:17 tb Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -583,20 +583,143 @@ BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) | |||
| 583 | return (ret); | 583 | return (ret); |
| 584 | } | 584 | } |
| 585 | 585 | ||
| 586 | typedef enum { | ||
| 587 | big, | ||
| 588 | little, | ||
| 589 | } endianness_t; | ||
| 590 | |||
| 586 | /* ignore negative */ | 591 | /* ignore negative */ |
| 592 | static int | ||
| 593 | bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness) | ||
| 594 | { | ||
| 595 | int n; | ||
| 596 | size_t i, lasti, j, atop, mask; | ||
| 597 | BN_ULONG l; | ||
| 598 | |||
| 599 | /* | ||
| 600 | * In case |a| is fixed-top, BN_num_bytes can return bogus length, | ||
| 601 | * but it's assumed that fixed-top inputs ought to be "nominated" | ||
| 602 | * even for padded output, so it works out... | ||
| 603 | */ | ||
| 604 | n = BN_num_bytes(a); | ||
| 605 | if (tolen == -1) | ||
| 606 | tolen = n; | ||
| 607 | else if (tolen < n) { /* uncommon/unlike case */ | ||
| 608 | BIGNUM temp = *a; | ||
| 609 | |||
| 610 | bn_correct_top(&temp); | ||
| 611 | |||
| 612 | n = BN_num_bytes(&temp); | ||
| 613 | if (tolen < n) | ||
| 614 | return -1; | ||
| 615 | } | ||
| 616 | |||
| 617 | /* Swipe through whole available data and don't give away padded zero. */ | ||
| 618 | atop = a->dmax * BN_BYTES; | ||
| 619 | if (atop == 0) { | ||
| 620 | explicit_bzero(to, tolen); | ||
| 621 | return tolen; | ||
| 622 | } | ||
| 623 | |||
| 624 | lasti = atop - 1; | ||
| 625 | atop = a->top * BN_BYTES; | ||
| 626 | |||
| 627 | if (endianness == big) | ||
| 628 | to += tolen; /* start from the end of the buffer */ | ||
| 629 | |||
| 630 | for (i = 0, j = 0; j < (size_t)tolen; j++) { | ||
| 631 | unsigned char val; | ||
| 632 | |||
| 633 | l = a->d[i / BN_BYTES]; | ||
| 634 | mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); | ||
| 635 | val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); | ||
| 636 | |||
| 637 | if (endianness == big) | ||
| 638 | *--to = val; | ||
| 639 | else | ||
| 640 | *to++ = val; | ||
| 641 | |||
| 642 | i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ | ||
| 643 | } | ||
| 644 | |||
| 645 | return tolen; | ||
| 646 | } | ||
| 647 | |||
| 648 | int | ||
| 649 | BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) | ||
| 650 | { | ||
| 651 | if (tolen < 0) | ||
| 652 | return -1; | ||
| 653 | return bn2binpad(a, to, tolen, big); | ||
| 654 | } | ||
| 655 | |||
| 587 | int | 656 | int |
| 588 | BN_bn2bin(const BIGNUM *a, unsigned char *to) | 657 | BN_bn2bin(const BIGNUM *a, unsigned char *to) |
| 589 | { | 658 | { |
| 590 | int n, i; | 659 | return bn2binpad(a, to, -1, big); |
| 660 | } | ||
| 661 | |||
| 662 | BIGNUM * | ||
| 663 | BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret) | ||
| 664 | { | ||
| 665 | unsigned int i, m, n; | ||
| 591 | BN_ULONG l; | 666 | BN_ULONG l; |
| 667 | BIGNUM *bn = NULL; | ||
| 592 | 668 | ||
| 593 | bn_check_top(a); | 669 | if (ret == NULL) |
| 594 | n = i=BN_num_bytes(a); | 670 | ret = bn = BN_new(); |
| 595 | while (i--) { | 671 | if (ret == NULL) |
| 596 | l = a->d[i / BN_BYTES]; | 672 | return NULL; |
| 597 | *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; | 673 | |
| 674 | bn_check_top(ret); | ||
| 675 | |||
| 676 | s += len; | ||
| 677 | /* Skip trailing zeroes. */ | ||
| 678 | for (; len > 0 && s[-1] == 0; s--, len--) | ||
| 679 | continue; | ||
| 680 | |||
| 681 | n = len; | ||
| 682 | if (n == 0) { | ||
| 683 | ret->top = 0; | ||
| 684 | return ret; | ||
| 598 | } | 685 | } |
| 599 | return (n); | 686 | |
| 687 | i = ((n - 1) / BN_BYTES) + 1; | ||
| 688 | m = (n - 1) % BN_BYTES; | ||
| 689 | if (bn_wexpand(ret, (int)i) == NULL) { | ||
| 690 | BN_free(bn); | ||
| 691 | return NULL; | ||
| 692 | } | ||
| 693 | |||
| 694 | ret->top = i; | ||
| 695 | ret->neg = 0; | ||
| 696 | l = 0; | ||
| 697 | while (n-- > 0) { | ||
| 698 | s--; | ||
| 699 | l = (l << 8L) | *s; | ||
| 700 | if (m-- == 0) { | ||
| 701 | ret->d[--i] = l; | ||
| 702 | l = 0; | ||
| 703 | m = BN_BYTES - 1; | ||
| 704 | } | ||
| 705 | } | ||
| 706 | |||
| 707 | /* | ||
| 708 | * need to call this due to clear byte at top if avoiding having the | ||
| 709 | * top bit set (-ve number) | ||
| 710 | */ | ||
| 711 | bn_correct_top(ret); | ||
| 712 | |||
| 713 | return ret; | ||
| 714 | } | ||
| 715 | |||
| 716 | int | ||
| 717 | BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen) | ||
| 718 | { | ||
| 719 | if (tolen < 0) | ||
| 720 | return -1; | ||
| 721 | |||
| 722 | return bn2binpad(a, to, tolen, little); | ||
| 600 | } | 723 | } |
| 601 | 724 | ||
| 602 | int | 725 | int |
