summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbcook <>2016-09-03 17:26:29 +0000
committerbcook <>2016-09-03 17:26:29 +0000
commit05812bec7df03184841379790bd48dadca90c010 (patch)
tree5a55fa6d7a407158eb3e24dce67281670f92a99c /src
parent06907d7e2bc335e13382062e78c2e1c5aa05fbfe (diff)
downloadopenbsd-05812bec7df03184841379790bd48dadca90c010.tar.gz
openbsd-05812bec7df03184841379790bd48dadca90c010.tar.bz2
openbsd-05812bec7df03184841379790bd48dadca90c010.zip
add constant-time MOD_EXP_CTIME_COPY_FROM_PREBUF.
Patch based on OpenSSL commit d7a854c055ff22fb7da80c3b0e7cb08d248591d0 "Performance penalty varies from platform to platform, and even key length. For rsa2048 sign it was observed to reach almost 10%." CVE-2016-0702 ok beck@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/bn/bn_exp.c71
1 files changed, 55 insertions, 16 deletions
diff --git a/src/lib/libcrypto/bn/bn_exp.c b/src/lib/libcrypto/bn/bn_exp.c
index 87b5775886..64c8cbf375 100644
--- a/src/lib/libcrypto/bn/bn_exp.c
+++ b/src/lib/libcrypto/bn/bn_exp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bn_exp.c,v 1.25 2016/09/03 17:21:38 bcook Exp $ */ 1/* $OpenBSD: bn_exp.c,v 1.26 2016/09/03 17:26:29 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 *
@@ -115,6 +115,7 @@
115#include <openssl/err.h> 115#include <openssl/err.h>
116 116
117#include "bn_lcl.h" 117#include "bn_lcl.h"
118#include "constant_time_locl.h"
118 119
119/* maximum precomputation table size for *variable* sliding windows */ 120/* maximum precomputation table size for *variable* sliding windows */
120#define TABLE_SIZE 32 121#define TABLE_SIZE 32
@@ -541,14 +542,17 @@ err:
541 542
542static int 543static int
543MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf, 544MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf,
544 int idx, int width) 545 int idx, int window)
545{ 546{
546 size_t i, j; 547 int i, j;
548 int width = 1 << window;
549 BN_ULONG *table = (BN_ULONG *)buf;
547 550
548 if (top > b->top) 551 if (top > b->top)
549 top = b->top; /* this works because 'buf' is explicitly zeroed */ 552 top = b->top; /* this works because 'buf' is explicitly zeroed */
550 for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) { 553
551 buf[j] = ((unsigned char*)b->d)[i]; 554 for (i = 0, j = idx; i < top; i++, j += width) {
555 table[j] = b->d[i];
552 } 556 }
553 557
554 return 1; 558 return 1;
@@ -556,17 +560,52 @@ MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, unsigned char *buf,
556 560
557static int 561static int
558MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx, 562MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, unsigned char *buf, int idx,
559 int width) 563 int window)
560{ 564{
561 size_t i, j; 565 int i, j;
566 int width = 1 << window;
567 volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
562 568
563 if (bn_wexpand(b, top) == NULL) 569 if (bn_wexpand(b, top) == NULL)
564 return 0; 570 return 0;
565 571
566 for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) { 572 if (window <= 3) {
567 ((unsigned char*)b->d)[i] = buf[j]; 573 for (i = 0; i < top; i++, table += width) {
568 } 574 BN_ULONG acc = 0;
575
576 for (j = 0; j < width; j++) {
577 acc |= table[j] &
578 ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
579 }
580
581 b->d[i] = acc;
582 }
583 } else {
584 int xstride = 1 << (window - 2);
585 BN_ULONG y0, y1, y2, y3;
569 586
587 i = idx >> (window - 2); /* equivalent of idx / xstride */
588 idx &= xstride - 1; /* equivalent of idx % xstride */
589
590 y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);
591 y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);
592 y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);
593 y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);
594
595 for (i = 0; i < top; i++, table += width) {
596 BN_ULONG acc = 0;
597
598 for (j = 0; j < xstride; j++) {
599 acc |= ( (table[j + 0 * xstride] & y0) |
600 (table[j + 1 * xstride] & y1) |
601 (table[j + 2 * xstride] & y2) |
602 (table[j + 3 * xstride] & y3) )
603 & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
604 }
605
606 b->d[i] = acc;
607 }
608 }
570 b->top = top; 609 b->top = top;
571 bn_correct_top(b); 610 bn_correct_top(b);
572 return 1; 611 return 1;
@@ -772,10 +811,10 @@ BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
772#endif 811#endif
773 { 812 {
774 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, 813 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0,
775 numPowers)) 814 window))
776 goto err; 815 goto err;
777 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, 816 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1,
778 numPowers)) 817 window))
779 goto err; 818 goto err;
780 819
781 /* If the window size is greater than 1, then calculate 820 /* If the window size is greater than 1, then calculate
@@ -787,7 +826,7 @@ BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
787 if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) 826 if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
788 goto err; 827 goto err;
789 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 828 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf,
790 2, numPowers)) 829 2, window))
791 goto err; 830 goto err;
792 for (i = 3; i < numPowers; i++) { 831 for (i = 3; i < numPowers; i++) {
793 /* Calculate a^i = a^(i-1) * a */ 832 /* Calculate a^i = a^(i-1) * a */
@@ -795,7 +834,7 @@ BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
795 mont, ctx)) 834 mont, ctx))
796 goto err; 835 goto err;
797 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, 836 if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top,
798 powerbuf, i, numPowers)) 837 powerbuf, i, window))
799 goto err; 838 goto err;
800 } 839 }
801 } 840 }
@@ -804,7 +843,7 @@ BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
804 for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) 843 for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
805 wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); 844 wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
806 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, 845 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf,
807 wvalue, numPowers)) 846 wvalue, window))
808 goto err; 847 goto err;
809 848
810 /* Scan the exponent one window at a time starting from the most 849 /* Scan the exponent one window at a time starting from the most
@@ -823,7 +862,7 @@ BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
823 862
824 /* Fetch the appropriate pre-computed value from the pre-buf */ 863 /* Fetch the appropriate pre-computed value from the pre-buf */
825 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, 864 if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf,
826 wvalue, numPowers)) 865 wvalue, window))
827 goto err; 866 goto err;
828 867
829 /* Multiply the result into the intermediate result */ 868 /* Multiply the result into the intermediate result */