[rdrand] add an untested workaround for i686 machine

This commit is contained in:
Vincent Hanquez 2016-06-03 07:12:38 +01:00
parent 5cf7d08ca6
commit f5a811e755

View File

@ -65,17 +65,38 @@ static inline int crypto_random_rdrand64_step(uint64_t *buffer)
: \
: "cc")
/* inline encoding of 'rdrand %eax' to cover old binutils
* - no inputs
* - 'cc' to the clobber list as we modify condition code.
* - output of rdrand in eax and have a 8 bit error condition
*/
#define inline_rdrand_eax(val, err) \
asm(".byte 0x0f,0xc7,0xf0; setc %1" \
: "=a" (val), "=q" (err) \
: \
: "cc")
#ifdef __x86_64__
# define RDRAND_SZ 8
# define RDRAND_T uint64_t
#define inline_rdrand(val, err) inline_rdrand_rax(val, err)
#else
# define RDRAND_SZ 4
# define RDRAND_T uint32_t
#define inline_rdrand(val, err) inline_rdrand_eax(val, err)
#endif
/* Returns the number of bytes succesfully generated */
int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len)
{
uint64_t tmp;
int aligned = (intptr_t) buffer % 8;
RDRAND_T tmp;
int aligned = (intptr_t) buffer % RDRAND_SZ;
int orig_len = len;
int to_alignment = 8 - aligned;
int to_alignment = RDRAND_SZ - aligned;
uint8_t ok;
if (aligned != 0) {
inline_rdrand_rax(tmp, ok);
inline_rdrand(tmp, ok);
if (!ok)
return 0;
memcpy(buffer, (uint8_t *) &tmp, to_alignment);
@ -83,15 +104,15 @@ int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len)
len -= to_alignment;
}
for (; len >= 8; buffer += 8, len -= 8) {
inline_rdrand_rax(tmp, ok);
for (; len >= RDRAND_SZ; buffer += RDRAND_SZ, len -= RDRAND_SZ) {
inline_rdrand(tmp, ok);
if (!ok)
return (orig_len - len);
*((uint64_t *) buffer) = tmp;
}
if (len > 0) {
inline_rdrand_rax(tmp, ok);
inline_rdrand(tmp, ok);
if (!ok)
return (orig_len - len);
memcpy(buffer, (uint8_t *) &tmp, len);