diff options
| author | bcook <> | 2015-02-25 15:39:49 +0000 |
|---|---|---|
| committer | bcook <> | 2015-02-25 15:39:49 +0000 |
| commit | f3031aa7bff24911a8cae9bdd7cdcd88d8554f42 (patch) | |
| tree | fca56e3d23c024e7f0d0132456914f4f3181e5df /src/lib/libcrypto/bn/bn_asm.c | |
| parent | 2725a02f7a7b4932578ec02826b4501c29e21ddf (diff) | |
| download | openbsd-f3031aa7bff24911a8cae9bdd7cdcd88d8554f42.tar.gz openbsd-f3031aa7bff24911a8cae9bdd7cdcd88d8554f42.tar.bz2 openbsd-f3031aa7bff24911a8cae9bdd7cdcd88d8554f42.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; |
