提交 d6482a82 编写于 作者: A Andy Polyakov 提交者: Matt Caswell

bn/bn_exp.c: constant-time MOD_EXP_CTIME_COPY_FROM_PREBUF.

Performance penalty varies from platform to platform, and even
key length. For rsa2048 sign it was observed to reach almost 10%.

CVE-2016-0702
Reviewed-by: NRichard Levitte <levitte@openssl.org>
Reviewed-by: NRich Salz <rsalz@openssl.org>
上级 2e0956ba
...@@ -109,6 +109,7 @@ ...@@ -109,6 +109,7 @@
*/ */
#include "internal/cryptlib.h" #include "internal/cryptlib.h"
#include "internal/constant_time_locl.h"
#include "bn_lcl.h" #include "bn_lcl.h"
#include <stdlib.h> #include <stdlib.h>
...@@ -605,15 +606,17 @@ static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos) ...@@ -605,15 +606,17 @@ static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos)
static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top,
unsigned char *buf, int idx, unsigned char *buf, int idx,
int width) int window)
{ {
size_t i, j; int i, j;
int width = 1 << window;
BN_ULONG *table = (BN_ULONG *)buf;
if (top > b->top) if (top > b->top)
top = b->top; /* this works because 'buf' is explicitly top = b->top; /* this works because 'buf' is explicitly
* zeroed */ * zeroed */
for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) { for (i = 0, j = idx; i < top; i++, j += width) {
buf[j] = ((unsigned char *)b->d)[i]; table[j] = b->d[i];
} }
return 1; return 1;
...@@ -621,15 +624,51 @@ static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, ...@@ -621,15 +624,51 @@ static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top,
static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
unsigned char *buf, int idx, unsigned char *buf, int idx,
int width) int window)
{ {
size_t i, j; int i, j;
int width = 1 << window;
volatile BN_ULONG *table = (volatile BN_ULONG *)buf;
if (bn_wexpand(b, top) == NULL) if (bn_wexpand(b, top) == NULL)
return 0; return 0;
for (i = 0, j = idx; i < top * sizeof b->d[0]; i++, j += width) { if (window <= 3) {
((unsigned char *)b->d)[i] = buf[j]; for (i = 0; i < top; i++, table += width) {
BN_ULONG acc = 0;
for (j = 0; j < width; j++) {
acc |= table[j] &
((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
}
b->d[i] = acc;
}
} else {
int xstride = 1 << (window - 2);
BN_ULONG y0, y1, y2, y3;
i = idx >> (window - 2); /* equivalent of idx / xstride */
idx &= xstride - 1; /* equivalent of idx % xstride */
y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1);
y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1);
y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1);
y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1);
for (i = 0; i < top; i++, table += width) {
BN_ULONG acc = 0;
for (j = 0; j < xstride; j++) {
acc |= ( (table[j + 0 * xstride] & y0) |
(table[j + 1 * xstride] & y1) |
(table[j + 2 * xstride] & y2) |
(table[j + 3 * xstride] & y3) )
& ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1));
}
b->d[i] = acc;
}
} }
b->top = top; b->top = top;
...@@ -1063,9 +1102,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, ...@@ -1063,9 +1102,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
} else } else
#endif #endif
{ {
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, numPowers)) if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window))
goto err; goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, numPowers)) if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window))
goto err; goto err;
/* /*
...@@ -1077,15 +1116,15 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, ...@@ -1077,15 +1116,15 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
if (window > 1) { if (window > 1) {
if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx))
goto err; goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2,
(&tmp, top, powerbuf, 2, numPowers)) window))
goto err; goto err;
for (i = 3; i < numPowers; i++) { for (i = 3; i < numPowers; i++) {
/* Calculate a^i = a^(i-1) * a */ /* Calculate a^i = a^(i-1) * a */
if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx))
goto err; goto err;
if (!MOD_EXP_CTIME_COPY_TO_PREBUF if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i,
(&tmp, top, powerbuf, i, numPowers)) window))
goto err; goto err;
} }
} }
...@@ -1093,8 +1132,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, ...@@ -1093,8 +1132,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
bits--; bits--;
for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) for (wvalue = 0, i = bits % window; i >= 0; i--, bits--)
wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
if (!MOD_EXP_CTIME_COPY_FROM_PREBUF if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue,
(&tmp, top, powerbuf, wvalue, numPowers)) window))
goto err; goto err;
/* /*
...@@ -1114,8 +1153,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, ...@@ -1114,8 +1153,8 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
/* /*
* Fetch the appropriate pre-computed value from the pre-buf * Fetch the appropriate pre-computed value from the pre-buf
*/ */
if (!MOD_EXP_CTIME_COPY_FROM_PREBUF if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue,
(&am, top, powerbuf, wvalue, numPowers)) window))
goto err; goto err;
/* Multiply the result into the intermediate result */ /* Multiply the result into the intermediate result */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册