> From: openssl-users [mailto:openssl-users-boun...@openssl.org] On Behalf Of 
> Sudarshan Soma
> Sent: Wednesday, July 25, 2018 12:13

> But rand() returns max value of 32767 .  Is there a recomended way to
> convert RAND_bytes to libc rand()
> something like this?

> unsigned char buf[2];
> RAND_bytes(buf,2)
> int *rndp = malloc(4);
> memcpy(rndp,buf,2);
> return (unsigned) ((*rndp) % 32768)

Ugh. Memory leak, unnecessary malloc, undefined behavior (only part of the rdnp 
object is initialized)... I really hope you don't have code like this in your 
application.

C guarantees unsigned integer types use a pure binary representation, and 32767 
is 2**15 - 1. So assuming you're only using octet-based C implementations 
(limits.h defines CHAR_BIT as 8), which is very likely the case, just do this:

unsigned int openssl_rand(void) {
   unsigned char bytes[2];
   RAND_bytes(bytes, 2);
   return (bytes[0] | (bytes[1] << 8)) & 0x7fff;
}

Untested, but I think that will work on any conforming C implementation with 
CHAR_BIT == 8, and as long as the 15 least-significant bits of the output of 
RAND_bytes are unbiased, the result will be an unbiased value in [0,32767].

Note this does not give you the semantics of C's rand, as it ignores any 
invocation of srand. Some C programs require a predictable rand; they use it 
for reproducible Monte Carlo test runs, for example. So replacing rand this way 
is not necessarily valid.

Also, calling it "rand" would be a violation of the C specification, so if you 
want your C applications to conform to the spec, you'll have to change them 
anyway. Or use a macro, provided the application code never suppresses a macro 
definition for rand.

--
Michael Wojcik
Distinguished Engineer, Micro Focus


-- 
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

Reply via email to