How to Use the RDRAND Engine in OpenSSL* for Random Number Generation

By John P Mechalas, Published: 07/30/2014, Last Updated: 07/30/2014

The OpenSSL* ENGINE API includes an engine specifically for Intel® Data Protection Technology with Secure Key. When this engine is enabled, the RAND_bytes() function will exclusively use the RDRAND instruction for generating random numbers and will not need to rely on the OS's entropy pool for reseeding. End applications can simply call RAND_bytes(), do not have to invoke RAND_seed() or RAND_add(), and the OpenSSL library will not call RAND_poll() internally.

Download the complete code sample at the bottom of the article.

Enabling the Engine

Enabling the ENGINE is a two-step process:

  1. Initialize the engine
  2. Set the engine as the default for random number generation

The following code snippets show how this is done. A complete sample program, distributed under the Intel Sample Source Code License, can also be downloaded using the link on this page. The sample code is designed to be compiled under Linux*, but can very easily be adapted to a Windows* or OS X* environment.

Initialization

The first step in initializing the engine is to call ENGINE_load_rdrand() in your C or C++ source. To avoid compile errors it is up the developer to either ensure that have a version of OpenSSL with RDRAND support, or (if developing a software package for distribution as source code) determine prior to compilation whether or not this function exists in the OpenSSL library. On UNIX systems, the latter can be accomplished using the GNU* Autoconf autoconfiguration tool or similar utilities.

Once ENGINE_lad_rdrand() has been called, the developer must then call ENGINE_by_id() to check for the existence of an engine with the name "rdrand". If this function returns NULL, then the rdrand engine was not able to load. The most common cause for this error would be lack of processor support for Intel Data Protection Technology with Secure Key.

ENGINE *engine;

ENGINE_load_rdrand();

engine= ENGINE_by_id("rdrand");
if ( engine == NULL ) {
	fprintf(stderr, "ENGINE_load_rdrand returned %lu\n", ERR_get_error());
	exit(1);
}

With the presence of the RDRAND engine verified, you then call ENGINE_init() to prepare it for use.

if ( ! ENGINE_init(engine) ) {
	fprintf(stderr, "ENGINE_init returned %lu\n", ERR_get_error());
	exit(1);
}

Using the Engine

With the engine properly initialized, you then set it as the default for random number generation. This is done with the ENGINE_set_default() function.
if ( ! ENGINE_set_default(engine, ENGINE_METHOD_RAND) ) {
	fprintf(stderr, "ENGINE_set_default returned %lu\n", ERR_get_error());
	exit(1);
}

Now all that is left is to call RAND_bytes() to generate random numbers.

RAND_bytes(buf, BUFFERSZ);

Cleanup

When your program is done with the engine, it is good form to clean up afterwards to free up any resources that the engine is using.

ENGINE_finish(engine);
ENGINE_free(engine);
ENGINE_cleanup();

Summary

Using the rdrand engine in OpenSSL is a straight-forward process, easily accomplished in just a few lines of C/C++. With it, you can ensure that the output of RAND_bytes() is generated entirely by the RDRAND instruction on supported hardware.

§

*Other names and brands may be claimed as the property of others

Attachment Size
rdrand-engine-sample-0714.tgz 37.3 KB

Product and Performance Information

1

Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice.

Notice revision #20110804