|
|
@@ -197,58 +197,33 @@ int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) { |
|
|
|
|
|
|
|
int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, |
|
|
|
const BIGNUM *max_exclusive) { |
|
|
|
unsigned n; |
|
|
|
unsigned count = 100; |
|
|
|
|
|
|
|
if (BN_cmp_word(max_exclusive, min_inclusive) <= 0) { |
|
|
|
OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
n = BN_num_bits(max_exclusive); /* n > 0 */ |
|
|
|
|
|
|
|
/* BN_is_bit_set(range, n - 1) always holds */ |
|
|
|
if (n == 1) { |
|
|
|
BN_zero(r); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
/* This function is used to implement steps 4 through 7 of FIPS 186-4 |
|
|
|
* appendices B.4.2 and B.5.2. When called in those contexts, |max_exclusive| |
|
|
|
* is n and |min_inclusive| is one. */ |
|
|
|
unsigned count = 100; |
|
|
|
unsigned n = BN_num_bits(max_exclusive); /* n > 0 */ |
|
|
|
do { |
|
|
|
if (!--count) { |
|
|
|
OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
if (!BN_is_bit_set(max_exclusive, n - 2) && |
|
|
|
!BN_is_bit_set(max_exclusive, n - 3)) { |
|
|
|
/* range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer |
|
|
|
* than range. This is a common scenario when generating a random value |
|
|
|
* modulo an RSA public modulus, e.g. for RSA base blinding. */ |
|
|
|
if (!BN_rand(r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/* If r < 3*range, use r := r MOD range (which is either r, r - range, or |
|
|
|
* r - 2*range). Otherwise, iterate again. Since 3*range = 11..._2, each |
|
|
|
* iteration succeeds with probability >= .75. */ |
|
|
|
if (BN_cmp(r, max_exclusive) >= 0) { |
|
|
|
if (!BN_sub(r, r, max_exclusive)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if (BN_cmp(r, max_exclusive) >= 0) { |
|
|
|
if (!BN_sub(r, r, max_exclusive)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
/* range = 11..._2 or range = 101..._2 */ |
|
|
|
if (!BN_rand(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
if (/* steps 4 and 5 */ |
|
|
|
!BN_rand(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY) || |
|
|
|
/* step 7 */ |
|
|
|
!BN_add_word(r, min_inclusive)) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} while (BN_cmp_word(r, min_inclusive) < 0 || |
|
|
|
BN_cmp(r, max_exclusive) >= 0); |
|
|
|
|
|
|
|
/* Step 6. This loops if |r| >= |max_exclusive|. This is identical to |
|
|
|
* checking |r| > |max_exclusive| - 1 or |r| - 1 > |max_exclusive| - 2, the |
|
|
|
* formulation stated in FIPS 186-4. */ |
|
|
|
} while (BN_cmp(r, max_exclusive) >= 0); |
|
|
|
|
|
|
|
return 1; |
|
|
|
} |
|
|
|