diff options
author | bcook <> | 2015-02-25 15:39:49 +0000 |
---|---|---|
committer | bcook <> | 2015-02-25 15:39:49 +0000 |
commit | 432e1d553bd75841b5b29f1a8008b519d538f765 (patch) | |
tree | fca56e3d23c024e7f0d0132456914f4f3181e5df /src/lib/libcrypto/bn/bn_asm.c | |
parent | c95a8d3fbea64773cc8d6de4314c26a413e58a60 (diff) | |
download | openbsd-432e1d553bd75841b5b29f1a8008b519d538f765.tar.gz openbsd-432e1d553bd75841b5b29f1a8008b519d538f765.tar.bz2 openbsd-432e1d553bd75841b5b29f1a8008b519d538f765.zip |
Fix CVE-2014-3570: properly calculate the square of a BIGNUM value.
See https://www.openssl.org/news/secadv_20150108.txt for a more detailed
discussion.
Original OpenSSL patch here:
https://github.com/openssl/openssl/commit/a7a44ba55cb4f884c6bc9ceac90072dea38e66d0
The regression test is modified a little for KNF.
ok miod@
Diffstat (limited to 'src/lib/libcrypto/bn/bn_asm.c')
-rw-r--r-- | src/lib/libcrypto/bn/bn_asm.c | 243 |
1 files changed, 123 insertions, 120 deletions
diff --git a/src/lib/libcrypto/bn/bn_asm.c b/src/lib/libcrypto/bn/bn_asm.c index c6efd2513a..49f0ba5d7b 100644 --- a/src/lib/libcrypto/bn/bn_asm.c +++ b/src/lib/libcrypto/bn/bn_asm.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bn_asm.c,v 1.13 2014/07/11 08:44:47 jsing Exp $ */ | 1 | /* $OpenBSD: bn_asm.c,v 1.14 2015/02/25 15:39:49 bcook 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 | * |
@@ -495,116 +495,143 @@ bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
495 | /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ | 495 | /* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */ |
496 | 496 | ||
497 | #ifdef BN_LLONG | 497 | #ifdef BN_LLONG |
498 | #define mul_add_c(a,b,c0,c1,c2) \ | 498 | /* |
499 | t=(BN_ULLONG)a*b; \ | 499 | * Keep in mind that additions to multiplication result can not |
500 | t1=(BN_ULONG)Lw(t); \ | 500 | * overflow, because its high half cannot be all-ones. |
501 | t2=(BN_ULONG)Hw(t); \ | 501 | */ |
502 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | 502 | #define mul_add_c(a,b,c0,c1,c2) do { \ |
503 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | 503 | BN_ULONG hi; \ |
504 | 504 | BN_ULLONG t = (BN_ULLONG)(a)*(b); \ | |
505 | #define mul_add_c2(a,b,c0,c1,c2) \ | 505 | t += c0; /* no carry */ \ |
506 | t=(BN_ULLONG)a*b; \ | 506 | c0 = (BN_ULONG)Lw(t); \ |
507 | tt=(t+t)&BN_MASK; \ | 507 | hi = (BN_ULONG)Hw(t); \ |
508 | if (tt < t) c2++; \ | 508 | c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \ |
509 | t1=(BN_ULONG)Lw(tt); \ | 509 | } while(0) |
510 | t2=(BN_ULONG)Hw(tt); \ | 510 | |
511 | c0=(c0+t1)&BN_MASK2; \ | 511 | #define mul_add_c2(a,b,c0,c1,c2) do { \ |
512 | if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \ | 512 | BN_ULONG hi; \ |
513 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | 513 | BN_ULLONG t = (BN_ULLONG)(a)*(b); \ |
514 | 514 | BN_ULLONG tt = t+c0; /* no carry */ \ | |
515 | #define sqr_add_c(a,i,c0,c1,c2) \ | 515 | c0 = (BN_ULONG)Lw(tt); \ |
516 | t=(BN_ULLONG)a[i]*a[i]; \ | 516 | hi = (BN_ULONG)Hw(tt); \ |
517 | t1=(BN_ULONG)Lw(t); \ | 517 | c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \ |
518 | t2=(BN_ULONG)Hw(t); \ | 518 | t += c0; /* no carry */ \ |
519 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | 519 | c0 = (BN_ULONG)Lw(t); \ |
520 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | 520 | hi = (BN_ULONG)Hw(t); \ |
521 | c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \ | ||
522 | } while(0) | ||
523 | |||
524 | #define sqr_add_c(a,i,c0,c1,c2) do { \ | ||
525 | BN_ULONG hi; \ | ||
526 | BN_ULLONG t = (BN_ULLONG)a[i]*a[i]; \ | ||
527 | t += c0; /* no carry */ \ | ||
528 | c0 = (BN_ULONG)Lw(t); \ | ||
529 | hi = (BN_ULONG)Hw(t); \ | ||
530 | c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \ | ||
531 | } while(0) | ||
521 | 532 | ||
522 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ | 533 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ |
523 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) | 534 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) |
524 | 535 | ||
525 | #elif defined(BN_UMULT_LOHI) | 536 | #elif defined(BN_UMULT_LOHI) |
526 | 537 | /* | |
527 | #define mul_add_c(a,b,c0,c1,c2) { \ | 538 | * Keep in mind that additions to hi can not overflow, because |
528 | BN_ULONG ta=(a),tb=(b); \ | 539 | * the high word of a multiplication result cannot be all-ones. |
529 | BN_UMULT_LOHI(t1,t2,ta,tb); \ | 540 | */ |
530 | c0 += t1; t2 += (c0<t1)?1:0; \ | 541 | #define mul_add_c(a,b,c0,c1,c2) do { \ |
531 | c1 += t2; c2 += (c1<t2)?1:0; \ | 542 | BN_ULONG ta = (a), tb = (b); \ |
532 | } | 543 | BN_ULONG lo, hi; \ |
533 | 544 | BN_UMULT_LOHI(lo,hi,ta,tb); \ | |
534 | #define mul_add_c2(a,b,c0,c1,c2) { \ | 545 | c0 += lo; hi += (c0<lo)?1:0; \ |
535 | BN_ULONG ta=(a),tb=(b),t0; \ | 546 | c1 += hi; c2 += (c1<hi)?1:0; \ |
536 | BN_UMULT_LOHI(t0,t1,ta,tb); \ | 547 | } while(0) |
537 | t2 = t1+t1; c2 += (t2<t1)?1:0; \ | 548 | |
538 | t1 = t0+t0; t2 += (t1<t0)?1:0; \ | 549 | #define mul_add_c2(a,b,c0,c1,c2) do { \ |
539 | c0 += t1; t2 += (c0<t1)?1:0; \ | 550 | BN_ULONG ta = (a), tb = (b); \ |
540 | c1 += t2; c2 += (c1<t2)?1:0; \ | 551 | BN_ULONG lo, hi, tt; \ |
541 | } | 552 | BN_UMULT_LOHI(lo,hi,ta,tb); \ |
542 | 553 | c0 += lo; tt = hi+((c0<lo)?1:0); \ | |
543 | #define sqr_add_c(a,i,c0,c1,c2) { \ | 554 | c1 += tt; c2 += (c1<tt)?1:0; \ |
544 | BN_ULONG ta=(a)[i]; \ | 555 | c0 += lo; hi += (c0<lo)?1:0; \ |
545 | BN_UMULT_LOHI(t1,t2,ta,ta); \ | 556 | c1 += hi; c2 += (c1<hi)?1:0; \ |
546 | c0 += t1; t2 += (c0<t1)?1:0; \ | 557 | } while(0) |
547 | c1 += t2; c2 += (c1<t2)?1:0; \ | 558 | |
548 | } | 559 | #define sqr_add_c(a,i,c0,c1,c2) do { \ |
560 | BN_ULONG ta = (a)[i]; \ | ||
561 | BN_ULONG lo, hi; \ | ||
562 | BN_UMULT_LOHI(lo,hi,ta,ta); \ | ||
563 | c0 += lo; hi += (c0<lo)?1:0; \ | ||
564 | c1 += hi; c2 += (c1<hi)?1:0; \ | ||
565 | } while(0) | ||
549 | 566 | ||
550 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ | 567 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ |
551 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) | 568 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) |
552 | 569 | ||
553 | #elif defined(BN_UMULT_HIGH) | 570 | #elif defined(BN_UMULT_HIGH) |
554 | 571 | /* | |
555 | #define mul_add_c(a,b,c0,c1,c2) { \ | 572 | * Keep in mind that additions to hi can not overflow, because |
556 | BN_ULONG ta=(a),tb=(b); \ | 573 | * the high word of a multiplication result cannot be all-ones. |
557 | t1 = ta * tb; \ | 574 | */ |
558 | t2 = BN_UMULT_HIGH(ta,tb); \ | 575 | #define mul_add_c(a,b,c0,c1,c2) do { \ |
559 | c0 += t1; t2 += (c0<t1)?1:0; \ | 576 | BN_ULONG ta = (a), tb = (b); \ |
560 | c1 += t2; c2 += (c1<t2)?1:0; \ | 577 | BN_ULONG lo = ta * tb; \ |
561 | } | 578 | BN_ULONG hi = BN_UMULT_HIGH(ta,tb); \ |
562 | 579 | c0 += lo; hi += (c0<lo)?1:0; \ | |
563 | #define mul_add_c2(a,b,c0,c1,c2) { \ | 580 | c1 += hi; c2 += (c1<hi)?1:0; \ |
564 | BN_ULONG ta=(a),tb=(b),t0; \ | 581 | } while(0) |
565 | t1 = BN_UMULT_HIGH(ta,tb); \ | 582 | |
566 | t0 = ta * tb; \ | 583 | #define mul_add_c2(a,b,c0,c1,c2) do { \ |
567 | t2 = t1+t1; c2 += (t2<t1)?1:0; \ | 584 | BN_ULONG ta = (a), tb = (b), tt; \ |
568 | t1 = t0+t0; t2 += (t1<t0)?1:0; \ | 585 | BN_ULONG lo = ta * tb; \ |
569 | c0 += t1; t2 += (c0<t1)?1:0; \ | 586 | BN_ULONG hi = BN_UMULT_HIGH(ta,tb); \ |
570 | c1 += t2; c2 += (c1<t2)?1:0; \ | 587 | c0 += lo; tt = hi + ((c0<lo)?1:0); \ |
571 | } | 588 | c1 += tt; c2 += (c1<tt)?1:0; \ |
572 | 589 | c0 += lo; hi += (c0<lo)?1:0; \ | |
573 | #define sqr_add_c(a,i,c0,c1,c2) { \ | 590 | c1 += hi; c2 += (c1<hi)?1:0; \ |
574 | BN_ULONG ta=(a)[i]; \ | 591 | } while(0) |
575 | t1 = ta * ta; \ | 592 | |
576 | t2 = BN_UMULT_HIGH(ta,ta); \ | 593 | #define sqr_add_c(a,i,c0,c1,c2) do { \ |
577 | c0 += t1; t2 += (c0<t1)?1:0; \ | 594 | BN_ULONG ta = (a)[i]; \ |
578 | c1 += t2; c2 += (c1<t2)?1:0; \ | 595 | BN_ULONG lo = ta * ta; \ |
579 | } | 596 | BN_ULONG hi = BN_UMULT_HIGH(ta,ta); \ |
597 | c0 += lo; hi += (c0<lo)?1:0; \ | ||
598 | c1 += hi; c2 += (c1<hi)?1:0; \ | ||
599 | } while(0) | ||
580 | 600 | ||
581 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ | 601 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ |
582 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) | 602 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) |
583 | 603 | ||
584 | #else /* !BN_LLONG */ | 604 | #else /* !BN_LLONG */ |
585 | #define mul_add_c(a,b,c0,c1,c2) \ | 605 | /* |
586 | t1=LBITS(a); t2=HBITS(a); \ | 606 | * Keep in mind that additions to hi can not overflow, because |
587 | bl=LBITS(b); bh=HBITS(b); \ | 607 | * the high word of a multiplication result cannot be all-ones. |
588 | mul64(t1,t2,bl,bh); \ | 608 | */ |
589 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | 609 | #define mul_add_c(a,b,c0,c1,c2) do { \ |
590 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | 610 | BN_ULONG lo = LBITS(a), hi = HBITS(a); \ |
591 | 611 | BN_ULONG bl = LBITS(b), bh = HBITS(b); \ | |
592 | #define mul_add_c2(a,b,c0,c1,c2) \ | 612 | mul64(lo,hi,bl,bh); \ |
593 | t1=LBITS(a); t2=HBITS(a); \ | 613 | c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \ |
594 | bl=LBITS(b); bh=HBITS(b); \ | 614 | c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \ |
595 | mul64(t1,t2,bl,bh); \ | 615 | } while(0) |
596 | if (t2 & BN_TBIT) c2++; \ | 616 | |
597 | t2=(t2+t2)&BN_MASK2; \ | 617 | #define mul_add_c2(a,b,c0,c1,c2) do { \ |
598 | if (t1 & BN_TBIT) t2++; \ | 618 | BN_ULONG tt; \ |
599 | t1=(t1+t1)&BN_MASK2; \ | 619 | BN_ULONG lo = LBITS(a), hi = HBITS(a); \ |
600 | c0=(c0+t1)&BN_MASK2; \ | 620 | BN_ULONG bl = LBITS(b), bh = HBITS(b); \ |
601 | if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \ | 621 | mul64(lo,hi,bl,bh); \ |
602 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | 622 | tt = hi; \ |
603 | 623 | c0 = (c0+lo)&BN_MASK2; if (c0<lo) tt++; \ | |
604 | #define sqr_add_c(a,i,c0,c1,c2) \ | 624 | c1 = (c1+tt)&BN_MASK2; if (c1<tt) c2++; \ |
605 | sqr64(t1,t2,(a)[i]); \ | 625 | c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \ |
606 | c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ | 626 | c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \ |
607 | c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; | 627 | } while(0) |
628 | |||
629 | #define sqr_add_c(a,i,c0,c1,c2) do { \ | ||
630 | BN_ULONG lo, hi; \ | ||
631 | sqr64(lo,hi,(a)[i]); \ | ||
632 | c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \ | ||
633 | c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \ | ||
634 | } while(0) | ||
608 | 635 | ||
609 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ | 636 | #define sqr_add_c2(a,i,j,c0,c1,c2) \ |
610 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) | 637 | mul_add_c2((a)[i],(a)[j],c0,c1,c2) |
@@ -613,12 +640,6 @@ bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n) | |||
613 | void | 640 | void |
614 | bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | 641 | bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) |
615 | { | 642 | { |
616 | #ifdef BN_LLONG | ||
617 | BN_ULLONG t; | ||
618 | #elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH) | ||
619 | BN_ULONG bl, bh; | ||
620 | #endif | ||
621 | BN_ULONG t1, t2; | ||
622 | BN_ULONG c1, c2, c3; | 643 | BN_ULONG c1, c2, c3; |
623 | 644 | ||
624 | c1 = 0; | 645 | c1 = 0; |
@@ -723,12 +744,6 @@ bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | |||
723 | void | 744 | void |
724 | bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | 745 | bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) |
725 | { | 746 | { |
726 | #ifdef BN_LLONG | ||
727 | BN_ULLONG t; | ||
728 | #elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH) | ||
729 | BN_ULONG bl, bh; | ||
730 | #endif | ||
731 | BN_ULONG t1, t2; | ||
732 | BN_ULONG c1, c2, c3; | 747 | BN_ULONG c1, c2, c3; |
733 | 748 | ||
734 | c1 = 0; | 749 | c1 = 0; |
@@ -769,12 +784,6 @@ bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) | |||
769 | void | 784 | void |
770 | bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) | 785 | bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) |
771 | { | 786 | { |
772 | #ifdef BN_LLONG | ||
773 | BN_ULLONG t, tt; | ||
774 | #elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH) | ||
775 | BN_ULONG bl, bh; | ||
776 | #endif | ||
777 | BN_ULONG t1, t2; | ||
778 | BN_ULONG c1, c2, c3; | 787 | BN_ULONG c1, c2, c3; |
779 | 788 | ||
780 | c1 = 0; | 789 | c1 = 0; |
@@ -851,12 +860,6 @@ bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) | |||
851 | void | 860 | void |
852 | bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) | 861 | bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) |
853 | { | 862 | { |
854 | #ifdef BN_LLONG | ||
855 | BN_ULLONG t, tt; | ||
856 | #elif !defined(BN_UMULT_LOHI) && !defined(BN_UMULT_HIGH) | ||
857 | BN_ULONG bl, bh; | ||
858 | #endif | ||
859 | BN_ULONG t1, t2; | ||
860 | BN_ULONG c1, c2, c3; | 863 | BN_ULONG c1, c2, c3; |
861 | 864 | ||
862 | c1 = 0; | 865 | c1 = 0; |