Beispiel #1
0
/*
 * Acquire entropy using Intel-specific cpu instructions
 *
 * Uses the RDSEED instruction if available, otherwise uses
 * RDRAND if available.
 *
 * For the differences between RDSEED and RDRAND, and why RDSEED
 * is the preferred choice, see https://goo.gl/oK3KcN
 *
 * Returns the total entropy count, if it exceeds the requested
 * entropy count. Otherwise, returns an entropy count of 0.
 */
size_t rand_acquire_entropy_from_cpu(RAND_POOL *pool)
{
    size_t bytes_needed;
    unsigned char *buffer;

    bytes_needed = RAND_POOL_bytes_needed(pool, 8 /*entropy_per_byte*/);
    if (bytes_needed > 0) {
        buffer = RAND_POOL_add_begin(pool, bytes_needed);

        if (buffer != NULL) {

            /* If RDSEED is available, use that. */
            if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) {
                if (OPENSSL_ia32_rdseed_bytes(buffer, bytes_needed)
                    == bytes_needed)
                    return RAND_POOL_add_end(pool,
                                             bytes_needed,
                                             8 * bytes_needed);
            }

            /* Second choice is RDRAND. */
            if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
                if (OPENSSL_ia32_rdrand_bytes(buffer, bytes_needed)
                    == bytes_needed)
                    return RAND_POOL_add_end(pool,
                                             bytes_needed,
                                             8 * bytes_needed);
            }

            return RAND_POOL_add_end(pool, 0, 0);
        }
    }

    return RAND_POOL_entropy_available(pool);
}
Beispiel #2
0
int rand_read_cpu(RAND_poll_cb rand_add, void *arg)
{
    char buff[RANDOMNESS_NEEDED];

    /* If RDSEED is available, use that. */
    if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) {
        if (OPENSSL_ia32_rdseed_bytes(buff, sizeof(buff)) == sizeof(buff)) {
            rand_add(arg, buff, (int)sizeof(buff), sizeof(buff));
            return 1;
        }
    }

    /* Second choice is RDRAND. */
    if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
        if (OPENSSL_ia32_rdrand_bytes(buff, sizeof(buff)) == sizeof(buff)) {
            rand_add(arg, buff, (int)sizeof(buff), sizeof(buff));
            return 1;
        }
    }

    return 0;
}