rand: move the entropy source out of the FIPS provider
authorPauli <paul.dale@oracle.com>
Fri, 30 Oct 2020 05:53:22 +0000 (15:53 +1000)
committerPauli <paul.dale@oracle.com>
Thu, 19 Nov 2020 22:24:21 +0000 (08:24 +1000)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/13226)

14 files changed:
crypto/err/openssl.txt
crypto/evp/evp_rand.c
crypto/provider_core.c
crypto/rand/build.info
crypto/rand/prov_seed.c [new file with mode: 0644]
crypto/rand/rand_err.c
crypto/rand/rand_lib.c
crypto/rand/rand_pool.c
include/crypto/rand.h
include/openssl/core_dispatch.h
include/openssl/core_names.h
include/openssl/randerr.h
providers/common/include/prov/providercommonerr.h
providers/common/provider_err.c

index 7bb83593a6b5130ddf166c7b9bf6f41837d7dca8..690bd197cd1a4974be22a5d9b0b4cf625f7773c4 100644 (file)
@@ -2944,6 +2944,8 @@ PROV_R_NO_PARAMETERS_SET:177:no parameters set
 PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:178:\
        operation not supported for this keytype
 PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small
+PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS:228:\
+        parent cannot generate random numbers
 PROV_R_PARENT_LOCKING_NOT_ENABLED:182:parent locking not enabled
 PROV_R_PARENT_STRENGTH_TOO_WEAK:194:parent strength too weak
 PROV_R_PATH_MUST_BE_ABSOLUTE:219:path must be absolute
@@ -2965,7 +2967,6 @@ PROV_R_UNABLE_TO_GET_NONCE:203:unable to get nonce
 PROV_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER:198:\
        unable to get parent reseed prop counter
 PROV_R_UNABLE_TO_GET_PARENT_STRENGTH:199:unable to get parent strength
-PROV_R_UNABLE_TO_GET_RESEED_PROP_CTR:200:unable to get reseed prop ctr
 PROV_R_UNABLE_TO_INITIALISE_CIPHERS:208:unable to initialise ciphers
 PROV_R_UNABLE_TO_LOAD_SHA1:143:unable to load sha1
 PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256
@@ -3027,7 +3028,7 @@ RAND_R_UNABLE_TO_FETCH_DRBG:144:unable to fetch drbg
 RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER:141:\
        unable to get parent reseed prop counter
 RAND_R_UNABLE_TO_GET_PARENT_STRENGTH:138:unable to get parent strength
-RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR:142:unable to get reseed prop ctr
+RAND_R_UNABLE_TO_GET_RESEED_COUNTER :142:unable to get reseed counter
 RAND_R_UNABLE_TO_LOCK_PARENT:140:unable to lock parent
 RAND_R_UNSUPPORTED_DRBG_FLAGS:132:unsupported drbg flags
 RAND_R_UNSUPPORTED_DRBG_TYPE:120:unsupported drbg type
index 07d1ad9db265241995e2af5ee30f6c0f63bf722f..6a4f57414c35ab7c3c93b0df83cc2b614768a5d7 100644 (file)
@@ -511,7 +511,7 @@ static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out,
     size_t chunk, max_request = 0;
     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
 
-    params[0] = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_REQUEST,
+    params[0] = OSSL_PARAM_construct_size_t(OSSL_RAND_PARAM_MAX_REQUEST,
                                             &max_request);
     if (!evp_rand_get_ctx_params_locked(ctx, params)
             || max_request == 0) {
index d919a95b4005eb9346b88dd414fdf3a4ab0e9d98..954befd4a2129ea21f7ef3aa7e16e6ff7e0fa058 100644 (file)
@@ -15,6 +15,7 @@
 #include <openssl/opensslv.h>
 #include "crypto/cryptlib.h"
 #include "crypto/evp.h" /* evp_method_store_flush */
+#include "crypto/rand.h"
 #include "internal/nelem.h"
 #include "internal/thread_once.h"
 #include "internal/provider.h"
@@ -1074,8 +1075,7 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle)
 #endif /* FIPS_MODULE */
 
 /*
- * Functions provided by the core.  Blank line separates "families" of related
- * functions.
+ * Functions provided by the core.
  */
 static const OSSL_DISPATCH core_dispatch_[] = {
     { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params },
@@ -1101,6 +1101,10 @@ static const OSSL_DISPATCH core_dispatch_[] = {
     { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf },
     { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf },
     { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))OSSL_SELF_TEST_get_callback },
+    { OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy },
+    { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))ossl_rand_cleanup_entropy },
+    { OSSL_FUNC_GET_NONCE, (void (*)(void))ossl_rand_get_nonce },
+    { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))ossl_rand_cleanup_nonce },
 #endif
     { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc },
     { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc },
index f58a026f3b4815cdf3564e2198e7d621e74b7445..b9dc16a6c7ddea621660d0ad969ae44fc6d86a10 100644 (file)
@@ -1,7 +1,7 @@
 LIBS=../../libcrypto
 
 $COMMON=rand_lib.c rand_meth.c
-$CRYPTO=randfile.c rand_err.c rand_deprecated.c
+$CRYPTO=randfile.c rand_err.c rand_deprecated.c prov_seed.c rand_pool.c
 
 IF[{- !$disabled{'egd'} -}]
   $CRYPTO=$CRYPTO rand_egd.c
diff --git a/crypto/rand/prov_seed.c b/crypto/rand/prov_seed.c
new file mode 100644 (file)
index 0000000..f799551
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 "crypto/rand.h"
+#include "crypto/rand_pool.h"
+#include <openssl/core_dispatch.h>
+#include <openssl/err.h>
+
+size_t ossl_rand_get_entropy(ossl_unused OSSL_CORE_HANDLE *handle,
+                             unsigned char **pout, int entropy,
+                             size_t min_len, size_t max_len)
+{
+    size_t ret = 0;
+    size_t entropy_available;
+    RAND_POOL *pool;
+
+    pool = rand_pool_new(entropy, 1, min_len, max_len);
+    if (pool == NULL) {
+        ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    /* Get entropy by polling system entropy sources. */
+    entropy_available = ossl_pool_acquire_entropy(pool);
+
+    if (entropy_available > 0) {
+        ret   = rand_pool_length(pool);
+        *pout = rand_pool_detach(pool);
+    }
+
+    rand_pool_free(pool);
+    return ret;
+}
+
+void ossl_rand_cleanup_entropy(ossl_unused OSSL_CORE_HANDLE *handle,
+                               unsigned char *buf, size_t len)
+{
+    OPENSSL_secure_clear_free(buf, len);
+}
+
+size_t ossl_rand_get_nonce(ossl_unused OSSL_CORE_HANDLE *handle,
+                           unsigned char **pout, size_t min_len, size_t max_len,
+                           const void *salt, size_t salt_len)
+{
+    size_t ret = 0;
+    RAND_POOL *pool;
+
+    pool = rand_pool_new(0, 0, min_len, max_len);
+    if (pool == NULL) {
+        ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    if (!ossl_pool_add_nonce_data(pool))
+        goto err;
+
+    if (salt != NULL && !rand_pool_add(pool, salt, salt_len, 0))
+        goto err;
+    ret   = rand_pool_length(pool);
+    *pout = rand_pool_detach(pool);
+ err:
+    rand_pool_free(pool);
+    return ret;
+}
+
+void ossl_rand_cleanup_nonce(ossl_unused OSSL_CORE_HANDLE *handle,
+                             unsigned char *buf, size_t len)
+{
+    OPENSSL_clear_free(buf, len);
+}
index b70cc4cb9f0fa929280d315bd8984892089cceaf..ecf7cb2e599bc79fc89818b86753c1a9e8bc68e4 100644 (file)
@@ -87,8 +87,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
     "unable to get parent reseed prop counter"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH),
     "unable to get parent strength"},
-    {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR),
-    "unable to get reseed prop ctr"},
+    {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_RESEED_COUNTER),
+    "unable to get reseed counter"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_LOCK_PARENT),
     "unable to lock parent"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_FLAGS),
index 9790b216469785715d40770d8efb1eb215310a26..73d509a8dc5f2417620eab4c3aad0ec05332d62c 100644 (file)
@@ -27,7 +27,7 @@
 #include "e_os.h"
 
 #ifndef FIPS_MODULE
-# include "prov/rand_pool.h"
+# include "crypto/rand_pool.h"
 # include "prov/seeding.h"
 
 # ifndef OPENSSL_NO_ENGINE
index c66c0e3fa8ce0faccbf0db89d37cac7e6f8cda5d..ebb9078ce6684e08af91d1b04cfce672a603141a 100644 (file)
@@ -14,7 +14,7 @@
 #include "crypto/rand.h"
 #include <openssl/engine.h>
 #include "internal/thread_once.h"
-#include "prov/rand_pool.h"
+#include "crypto/rand_pool.h"
 
 /*
  * Allocate memory and initialize a new random pool
index a437565fe82a80485f4e5f3f571de44e7075c572..c870245521a4c9ce3a90879df2473b0de8af3443 100644 (file)
@@ -19,6 +19,7 @@
 # define OSSL_CRYPTO_RAND_H
 
 # include <openssl/rand.h>
+# include "crypto/rand_pool.h"
 
 /*
  * Defines related to seed sources
@@ -93,4 +94,24 @@ void rand_pool_keep_random_devices_open(int keep);
  */
 void ossl_random_add_conf_module(void);
 
+/*
+ * Get and cleanup random seed material.
+ */
+size_t ossl_rand_get_entropy(ossl_unused OSSL_CORE_HANDLE *handle,
+                             unsigned char **pout, int entropy,
+                             size_t min_len, size_t max_len);
+void ossl_rand_cleanup_entropy(ossl_unused OSSL_CORE_HANDLE *handle,
+                               unsigned char *buf, size_t len);
+size_t ossl_rand_get_nonce(ossl_unused OSSL_CORE_HANDLE *handle,
+                           unsigned char **pout, size_t min_len, size_t max_len,
+                           const void *salt, size_t salt_len);
+void ossl_rand_cleanup_nonce(ossl_unused OSSL_CORE_HANDLE *handle,
+                             unsigned char *buf, size_t len);
+
+/*
+ * Get seeding material from the operating system sources.
+ */
+size_t ossl_pool_acquire_entropy(RAND_POOL *pool);
+int ossl_pool_add_nonce_data(RAND_POOL *pool);
+
 #endif
index d4d581df5786b02f0b111dcebfe0d0e371e94beb..bbd04297188e4fed0aaeef26d861920d5f3a1b8c 100644 (file)
@@ -161,6 +161,23 @@ OSSL_CORE_MAKE_FUNC(int, BIO_ctrl, (OSSL_CORE_BIO *bio,
 OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb,
                                          void **cbarg))
 
+/* Functions to get seed material from the operating system */
+#define OSSL_FUNC_GET_ENTROPY                101
+#define OSSL_FUNC_CLEANUP_ENTROPY            102
+#define OSSL_FUNC_GET_NONCE                  103
+#define OSSL_FUNC_CLEANUP_NONCE              104
+OSSL_CORE_MAKE_FUNC(size_t, get_entropy, (const OSSL_CORE_HANDLE *handle,
+                                          unsigned char **pout, int entropy,
+                                          size_t min_len, size_t max_len))
+OSSL_CORE_MAKE_FUNC(void, cleanup_entropy, (const OSSL_CORE_HANDLE *handle,
+                                            unsigned char *buf, size_t len))
+OSSL_CORE_MAKE_FUNC(size_t, get_nonce, (const OSSL_CORE_HANDLE *handle,
+                                        unsigned char **pout, size_t min_len,
+                                        size_t max_len, const void *salt,
+                                        size_t salt_len))
+OSSL_CORE_MAKE_FUNC(void, cleanup_nonce, (const OSSL_CORE_HANDLE *handle,
+                                          unsigned char *buf, size_t len))
+
 /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */
 # define OSSL_FUNC_PROVIDER_TEARDOWN           1024
 OSSL_CORE_MAKE_FUNC(void,provider_teardown,(void *provctx))
index f0b0cd0163de694e49f8bf8293e95f9417fc4ea8..d41feeb144231e9bf46ab4fa5b4f1ab1e8b70edc 100644 (file)
@@ -219,13 +219,13 @@ extern "C" {
 /* Known RAND names */
 #define OSSL_RAND_PARAM_STATE                   "state"
 #define OSSL_RAND_PARAM_STRENGTH                "strength"
+#define OSSL_RAND_PARAM_MAX_REQUEST             "max_request"
 #define OSSL_RAND_PARAM_TEST_ENTROPY            "test_entropy"
 #define OSSL_RAND_PARAM_TEST_NONCE              "test_nonce"
 
 /* RAND/DRBG names */
 #define OSSL_DRBG_PARAM_RESEED_REQUESTS         "reseed_requests"
 #define OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL    "reseed_time_interval"
-#define OSSL_DRBG_PARAM_MAX_REQUEST             "max_request"
 #define OSSL_DRBG_PARAM_MIN_ENTROPYLEN          "min_entropylen"
 #define OSSL_DRBG_PARAM_MAX_ENTROPYLEN          "max_entropylen"
 #define OSSL_DRBG_PARAM_MIN_NONCELEN            "min_noncelen"
index 3eef9afdd23e31d1cbe5adabebe6008f0fd9b50b..40e57873085bc5d963b2ee5979b7a7993fed29e0 100644 (file)
@@ -102,7 +102,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_R_UNABLE_TO_FETCH_DRBG                      144
 # define RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER  141
 # define RAND_R_UNABLE_TO_GET_PARENT_STRENGTH             138
-# define RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR             142
+# define RAND_R_UNABLE_TO_GET_RESEED_COUNTER              142
 # define RAND_R_UNABLE_TO_LOCK_PARENT                     140
 # define RAND_R_UNSUPPORTED_DRBG_FLAGS                    132
 # define RAND_R_UNSUPPORTED_DRBG_TYPE                     120
index d972a819e2c7ea09482a9c7ed7325c10bc0ade9a..05ca8abef04166d174acde7251dd5869300a339f 100644 (file)
@@ -160,7 +160,6 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_UNABLE_TO_GET_NONCE                       203
 # define PROV_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER  198
 # define PROV_R_UNABLE_TO_GET_PARENT_STRENGTH             199
-# define PROV_R_UNABLE_TO_GET_RESEED_PROP_CTR             200
 # define PROV_R_UNABLE_TO_INITIALISE_CIPHERS              208
 # define PROV_R_UNABLE_TO_LOAD_SHA1                       143
 # define PROV_R_UNABLE_TO_LOAD_SHA256                     147
index 606d78cc57ccacb0835030253b44c06d7cd6326d..2b65903a313bcef84aed3bec83d1074b2ab051ff 100644 (file)
@@ -186,8 +186,6 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     "unable to get parent reseed prop counter"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH),
     "unable to get parent strength"},
-    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_RESEED_PROP_CTR),
-    "unable to get reseed prop ctr"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_INITIALISE_CIPHERS),
     "unable to initialise ciphers"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOAD_SHA1),