diff options
-rw-r--r-- | providers/implementations/rands/seeding/rand_vms.c | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/providers/implementations/rands/seeding/rand_vms.c b/providers/implementations/rands/seeding/rand_vms.c index abc06ffd5b..47ba5caab4 100644 --- a/providers/implementations/rands/seeding/rand_vms.c +++ b/providers/implementations/rands/seeding/rand_vms.c @@ -474,34 +474,6 @@ size_t data_collect_method(RAND_POOL *pool) return ossl_rand_pool_entropy_available(pool); } -int ossl_pool_add_nonce_data(RAND_POOL *pool) -{ - struct { - pid_t pid; - CRYPTO_THREAD_ID tid; - unsigned __int64 time; - } data; - - /* Erase the entire structure including any padding */ - memset(&data, 0, sizeof(data)); - - /* - * Add process id, thread id, and a high resolution timestamp - * (where available, which is OpenVMS v8.4 and up) to ensure that - * the nonce is unique with high probability for different process - * instances. - */ - data.pid = getpid(); - data.tid = CRYPTO_THREAD_get_current_id(); -#if __CRTL_VER >= 80400000 - sys$gettim_prec(&data.time); -#else - sys$gettim((void*)&data.time); -#endif - - return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); -} - /* * SYS$GET_ENTROPY METHOD * ====================== @@ -575,28 +547,56 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool) return data_collect_method(pool); } - -int ossl_rand_pool_add_additional_data(RAND_POOL *pool) +int ossl_pool_add_nonce_data(RAND_POOL *pool) { + /* + * Two variables to ensure that two nonces won't ever be the same + */ + static unsigned __int64 last_time = 0; + static unsigned __int32 last_seq = 0; + struct { + pid_t pid; CRYPTO_THREAD_ID tid; unsigned __int64 time; + unsigned __int32 seq; } data; /* Erase the entire structure including any padding */ memset(&data, 0, sizeof(data)); /* - * Add some noise from the thread id and a high resolution timer. - * The thread id adds a little randomness if the drbg is accessed - * concurrently (which is the case for the <master> drbg). + * Add process id, thread id, a timestamp, and a sequence number in case + * the same time stamp is repeated, to ensure that the nonce is unique + * with high probability for different process instances. + * + * The normal OpenVMS time is specified to be high granularity (100ns), + * but the time update granularity given by sys$gettim() may be lower. + * + * OpenVMS version 8.4 (which is the latest for Alpha and Itanium) and + * on have sys$gettim_prec() as well, which is supposedly having a better + * time update granularity, but tests on Itanium (and even Alpha) have + * shown that compared with sys$gettim(), the difference is marginal, + * so of very little significance in terms of entropy. + * Given that, and that it's a high ask to expect everyone to have + * upgraded to OpenVMS version 8.4, only sys$gettim() is used, and a + * sequence number is added as well, in case sys$gettim() returns the + * same time value more than once. + * + * This function is assumed to be called under thread lock, and does + * therefore not take concurrency into account. */ + data.pid = getpid(); data.tid = CRYPTO_THREAD_get_current_id(); -#if __CRTL_VER >= 80400000 - sys$gettim_prec(&data.time); -#else + data.seq = 0; sys$gettim((void*)&data.time); -#endif + + if (data.time == last_time) { + data.seq = ++last_seq; + } else { + last_time = data.time; + last_seq = 0; + } return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); } |