Bug fixes for RAND_add(), RAND_seed() and RAND_load_file()#7456
Bug fixes for RAND_add(), RAND_seed() and RAND_load_file()#7456mspncp wants to merge 3 commits intoopenssl:masterfrom
Conversation
|
One test is missing, because my perl-fu was not sufficient to implement it. It would be great if one of the perl-gurus (@levitte?) could convert this naive shell script into a portable test recipe. test-rand-load-file #!/bin/bash
RAND_BUF_SIZE=1024
RAND_DRBG_STRENGTH=256
RAND_LOAD_BUF_SIZE=$((RAND_BUF_SIZE + RAND_DRBG_STRENGTH))
for n in $(seq $((2*${RAND_LOAD_BUF_SIZE}))); do
truncate -s $n RANDFILE
../util/shlib_wrap.sh ../apps/openssl rand -rand RANDFILE -hex 10 > /dev/null || echo $n failed
doneThe test-rand-load-file script can be tested by letting it fail on 02107968d423. |
|
Note: the test-rand-load-file script was outdated and needed some corrections. |
|
What also needs more testing is the case without os entropy source (OPENSSL_RAND_SEED_NONE). Originally, Kurt had implemented a test which simulated this situation by replacing the get_entropy() callbacks, but it turned out that ef40152c5e8c can be tested authentically only if one configures |
crypto/rand/drbg_lib.c
Outdated
There was a problem hiding this comment.
This makes me nervous. Could we lose the static here, delete the copy in drbgtest.c and statically link the drbgtest executable? The symbol won't be exported from libcrypto, the test will gain access and the duplication is gone.
There was a problem hiding this comment.
Of course I tried to to reuse the function from drbg_lib.c in the tests. In fact, I thought I had read in some place that the tests were linked statically. After this proved wrong I did not want to export a private symbol, so I thought adding a warning comment would be the best compromise.
Changing the test framework to link the tests statically is out of my scope, so one of you would have to do that.
There was a problem hiding this comment.
@paulidale thanks for your hints regarding build.info, with your explanation the change was really trivial, see #7462.
crypto/rand/drbg_lib.c
Outdated
There was a problem hiding this comment.
Nit: spaces around the '*'
ef40152 to
d569cf3
Compare
|
@paulidale, I rebased on master, without any squashing, i.e. all fixups related to your comments are separate commits. Note also that commit 6f891202ce is a substitute for PR #7462. d569cf3d41 fixup! DRBG: fix implementations of RAND_add() and RAND_seed() |
crypto/rand/drbg_lib.c
Outdated
There was a problem hiding this comment.
Cast to size_t instead of unsigned int?
|
@paulidale @levitte it looks like currently the price for avoiding a single duplicated function ( My suggestion now is to revert the static linking of the What's your opinion? |
|
Okay with me, apologies for sending you on this quixotic chase. I thought it was easy... |
|
No problem. You were right to ask for it and you couldn't know. |
|
@paulidale I will squash the fixups shortly and put the pull request out of WIP. For better transparency, I push all fixups first before doing the squashing. commit 64f3eed257a9ae265f5292241f95a09a1bc4b721 (HEAD -> pr-fix-rand-add-and-friends, msp/pr-fix-rand-add-and-friends) Revert conversion to drbgtest to static linking
|
5e6248d to
83b746e
Compare
|
Ok, branch has been squashed without moving merge-base. The unsquashed branch was retained at https://github.com/mspncp/openssl/commits/pr-fix-rand-add-and-friends-unsquashed. I noticed that the commit messages still need to be completed. I'll do that this evening and then put it out of WIP. |
The failure of RAND_load_file was only noticed because of the heap corruption which was reported in openssl#7499 and fixed in commit 5b4cb38. To prevent this in the future, RAND_load_file() now explicitly checks RAND_status() and reports an error if it fails. Related-to openssl#7449
Increase the load buffer size such that it exceeds the chunk size by a comfortable amount. This is done to avoid calling RAND_add() with a small final chunk. Instead, such a small final chunk will be added together with the previous chunk (unless it's the only one). Related-to openssl#7449
Commit 5b4cb38 (openssl#7382) introduced a bug which had the effect that RAND_add()/RAND_seed() failed for buffer sizes less than 32 bytes. The reason was that now the added random data was used exlusively as entropy source for reseeding. When the random input was too short or contained not enough entropy, the DRBG failed without querying the available entropy sources. This commit makes drbg_add() act smarter: it checks the entropy requirements explicitely. If the random input fails this check, it won't be added as entropy input, but only as additional data. More precisely, the behaviour depends on whether an os entropy source was configured (which is the default on most os): - If an os entropy source is avaible then we declare the buffer content as additional data by setting randomness to zero and trigger a regular reseeding. - If no os entropy source is available, a reseeding will fail inevitably. So drbg_add() uses a trick to mix the buffer contents into the DRBG state without forcing a reseeding: it generates a dummy random byte, using the buffer content as additional data. Related-to openssl#7449
83b746e to
b75b060
Compare
|
@paulidale the commit messages are now complete and the pr is ready for final review. I decided to squash the tests into commit b75b060, where they belong to thematically. To make reviewing easier for you, I left the unsquashed branch on my repo for you as a reference (noted already above). This is how you can get it and verify that the code trees are identical: In fact, both commits point to the same tree b53a3911dba0: |
The failure of RAND_load_file was only noticed because of the heap corruption which was reported in #7499 and fixed in commit 5b4cb38. To prevent this in the future, RAND_load_file() now explicitly checks RAND_status() and reports an error if it fails. Related-to: #7449 Reviewed-by: Paul Dale <[email protected]> (Merged from #7456)
Increase the load buffer size such that it exceeds the chunk size by a comfortable amount. This is done to avoid calling RAND_add() with a small final chunk. Instead, such a small final chunk will be added together with the previous chunk (unless it's the only one). Related-to: #7449 Reviewed-by: Paul Dale <[email protected]> (Merged from #7456)
Commit 5b4cb38 (#7382) introduced a bug which had the effect that RAND_add()/RAND_seed() failed for buffer sizes less than 32 bytes. The reason was that now the added random data was used exlusively as entropy source for reseeding. When the random input was too short or contained not enough entropy, the DRBG failed without querying the available entropy sources. This commit makes drbg_add() act smarter: it checks the entropy requirements explicitely. If the random input fails this check, it won't be added as entropy input, but only as additional data. More precisely, the behaviour depends on whether an os entropy source was configured (which is the default on most os): - If an os entropy source is avaible then we declare the buffer content as additional data by setting randomness to zero and trigger a regular reseeding. - If no os entropy source is available, a reseeding will fail inevitably. So drbg_add() uses a trick to mix the buffer contents into the DRBG state without forcing a reseeding: it generates a dummy random byte, using the buffer content as additional data. Related-to: #7449 Reviewed-by: Paul Dale <[email protected]> (Merged from #7456)
The failure of RAND_load_file was only noticed because of the heap corruption which was reported in openssl#7499 and fixed in commit 5b4cb38. To prevent this in the future, RAND_load_file() now explicitly checks RAND_status() and reports an error if it fails. Related-to: openssl#7449 Reviewed-by: Paul Dale <[email protected]> (Merged from openssl#7456)
|
@paulidale there was trivial conflict while cherry-picking the third of the three commits (8817215) from master to 1.1.1: It was caused by the renaming of The conflict was resolved by picking the (incoming) version from master: The cherry-picked commit can be found here: mspncp@026d39b Please approve the conflict resolution or let me know whether you prefer a separate pull request. |
Increase the load buffer size such that it exceeds the chunk size by a comfortable amount. This is done to avoid calling RAND_add() with a small final chunk. Instead, such a small final chunk will be added together with the previous chunk (unless it's the only one). Related-to: #7449 Reviewed-by: Paul Dale <[email protected]> (Merged from #7456)
In commit 8bf3665 some renamings andd typo fixes were made while adding back the DRBG-HMAC and DRBG-HASH implementation. Since the commit could not be backported, a lot of unnecessary differences between master and 1.1.1 were introduced. These differences result in tiresome merge conflicts when cherry-picking. To minimize these merge-conflicts, this patch ports all 'non-feature' changes of commit 8bf3665 (e.g., renamings of private variables, fixes of typographical errors, comment changes) manually back to 1.1.1. The commits a83dc59 (openssl#7399) and 8817215 (openssl#7456) failed to cherry-pick previously to 1.1.1, with this patch they both cherry-pick without conflicts.
|
@paulidale I found a better and more general solution, see fix #7505. With that fix, the remaining commit will cherry-pick cleanly to 1.1.1, so no reapproval is required. |
In commit 8bf3665 some renamings andd typo fixes were made while adding back the DRBG-HMAC and DRBG-HASH implementation. Since the commit could not be backported, a lot of unnecessary differences between master and 1.1.1 were introduced. These differences result in tiresome merge conflicts when cherry-picking. To minimize these merge-conflicts, this patch ports all 'non-feature' changes of commit 8bf3665 (e.g., renamings of private variables, fixes of typographical errors, comment changes) manually back to 1.1.1. The commits a83dc59 (#7399) and 8817215 (#7456) failed to cherry-pick previously to 1.1.1, with this patch they both cherry-pick without conflicts. Reviewed-by: Richard Levitte <[email protected]> Reviewed-by: Bernd Edlinger <[email protected]> (Merged from #7505)
Commit 5b4cb38 (#7382) introduced a bug which had the effect that RAND_add()/RAND_seed() failed for buffer sizes less than 32 bytes. The reason was that now the added random data was used exlusively as entropy source for reseeding. When the random input was too short or contained not enough entropy, the DRBG failed without querying the available entropy sources. This commit makes drbg_add() act smarter: it checks the entropy requirements explicitely. If the random input fails this check, it won't be added as entropy input, but only as additional data. More precisely, the behaviour depends on whether an os entropy source was configured (which is the default on most os): - If an os entropy source is avaible then we declare the buffer content as additional data by setting randomness to zero and trigger a regular reseeding. - If no os entropy source is available, a reseeding will fail inevitably. So drbg_add() uses a trick to mix the buffer contents into the DRBG state without forcing a reseeding: it generates a dummy random byte, using the buffer content as additional data. Related-to: #7449 Reviewed-by: Paul Dale <[email protected]> (Merged from #7456) (cherry picked from commit 8817215)
|
Finally completed, the last commit has been cherry-picked to 1.1.1. Thanks! |
(Note: this pull request is based on #7455)It turned out that the heap corruption #7449 was only the tip of an iceberg and solving it revealed several other problems. The long story short is
This pull request attempts to
The third part is an essential conclusion from the analysis of #7449: How can it be that such a cardinal error was not caught by a test? It would have gone unnoticed if it hadn't been for the heap corruption to unveil it. So I tried to improve testing. Currently, the tests are commit separately before fixing the issue they address, such that one can test whether the tests work by resetting the HEAD to the respective commit. In the end, I might squash them into the commits which their failures.
Checklist