
AMD Secure Random Number Generator Library INTRODUCTION Random numbers and their generation is a crucial component in many areas of computational science. Monte Carlo simulation, modeling, cryptography, games and many more. One of the vital fields where random numbers are used is Cryptography. Cryptographic applications require random numbers for key generation, encrypting messages or to mask certain content. In order to be secure, they need high quality random numbers that must be unpredictable and robust. There are mainly two types of Random Number Generators (RNG); software based pseudorandom number generators (PRNG) and hardware random number generators. Pseudorandom number generators use a mathematical model and are implemented in software. Hardware random number generators on the other hand, rely on a dedicated hardware unit to generate random numbers. • Pseudorandom number generators: Pseudorandom number generators follow a deterministic approach and an algorithmic implementation of a mathematical model. Depending on the initial state (seed), they generate a sequence of random numbers. While they may have good statistical properties (statistically independent and uniform distribution), they are vulnerable to state compromise attacks once an adversary becomes aware of the seed. If one is able to guess the initial state of the generator and the mathematical model, they will be able to calculate rest of the sequence of random numbers. Hence pseudorandom numbers are not a good choice for cryptographic applications. • Hardware random number generators: Hardware random number generators provide more unpredictable random numbers. They generate random numbers utilizing a hardware unit as a source of entropy (randomness) unlike a fixed mathematical model in PRNG. Determining pattern of random numbers from such a physical source is much harder and hence have more suitable cryptographic properties. AMD’s latest microprocessor architecture are equipped with Cryptographic Co-processor hardware that enables generation of cryptographically secure random numbers. In this whitepaper, we provide details on AMD Secure Random Number Generator (Secure RNG) library which provides an easy-to-use software Application Programming Interface (API) to access random numbers generated by AMD’s hardware RNG implementation. AMD HARDWARE RNG ARCHITECTURE AMD’s Family 17h processor and other products of 2016 and beyond are equipped with Cryptographic Co-processor 5.0 hardware that enables the generation of cryptographically secure random numbers. AMD’s hardware RNG architecture is shown in the figure below Random Number Generator Ring Oscillator Ring Oscillator Random AES-256 AES-256 Number CBC-MAC CTR_DRBG FIFO Ring Oscillator RDSEED RDRAND source:AMD RNG Whitepaper by David Kaplan[3] Figure 1. AMD Hardware RNG Architecture The main components are 1. Noise Source: The RNG uses 16 separate ring oscillator chains as the noise source. During runtime, the 16 ring oscillators are continually sampled to generate noise values. 2. Entropy Conditioner: The 16-bits of ring oscillator noise are fed into the entropy conditioner, based on AES-256[1] CBC-MAC[2], which gathers multiple noise samples over time to use in generating the entropy needed by the RNG design. To create a seed value, 3 iterations are executed, each generating 128 bits of full entropy, thus generating a 384-bit seed. The seed is then fed into the deterministic random bit generator, AES-256 CTR_DRBG module. 3. Deterministic Random Bit Generator (DRBG): AMD RNG design includes a deterministic random bit generator, based on AES-256 CTR_DRBG construct. It uses the 384-bit seed value from the entropy conditioner and produces fast, high- quality random values. The values are stored in a FIFO buffer to support fast read bursts. Maximum of 2048 32-bit samples are generated per seed by the DRBG module. It attempts to aggressively re-seed well before this limit is reached. The DRBG module is compliant with NIST SP 800-90A standard [1] for random bit generation. AMD SECURE RNG LIBRARY The AMD hardware RNG design allows access to output registers that allow reading the random values generated by the hardware. These registers are accessible to software through x86 user-level instructions. The x86 instructions are: 1. RDRAND : Returns a 16-bit, 32-bit or 64-bit random value 2. RDSEED : Returns a 16-bit, 32-bit or 64-bit conditioned random value Accessing the random values using these low-level instructions can be cumbersome in high level applications. Also, most applications would need a stream of random numbers which means multiple calls to RDRAND/RDSEED instructions. AMD Secure RNG library provides an easy-to-use API library for accessing the hardware generated random numbers. The use of library has several advantages • Applications can just link to the library and invoke either a single or stream of random numbers. • It abstracts out low level programming for accessing RDRAND and RDSEED instructions as well as handling some of the possible outcomes based on register outputs. • Library also manages checking for any hardware failure while generation and allows user to specify retrial attempts • The intuitive API interfaces enables more applications to use the library and thus the underlying AMD RNG implementation. The Secure RNG library exposes several APIs that makes use of the above instructions to either return a single random value or a stream of them. The APIs and their functionality is as described in the table below. Feature API Description Hardware int is_RDRAND_Supported( ) Check RDRAND instruction support Support Parameters: None Return type int: Indicates whether RDRAND is supported or not. 1 – Success int is_RDSEED_Supported( ) Check RDSEED instruction support Parameters: None Return type int: Indicates whether RDSEED is supported or not. 1 – Success int get_rdrand16u( Fetch a single 16-bit value by calling the uint16_t *rng_val, RDRAND instruction unsigned int retry_count) Parameters: rng_val - Pointer to memory to store the value returned by RDRAND retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdrand32u( Fetch a single 32-bit value by calling the uint32_t *rng_val, RDRAND instruction unsigned int retry_count) Parameters: rng_val - Pointer to memory to store the value returned by RDRAND retry_count - Number of retry attempts Return type int: Success or failure status of function call RDRAND int get_rdrand64u( Fetch a single 64-bit value by calling the uint64_t *rng_val, RDRAND instruction unsigned int retry_count) Parameters: rng_val - Pointer to memory to store the value returned by RDRAND retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdrand32u_arr( Fetch an array of 32-bit values of size N by uint32_t *rng_arr, calling the RDRAND instruction unsigned int N, unsigned int retry_count) Parameters: rng_arr - Pointer to memory to store the value returned by RDRAND N - Number of random values to return retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdrand64u_arr( Fetch an array of 64-bit values of size N by uint64_t *rng_arr, calling the RDRAND instruction unsigned int N, unsigned int retry_count) Parameters: rng_arr - Pointer to memory to store the value returned by RDRAND N - Number of random values to return retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdrand_bytes_arr( Fetch an array of random bytes of a given unsigned char *rng_arr, size by calling the RDRAND instruction unsigned int N, unsigned int retry_count) Parameters: rng_arr - Pointer to memory to store the random bytes N - Number of random bytes to return retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdseed16u( Fetch a single 16-bit value by calling the uint16_t* rng_val, RDSEED instruction unsigned int retry_count) Parameters: rng_val - Pointer to memory to store the value returned by RDSEED retry_count - Number of retry attempts Return type int: Success or failure status of RDSEED function call int get_rdseed32u( Fetch a single 32-bit value by calling the uint32_t* rng_val, RDSEED instruction unsigned int retry_count) Parameters: rng_val - Pointer to memory to store the value returned by RDSEED retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdseed64u( Fetch a single 64-bit value by calling the uint64_t *rng_val, RDSEED instruction unsigned int retry_count) Parameters: rng_val - Pointer to memory to store the value returned by RDSEED retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdseed32u_arr( Returns an array of 32-bit values of size N by uint32_t *rng_arr, calling the RDSEED instruction unsigned int N, Parameters: unsigned int retry_count) rng_arr - Pointer to memory to store the value returned by RDSEED N - Number of random values to return retry_count - Number of retry attempts Return type int: Success or failure status of function call int get_rdseed64u_arr( Fetch an array of 64-bit values of size N by uint32_t *rng_arr, calling the RDSEED instruction unsigned int N, Parameters: unsigned int retry_count) rng_arr - Pointer to memory to store the value returned by RDSEED N - Number of random values to return retry_count - Number of retry attempts Return type int: Success or failure status of function call
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages10 Page
-
File Size-