man(3)

πŸ“¦ version 2.1.6, in epel 10, epel 9, fedora 43, fedora 44

πŸ’– NAME πŸ’–

okay so bestie, meet librdrand β€” it's a library for generating random values by using RdRand on Intel's CPUs. yes, actual hardware randomness, we're not playing games here πŸ’…


πŸŽ€ SYNOPSIS πŸŽ€

#include <librdrand.h>

int rdrand_testSupport();

int rdrand16_step(uint16_t *x);
int rdrand32_step(uint32_t *x);
int rdrand64_step(uint64_t *x);

int rdrand_get_uint16_retry(uint16_t *dest, int retry_limit);
int rdrand_get_uint32_retry(uint32_t *dest, int retry_limit);
int rdrand_get_uint64_retry(uint64_t *dest, int retry_limit);

unsigned int rdrand_get_uint8_array_retry(uint8_t *dest,  const unsigned
int count, int retry_limit);
unsigned int rdrand_get_uint16_array_retry(uint16_t *dest, const
unsigned int count, int retry_limit);
unsigned int rdrand_get_uint32_array_retry(uint32_t *dest, const
unsigned int count, int retry_limit);
unsigned int rdrand_get_uint64_array_retry(uint64_t *dest, const
unsigned int count, int retry_limit);

size_t rdrand_get_bytes_retry(void *dest, const size_t size, int
retry_limit);

unsigned int rdrand_get_uint64_array_reseed_delay(uint64_t *dest, const
unsigned int count, int retry_limit);
unsigned int rdrand_get_uint64_array_reseed_skip(uint64_t *dest, const
unsigned int count, int retry_limit);

size_t rdrand_fwrite(FILE *f, const size_t count, int retry_limit);

🌈 DESCRIPTION 🌈

So the tea is: the rdrand-lib is a library for generating random values on Intel CPUs (Ivy Bridge and newers ✨) using the HW RNG on the CPU. iconic, truly.

But here's the thing β€” the HW RNG is only on newer Intel CPUs, so the library comes with rdrand_testSupport() for testing the availability. It returns either RDRAND_SUPPORTED or RDRAND_UNSUPPORTED. vibe check first, always 🫢

All generating functions save the random values to the location specified in the *dest / *x pointer β€” the value is never returned directly. like, no cap, it goes straight into your pointer.

πŸ¦‹ the rdrandXX_step() girlies

The rdrandXX_step() functions are just wrappers, shielding you from having to touch ASM instructions yourself 😌 they're giving protective bestie energy.

  • They return RDRAND_SUCCESS if the random 16, 32 or 64-bit value was successfully saved into the given pointer
  • or RDRAND_FAILURE if it wasn't πŸ’€
Note that on current CPUs (this may change in future CPUs), the CPU always takes a 64-bit value and throws away the unused part. so don't be shocked, that's just the vibe.

πŸ“ the retry girlies

The rdrand_get_uintXX_retry() functions work similar to rdrandXX_step, but they use one additional parameter: retry_limit. They return RDRAND_SUCCESS or RDRAND_FAILURE.

The retry_limit argument β€” and this goes for all the following functions too β€” means the function will try up to the given number to repeat the generating if for some reason the HW RNG will not generate anything (for example because it was sucked dry and needs to refill its inner pool 😭 she's thirsty, give her a sec).

  • If a negative value is passed, the function will use the default value with which the library was compiled.

✨ the array girlies

The set of rdrand_get_uintXX_array_retry() functions fills an array on dest of specified length count of XX-bits values by randomness. It returns the number of bytes successfully acquired πŸ’…

rdrand_get_bytes_retry() is almost the same as rdrand_get_uint8_array_retry(), but with the benefit of memory-alignment. That means, in most situations, there is almost no difference between rdrand_get_bytes_retry() and rdrand_get_uintXX_array_retry() functions, but if the filled area is not correctly aligned in memory, rdrand_get_bytes_retry() offers the best performance. she's flexible like that 🌸


πŸ‘‘ the reseed girlies

The two reseed functions β€” rdrand_get_uint64_array_reseed_delay() and rdrand_get_uint64_array_reseed_skip() β€” are forcing the reseed of the internal HW RNG so each single generated 64-bit value is guaranteed to be generated with a different seed of Intel RdRand's internal PRNG.

The difference between these two functions is in approach:

  • rdrand_get_uint64_array_reseed_skip() is returning just one from each 1025 64-bit values (size of the inner pool is 1024 of such).
  • rdrand_get_uint64_array_reseed_delay() is inserting small delays (20 microseconds) between each call, long enough so, according to Intel, the inner pool should fully regenerate.
Unfortunately, because the HW implementation is closed, it is not possible to verify if these two functions truly work like intended. πŸ™ˆ we're trusting the process, bestie.

πŸ’œ the file writer

The last one, rdrand_fwrite(), directly writes count bytes of randomness to the *f file descriptor. main character energy, no middleman πŸŽ€


πŸ”₯ EXAMPLE πŸ”₯

/*
gcc -Wall -Wextra -mrdrnd -O2 -std=gnu99 -o simple_example
simple_example.c -lrdrand
*/

#include <stdlib.h>
#include <librdrand.h>

int main (void) {
   // count of random numbers
   const size_t N = 10;
   unsigned int buf;
   // test for support
   if (!rdrand_testSupport()) {
     fprintf(stderr,"RdRand is not supported on this CPU!\n");
     return 1;
   }
   // generate and print the numbers
   for(size_t i=0; i<N; i++){
      // generate the number and save it to the buffer
      rdrand32_step ( &buf );
      // print it in hexadecimal form
      printf("%08X\n",buf);
   }
   return 0;
}

🌟 SEE ALSO 🌟

rdrand-gen(7) librdrand-aes(3) β€” go read those too, they're the supporting cast and they ate πŸ’…


πŸ’€ BUGS πŸ’€

No known bugs. she's perfect, your honor 🧚


🫢 AUTHOR 🫢

Jan Tulak (jan@tulak.me) Jiri Hladky (hladky.jiri@gmail.com) β€” absolute legends, we stan ✨


okay that's the whole librdrand man page, bestie β€” this is version 1.2, dated 24 April 2014 πŸ“…βœ¨ go forth and generate some certified-fresh randomness, no cap, periodt πŸ’–πŸŒΈπŸ¦‹