int RAND_bytes(uint8_t *out, size_t out_len) { static const uint8_t kZeroAdditionalData[32] = {0}; RAND_bytes_with_additional_data(out, out_len, kZeroAdditionalData); return 1; }
static int bn_rand_with_additional_data(BIGNUM *rnd, int bits, int top, int bottom, const uint8_t additional_data[32]) { uint8_t *buf = NULL; int ret = 0, bit, bytes, mask; if (rnd == NULL) { return 0; } if (top != BN_RAND_TOP_ANY && top != BN_RAND_TOP_ONE && top != BN_RAND_TOP_TWO) { OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (bottom != BN_RAND_BOTTOM_ANY && bottom != BN_RAND_BOTTOM_ODD) { OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } if (bits == 0) { BN_zero(rnd); return 1; } bytes = (bits + 7) / 8; bit = (bits - 1) % 8; mask = 0xff << (bit + 1); buf = OPENSSL_malloc(bytes); if (buf == NULL) { OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); goto err; } /* Make a random number and set the top and bottom bits. */ RAND_bytes_with_additional_data(buf, bytes, additional_data); if (top != BN_RAND_TOP_ANY) { if (top == BN_RAND_TOP_TWO && bits > 1) { if (bit == 0) { buf[0] = 1; buf[1] |= 0x80; } else { buf[0] |= (3 << (bit - 1)); } } else { buf[0] |= (1 << bit); } } buf[0] &= ~mask; /* Set the bottom bit if requested, */ if (bottom == BN_RAND_BOTTOM_ODD) { buf[bytes - 1] |= 1; } if (!BN_bin2bn(buf, bytes, rnd)) { goto err; } ret = 1; err: if (buf != NULL) { OPENSSL_cleanse(buf, bytes); OPENSSL_free(buf); } return (ret); }