Hi Rich, > I think the only way to do that in the DRBG model is to treat it as > “additional input” and do a generate > call. I think that would achieve the same effect, but it wouldn’t delay any > possible seeding of randomness > that the DRBG itself needs at some point.
You're right, well, almost. The implementation of drbg_add() (which implements RAND_add()) could be actually as simple as this little function: static int drbg_add(const void *buf, int num, double randomness) { int ret = 0; CRYPTO_THREAD_write_lock(rand_drbg.lock); ret = RAND_DRBG_reseed(&rand_drbg, buf, num); err: CRYPTO_THREAD_unlock(rand_drbg.lock); return ret; } The problem is that currently this would create a circular dependency, because now RAND_add() is involved both in pushing and in pulling entropy. RAND_add() -> drbg_add() -> RAND_DRBG_reseed() -> get_entropy() -> get_entropy_from_system() -> RAND_poll_ex() -> RAND_add() Using RAND_DRBG_generate() instead of RAND_DRBG_reseed() does not solve the problem, because the former can occasionally trigger a reseed. I already have the solution in my mind how to break up this vicious circle, but I need some time to write it down. Here is a sketch: 1) Use RAND_add() only for pushing to break the circular dependency =================================================================== Add a new function rand_drbg_add() which is identical to RAND_DRBG_reseed(), except that it does not pull fresh entropy (and consequently does not reset the reseed_counter). Then the left hand side of the becomes RAND_add() -> drbg_add() -> rand_drbg_add() The code of drbg_add() and rand_drbg_add() is at the end of this mail. (This is the easy part :-) ) 2) Reorganize the backend code for pulling entropy ================================================== Reorganize get_entropy_from_system() in a way that it collects the entropy in the way it was originally intended, without calling RAND_add() and without using this evil fixed size 'rand_bytes' buffer, from which I tried to dissuade you ever since, Rich (no offence ;-) ) This part is more complicated, because one has to be careful not to break RAND_poll() for applications which don't use the default RAND_OpenSSL() method. So please give me some time, I will try to turn my ideas into a PR. Matthias ___ drbg_lib.c: /* * Mix in the specified data without reseeding |drbg|. * * Used by drbg_add() only. * * Similar to RAND_DRBG_reseed(), but there is no call to * get_entropy() and the reseed_counter is not reset */ int rand_drbg_add(RAND_DRBG *drbg, const unsigned char *adin, size_t adinlen) { if (drbg->state == DRBG_ERROR) { RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_IN_ERROR_STATE); return 0; } if (drbg->state == DRBG_UNINITIALISED) { RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_NOT_INSTANTIATED); return 0; } if (adin == NULL) adinlen = 0; else if (adinlen > drbg->max_adinlen) { RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ADDITIONAL_INPUT_TOO_LONG); return 0; } drbg->state = DRBG_ERROR; if (!ctr_reseed(drbg, NULL, 0, adin, adinlen)) goto end; drbg->state = DRBG_READY; end: if (drbg->state == DRBG_READY) return 1; return 0; } ... static int drbg_add(const void *buf, int num, double randomness) { int ret = 0; CRYPTO_THREAD_write_lock(rand_drbg.lock); ret = rand_drbg_add(&rand_drbg, buf, num); err: CRYPTO_THREAD_unlock(rand_drbg.lock); return ret; }
smime.p7s
Description: S/MIME cryptographic signature
-- openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev