New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Current master does not load RDRAND engine by default? #16996
Comments
Did you read the INSTALL.md file? Configure with |
I did read it - and my config includes |
That's unexpected, the engine isn't trying to use RDSEED whereas the built-in source does. Is it possible that RDSEED is found but not working? |
My point exactly! ;-)
99.999% that RDSEED is working fine on these CPUs. However, if memory serves me, RDSEED can fail, and much more often than RDRAND (e.g., see https://stackoverflow.com/questions/14413839/what-are-the-exhaustion-characteristics-of-rdrand-on-ivy-bridge). |
Running a test-program on this machine shows that RDSEED is not only detectable, but works quite well:
Here's the source: /* Compare the performance of RDSEED and RDRAND.
*
* Compute the CPU time used to fill a buffer with (pseudo) random bits
* using each instruction.
*
* Compile with: gcc -mrdrnd -mrdseed
*/
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <x86intrin.h>
#define BUFSIZE (1<<24)
int main() {
unsigned int ok, i;
unsigned long long *rand = malloc(BUFSIZE*sizeof(unsigned long long)),
*seed = malloc(BUFSIZE*sizeof(unsigned long long));
clock_t start, end, bm;
// RDRAND (the benchmark)
start = clock();
for (i = 0; i < BUFSIZE; i++) {
while (!_rdrand64_step(&rand[i]))
;
}
bm = clock() - start;
printf("RDRAND: %li\n", bm);
// RDSEED
start = clock();
for (i = 0; i < BUFSIZE; i++) {
while (!_rdseed64_step(&seed[i]))
;
}
end = clock();
printf("RDSEED: %li, %.2lf\n", end - start, (double)(end-start)/bm);
free(rand);
free(seed);
return 0;
} |
In 1.1.1, the code calling RDRAND/RDSEED is identical to 3.0 and master as far as I can see. It doesn't fall back from RDRAND to RDSEED. This is deliberate since the former is specifically recommended as the source for RNGs. The Was 1.1.1 also configured with just the CPU randomness source enabled? |
I changed configuration to 1.1.1 has always been configured with "rdcpu,os". Thankfully, it didn't exhibit this weird problem. RDSEED is considered "more secure", but in my opinion RDRAND is secure enough to fallback to it. Perhaps you can add a config (or runtime) parameter to enable this fallback? Though I admit I can't be sure that RDSEED is the cause of it. It appears to me that 3.x somehow fails to "fully load" RDRAND engine - so, on one hand is aware that it's present and doors not fall back to another source ("os"?), but on the other hand, it didn't complete the actual loading - so requests do but reach it. Just my vague theory. |
Neither 1.1.1 nor 3.0 use the RDRAND engine to access these instructions. Loading the engine adds a different path. That one works and the other doesn't is a mystery currently. |
Anything I can do to help unravel this mystery? Also, let me repeat myself: if indeed it's failing on RDSEED - I think it would be a good idea to have a config-parameter-controlled fallback to RDRAND. UpdateIs there any way to make RDRAND engine automatically loaded (and initialized)? Since there doesn't seem to be a separate Here's one reason why I want it:
|
Is it possible to determine that RDSEED is indeed the problem? The code is in: openssl/providers/implementations/rands/seeding/rand_cpu_x86.c Lines 91 to 102 in 90c3113
If RDSEED is a problem, RDRAND might be too so it would be worthwhile checking this. It can be done via the OPENSSL_ia32cap environment variable which avoids a recompile. |
@paulidale first - doesn't the program I ran (see the source above) prove that both RDRAND and RDSEED basically work OK on this machine/CPU? Second - I think I understand what the code you listed actually does, and probably can figure how to modify it to behave in the way I suggested. But I doubt I could use it as a "template" to write my standalone test... And again, sorry for repeating myself - I strongly doubt the problem is RDRAND, because if it was - then choosing a different path by involving RDRAND engine* wouldn't've saved the day. For that engine uses RDRAND (and/or RDSEED) for sure. Thus, the problem must be somewhere in this path... Do I make sense? Oh, in case it matters:
And here's what Botan thinks of the CPU extensions:
|
If it's not the seed generation, most likly be failing to get there. Not much happens post collection that's likely to fail. That fits with the known data. Is it possible to set a breakpoint in
|
It does not seem to reach there...?! I tried:
In case it helps: and Lines 1211 to 1239 in 90c3113
|
That's useful. Now to figure out what to do next.... |
Darn... I found the problem, though not its cause. This works:
This does not:
In other words, I'd appreciate if you could elucidate on what may be going on. |
Phew! This makes some kind of sense. I'm guessing the PKCS#11 engine is installing a default randomness source. This will override the built-in sources. I'd not even considered this possibility. Good sleuthing. Adding the command line option will add the rdrand source over the top. |
Be careful if using rand from card if card used for login. That might lead
an attack on your system.
…On Tue, Nov 9, 2021, 10:36 PM Pauli ***@***.***> wrote:
Phew! This makes some kind of sense.
I'm guessing the PKCS#11 engine is installing a default randomness source.
This will override the built-in sources. I'd not even considered this
possibility. Good sleuthing.
Adding the command line option will add the rdrand source over the top.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#16996 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGTIMKN52U23C7AKLQ3VZLULHZGJANCNFSM5HULNFVQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Could you please provide more details? |
I'm pretty sure the underlying problem is that there is a call to RAND_set_rand_method() or RAND_set_rand_engine() occurring (likely the latter). These completely replace the built in RNG infrastructure with the RAND_METHOD/engine. If the engine then fails to produce output for any reason, the observed results will present. Adding the RDRAND engine again replaces the RAND_METHOD and things begin working. I've no idea why the PKCS#11 engine has stopped working with 3.0. It wasn't meant to. |
@mouse07410, Sorry, I assumed you where asking on the OpenSC list and assumed you were trying to use a random number generator from a smart card via PKCS11. If the host was going to use the card to provide a random number that would be used help authenticate the user, it might be possible for an attacker to use a bogus device that returned a carefully crafted non-random number. This might help in hacking the authentication. |
@dengert thank you - I understand the threat now. As I see it, good defense would be to only use card-extracted randomness when the user is present and observes that the card is "genuine". Also, Doug, it looks like |
@paulidale I checked the sources of the
But I found this in . . . . .
static RAND_METHOD *PKCS11_get_rand_method(void) {
static RAND_METHOD ops = {
.bytes = rand_bytes,
};
return &ops;
}
/* This internal function is used by ENGINE_pkcs11() and possibly by the
* "dynamic" ENGINE support too */
static int bind_helper(ENGINE *e)
{
if (!ENGINE_set_id(e, PKCS11_ENGINE_ID) ||
!ENGINE_set_destroy_function(e, engine_destroy) ||
!ENGINE_set_init_function(e, engine_init) ||
!ENGINE_set_finish_function(e, engine_finish) ||
!ENGINE_set_ctrl_function(e, engine_ctrl) ||
!ENGINE_set_cmd_defns(e, engine_cmd_defns) ||
!ENGINE_set_name(e, PKCS11_ENGINE_NAME) ||
//#if OPENSSL_VERSION_NUMBER < 0x10100002L
!ENGINE_set_RAND(e, PKCS11_get_rand_method()) ||
//#endif /* OPENSSL_VERSION_NUMBER */
#ifndef OPENSSL_NO_RSA
!ENGINE_set_RSA(e, PKCS11_get_rsa_method()) ||
#endif
. . . . . Testing now with those lines removed. |
Removing that binding alleviated the problem. |
OpenSSL-1.1.1 seemed to have no problem finding RDRAND engine:
Needless to say, I want/need RDRAND engine to be loaded by default (in 3.+). What do I need to do with
openssl.cnf
to get it?The text was updated successfully, but these errors were encountered: