[openssl-users] conversion of RAND_bytes to rand in fips apporved way

William Roberts bill.c.roberts at gmail.com
Wed Jul 25 19:00:17 UTC 2018


On Wed, Jul 25, 2018 at 11:30 AM, Michael Wojcik
<Michael.Wojcik at microfocus.com> wrote:
>> From: openssl-users [mailto:openssl-users-bounces at 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) {

LibC's rand() is int, so if it matters you'll want to match that
interface. But usually, you want to avoid signed numbers when negative
doesn't matter..

>    unsigned char bytes[2];
>    RAND_bytes(bytes, 2);
>    return (bytes[0] | (bytes[1] << 8)) & 0x7fff;

You can ditch the shift logic. Offhand,  i'm not sure what would
happen on Big Endian machine, would it leave bit 15 high since it's in
byte 0?

int openssl_rand(void) {
    uint16_t x;
    RAND_bytes((unsigned char *)&x, sizeof(x));
    return x & 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


More information about the openssl-users mailing list