]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add a "random" configuration section.
authorPauli <paul.dale@oracle.com>
Mon, 21 Sep 2020 06:07:34 +0000 (16:07 +1000)
committerPauli <paul.dale@oracle.com>
Wed, 23 Sep 2020 05:28:29 +0000 (15:28 +1000)
This permits the default trio of DRBGs to have their type and parameters set
using configuration.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)

crypto/conf/conf_mall.c
crypto/cpt_err.c
crypto/err/openssl.txt
crypto/rand/rand_lib.c
doc/internal/man3/ossl_random_add_conf_module.pod [new file with mode: 0644]
doc/man5/config.pod
include/crypto/rand.h
include/openssl/cryptoerr.h

index 123e2abaad8de915f343ecf1e80c67857aefe5cd..5d24a36cd93e26ca975e95208150c379a3c9cca7 100644 (file)
@@ -18,6 +18,7 @@
 #include <openssl/asn1.h>
 #include <openssl/engine.h>
 #include "internal/provider.h"
+#include "crypto/rand.h"
 #include "conf_local.h"
 
 /* Load all OpenSSL builtin modules */
@@ -33,4 +34,5 @@ void OPENSSL_load_builtin_modules(void)
     EVP_add_alg_module();
     conf_add_ssl_module();
     ossl_provider_add_conf_module();
+    ossl_random_add_conf_module();
 }
index 0201f31e61da30fd0593838a070e231c4343dedc..04b6cdb27f8d821db75488a400e9ecc60823b956 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * 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
@@ -38,6 +38,8 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = {
     "provider already exists"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_SECTION_ERROR),
     "provider section error"},
+    {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_RANDOM_SECTION_ERROR),
+    "random section error"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_SECURE_MALLOC_FAILURE),
     "secure malloc failure"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_STRING_TOO_LONG), "string too long"},
@@ -46,6 +48,8 @@ static const ERR_STRING_DATA CRYPTO_str_reasons[] = {
     "too many records"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_SMALL_BUFFER),
     "too small buffer"},
+    {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION),
+    "unknown name in random section"},
     {ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ZERO_LENGTH_NUMBER),
     "zero length number"},
     {0, NULL}
index 775bf6f3c4134c2d5351a9dd825034288589fd6f..1d9dd9366f0e632eddf95068cae8cf9926fac010 100644 (file)
@@ -2320,11 +2320,13 @@ CRYPTO_R_INVALID_OSSL_PARAM_TYPE:110:invalid ossl param type
 CRYPTO_R_ODD_NUMBER_OF_DIGITS:103:odd number of digits
 CRYPTO_R_PROVIDER_ALREADY_EXISTS:104:provider already exists
 CRYPTO_R_PROVIDER_SECTION_ERROR:105:provider section error
+CRYPTO_R_RANDOM_SECTION_ERROR:119:random section error
 CRYPTO_R_SECURE_MALLOC_FAILURE:111:secure malloc failure
 CRYPTO_R_STRING_TOO_LONG:112:string too long
 CRYPTO_R_TOO_MANY_BYTES:113:too many bytes
 CRYPTO_R_TOO_MANY_RECORDS:114:too many records
 CRYPTO_R_TOO_SMALL_BUFFER:116:too small buffer
+CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION:120:unknown name in random section
 CRYPTO_R_ZERO_LENGTH_NUMBER:115:zero length number
 CT_R_BASE64_DECODE_ERROR:108:base64 decode error
 CT_R_INVALID_LOG_ID_LENGTH:100:invalid log id length
index a37a575e5bb86ddf6a92c54da041e3e88bbaa6cc..6b2eaab68d12b3623c29118b48518451e5db5a78 100644 (file)
 
 #include <stdio.h>
 #include <time.h>
+#include <limits.h>
+#include <openssl/trace.h>
+#include <openssl/err.h>
+#include <openssl/conf.h>
 #include "internal/cryptlib.h"
 #include <openssl/opensslconf.h>
 #include "crypto/rand.h"
@@ -353,6 +357,12 @@ typedef struct rand_global_st {
      * instance per thread.
      */
     CRYPTO_THREAD_LOCAL private;
+
+    /* Which RNG is being used by default and it's configuration settings */
+    char *rng_name;
+    char *rng_cipher;
+    char *rng_digest;
+    char *rng_propq;
 } RAND_GLOBAL;
 
 /*
@@ -405,6 +415,10 @@ static void rand_ossl_ctx_free(void *vdgbl)
     EVP_RAND_CTX_free(dgbl->primary);
     CRYPTO_THREAD_cleanup_local(&dgbl->private);
     CRYPTO_THREAD_cleanup_local(&dgbl->public);
+    OPENSSL_free(dgbl->rng_name);
+    OPENSSL_free(dgbl->rng_cipher);
+    OPENSSL_free(dgbl->rng_digest);
+    OPENSSL_free(dgbl->rng_propq);
 
     OPENSSL_free(dgbl);
 }
@@ -442,10 +456,14 @@ static EVP_RAND_CTX *rand_new_drbg(OPENSSL_CTX *libctx, EVP_RAND_CTX *parent,
                                    unsigned int reseed_interval,
                                    time_t reseed_time_interval)
 {
-    EVP_RAND *rand = EVP_RAND_fetch(libctx, "CTR-DRBG", NULL);
+    EVP_RAND *rand;
+    RAND_GLOBAL *dgbl = rand_get_global(libctx);
     EVP_RAND_CTX *ctx;
-    OSSL_PARAM params[4], *p = params;
-    
+    OSSL_PARAM params[7], *p = params;
+    char *name, *cipher;
+
+    name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG";
+    rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq);
     if (rand == NULL) {
         RANDerr(0, RAND_R_UNABLE_TO_FETCH_DRBG);
         return NULL;
@@ -457,8 +475,20 @@ static EVP_RAND_CTX *rand_new_drbg(OPENSSL_CTX *libctx, EVP_RAND_CTX *parent,
         return NULL;
     }
 
+    /*
+     * Rather than trying to decode the DRBG settings, just pass them through
+     * and rely on the other end to ignore those it doesn't care about.
+     */
+    cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR";
     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER,
-                                            "AES-256-CTR", 0);
+                                            cipher, 0);
+    if (dgbl->rng_digest != NULL)
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST,
+                                                dgbl->rng_digest, 0);
+    if (dgbl->rng_propq != NULL)
+        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES,
+                                                dgbl->rng_propq, 0);
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC, "HMAC", 0);
     *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS,
                                      &reseed_interval);
     *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL,
@@ -565,3 +595,73 @@ EVP_RAND_CTX *RAND_get0_private(OPENSSL_CTX *ctx)
     }
     return rand;
 }
+
+#ifndef FIPS_MODULE
+static int random_set_string(char **p, const char *s)
+{
+    char *d = OPENSSL_strdup(s);
+
+    if (d == NULL) {
+        CRYPTOerr(0, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    OPENSSL_free(*p);
+    *p = d;
+    return 1;
+}
+
+/*
+ * Load the DRBG definitions from a configuration file.
+ */
+static int random_conf_init(CONF_IMODULE *md, const CONF *cnf)
+{
+    STACK_OF(CONF_VALUE) *elist;
+    CONF_VALUE *cval;
+    RAND_GLOBAL *dgbl = rand_get_global(cnf->libctx);
+    int i, r = 1;
+
+    OSSL_TRACE1(CONF, "Loading random module: section %s\n",
+                CONF_imodule_get_value(md));
+
+    /* Value is a section containing RANDOM configuration */
+    elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
+    if (elist == NULL) {
+        CRYPTOerr(0, CRYPTO_R_RANDOM_SECTION_ERROR);
+        return 0;
+    }
+
+    for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
+        cval = sk_CONF_VALUE_value(elist, i);
+        if (strcasecmp(cval->name, "random") == 0) {
+            if (!random_set_string(&dgbl->rng_name, cval->value))
+                return 0;
+        } else if (strcasecmp(cval->name, "cipher") == 0) {
+            if (!random_set_string(&dgbl->rng_cipher, cval->value))
+                return 0;
+        } else if (strcasecmp(cval->name, "digest") == 0) {
+            if (!random_set_string(&dgbl->rng_digest, cval->value))
+                return 0;
+        } else if (strcasecmp(cval->name, "properties") == 0) {
+            if (!random_set_string(&dgbl->rng_propq, cval->value))
+                return 0;
+        } else {
+            CRYPTOerr(0, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION);
+            ERR_add_error_data(4, "name=", cval->name, ", value=", cval->value);
+            r = 0;
+        }
+    }
+    return r;
+}
+
+
+static void random_conf_deinit(CONF_IMODULE *md)
+{
+    OSSL_TRACE(CONF, "Cleaned up random\n");
+}
+
+void ossl_random_add_conf_module(void)
+{
+    OSSL_TRACE(CONF, "Adding config module 'random'\n");
+    CONF_module_add("random", random_conf_init, random_conf_deinit);
+}
+#endif
diff --git a/doc/internal/man3/ossl_random_add_conf_module.pod b/doc/internal/man3/ossl_random_add_conf_module.pod
new file mode 100644 (file)
index 0000000..6d4f581
--- /dev/null
@@ -0,0 +1,42 @@
+=pod
+
+=head1 NAME
+
+ossl_random_add_conf_module - internal random configuration module
+
+=head1 SYNOPSIS
+
+ #include "crypto/rand.h"
+
+ /* Configuration */
+ void ossl_random_add_conf_module(void);
+
+=head1 DESCRIPTION
+
+ossl_random_add_conf_module() adds the random configuration module
+for providers.
+This allows the type and parameters of the stardard setup of random number
+generators to be configured with an OpenSSL L<config(5)> file.
+
+=head1 RETURN VALUES
+
+ossl_random_add_conf_module() doesn't return any value.
+
+=head1 SEE ALSO
+
+L<OSSL_PROVIDER(3)>, L<ossl_provider_new(3)>, L<provider-rand(7)>
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index 46d60f6cedbc8de03d09d1b1573b086812f242f0..0a28f4ea4b2731af565620c4c45ab38bf86f3778 100644 (file)
@@ -175,6 +175,7 @@ production.
  alg_section = evp_properties
  ssl_conf = ssl_configuration
  engines = engines
+ random = random
 
  [oids]
  ... new oids here ...
@@ -191,6 +192,9 @@ production.
  [engines]
  ... engine properties here ...
 
+ [random]
+ ... random properties here ...
+
 The semantics of each module are described below. The phrase "in the
 initialization section" refers to the section identified by the
 B<openssl_conf> or other name (given as B<openssl_init> in the
@@ -389,6 +393,53 @@ For example:
  default_algorithms = ALL
  other_ctrl = EMPTY
 
+=head2 Random Configuration
+
+The name B<random> in the initialization section names the section
+containing the random number generater settings.
+
+Within the random section, the following names have meaning:
+
+=over 4
+
+=item B<random>
+
+This is used to specify the random bit generator.
+For example:
+
+ [random]
+ random = CTR-DRBG
+
+The available random bit generators are:
+
+=over 4
+
+=item B<CTR-DRBG>
+
+=item B<HASH-DRBG>
+
+=item B<HMAC-DRBG>
+
+=back
+
+=item B<cipher>
+
+This specifies what cipher a B<CTR-DRBG> random bit generator will use.
+Other random bit generators ignore this name.
+The default value is B<AES-256-CTR>.
+
+=item B<digest>
+
+This specifies what digest the B<HASH-DRBG> or B<HMAC-DRBG> random bit
+generators will use.  Other random bit generators ignore this name.
+
+=item B<properties>
+
+This sets the property query used when fetching the random bit generator and
+any underlying algorithms.
+
+=back
+
 =head1 EXAMPLES
 
 This example shows how to use quoting and escaping.
index c5eef81462baf553fdffb6236e57b803d214590e..a437565fe82a80485f4e5f3f571de44e7075c572 100644 (file)
@@ -88,4 +88,9 @@ void rand_pool_cleanup(void);
  */
 void rand_pool_keep_random_devices_open(int keep);
 
+/*
+ * Configuration
+ */
+void ossl_random_add_conf_module(void);
+
 #endif
index 5ccddd0214a354f307f6cb9fafa0594325baf0ed..6add92a9ca663e661e825fb6ab5b8bbd614d41dd 100644 (file)
@@ -90,11 +90,13 @@ int ERR_load_CRYPTO_strings(void);
 # define CRYPTO_R_ODD_NUMBER_OF_DIGITS                    103
 # define CRYPTO_R_PROVIDER_ALREADY_EXISTS                 104
 # define CRYPTO_R_PROVIDER_SECTION_ERROR                  105
+# define CRYPTO_R_RANDOM_SECTION_ERROR                    119
 # define CRYPTO_R_SECURE_MALLOC_FAILURE                   111
 # define CRYPTO_R_STRING_TOO_LONG                         112
 # define CRYPTO_R_TOO_MANY_BYTES                          113
 # define CRYPTO_R_TOO_MANY_RECORDS                        114
 # define CRYPTO_R_TOO_SMALL_BUFFER                        116
+# define CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION          120
 # define CRYPTO_R_ZERO_LENGTH_NUMBER                      115
 
 #endif