buf=(unsigned char *)OPENSSL_malloc(bytes);
if (buf == NULL)
{
- BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE);
+ BNerr(BN_F_BNRAND,ERR_R_MALLOC_FAILURE);
goto err;
}
/* make a random number and set the top and bottom bits */
time(&tim);
- RAND_add(&tim,sizeof(tim),0);
+ RAND_add(&tim,sizeof(tim),0.0);
if (pseudorand)
{
err:
if (buf != NULL)
{
- memset(buf,0,bytes);
+ OPENSSL_cleanse(buf,bytes);
OPENSSL_free(buf);
}
+ bn_check_top(rnd);
return(ret);
}
/* random number r: 0 <= r < range */
-static int bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range)
+static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
{
int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand;
int n;
+ int count = 100;
if (range->neg || BN_is_zero(range))
{
n = BN_num_bits(range); /* n > 0 */
+ /* BN_is_bit_set(range, n - 1) always holds */
+
if (n == 1)
+ BN_zero(r);
+ else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3))
{
- if (!BN_zero(r)) return 0;
- }
- else if (BN_is_bit_set(range, n - 2))
- {
- do
- {
- /* range = 11..._2, so each iteration succeeds with probability >= .75 */
- if (!bn_rand(r, n, -1, 0)) return 0;
- }
- while (BN_cmp(r, range) >= 0);
- }
- else
- {
- /* range = 10..._2,
+ /* range = 100..._2,
* so 3*range (= 11..._2) is exactly one bit longer than range */
do
{
if (BN_cmp(r, range) >= 0)
if (!BN_sub(r, r, range)) return 0;
}
+
+ if (!--count)
+ {
+ BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+ return 0;
+ }
+
+ }
+ while (BN_cmp(r, range) >= 0);
+ }
+ else
+ {
+ do
+ {
+ /* range = 11..._2 or range = 101..._2 */
+ if (!bn_rand(r, n, -1, 0)) return 0;
+
+ if (!--count)
+ {
+ BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
+ return 0;
+ }
}
while (BN_cmp(r, range) >= 0);
}
+ bn_check_top(r);
return 1;
}
-int BN_rand_range(BIGNUM *r, BIGNUM *range)
+int BN_rand_range(BIGNUM *r, const BIGNUM *range)
{
return bn_rand_range(0, r, range);
}
-int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range)
+int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
{
return bn_rand_range(1, r, range);
}