rand: add seeding sources to providers.
authorPauli <paul.dale@oracle.com>
Mon, 11 May 2020 02:06:37 +0000 (12:06 +1000)
committerPauli <paul.dale@oracle.com>
Wed, 24 Jun 2020 10:05:41 +0000 (20:05 +1000)
Also separate out the TSC and RDRAND based sources into their own file in the
seeding subdirectory.

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/11682)

providers/implementations/rands/build.info
providers/implementations/rands/rand_pool.c [new file with mode: 0644]
providers/implementations/rands/seeding/build.info [new file with mode: 0644]
providers/implementations/rands/seeding/rand_cpu_x86.c [new file with mode: 0644]
providers/implementations/rands/seeding/rand_tsc.c [new file with mode: 0644]
providers/implementations/rands/seeding/rand_unix.c
providers/implementations/rands/seeding/rand_vms.c
providers/implementations/rands/seeding/rand_vxworks.c
providers/implementations/rands/seeding/rand_win.c
providers/implementations/rands/seeding/seeding.h [new file with mode: 0644]

index 00f62e5..5d55c27 100644 (file)
@@ -1,3 +1,4 @@
+SUBDIRS=seeding
 
 # Missing: drbg_ctr.c
 SOURCE[../../libfips.a]=drbg.c
diff --git a/providers/implementations/rands/rand_pool.c b/providers/implementations/rands/rand_pool.c
new file mode 100644 (file)
index 0000000..71b7119
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
diff --git a/providers/implementations/rands/seeding/build.info b/providers/implementations/rands/seeding/build.info
new file mode 100644 (file)
index 0000000..e75a941
--- /dev/null
@@ -0,0 +1,11 @@
+$COMMON=rand_unix.c rand_win.c rand_tsc.c rand_cpu_x86.c
+IF[{- $config{target} =~ /vxworks/i -}]
+  $COMMON=$COMMON rand_vxworks.c
+ENDIF
+IF[{- $config{target} =~ /vms/i -}]
+  $COMMON=$COMMON rand_vms.c
+ENDIF
+
+SOURCE[../../../libfips.a]=$COMMON
+SOURCE[../../../libnonfips.a]=$COMMON
+
diff --git a/providers/implementations/rands/seeding/rand_cpu_x86.c b/providers/implementations/rands/seeding/rand_cpu_x86.c
new file mode 100644 (file)
index 0000000..3b276c8
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/cryptlib.h"
+#include <openssl/opensslconf.h>
+#include "crypto/rand_pool.h"
+
+#ifdef OPENSSL_RAND_SEED_RDCPU
+size_t OPENSSL_ia32_rdseed_bytes(unsigned char *buf, size_t len);
+size_t OPENSSL_ia32_rdrand_bytes(unsigned char *buf, size_t len);
+
+/*
+ * Acquire entropy using Intel-specific cpu instructions
+ *
+ * Uses the RDSEED instruction if available, otherwise uses
+ * RDRAND if available.
+ *
+ * For the differences between RDSEED and RDRAND, and why RDSEED
+ * is the preferred choice, see https://goo.gl/oK3KcN
+ *
+ * Returns the total entropy count, if it exceeds the requested
+ * entropy count. Otherwise, returns an entropy count of 0.
+ */
+size_t prov_acquire_entropy_from_cpu(RAND_POOL *pool)
+{
+    size_t bytes_needed;
+    unsigned char *buffer;
+
+    bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
+    if (bytes_needed > 0) {
+        buffer = rand_pool_add_begin(pool, bytes_needed);
+
+        if (buffer != NULL) {
+            /* Whichever comes first, use RDSEED, RDRAND or nothing */
+            if ((OPENSSL_ia32cap_P[2] & (1 << 18)) != 0) {
+                if (OPENSSL_ia32_rdseed_bytes(buffer, bytes_needed)
+                    == bytes_needed) {
+                    rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
+                }
+            } else if ((OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) != 0) {
+                if (OPENSSL_ia32_rdrand_bytes(buffer, bytes_needed)
+                    == bytes_needed) {
+                    rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
+                }
+            } else {
+                rand_pool_add_end(pool, 0, 0);
+            }
+        }
+    }
+
+    return rand_pool_entropy_available(pool);
+}
+#else
+NON_EMPTY_TRANSLATION_UNIT
+#endif
diff --git a/providers/implementations/rands/seeding/rand_tsc.c b/providers/implementations/rands/seeding/rand_tsc.c
new file mode 100644 (file)
index 0000000..2121abe
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/cryptlib.h"
+#include <openssl/opensslconf.h>
+#include "crypto/rand_pool.h"
+
+#ifdef OPENSSL_RAND_SEED_RDTSC
+/*
+ * IMPORTANT NOTE:  It is not currently possible to use this code
+ * because we are not sure about the amount of randomness it provides.
+ * Some SP800-90B tests have been run, but there is internal skepticism.
+ * So for now this code is not used.
+ */
+# error "RDTSC enabled?  Should not be possible!"
+
+/*
+ * Acquire entropy from high-speed clock
+ *
+ * Since we get some randomness from the low-order bits of the
+ * high-speed clock, it can help.
+ *
+ * Returns the total entropy count, if it exceeds the requested
+ * entropy count. Otherwise, returns an entropy count of 0.
+ */
+size_t prov_acquire_entropy_from_tsc(RAND_POOL *pool)
+{
+    unsigned char c;
+    int i;
+
+    if ((OPENSSL_ia32cap_P[0] & (1 << 4)) != 0) {
+        for (i = 0; i < TSC_READ_COUNT; i++) {
+            c = (unsigned char)(OPENSSL_rdtsc() & 0xFF);
+            rand_pool_add(pool, &c, 1, 4);
+        }
+    }
+    return rand_pool_entropy_available(pool);
+}
+#else
+NON_EMPTY_TRANSLATION_UNIT
+#endif
index 869c2d0..050b3e9 100644 (file)
 #ifndef _GNU_SOURCE
 # define _GNU_SOURCE
 #endif
-#include "e_os.h"
+#include "../e_os.h"
 #include <stdio.h>
 #include "internal/cryptlib.h"
 #include <openssl/rand.h>
 #include <openssl/crypto.h>
-#include "rand_local.h"
+#include "crypto/rand_pool.h"
 #include "crypto/rand.h"
 #include <stdio.h>
 #include "internal/dso.h"
+#include "seeding.h"
 
 #ifdef __linux
 # include <sys/syscall.h>
@@ -131,7 +132,7 @@ static uint64_t get_timer_bits(void);
  *
  * As a precaution, we assume only 2 bits of entropy per byte.
  */
-size_t rand_pool_acquire_entropy(RAND_POOL *pool)
+size_t prov_pool_acquire_entropy(RAND_POOL *pool)
 {
     short int code;
     int i, k;
@@ -603,7 +604,7 @@ void rand_pool_keep_random_devices_open(int keep)
  * of input from the different entropy sources (trust, quality,
  * possibility of blocking).
  */
-size_t rand_pool_acquire_entropy(RAND_POOL *pool)
+size_t prov_pool_acquire_entropy(RAND_POOL *pool)
 {
 #  if defined(OPENSSL_RAND_SEED_NONE)
     return rand_pool_entropy_available(pool);
@@ -729,7 +730,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
 
 #if (defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_SYS_VXWORKS)) \
      || defined(__DJGPP__)
-int rand_pool_add_nonce_data(RAND_POOL *pool)
+int prov_pool_add_nonce_data(RAND_POOL *pool)
 {
     struct {
         pid_t pid;
index 6b9fa2c..761dad1 100644 (file)
@@ -14,7 +14,8 @@
 #include "internal/cryptlib.h"
 #include <openssl/rand.h>
 #include "crypto/rand.h"
-#include "rand_local.h"
+#include "crypto/rand_pool.h"
+#include "seeding.h"
 #include <descrip.h>
 #include <dvidef.h>
 #include <jpidef.h>
@@ -473,7 +474,7 @@ size_t data_collect_method(RAND_POOL *pool)
     return rand_pool_entropy_available(pool);
 }
 
-int rand_pool_add_nonce_data(RAND_POOL *pool)
+int prov_pool_add_nonce_data(RAND_POOL *pool)
 {
     struct {
         pid_t pid;
@@ -567,7 +568,7 @@ size_t get_entropy_method(RAND_POOL *pool)
  * These functions are called by the RAND / DRBG functions
  */
 
-size_t rand_pool_acquire_entropy(RAND_POOL *pool)
+size_t prov_pool_acquire_entropy(RAND_POOL *pool)
 {
     if (init_get_entropy_address())
         return get_entropy_method(pool);
index 427d50d..ec9004c 100644 (file)
 #include <openssl/opensslconf.h>
 
 #include <openssl/rand.h>
-#include "rand_local.h"
+#include "crypto/rand_pool.h"
 #include "crypto/rand.h"
 #include "internal/cryptlib.h"
+#include "seeding.h"
 #include <version.h>
 #include <taskLib.h>
 
@@ -95,7 +96,7 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
     return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
 }
 
-int rand_pool_add_nonce_data(RAND_POOL *pool)
+int prov_pool_add_nonce_data(RAND_POOL *pool)
 {
     struct {
         pid_t pid;
@@ -117,7 +118,7 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
     return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
 }
 
-size_t rand_pool_acquire_entropy(RAND_POOL *pool)
+size_t prov_pool_acquire_entropy(RAND_POOL *pool)
 {
 #if defined(RAND_SEED_VXRANDLIB)
     /* vxRandLib based entropy method */
index 89f9d6f..d5c5b59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -9,8 +9,9 @@
 
 #include "internal/cryptlib.h"
 #include <openssl/rand.h>
-#include "rand_local.h"
+#include "crypto/rand_pool.h"
 #include "crypto/rand.h"
+#include "seeding.h"
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
 
 # ifndef OPENSSL_RAND_SEED_OS
@@ -40,7 +41,7 @@
 #  define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
 # endif
 
-size_t rand_pool_acquire_entropy(RAND_POOL *pool)
+size_t prov_pool_acquire_entropy(RAND_POOL *pool)
 {
 # ifndef USE_BCRYPTGENRANDOM
     HCRYPTPROV hProvider;
@@ -120,7 +121,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
 }
 
 
-int rand_pool_add_nonce_data(RAND_POOL *pool)
+int prov_pool_add_nonce_data(RAND_POOL *pool)
 {
     struct {
         DWORD pid;
@@ -163,19 +164,6 @@ int rand_pool_add_additional_data(RAND_POOL *pool)
     return rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
 }
 
-# if !defined(OPENSSL_NO_DEPRECATED_1_1_0) && !defined(FIPS_MODULE)
-int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
-{
-    RAND_poll();
-    return RAND_status();
-}
-
-void RAND_screen(void)
-{
-    RAND_poll();
-}
-# endif
-
 int rand_pool_init(void)
 {
     return 1;
diff --git a/providers/implementations/rands/seeding/seeding.h b/providers/implementations/rands/seeding/seeding.h
new file mode 100644 (file)
index 0000000..bd0a57a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "prov/rand_pool.h"
+
+/* Hardware-based seeding functions. */
+size_t prov_acquire_entropy_from_tsc(RAND_POOL *pool);
+size_t prov_acquire_entropy_from_cpu(RAND_POOL *pool);
+
+/* DRBG entropy callbacks. */
+size_t prov_drbg_get_additional_data(RAND_POOL *pool, unsigned char **pout);
+
+void prov_drbg_cleanup_additional_data(RAND_POOL *pool, unsigned char *out);
+
+size_t prov_pool_acquire_entropy(RAND_POOL *pool);
+int prov_pool_add_nonce_data(RAND_POOL *pool);
+
+/*
+ * Add some platform specific additional data
+ *
+ * This function is platform specific and adds some random noise to the
+ * additional data used for generating random bytes and for reseeding
+ * the drbg.
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+int rand_pool_add_additional_data(RAND_POOL *pool);
+