diff options
Diffstat (limited to 'src/crypto/rand/hwrand.c')
-rw-r--r-- | src/crypto/rand/hwrand.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/src/crypto/rand/hwrand.c b/src/crypto/rand/hwrand.c index f0bbccd..73d3de7 100644 --- a/src/crypto/rand/hwrand.c +++ b/src/crypto/rand/hwrand.c @@ -14,52 +14,43 @@ #include <openssl/rand.h> -#include <assert.h> +#include <stdlib.h> #include <string.h> #include <openssl/cpu.h> -#include "internal.h" - #if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) -/* These functions are defined in asm/rdrand-x86_64.pl */ -extern int CRYPTO_rdrand(uint8_t out[8]); -extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len); - -static int have_rdrand(void) { +int CRYPTO_have_hwrand(void) { return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0; } -int CRYPTO_hwrand(uint8_t *buf, size_t len) { - if (!have_rdrand()) { - return 0; - } +/* CRYPTO_rdrand is defined in asm/rdrand-x86_64.pl */ +extern uint64_t CRYPTO_rdrand(void); - const size_t len_multiple8 = len & ~7; - if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) { - return 0; +void CRYPTO_hwrand(uint8_t *buf, size_t len) { + while (len >= 8) { + uint64_t rand = CRYPTO_rdrand(); + memcpy(buf, &rand, sizeof(rand)); + len -= sizeof(rand); + buf += sizeof(rand); } - len -= len_multiple8; - - if (len != 0) { - assert(len < 8); - uint8_t rand_buf[8]; - if (!CRYPTO_rdrand(rand_buf)) { - return 0; - } - memcpy(buf + len_multiple8, rand_buf, len); + if (len > 0) { + uint64_t rand = CRYPTO_rdrand(); + memcpy(buf, &rand, len); } - - return 1; } #else -int CRYPTO_hwrand(uint8_t *buf, size_t len) { +int CRYPTO_have_hwrand(void) { return 0; } +void CRYPTO_hwrand(uint8_t *buf, size_t len) { + abort(); +} + #endif |