1 /* SPDX-License-Identifier: GPL-2.0-only */
7 * Intel recommends that applications attempt 10 retries in a tight loop
8 * in the unlikely event that the RDRAND instruction does not successfully
9 * return a random number. The odds of ten failures in a row would in fact
10 * be an indication of a larger CPU issue.
12 #define RDRAND_RETRY_LOOPS 10
15 * Generate a 32-bit random number through RDRAND instruction.
16 * Carry flag is set on RDRAND success and 0 on failure.
18 static inline uint8_t rdrand_32(uint32_t *rand
)
23 ".byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
24 : "=a" (*rand
), "=qm" (carry
));
30 * Generate a 64-bit random number through RDRAND instruction.
31 * Carry flag is set on RDRAND success and 0 on failure.
33 static inline uint8_t rdrand_64(uint64_t *rand
)
38 ".byte 0x48; .byte 0x0f; .byte 0xc7; .byte 0xf0; setc %1"
39 : "=a" (*rand
), "=qm" (carry
));
44 enum cb_err
get_random_number_32(uint32_t *rand
)
48 /* Perform a loop call until RDRAND succeeds or returns failure. */
49 for (i
= 0; i
< RDRAND_RETRY_LOOPS
; i
++) {
56 enum cb_err
get_random_number_64(uint64_t *rand
)
59 uint32_t rand_high
, rand_low
;
61 /* Perform a loop call until RDRAND succeeds or returns failure. */
62 for (i
= 0; i
< RDRAND_RETRY_LOOPS
; i
++) {
67 if (rdrand_32(&rand_high
) && rdrand_32(&rand_low
)) {
68 *rand
= ((uint64_t)rand_high
<< 32) |