#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 */
EVP_add_alg_module();
conf_add_ssl_module();
ossl_provider_add_conf_module();
+ ossl_random_add_conf_module();
}
/*
* 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
"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"},
"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}
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
#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"
* 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;
/*
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);
}
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;
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,
}
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
--- /dev/null
+=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
alg_section = evp_properties
ssl_conf = ssl_configuration
engines = engines
+ random = random
[oids]
... new oids here ...
[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
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.
*/
void rand_pool_keep_random_devices_open(int keep);
+/*
+ * Configuration
+ */
+void ossl_random_add_conf_module(void);
+
#endif
# 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