summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPauli <paul.dale@oracle.com>2020-09-21 16:07:34 +1000
committerPauli <paul.dale@oracle.com>2020-09-23 15:28:29 +1000
commit44d2482ba62bf7fc2fd4cfc250ad09e0feaa42da (patch)
tree968b0231029d09c71040c76e66554fbbc0d9ca08
parent11b93a1c82f2cb2be67b2d08cac4168a16555364 (diff)
Add a "random" configuration section.
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)
-rw-r--r--crypto/conf/conf_mall.c2
-rw-r--r--crypto/cpt_err.c6
-rw-r--r--crypto/err/openssl.txt2
-rw-r--r--crypto/rand/rand_lib.c108
-rw-r--r--doc/internal/man3/ossl_random_add_conf_module.pod42
-rw-r--r--doc/man5/config.pod51
-rw-r--r--include/crypto/rand.h5
-rw-r--r--include/openssl/cryptoerr.h2
8 files changed, 213 insertions, 5 deletions
diff --git a/crypto/conf/conf_mall.c b/crypto/conf/conf_mall.c
index 123e2abaad..5d24a36cd9 100644
--- a/crypto/conf/conf_mall.c
+++ b/crypto/conf/conf_mall.c
@@ -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();
}
diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c
index 0201f31e61..04b6cdb27f 100644
--- a/crypto/cpt_err.c
+++ b/crypto/cpt_err.c
@@ -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}
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 775bf6f3c4..1d9dd9366f 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -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
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index a37a575e5b..6b2eaab68d 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -12,6 +12,10 @@
#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
index 0000000000..6d4f5810dc
--- /dev/null
+++ b/doc/internal/man3/ossl_random_add_conf_module.pod
@@ -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
diff --git a/doc/man5/config.pod b/doc/man5/config.pod
index 46d60f6ced..0a28f4ea4b 100644
--- a/doc/man5/config.pod
+++ b/doc/man5/config.pod
@@ -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.
diff --git a/include/crypto/rand.h b/include/crypto/rand.h
index c5eef81462..a437565fe8 100644
--- a/include/crypto/rand.h
+++ b/include/crypto/rand.h
@@ -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
diff --git a/include/openssl/cryptoerr.h b/include/openssl/cryptoerr.h
index 5ccddd0214..6add92a9ca 100644
--- a/include/openssl/cryptoerr.h
+++ b/include/openssl/cryptoerr.h
@@ -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