Using engines for random number generation

2019-07-20 17:23发布

I am trying to use the RAND_bytes API of OpenSSL, but I want to try it with various Random Number Generating Engines.

Is there a recommended way of generating Random bytes and adding entropy in OpenSSL? Where can I get other Engine implementations, and how can I swap them in?

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-07-20 17:57

Is there a recommended way of generating Random bytes and adding entropy in OpenSSL?

Yes. See the OpenSSL wiki on Random Numbers. It takes you through adding entropy for a seed, and extracting bytes for use in keying and other secret material.

Adding entropy for seeding is covered under Random Numbers and Seeds. Extracting bytes for use in keysing and other secret material is covered at Random Numbers and Generation.


Where can I get other Engine implementations, and how can I swap them in?

OpenSSL comes with a few engines related to random numbers. The default is a software based PRNG engine, md_rand. You can find its source code at <openssl src>/crypto/rand/md_rand.c. Another is Intel's RDRAND engine. You can find the source at <openssl src>/crypto/engine/eng_rdrand.c.

You can also use hardware based RNGs if you have the hardware. You can even write your own engine that provides a SHA-512 HMAC. Or even one that combines (XORs) an SHA-512 HMAC with with RDRAND. The Mersenne Twister is popular, and you could even write an engine for it, too.

Here's how you swap in an engine to use for random numbers. Its taken from the OpenSSL wiki, and it swaps-in the Intel RDRAND engine:

 1    unsigned long err = 0;
 2    int rc = 0;
 3
 4    OPENSSL_cpuid_setup();
 5    ENGINE_load_rdrand();
 6
 7    ENGINE* eng = ENGINE_by_id("rdrand");
 8    err = ERR_get_error();
 9
10    if(NULL == eng) {
11        fprintf(stderr, "ENGINE_load_rdrand failed, err = 0x%lx\n", err);
12        abort(); /* failed */
13    }
14
15    rc = ENGINE_init(eng);
16    err = ERR_get_error();
17
18    if(0 == rc) {
19        fprintf(stderr, "ENGINE_init failed, err = 0x%lx\n", err);
20        abort(); /* failed */
21    }
22  
23    rc = ENGINE_set_default(eng, ENGINE_METHOD_RAND);
24    err = ERR_get_error();
25
26    if(0 == rc) {
27        fprintf(stderr, "ENGINE_set_default failed, err = 0x%lx\n", err);
28        abort(); /* failed */
29    }
30
31    /* OK to proceed */
32
33    ...
34    ENGINE_finish(eng);
35    ENGINE_free(eng);
36    ENGINE_cleanup();

... I am trying to use the RAND_bytes API of OpenSSL ...

You never do anything other than use RAND_bytes, RAND_add and friends as normal. How you use RAND_bytes, RAND_add and friends never changes.


The Mersenne Twister is popular, and you could even write an engine for it, too...

If you do this, then you might consider posting the source code for others to use. I would suggest creating a page on OpenSSL's wiki, explain the Mersenne Twister engine, explain how to use it, and provide a patch for it.

The other choice is to submit it to the RT system (the bug tracker) as a feature/enhancement. But its been my observation that most things wither and die once they enter RT.

查看更多
登录 后发表回答