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 use 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:
- Initialize the engine
- 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(). 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
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