Skip to content
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

Fast rng #685

Closed
wants to merge 17 commits into from
Closed

Fast rng #685

wants to merge 17 commits into from

Conversation

Labels
None yet
Projects
None yet
3 participants
@nmathewson
Copy link
Contributor

@nmathewson nmathewson commented Feb 7, 2019

No description provided.

nmathewson added 8 commits Feb 7, 2019
Using an anonymous mmap() is a good way to get pages that we can set
kernel-level flags on, like minherit() or madvise() or mlock().
We're going to use that so that we can make uninheritable locked
pages to store PRNG data.
I don't know how this got here, but this kind of a wrapper only
belongs in a header file.
Some of the code for getting a random value within a range wants to
be shared between crypto_rand() and the new crypto_fast_rng() code.
This is the second part of refactoring the random-int-in-range code.
test_crypto.c is pretty big; it wouldn't hurt to split it up some
more before I start adding stuff to the PRNG tests.
This module is currently implemented to use the same technique as
libottery (later used by the bsds' arc4random replacement), using
AES-CTR-256 as its underlying stream cipher.  It's backtracking-
resistant immediately after each call, and prediction-resistant
after a while.

Here's how it works:

We generate psuedorandom bytes using AES-CTR-256.  We generate BUFLEN bytes
at a time.  When we do this, we keep the first SEED_LEN bytes as the key
and the IV for our next invocation of AES_CTR, and yield the remaining
BUFLEN - SEED_LEN bytes to the user as they invoke the PRNG.  As we yield
bytes to the user, we clear them from the buffer.

Every RESEED_AFTER times we refill the buffer, we mix in an additional
SEED_LEN bytes from our strong PRNG into the seed.

If the user ever asks for a huge number of bytes at once, we pull SEED_LEN
bytes from the PRNG and use them with our stream cipher to fill the user's
request.
@coveralls
Copy link

@coveralls coveralls commented Feb 7, 2019

Pull Request Test Coverage Report for Build 3798

  • 104 of 112 (92.86%) changed or added relevant lines in 3 files are covered.
  • 1132 unchanged lines in 6 files lost coverage.
  • Overall coverage increased (+0.03%) to 61.773%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/lib/crypt_ops/crypto_rand_fast.c 50 58 86.21%
Files with Coverage Reduction New Missed Lines %
src/feature/hs/hs_client.c 2 51.32%
src/core/or/circuitpadding.c 2 97.27%
src/core/proto/proto_socks.c 11 92.72%
src/lib/sandbox/sandbox.c 182 1.6%
src/feature/nodelist/networkstatus.c 333 53.29%
src/app/config/config.c 602 72.5%
Totals Coverage Status
Change from base Build 3737: 0.03%
Covered Lines: 45336
Relevant Lines: 73391

💛 - Coveralls

src/lib/crypt_ops/crypto_rand_fast.c Outdated Show resolved Hide resolved
src/lib/crypt_ops/crypto_rand_fast.c Outdated Show resolved Hide resolved
src/lib/crypt_ops/crypto_rand_fast.c Outdated Show resolved Hide resolved
src/lib/crypt_ops/crypto_rand_fast.c Outdated Show resolved Hide resolved
src/lib/crypt_ops/crypto_rand_fast.c Outdated Show resolved Hide resolved
nmathewson added 7 commits Feb 13, 2019
Explain why crypto_rand_int doesn't call IMPLEMENT_RAND_UNSIGNED()
directly.
Use a symbolic value instead of 4 in the definition of BUFLEN
Clarify that "seed" means "key and IV" in a few more comments.
Rename a variable in crypto_fast_rng_getbytes_impl(); add an assert.

[I've verified that for me the assert doesn't slow us down.]
@nmathewson
Copy link
Contributor Author

@nmathewson nmathewson commented Feb 14, 2019

making a new squashed PR

@nmathewson nmathewson closed this Feb 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment