summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2022-05-07 07:47:24 +0000
committerjsing <>2022-05-07 07:47:24 +0000
commit06373cf29b7f2f1c4fdd09ce26d5671ac29e3675 (patch)
treefea88905a338e173a2ff4c9ba0fb67b479b0ff6c
parent14f29f49d99785d2e275fd406ac4227273b08b7e (diff)
downloadopenbsd-06373cf29b7f2f1c4fdd09ce26d5671ac29e3675.tar.gz
openbsd-06373cf29b7f2f1c4fdd09ce26d5671ac29e3675.tar.bz2
openbsd-06373cf29b7f2f1c4fdd09ce26d5671ac29e3675.zip
Avoid strict aliasing violations in BN_nist_mod_*()
The optimised code path switches from processing data via unsigned long to processing data via unsigned int, which requires type punning. This is currently attempted via a union (for one case), however this fails since a pointer to a union member is passed to another function (these unions were added to "fix strict-aliasing compiler warning" - it would seem the warnings stopped but the undefined behaviour remained). The second case does not use a union and simply casts from one type to another. Undefined behaviour is currently triggered when compiling with clang 14 using -03 and -fstrict-aliasing, while disabling assembly (in order to use this C code). The resulting binary produces incorrect results. Avoid strict aliasing violations by copying from an unsigned long array to an unsigned int array, then copying back the result. Any sensible compiler will omit the copies, while avoiding undefined behaviour that would result from unsafe type punning via pointer type casting. Thanks to Guido Vranken for reporting the issue and testing the fix. ok tb@
-rw-r--r--src/lib/libcrypto/bn/bn_nist.c223
1 files changed, 137 insertions, 86 deletions
diff --git a/src/lib/libcrypto/bn/bn_nist.c b/src/lib/libcrypto/bn/bn_nist.c
index 3a04c471c4..871b37cf89 100644
--- a/src/lib/libcrypto/bn/bn_nist.c
+++ b/src/lib/libcrypto/bn/bn_nist.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_nist.c,v 1.19 2021/11/09 18:40:20 bcook Exp $ */ 1/* $OpenBSD: bn_nist.c,v 1.20 2022/05/07 07:47:24 jsing Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project 3 * Written by Nils Larsch for the OpenSSL project
4 */ 4 */
@@ -62,6 +62,9 @@
62 62
63#include "bn_lcl.h" 63#include "bn_lcl.h"
64 64
65#define CTASSERT(x) extern char _ctassert[(x) ? 1 : -1 ] \
66 __attribute__((__unused__))
67
65#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 68#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2
66#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 69#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2
67#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 70#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2
@@ -425,11 +428,7 @@ BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
425 int top = a->top, i; 428 int top = a->top, i;
426 int carry; 429 int carry;
427 BN_ULONG *r_d, *a_d = a->d; 430 BN_ULONG *r_d, *a_d = a->d;
428 union { 431 BN_ULONG bnbuf[BN_NIST_192_TOP] = { 0 };
429 BN_ULONG bn[BN_NIST_192_TOP];
430 unsigned int ui[BN_NIST_192_TOP *
431 sizeof(BN_ULONG) / sizeof(unsigned int)];
432 } buf;
433 BN_ULONG c_d[BN_NIST_192_TOP], *res; 432 BN_ULONG c_d[BN_NIST_192_TOP], *res;
434 uintptr_t mask; 433 uintptr_t mask;
435 static const BIGNUM _bignum_nist_p_192_sqr = { 434 static const BIGNUM _bignum_nist_p_192_sqr = {
@@ -460,14 +459,31 @@ BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
460 } else 459 } else
461 r_d = a_d; 460 r_d = a_d;
462 461
463 nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, 462 nist_cp_bn_0(bnbuf, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP,
464 BN_NIST_192_TOP); 463 BN_NIST_192_TOP);
465 464
466#if defined(NIST_INT64) 465#if defined(NIST_INT64)
467 { 466 {
468 NIST_INT64 acc; /* accumulator */ 467 NIST_INT64 acc; /* accumulator */
469 unsigned int *rp = (unsigned int *)r_d; 468 unsigned int bbuf[BN_NIST_192_TOP *
470 const unsigned int *bp = (const unsigned int *)buf.ui; 469 sizeof(BN_ULONG) / sizeof(unsigned int)];
470 unsigned int rbuf[BN_NIST_192_TOP *
471 sizeof(BN_ULONG) / sizeof(unsigned int)];
472 const unsigned int *bp = bbuf;
473 unsigned int *rp = rbuf;
474
475 CTASSERT(sizeof(bbuf) == sizeof(bnbuf));
476 CTASSERT(sizeof(rbuf) == sizeof(bnbuf));
477
478 /*
479 * Avoid strict aliasing violations by copying from an unsigned
480 * long array to an unsigned int array, then copying back the
481 * result. Any sensible compiler will omit the copies, while
482 * avoiding undefined behaviour that would result from unsafe
483 * type punning via pointer type casting.
484 */
485 memcpy(bbuf, bnbuf, sizeof(bbuf));
486 memcpy(rbuf, r_d, sizeof(rbuf));
471 487
472 acc = rp[0]; 488 acc = rp[0];
473 acc += bp[3 * 2 - 6]; 489 acc += bp[3 * 2 - 6];
@@ -506,17 +522,19 @@ BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
506 acc += bp[5 * 2 - 5]; 522 acc += bp[5 * 2 - 5];
507 rp[5] = (unsigned int)acc; 523 rp[5] = (unsigned int)acc;
508 524
525 memcpy(r_d, rbuf, sizeof(rbuf));
526
509 carry = (int)(acc >> 32); 527 carry = (int)(acc >> 32);
510 } 528 }
511#else 529#else
512 { 530 {
513 BN_ULONG t_d[BN_NIST_192_TOP] = {0}; 531 BN_ULONG t_d[BN_NIST_192_TOP] = {0};
514 532
515 nist_set_192(t_d, buf.bn, 0, 3, 3); 533 nist_set_192(t_d, bnbuf, 0, 3, 3);
516 carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); 534 carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
517 nist_set_192(t_d, buf.bn, 4, 4, 0); 535 nist_set_192(t_d, bnbuf, 4, 4, 0);
518 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); 536 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
519 nist_set_192(t_d, buf.bn, 5, 5, 5) 537 nist_set_192(t_d, bnbuf, 5, 5, 5)
520 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); 538 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP);
521 } 539 }
522#endif 540#endif
@@ -564,17 +582,10 @@ BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
564 int top = a->top, i; 582 int top = a->top, i;
565 int carry; 583 int carry;
566 BN_ULONG *r_d, *a_d = a->d; 584 BN_ULONG *r_d, *a_d = a->d;
567 union { 585 BN_ULONG bnbuf[BN_NIST_224_TOP] = { 0 };
568 BN_ULONG bn[BN_NIST_224_TOP];
569 unsigned int ui[BN_NIST_224_TOP *
570 sizeof(BN_ULONG) / sizeof(unsigned int)];
571 } buf;
572 BN_ULONG c_d[BN_NIST_224_TOP], *res; 586 BN_ULONG c_d[BN_NIST_224_TOP], *res;
573 uintptr_t mask; 587 uintptr_t mask;
574 union { 588 bn_addsub_f addsubf;
575 bn_addsub_f f;
576 uintptr_t p;
577 } u;
578 static const BIGNUM _bignum_nist_p_224_sqr = { 589 static const BIGNUM _bignum_nist_p_224_sqr = {
579 (BN_ULONG *)_nist_p_224_sqr, 590 (BN_ULONG *)_nist_p_224_sqr,
580 sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]), 591 sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]),
@@ -603,26 +614,43 @@ BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
603 } else 614 } else
604 r_d = a_d; 615 r_d = a_d;
605 616
606 memset(&buf, 0, sizeof(buf)); 617 memset(&bnbuf, 0, sizeof(bnbuf));
607 618
608#if BN_BITS2==64 619#if BN_BITS2==64
609 /* copy upper 256 bits of 448 bit number ... */ 620 /* copy upper 256 bits of 448 bit number ... */
610 nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1), 621 nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1),
611 top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP); 622 top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP);
612 /* ... and right shift by 32 to obtain upper 224 bits */ 623 /* ... and right shift by 32 to obtain upper 224 bits */
613 nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8); 624 nist_set_224(bnbuf, c_d, 14, 13, 12, 11, 10, 9, 8);
614 /* truncate lower part to 224 bits too */ 625 /* truncate lower part to 224 bits too */
615 r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l; 626 r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l;
616#else 627#else
617 nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, 628 nist_cp_bn_0(bnbuf, a_d + BN_NIST_224_TOP,
618 top - BN_NIST_224_TOP, BN_NIST_224_TOP); 629 top - BN_NIST_224_TOP, BN_NIST_224_TOP);
619#endif 630#endif
620 631
621#if defined(NIST_INT64) && BN_BITS2!=64 632#if defined(NIST_INT64) && BN_BITS2!=64
622 { 633 {
623 NIST_INT64 acc; /* accumulator */ 634 NIST_INT64 acc; /* accumulator */
624 unsigned int *rp = (unsigned int *)r_d; 635 unsigned int bbuf[BN_NIST_224_TOP *
625 const unsigned int *bp = (const unsigned int *)buf.ui; 636 sizeof(BN_ULONG) / sizeof(unsigned int)];
637 unsigned int rbuf[BN_NIST_224_TOP *
638 sizeof(BN_ULONG) / sizeof(unsigned int)];
639 const unsigned int *bp = bbuf;
640 unsigned int *rp = rbuf;
641
642 CTASSERT(sizeof(bbuf) == sizeof(bnbuf));
643 CTASSERT(sizeof(rbuf) == sizeof(bnbuf));
644
645 /*
646 * Avoid strict aliasing violations by copying from an unsigned
647 * long array to an unsigned int array, then copying back the
648 * result. Any sensible compiler will omit the copies, while
649 * avoiding undefined behaviour that would result from unsafe
650 * type punning via pointer type casting.
651 */
652 memcpy(bbuf, bnbuf, sizeof(bbuf));
653 memcpy(rbuf, r_d, sizeof(rbuf));
626 654
627 acc = rp[0]; 655 acc = rp[0];
628 acc -= bp[7 - 7]; 656 acc -= bp[7 - 7];
@@ -668,6 +696,8 @@ BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
668 acc -= bp[13 - 7]; 696 acc -= bp[13 - 7];
669 rp[6] = (unsigned int)acc; 697 rp[6] = (unsigned int)acc;
670 698
699 memcpy(r_d, rbuf, sizeof(rbuf));
700
671 carry = (int)(acc >> 32); 701 carry = (int)(acc >> 32);
672# if BN_BITS2==64 702# if BN_BITS2==64
673 rp[7] = carry; 703 rp[7] = carry;
@@ -677,13 +707,13 @@ BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
677 { 707 {
678 BN_ULONG t_d[BN_NIST_224_TOP] = {0}; 708 BN_ULONG t_d[BN_NIST_224_TOP] = {0};
679 709
680 nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0); 710 nist_set_224(t_d, bnbuf, 10, 9, 8, 7, 0, 0, 0);
681 carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); 711 carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
682 nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0); 712 nist_set_224(t_d, bnbuf, 0, 13, 12, 11, 0, 0, 0);
683 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); 713 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP);
684 nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7); 714 nist_set_224(t_d, bnbuf, 13, 12, 11, 10, 9, 8, 7);
685 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); 715 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
686 nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11); 716 nist_set_224(t_d, bnbuf, 0, 0, 0, 0, 13, 12, 11);
687 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); 717 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP);
688 718
689#if BN_BITS2==64 719#if BN_BITS2==64
@@ -691,7 +721,7 @@ BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
691#endif 721#endif
692 } 722 }
693#endif 723#endif
694 u.f = bn_sub_words; 724 addsubf = bn_sub_words;
695 if (carry > 0) { 725 if (carry > 0) {
696 carry = (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1], 726 carry = (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1],
697 BN_NIST_224_TOP); 727 BN_NIST_224_TOP);
@@ -707,14 +737,13 @@ BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
707 * adjusted by *subtracting* the latter. */ 737 * adjusted by *subtracting* the latter. */
708 carry = (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1], 738 carry = (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1],
709 BN_NIST_224_TOP); 739 BN_NIST_224_TOP);
710 mask = 0 - (uintptr_t)carry; 740 if (carry == 0)
711 u.p = ((uintptr_t)bn_sub_words & mask) | 741 addsubf = bn_add_words;
712 ((uintptr_t)bn_add_words & ~mask);
713 } else 742 } else
714 carry = 1; 743 carry = 1;
715 744
716 /* otherwise it's effectively same as in BN_nist_mod_192... */ 745 /* otherwise it's effectively same as in BN_nist_mod_192... */
717 mask = 0 - (uintptr_t)(*u.f)(c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP); 746 mask = 0 - (uintptr_t)(*addsubf)(c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP);
718 mask &= 0 - (uintptr_t)carry; 747 mask &= 0 - (uintptr_t)carry;
719 res = c_d; 748 res = c_d;
720 res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask)); 749 res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));
@@ -743,17 +772,10 @@ BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
743 int i, top = a->top; 772 int i, top = a->top;
744 int carry = 0; 773 int carry = 0;
745 BN_ULONG *a_d = a->d, *r_d; 774 BN_ULONG *a_d = a->d, *r_d;
746 union { 775 BN_ULONG bnbuf[BN_NIST_256_TOP] = { 0 };
747 BN_ULONG bn[BN_NIST_256_TOP];
748 unsigned int ui[BN_NIST_256_TOP *
749 sizeof(BN_ULONG) / sizeof(unsigned int)];
750 } buf;
751 BN_ULONG c_d[BN_NIST_256_TOP] = {0}, *res; 776 BN_ULONG c_d[BN_NIST_256_TOP] = {0}, *res;
752 uintptr_t mask; 777 uintptr_t mask;
753 union { 778 bn_addsub_f addsubf;
754 bn_addsub_f f;
755 uintptr_t p;
756 } u;
757 static const BIGNUM _bignum_nist_p_256_sqr = { 779 static const BIGNUM _bignum_nist_p_256_sqr = {
758 (BN_ULONG *)_nist_p_256_sqr, 780 (BN_ULONG *)_nist_p_256_sqr,
759 sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]), 781 sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]),
@@ -782,14 +804,31 @@ BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
782 } else 804 } else
783 r_d = a_d; 805 r_d = a_d;
784 806
785 nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, 807 nist_cp_bn_0(bnbuf, a_d + BN_NIST_256_TOP,
786 top - BN_NIST_256_TOP, BN_NIST_256_TOP); 808 top - BN_NIST_256_TOP, BN_NIST_256_TOP);
787 809
788#if defined(NIST_INT64) 810#if defined(NIST_INT64)
789 { 811 {
790 NIST_INT64 acc; /* accumulator */ 812 NIST_INT64 acc; /* accumulator */
791 unsigned int *rp = (unsigned int *)r_d; 813 unsigned int bbuf[BN_NIST_256_TOP *
792 const unsigned int *bp = (const unsigned int *)buf.ui; 814 sizeof(BN_ULONG) / sizeof(unsigned int)];
815 unsigned int rbuf[BN_NIST_256_TOP *
816 sizeof(BN_ULONG) / sizeof(unsigned int)];
817 const unsigned int *bp = bbuf;
818 unsigned int *rp = rbuf;
819
820 CTASSERT(sizeof(bbuf) == sizeof(bnbuf));
821 CTASSERT(sizeof(rbuf) == sizeof(bnbuf));
822
823 /*
824 * Avoid strict aliasing violations by copying from an unsigned
825 * long array to an unsigned int array, then copying back the
826 * result. Any sensible compiler will omit the copies, while
827 * avoiding undefined behaviour that would result from unsafe
828 * type punning via pointer type casting.
829 */
830 memcpy(bbuf, bnbuf, sizeof(bbuf));
831 memcpy(rbuf, r_d, sizeof(rbuf));
793 832
794 acc = rp[0]; 833 acc = rp[0];
795 acc += bp[8 - 8]; 834 acc += bp[8 - 8];
@@ -877,6 +916,8 @@ BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
877 acc -= bp[13 - 8]; 916 acc -= bp[13 - 8];
878 rp[7] = (unsigned int)acc; 917 rp[7] = (unsigned int)acc;
879 918
919 memcpy(r_d, rbuf, sizeof(rbuf));
920
880 carry = (int)(acc >> 32); 921 carry = (int)(acc >> 32);
881 } 922 }
882#else 923#else
@@ -884,9 +925,9 @@ BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
884 BN_ULONG t_d[BN_NIST_256_TOP] = {0}; 925 BN_ULONG t_d[BN_NIST_256_TOP] = {0};
885 926
886 /*S1*/ 927 /*S1*/
887 nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0); 928 nist_set_256(t_d, bnbuf, 15, 14, 13, 12, 11, 0, 0, 0);
888 /*S2*/ 929 /*S2*/
889 nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0); 930 nist_set_256(c_d, bnbuf, 0, 15, 14, 13, 12, 0, 0, 0);
890 carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); 931 carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP);
891 /* left shift */ 932 /* left shift */
892 { 933 {
@@ -903,41 +944,40 @@ BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
903 } 944 }
904 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); 945 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
905 /*S3*/ 946 /*S3*/
906 nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8); 947 nist_set_256(t_d, bnbuf, 15, 14, 0, 0, 0, 10, 9, 8);
907 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); 948 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
908 /*S4*/ 949 /*S4*/
909 nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9); 950 nist_set_256(t_d, bnbuf, 8, 13, 15, 14, 13, 11, 10, 9);
910 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); 951 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP);
911 /*D1*/ 952 /*D1*/
912 nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11); 953 nist_set_256(t_d, bnbuf, 10, 8, 0, 0, 0, 13, 12, 11);
913 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 954 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
914 /*D2*/ 955 /*D2*/
915 nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12); 956 nist_set_256(t_d, bnbuf, 11, 9, 0, 0, 15, 14, 13, 12);
916 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 957 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
917 /*D3*/ 958 /*D3*/
918 nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13); 959 nist_set_256(t_d, bnbuf, 12, 0, 10, 9, 8, 15, 14, 13);
919 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 960 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
920 /*D4*/ 961 /*D4*/
921 nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14); 962 nist_set_256(t_d, bnbuf, 13, 0, 11, 10, 9, 0, 15, 14);
922 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); 963 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP);
923 964
924 } 965 }
925#endif 966#endif
926 /* see BN_nist_mod_224 for explanation */ 967 /* see BN_nist_mod_224 for explanation */
927 u.f = bn_sub_words; 968 addsubf = bn_sub_words;
928 if (carry > 0) 969 if (carry > 0)
929 carry = (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1], 970 carry = (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1],
930 BN_NIST_256_TOP); 971 BN_NIST_256_TOP);
931 else if (carry < 0) { 972 else if (carry < 0) {
932 carry = (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1], 973 carry = (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1],
933 BN_NIST_256_TOP); 974 BN_NIST_256_TOP);
934 mask = 0 - (uintptr_t)carry; 975 if (carry == 0)
935 u.p = ((uintptr_t)bn_sub_words & mask) | 976 addsubf = bn_add_words;
936 ((uintptr_t)bn_add_words & ~mask);
937 } else 977 } else
938 carry = 1; 978 carry = 1;
939 979
940 mask = 0 - (uintptr_t)(*u.f)(c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP); 980 mask = 0 - (uintptr_t)(*addsubf)(c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP);
941 mask &= 0 - (uintptr_t)carry; 981 mask &= 0 - (uintptr_t)carry;
942 res = c_d; 982 res = c_d;
943 res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask)); 983 res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));
@@ -970,17 +1010,10 @@ BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
970 int i, top = a->top; 1010 int i, top = a->top;
971 int carry = 0; 1011 int carry = 0;
972 BN_ULONG *r_d, *a_d = a->d; 1012 BN_ULONG *r_d, *a_d = a->d;
973 union { 1013 BN_ULONG bnbuf[BN_NIST_384_TOP] = { 0 };
974 BN_ULONG bn[BN_NIST_384_TOP];
975 unsigned int ui[BN_NIST_384_TOP *
976 sizeof(BN_ULONG) / sizeof(unsigned int)];
977 } buf;
978 BN_ULONG c_d[BN_NIST_384_TOP], *res; 1014 BN_ULONG c_d[BN_NIST_384_TOP], *res;
979 uintptr_t mask; 1015 uintptr_t mask;
980 union { 1016 bn_addsub_f addsubf;
981 bn_addsub_f f;
982 uintptr_t p;
983 } u;
984 static const BIGNUM _bignum_nist_p_384_sqr = { 1017 static const BIGNUM _bignum_nist_p_384_sqr = {
985 (BN_ULONG *)_nist_p_384_sqr, 1018 (BN_ULONG *)_nist_p_384_sqr,
986 sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]), 1019 sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]),
@@ -1009,14 +1042,31 @@ BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
1009 } else 1042 } else
1010 r_d = a_d; 1043 r_d = a_d;
1011 1044
1012 nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, 1045 nist_cp_bn_0(bnbuf, a_d + BN_NIST_384_TOP,
1013 top - BN_NIST_384_TOP, BN_NIST_384_TOP); 1046 top - BN_NIST_384_TOP, BN_NIST_384_TOP);
1014 1047
1015#if defined(NIST_INT64) 1048#if defined(NIST_INT64)
1016 { 1049 {
1017 NIST_INT64 acc; /* accumulator */ 1050 NIST_INT64 acc; /* accumulator */
1018 unsigned int *rp = (unsigned int *)r_d; 1051 unsigned int bbuf[BN_NIST_384_TOP *
1019 const unsigned int *bp = (const unsigned int *)buf.ui; 1052 sizeof(BN_ULONG) / sizeof(unsigned int)];
1053 unsigned int rbuf[BN_NIST_384_TOP *
1054 sizeof(BN_ULONG) / sizeof(unsigned int)];
1055 const unsigned int *bp = bbuf;
1056 unsigned int *rp = rbuf;
1057
1058 CTASSERT(sizeof(bbuf) == sizeof(bnbuf));
1059 CTASSERT(sizeof(rbuf) == sizeof(bnbuf));
1060
1061 /*
1062 * Avoid strict aliasing violations by copying from an unsigned
1063 * long array to an unsigned int array, then copying back the
1064 * result. Any sensible compiler will omit the copies, while
1065 * avoiding undefined behaviour that would result from unsafe
1066 * type punning via pointer type casting.
1067 */
1068 memcpy(bbuf, bnbuf, sizeof(bbuf));
1069 memcpy(rbuf, r_d, sizeof(rbuf));
1020 1070
1021 acc = rp[0]; 1071 acc = rp[0];
1022 acc += bp[12 - 12]; 1072 acc += bp[12 - 12];
@@ -1131,6 +1181,8 @@ BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
1131 acc -= bp[22 - 12]; 1181 acc -= bp[22 - 12];
1132 rp[11] = (unsigned int)acc; 1182 rp[11] = (unsigned int)acc;
1133 1183
1184 memcpy(r_d, rbuf, sizeof(rbuf));
1185
1134 carry = (int)(acc >> 32); 1186 carry = (int)(acc >> 32);
1135 } 1187 }
1136#else 1188#else
@@ -1138,7 +1190,7 @@ BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
1138 BN_ULONG t_d[BN_NIST_384_TOP] = {0}; 1190 BN_ULONG t_d[BN_NIST_384_TOP] = {0};
1139 1191
1140 /*S1*/ 1192 /*S1*/
1141 nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 1193 nist_set_256(t_d, bnbuf, 0, 0, 0, 0, 0, 23 - 4, 22 - 4,
1142 21 - 4); 1194 21 - 4);
1143 /* left shift */ 1195 /* left shift */
1144 { 1196 {
@@ -1155,49 +1207,48 @@ BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_CTX *ctx)
1155 carry = (int)bn_add_words(r_d + (128 / BN_BITS2), 1207 carry = (int)bn_add_words(r_d + (128 / BN_BITS2),
1156 r_d + (128 / BN_BITS2), t_d, BN_NIST_256_TOP); 1208 r_d + (128 / BN_BITS2), t_d, BN_NIST_256_TOP);
1157 /*S2 */ 1209 /*S2 */
1158 carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP); 1210 carry += (int)bn_add_words(r_d, r_d, bnbuf, BN_NIST_384_TOP);
1159 /*S3*/ 1211 /*S3*/
1160 nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 1212 nist_set_384(t_d, bnbuf, 20, 19, 18, 17, 16, 15, 14, 13, 12,
1161 23, 22, 21); 1213 23, 22, 21);
1162 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1214 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1163 /*S4*/ 1215 /*S4*/
1164 nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 1216 nist_set_384(t_d, bnbuf, 19, 18, 17, 16, 15, 14, 13, 12, 20,
1165 0, 23, 0); 1217 0, 23, 0);
1166 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1218 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1167 /*S5*/ 1219 /*S5*/
1168 nist_set_384(t_d, buf.bn, 0,0, 0,0, 23, 22, 21, 20, 0,0, 0, 0); 1220 nist_set_384(t_d, bnbuf, 0,0, 0,0, 23, 22, 21, 20, 0,0, 0, 0);
1169 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1221 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1170 /*S6*/ 1222 /*S6*/
1171 nist_set_384(t_d, buf.bn, 0,0, 0,0, 0,0, 23, 22, 21, 0,0, 20); 1223 nist_set_384(t_d, bnbuf, 0,0, 0,0, 0,0, 23, 22, 21, 0,0, 20);
1172 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1224 carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1173 /*D1*/ 1225 /*D1*/
1174 nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 1226 nist_set_384(t_d, bnbuf, 22, 21, 20, 19, 18, 17, 16, 15, 14,
1175 13, 12, 23); 1227 13, 12, 23);
1176 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1228 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1177 /*D2*/ 1229 /*D2*/
1178 nist_set_384(t_d, buf.bn, 0,0, 0,0, 0,0, 0,23, 22, 21, 20, 0); 1230 nist_set_384(t_d, bnbuf, 0,0, 0,0, 0,0, 0,23, 22, 21, 20, 0);
1179 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1231 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1180 /*D3*/ 1232 /*D3*/
1181 nist_set_384(t_d, buf.bn, 0,0, 0,0, 0,0, 0,23, 23, 0,0, 0); 1233 nist_set_384(t_d, bnbuf, 0,0, 0,0, 0,0, 0,23, 23, 0,0, 0);
1182 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); 1234 carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP);
1183 1235
1184 } 1236 }
1185#endif 1237#endif
1186 /* see BN_nist_mod_224 for explanation */ 1238 /* see BN_nist_mod_224 for explanation */
1187 u.f = bn_sub_words; 1239 addsubf = bn_sub_words;
1188 if (carry > 0) 1240 if (carry > 0)
1189 carry = (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1], 1241 carry = (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1],
1190 BN_NIST_384_TOP); 1242 BN_NIST_384_TOP);
1191 else if (carry < 0) { 1243 else if (carry < 0) {
1192 carry = (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1], 1244 carry = (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1],
1193 BN_NIST_384_TOP); 1245 BN_NIST_384_TOP);
1194 mask = 0 - (uintptr_t)carry; 1246 if (carry == 0)
1195 u.p = ((uintptr_t)bn_sub_words & mask) | 1247 addsubf = bn_add_words;
1196 ((uintptr_t)bn_add_words & ~mask);
1197 } else 1248 } else
1198 carry = 1; 1249 carry = 1;
1199 1250
1200 mask = 0 - (uintptr_t)(*u.f)(c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP); 1251 mask = 0 - (uintptr_t)(*addsubf)(c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP);
1201 mask &= 0 - (uintptr_t)carry; 1252 mask &= 0 - (uintptr_t)carry;
1202 res = c_d; 1253 res = c_d;
1203 res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask)); 1254 res = (BN_ULONG *)(((uintptr_t)res & ~mask) | ((uintptr_t)r_d & mask));