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)
This commit is contained in:
Pauli 2020-09-21 16:07:34 +10:00
parent 11b93a1c82
commit 44d2482ba6
8 changed files with 213 additions and 5 deletions

View 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();
}

View 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}

View 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

View File

@ -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

View File

@ -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

View 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.

View 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

View 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