소스 검색

Split BN_from_montgomery_word into a non-BIGNUM core.

bn_from_montgomery_in_place is actually constant-time. It is, of course,
only used by non-constant-time BIGNUM callers, but that will soon be
fixed.

Change-Id: I2b2c9943dc3b8d6a4b5b19a5bc4fa9ebad532bac
Reviewed-on: https://boringssl-review.googlesource.com/23069
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 7 년 전
committed by Adam Langley
부모
커밋
a01aa9aa9f
1개의 변경된 파일50개의 추가작업 그리고 47개의 파일을 삭제
  1. +50
    -47
      crypto/fipsmodule/bn/montgomery.c

+ 50
- 47
crypto/fipsmodule/bn/montgomery.c 파일 보기

@@ -260,72 +260,75 @@ int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
return BN_mod_mul_montgomery(ret, a, &mont->RR, mont, ctx);
}

static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
const BN_MONT_CTX *mont) {
const BIGNUM *n = &mont->N;
int nl = n->top;
if (nl == 0) {
ret->top = 0;
return 1;
}

int max = (2 * nl); // carry is stored separately
if (!bn_wexpand(r, max)) {
static int bn_from_montgomery_in_place(BN_ULONG *r, size_t num_r, BN_ULONG *a,
size_t num_a, const BN_MONT_CTX *mont) {
const BN_ULONG *n = mont->N.d;
size_t num_n = mont->N.top;
if (num_r != num_n || num_a != 2 * num_n) {
OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}

r->neg ^= n->neg;
BN_ULONG *np = n->d;
BN_ULONG *rp = r->d;

// Clear the top words of T.
if (max > r->top) {
OPENSSL_memset(&rp[r->top], 0, (max - r->top) * sizeof(BN_ULONG));
}

r->top = max;
BN_ULONG n0 = mont->n0[0];

// Add multiples of |n| to |r| until R = 2^(nl * BN_BITS2) divides it. On
// input, we had |r| < |n| * R, so now |r| < 2 * |n| * R. Note that |r|
// includes |carry| which is stored separately.
BN_ULONG n0 = mont->n0[0];
BN_ULONG carry = 0;
for (int i = 0; i < nl; i++, rp++) {
BN_ULONG v = bn_mul_add_words(rp, np, nl, rp[0] * n0);
v += carry + rp[nl];
carry |= (v != rp[nl]);
carry &= (v <= rp[nl]);
rp[nl] = v;
for (size_t i = 0; i < num_n; i++) {
BN_ULONG v = bn_mul_add_words(a + i, n, num_n, a[i] * n0);
v += carry + a[i + num_n];
carry |= (v != a[i + num_n]);
carry &= (v <= a[i + num_n]);
a[i + num_n] = v;
}

if (!bn_wexpand(ret, nl)) {
return 0;
}
ret->top = nl;
ret->neg = r->neg;
rp = ret->d;

// Shift |nl| words to divide by R. We have |ap| < 2 * |n|. Note that |ap|
// Shift |num_n| words to divide by R. We have |a| < 2 * |n|. Note that |a|
// includes |carry| which is stored separately.
BN_ULONG *ap = &(r->d[nl]);
a += num_n;

// |ap| thus requires at most one additional subtraction |n| to be reduced.
// |a| thus requires at most one additional subtraction |n| to be reduced.
// Subtract |n| and select the answer in constant time.
OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t),
crypto_word_t_too_small);
BN_ULONG v = bn_sub_words(rp, ap, np, nl) - carry;
// |v| is one if |ap| - |np| underflowed or zero if it did not. Note |v|
// cannot be -1. That would imply the subtraction did not fit in |nl| words,
// and we know at most one subtraction is needed.
BN_ULONG v = bn_sub_words(r, a, n, num_n) - carry;
// |v| is one if |a| - |n| underflowed or zero if it did not. Note |v| cannot
// be -1. That would imply the subtraction did not fit in |num_n| words, and
// we know at most one subtraction is needed.
v = 0u - v;
for (int i = 0; i < nl; i++) {
rp[i] = constant_time_select_w(v, ap[i], rp[i]);
ap[i] = 0;
for (size_t i = 0; i < num_n; i++) {
r[i] = constant_time_select_w(v, a[i], r[i]);
a[i] = 0;
}
return 1;
}

static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r,
const BN_MONT_CTX *mont) {
const BIGNUM *n = &mont->N;
if (n->top == 0) {
ret->top = 0;
return 1;
}

int max = (2 * n->top); // carry is stored separately
if (!bn_wexpand(r, max) ||
!bn_wexpand(ret, n->top)) {
return 0;
}
// Clear the top words of |r|.
if (max > r->top) {
OPENSSL_memset(r->d + r->top, 0, (max - r->top) * sizeof(BN_ULONG));
}
r->top = max;
ret->top = n->top;

if (!bn_from_montgomery_in_place(ret->d, ret->top, r->d, r->top, mont)) {
return 0;
}
ret->neg = r->neg;

bn_correct_top(r);
bn_correct_top(ret);

return 1;
}



불러오는 중...
취소
저장