summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bn/bn.h7
-rw-r--r--src/lib/libcrypto/bn/bn_lib.c139
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);
428void BN_swap(BIGNUM *a, BIGNUM *b); 428void BN_swap(BIGNUM *a, BIGNUM *b);
429BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); 429BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
430int BN_bn2bin(const BIGNUM *a, unsigned char *to); 430int BN_bn2bin(const BIGNUM *a, unsigned char *to);
431#if defined(LIBRESSL_INTERNAL)
432int BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen);
433BIGNUM *BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret);
434int BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen);
435#endif
431BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); 436BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret);
432int BN_bn2mpi(const BIGNUM *a, unsigned char *to); 437int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
433int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); 438int 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
586typedef enum {
587 big,
588 little,
589} endianness_t;
590
586/* ignore negative */ 591/* ignore negative */
592static int
593bn2binpad(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
648int
649BN_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
587int 656int
588BN_bn2bin(const BIGNUM *a, unsigned char *to) 657BN_bn2bin(const BIGNUM *a, unsigned char *to)
589{ 658{
590 int n, i; 659 return bn2binpad(a, to, -1, big);
660}
661
662BIGNUM *
663BN_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
716int
717BN_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
602int 725int