return rand_pool_entropy_available(pool);
}
-int rand_pool_add_nonce_data(RAND_POOL *pool)
-{
- struct {
- pid_t pid;
- CRYPTO_THREAD_ID tid;
- unsigned __int64 time;
- } data = { 0 };
-
- /*
- * 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 rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
-}
-
/*
* SYS$GET_ENTROPY METHOD
* ======================
return data_collect_method(pool);
}
+int rand_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 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();
+ data.seq = 0;
+ sys$gettim((void*)&data.time);
+
+ if (data.time == last_time) {
+ data.seq = ++last_seq;
+ } else {
+ last_time = data.time;
+ last_seq = 0;
+ }
+
+ return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
+}
int rand_pool_add_additional_data(RAND_POOL *pool)
{
} data = { 0 };
/*
- * 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 some noise from the thread id and a timer. The thread id adds a
+ * little randomness if the drbg is accessed concurrently (which is the
+ * case for the <master> drbg).
*/
data.tid = CRYPTO_THREAD_get_current_id();
-#if __CRTL_VER >= 80400000
- sys$gettim_prec(&data.time);
-#else
sys$gettim((void*)&data.time);
-#endif
return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
}