Conversation
|
At this stage, I'm trying to nail down a sensible API for the EVP_RAND interface and the libcrypto to provider interface. The intention is for libcrypto to create and link up the DRBG chains (master, public & private), however FIPS effectively mandates that the data moving between the DRBGs in the chain must stay within the FIPS boundary. Mapping existing RAND and DRBG APIs onto the new will be done as a best effort later. Note: only CTR DRBG was present in 1.1.1, so we've some flexibility to not wedge the other DRBGs into the framework. |
So...until that is done calls to |
|
If things go badly, yes. I hope that RAND and DRBG are reworked in time for release. Still, early days. |
|
Suppose you remove the ability to reseed across providers, but instead mandate that each provider has to seed from the environment and do seeding solely inside itself. In other words, follow the current openssl drbg-chaining. Doesn't that make things MUCH simpler? |
|
Also libcrypto could provide call (callback for providers?) to provide the entropy from environment. But how would be the per-thread and separate drbg for private and non-private data be done within a provider? I think the per-thread instances could be internal implementation detail of the provider but separating private and non-private RNGs would have to be somehow reflected in the provider interface. |
|
@t8m are you asking me or paul? If me, put the master drbg and the per-thread-data keys into OPENSSL_CTX. Then RAND_BYTES_ex just looks things up in the ctx data. Trivial. |
Doesn't this mandate adding down calls to the provider which wasn't popular?
From a FIPS perspective, this isn't workable. The seed material needs to stay within the FIPS boundary or be transferred using a secure channel. The DRBG callbacks will, of course, need to be supported. |
|
Can you explain why it's not workable if the provider calls to the OS to get seed material itself? You have to add some downcalls. I envision RAND{priv}bytes_ex calls to the provider to do the rand_generate and the reseeding. So only 3-4 downcalls are needed. |
|
The provider can call the OS to get seed material. That's FIPS friendly. There might be a nomenclature issue. I'm using down calls meaning calls to the OSSL_PROVIDER object as distinct to calls to the rand algorithm the provider has. I think this is the what @mattcaswell uses the term for too. At this stage this is just a pair of proposed APIs. One for EVP_RAND and one for the libcrypto/provider boundary. I think they should be workable within the available time but I made a mess of it last try... |
|
Nomenclature-wise, I've borrowed the terms used with SGX, where they talk about downcalls when it's calls from the insecure environment into the secure enclave, and upcalls when it's calls from the secure enclave to the insecure environment. I suspect that @mattcaswell uses the same nomenclature... at the very least, he seems to understand precisely what I mean when I use those terms. Side note: I recently discovered |
I am talking here about collecting the entropy from environment - what is the difference from calling getrandom() from glibc or calling a function OSSL_getrandom() from openssl which in turn calls getrandom() from glibc? BTW the buffer for the data can be supplied by the provider so there does not necessarily have to be any data transfer outside the FIPS boundary. |
|
Call glibc directly is acceptable in a FIPS context. Calling a wrapper in OpenSSL (outside of the FIPS boundary) requires a secure channel for the entropy. There is a world of difference. rand_platform.c needs to be inside the FIPS provider. |
|
And that's the time when the non-sensical FIPS rules strike again. Let's just imagine that the "secure channel" would be provided. Where the channel would end on the other side? In kernel? Unless kernel is a FIPS module it could not be. And if there would be no buffer copying involved in the imagined OpenSSL callback that would call the getrandom() the data as collected from the system would not even be transferred through OpenSSL itself so why we need any secure channel if there is no intermediary data transfer. (Not talking about the triviality that there is single process with a single address space involved anyway.) Anyway I am not going to fight FIPS rules here so let's duplicate some code! 😁 |
c3f2640 to
8908b8a
Compare
|
Just a side-note, in case this force-push was the result of an interactive rebase to edit commits: Unless you really need to integrate changes (e.g. bugfixes) from upstream, it would be convenient for the reviewers if you could avoid moving the merge-base, because then GitHub's force-push diff shows exactly your changes and not those from master as well. (Note the link which is displayed by GitHub automatically in the force-push message.)
You can either do this by specifying the number of commits to rebase (here: See git-rebase(1): |
|
The force push was primarily a rebase to the current master. |
|
Summary of changes:
|
494ea70 to
2953de9
Compare
|
24 hours has passed since 'approval: done' was set, but as this PR has been updated in that time the label 'approval: ready to merge' is not being automatically set. Please review the updates and set the label manually. |
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
The test RNG can provide pre-canned entropy and nonces for testing other algorithms. Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
POSIX mandates that time_t is a signed integer but it doesn't specify the lenght. Having wrappers lets uses ignore this. Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
…istory Reviewed-by: Paul Dale <[email protected]> (Merged from #11682)
Also separate out the TSC and RDRAND based sources into their own file in the seeding subdirectory. Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Paul Dale <[email protected]> (Merged from #11682)
Move the three different DRBGs to the provider.
As part of the move, the DRBG specific data was pulled out of a common
structure and into their own structures. Only these smaller structures are
securely allocated. This saves quite a bit of secure memory:
+-------------------------------+
| DRBG | Bytes | Secure |
+--------------+-------+--------+
| HASH | 376 | 512 |
| HMAC | 168 | 256 |
| CTR | 176 | 256 |
| Common (new) | 320 | 0 |
| Common (old) | 592 | 1024 |
+--------------+-------+--------+
Bytes is the structure size on the X86/64.
Secure is the number of bytes of secure memory used (power of two allocator).
Reviewed-by: Matthias St. Pierre <[email protected]>
(Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
EVP_RAND, the RNGs and provider-rand. Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
[extended tests] Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
THe EVP_RAND wrapper works with the underlying RNG to produce the amount of random data requested even if it is larger than the largest single generation the source allows. This test verified that this works. Reviewed-by: Matthias St. Pierre <[email protected]> (Merged from #11682)
|
CI failures aren't related. |
Another try at making random numbers available from providers.