[openssl] master update
Dr. Paul Dale
pauli at openssl.org
Wed Sep 23 05:33:04 UTC 2020
The branch master has been updated
via 2e9ab56edc6961aad779e1d41cb6e7414ae5a71d (commit)
via 2ff4e15dc2a981a447859558c8de2c96ba804c5b (commit)
via 0ed26fb63c814458e9906a916fe3ce5ca961842f (commit)
via c9452d74a4bad8853ca60889788e51d46328877d (commit)
via d8e52fd05e350ee308715c46ac13dbea2899a6ce (commit)
via 44d2482ba62bf7fc2fd4cfc250ad09e0feaa42da (commit)
from 11b93a1c82f2cb2be67b2d08cac4168a16555364 (commit)
- Log -----------------------------------------------------------------
commit 2e9ab56edc6961aad779e1d41cb6e7414ae5a71d
Author: Pauli <paul.dale at oracle.com>
Date: Tue Sep 22 15:09:25 2020 +1000
rand: add a test case for configuration based random
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)
commit 2ff4e15dc2a981a447859558c8de2c96ba804c5b
Author: Pauli <paul.dale at oracle.com>
Date: Tue Sep 22 09:36:53 2020 +1000
list: add capability to print details about the current DRBGs
This allows a user to confirm that the DRBG their configuration specified is
being used.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)
commit 0ed26fb63c814458e9906a916fe3ce5ca961842f
Author: Pauli <paul.dale at oracle.com>
Date: Tue Sep 22 09:26:23 2020 +1000
drbg: gettable parameters for cipher/digest/mac type.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)
commit c9452d74a4bad8853ca60889788e51d46328877d
Author: Pauli <paul.dale at oracle.com>
Date: Tue Sep 22 09:25:35 2020 +1000
kdf/mac: add name query calls for KDFs and MACs
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)
commit d8e52fd05e350ee308715c46ac13dbea2899a6ce
Author: Pauli <paul.dale at oracle.com>
Date: Tue Sep 22 08:29:58 2020 +1000
evp_rand: fix bug in gettable_ctx/settable_ctx calls
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)
commit 44d2482ba62bf7fc2fd4cfc250ad09e0feaa42da
Author: Pauli <paul.dale at oracle.com>
Date: Mon Sep 21 16:07:34 2020 +1000
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 at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12931)
-----------------------------------------------------------------------
Summary of changes:
apps/include/app_params.h | 1 +
apps/lib/app_params.c | 36 ++++++++
apps/list.c | 81 +++++++++++++++-
crypto/conf/conf_mall.c | 2 +
crypto/cpt_err.c | 6 +-
crypto/err/openssl.txt | 2 +
crypto/evp/evp_rand.c | 4 +-
crypto/evp/kdf_lib.c | 7 ++
crypto/evp/mac_lib.c | 7 ++
crypto/rand/rand_lib.c | 108 +++++++++++++++++++++-
doc/internal/man3/ossl_random_add_conf_module.pod | 42 +++++++++
doc/man3/EVP_KDF.pod | 9 +-
doc/man3/EVP_MAC.pod | 9 +-
doc/man5/config.pod | 51 ++++++++++
include/crypto/rand.h | 5 +
include/openssl/cryptoerr.h | 2 +
include/openssl/evp.h | 1 +
include/openssl/kdf.h | 1 +
providers/implementations/rands/drbg_ctr.c | 15 +++
providers/implementations/rands/drbg_hash.c | 11 +++
providers/implementations/rands/drbg_hmac.c | 22 +++++
test/recipes/20-test_rand_config.t | 103 +++++++++++++++++++++
util/libcrypto.num | 4 +-
23 files changed, 517 insertions(+), 12 deletions(-)
create mode 100644 doc/internal/man3/ossl_random_add_conf_module.pod
create mode 100644 test/recipes/20-test_rand_config.t
diff --git a/apps/include/app_params.h b/apps/include/app_params.h
index 2060b5200e..d282fd657f 100644
--- a/apps/include/app_params.h
+++ b/apps/include/app_params.h
@@ -10,4 +10,5 @@
#include <openssl/core.h>
int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent);
+void print_param_value(const OSSL_PARAM *p, int indent);
diff --git a/apps/lib/app_params.c b/apps/lib/app_params.c
index 3305b1e922..04337cbc83 100644
--- a/apps/lib/app_params.c
+++ b/apps/lib/app_params.c
@@ -94,3 +94,39 @@ int print_param_types(const char *thing, const OSSL_PARAM *pdefs, int indent)
return 1;
}
+void print_param_value(const OSSL_PARAM *p, int indent)
+{
+ int64_t i;
+ uint64_t u;
+
+ printf("%*s%s: ", indent, "", p->key);
+ switch (p->data_type) {
+ case OSSL_PARAM_UNSIGNED_INTEGER:
+ if (OSSL_PARAM_get_uint64(p, &u))
+ BIO_printf(bio_out, "%llu\n", (unsigned long long int)u);
+ else
+ BIO_printf(bio_out, "error getting value\n");
+ break;
+ case OSSL_PARAM_INTEGER:
+ if (OSSL_PARAM_get_int64(p, &i))
+ BIO_printf(bio_out, "%lld\n", (long long int)i);
+ else
+ BIO_printf(bio_out, "error getting value\n");
+ break;
+ case OSSL_PARAM_UTF8_PTR:
+ BIO_printf(bio_out, "'%s'\n", *(char **)(p->data));
+ break;
+ case OSSL_PARAM_UTF8_STRING:
+ BIO_printf(bio_out, "'%s'\n", (char *)p->data);
+ break;
+ case OSSL_PARAM_OCTET_PTR:
+ case OSSL_PARAM_OCTET_STRING:
+ BIO_printf(bio_out, "<%zu bytes>\n", p->data_size);
+ break;
+ default:
+ BIO_printf(bio_out, "unknown type (%u) of %zu bytes\n",
+ p->data_type, p->data_size);
+ break;
+ }
+}
+
diff --git a/apps/list.c b/apps/list.c
index fd018991e1..b2ddef9201 100644
--- a/apps/list.c
+++ b/apps/list.c
@@ -19,6 +19,7 @@
#include <openssl/encoder.h>
#include <openssl/decoder.h>
#include <openssl/core_names.h>
+#include <openssl/rand.h>
#include "apps.h"
#include "app_params.h"
#include "progs.h"
@@ -352,6 +353,74 @@ static void list_random_generators(void)
sk_EVP_RAND_pop_free(rands, EVP_RAND_free);
}
+static void display_random(const char *name, EVP_RAND_CTX *drbg)
+{
+ EVP_RAND *rand;
+ uint64_t u;
+ const char *p;
+ const OSSL_PARAM *gettables;
+ OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
+ unsigned char buf[1000];
+
+ BIO_printf(bio_out, "%s:\n", name);
+ if (drbg != NULL) {
+ rand = EVP_RAND_CTX_rand(drbg);
+
+ BIO_printf(bio_out, " %s", EVP_RAND_name(rand));
+ BIO_printf(bio_out, " @ %s\n",
+ OSSL_PROVIDER_name(EVP_RAND_provider(rand)));
+
+ switch (EVP_RAND_state(drbg)) {
+ case EVP_RAND_STATE_UNINITIALISED:
+ p = "uninitialised";
+ break;
+ case EVP_RAND_STATE_READY:
+ p = "ready";
+ break;
+ case EVP_RAND_STATE_ERROR:
+ p = "error";
+ break;
+ default:
+ p = "unknown";
+ break;
+ }
+ BIO_printf(bio_out, " state = %s\n", p);
+
+ gettables = EVP_RAND_gettable_ctx_params(rand);
+ if (gettables != NULL)
+ for (; gettables->key != NULL; gettables++) {
+ /* State has been dealt with already, so ignore */
+ if (strcasecmp(gettables->key, OSSL_RAND_PARAM_STATE) == 0)
+ continue;
+ /* Outside of verbose mode, we skip non-string values */
+ if (gettables->data_type != OSSL_PARAM_UTF8_STRING
+ && gettables->data_type != OSSL_PARAM_UTF8_PTR
+ && !verbose)
+ continue;
+ params->key = gettables->key;
+ params->data_type = gettables->data_type;
+ if (gettables->data_type == OSSL_PARAM_UNSIGNED_INTEGER
+ || gettables->data_type == OSSL_PARAM_INTEGER) {
+ params->data = &u;
+ params->data_size = sizeof(u);
+ } else {
+ params->data = buf;
+ params->data_size = sizeof(buf);
+ }
+ params->return_size = 0;
+ if (EVP_RAND_get_ctx_params(drbg, params))
+ print_param_value(params, 2);
+ }
+ }
+}
+
+static void list_random_instances(void)
+{
+ display_random("primary", RAND_get0_primary(NULL));
+ display_random("public", RAND_get0_public(NULL));
+ display_random("private", RAND_get0_private(NULL));
+}
+
/*
* Encoders
*/
@@ -819,8 +888,8 @@ typedef enum HELPLIST_CHOICE {
OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_MAC_ALGORITHMS, OPT_OPTIONS,
OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED,
- OPT_KDF_ALGORITHMS, OPT_RANDOM_GENERATORS, OPT_ENCODERS,
- OPT_DECODERS,
+ OPT_KDF_ALGORITHMS, OPT_RANDOM_INSTANCES, OPT_RANDOM_GENERATORS,
+ OPT_ENCODERS, OPT_DECODERS,
OPT_MISSING_HELP, OPT_OBJECTS,
#ifndef OPENSSL_NO_DEPRECATED_3_0
OPT_ENGINES,
@@ -844,6 +913,8 @@ const OPTIONS list_options[] = {
"List of message digest algorithms"},
{"kdf-algorithms", OPT_KDF_ALGORITHMS, '-',
"List of key derivation and pseudo random function algorithms"},
+ {"random-instances", OPT_RANDOM_INSTANCES, '-',
+ "List the primary, pubic and private random number generator details"},
{"random-generators", OPT_RANDOM_GENERATORS, '-',
"List of random number generators"},
{"mac-algorithms", OPT_MAC_ALGORITHMS, '-',
@@ -880,6 +951,7 @@ int list_main(int argc, char **argv)
int one = 0, done = 0;
struct {
unsigned int commands:1;
+ unsigned int random_instances:1;
unsigned int random_generators:1;
unsigned int digest_commands:1;
unsigned int digest_algorithms:1;
@@ -928,6 +1000,9 @@ opthelp:
case OPT_KDF_ALGORITHMS:
todo.kdf_algorithms = 1;
break;
+ case OPT_RANDOM_INSTANCES:
+ todo.random_instances = 1;
+ break;
case OPT_RANDOM_GENERATORS:
todo.random_generators = 1;
break;
@@ -986,6 +1061,8 @@ opthelp:
if (todo.commands)
list_type(FT_general, one);
+ if (todo.random_instances)
+ list_random_instances();
if (todo.random_generators)
list_random_generators();
if (todo.digest_commands)
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/evp/evp_rand.c b/crypto/evp/evp_rand.c
index 2e4edfff34..c0729656cb 100644
--- a/crypto/evp/evp_rand.c
+++ b/crypto/evp/evp_rand.c
@@ -433,7 +433,7 @@ const OSSL_PARAM *EVP_RAND_gettable_params(const EVP_RAND *rand)
const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand)
{
- if (rand->gettable_params == NULL)
+ if (rand->gettable_ctx_params == NULL)
return NULL;
return rand->gettable_ctx_params(
ossl_provider_ctx(EVP_RAND_provider(rand)));
@@ -441,7 +441,7 @@ const OSSL_PARAM *EVP_RAND_gettable_ctx_params(const EVP_RAND *rand)
const OSSL_PARAM *EVP_RAND_settable_ctx_params(const EVP_RAND *rand)
{
- if (rand->gettable_params == NULL)
+ if (rand->settable_ctx_params == NULL)
return NULL;
return rand->settable_ctx_params(
ossl_provider_ctx(EVP_RAND_provider(rand)));
diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c
index d22bb39c82..9ccaec8cc1 100644
--- a/crypto/evp/kdf_lib.c
+++ b/crypto/evp/kdf_lib.c
@@ -88,6 +88,13 @@ int EVP_KDF_number(const EVP_KDF *kdf)
return kdf->name_id;
}
+const char *EVP_KDF_name(const EVP_KDF *kdf)
+{
+ if (kdf->prov != NULL)
+ return evp_first_name(kdf->prov, kdf->name_id);
+ return NULL;
+}
+
int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name)
{
return evp_is_a(kdf->prov, kdf->name_id, NULL, name);
diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c
index 79dd49ae20..d76ffedcb8 100644
--- a/crypto/evp/mac_lib.c
+++ b/crypto/evp/mac_lib.c
@@ -162,6 +162,13 @@ int EVP_MAC_number(const EVP_MAC *mac)
return mac->name_id;
}
+const char *EVP_MAC_name(const EVP_MAC *mac)
+{
+ if (mac->prov != NULL)
+ return evp_first_name(mac->prov, mac->name_id);
+ return NULL;
+}
+
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name)
{
return evp_is_a(mac->prov, mac->name_id, NULL, name);
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/man3/EVP_KDF.pod b/doc/man3/EVP_KDF.pod
index d97d33936d..b041ccd4d9 100644
--- a/doc/man3/EVP_KDF.pod
+++ b/doc/man3/EVP_KDF.pod
@@ -6,7 +6,7 @@ EVP_KDF, EVP_KDF_fetch, EVP_KDF_free, EVP_KDF_up_ref,
EVP_KDF_CTX, EVP_KDF_CTX_new, EVP_KDF_CTX_free, EVP_KDF_CTX_dup,
EVP_KDF_reset, EVP_KDF_derive,
EVP_KDF_size, EVP_KDF_provider, EVP_KDF_CTX_kdf, EVP_KDF_is_a,
-EVP_KDF_number, EVP_KDF_names_do_all,
+EVP_KDF_number, EVP_KDF_name, EVP_KDF_names_do_all,
EVP_KDF_CTX_get_params, EVP_KDF_CTX_set_params, EVP_KDF_do_all_provided,
EVP_KDF_get_params, EVP_KDF_gettable_ctx_params, EVP_KDF_settable_ctx_params,
EVP_KDF_gettable_params - EVP KDF routines
@@ -31,6 +31,7 @@ EVP_KDF_gettable_params - EVP KDF routines
const char *properties);
int EVP_KDF_number(const EVP_KDF *kdf);
int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name);
+ const char *EVP_KDF_name(const EVP_KDF *kdf);
const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf);
void EVP_KDF_do_all_provided(OPENSSL_CTX *libctx,
void (*fn)(EVP_KDF *kdf, void *arg),
@@ -151,6 +152,10 @@ and the given I<arg> as argument.
EVP_KDF_number() returns the internal dynamic number assigned to
I<kdf>.
+EVP_KDF_name() return the name of the given KDF. For fetched KDFs
+with multiple names, only one of them is returned; it's
+recommended to use EVP_KDF_names_do_all() instead.
+
EVP_KDF_names_do_all() traverses all names for I<kdf>, and calls
I<fn> with each name and I<data>.
@@ -245,6 +250,8 @@ EVP_KDF_CTX_free() and EVP_KDF_reset() do not return a value.
EVP_KDF_size() returns the output size. B<SIZE_MAX> is returned to indicate
that the algorithm produces a variable amount of output; 0 to indicate failure.
+EVP_KDF_name() returns the name of the KDF, or NULL on error.
+
The remaining functions return 1 for success and 0 or a negative value for
failure. In particular, a return value of -2 indicates the operation is not
supported by the KDF algorithm.
diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod
index b33af5a670..8ce9f67d45 100644
--- a/doc/man3/EVP_MAC.pod
+++ b/doc/man3/EVP_MAC.pod
@@ -3,7 +3,7 @@
=head1 NAME
EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free,
-EVP_MAC_is_a, EVP_MAC_number, EVP_MAC_names_do_all,
+EVP_MAC_is_a, EVP_MAC_number, EVP_MAC_name, EVP_MAC_names_do_all,
EVP_MAC_provider, EVP_MAC_get_params, EVP_MAC_gettable_params,
EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup,
EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params,
@@ -24,6 +24,7 @@ EVP_MAC_do_all_provided - EVP MAC routines
void EVP_MAC_free(EVP_MAC *mac);
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name);
int EVP_MAC_number(const EVP_MAC *mac);
+ const char *EVP_MAC_name(const EVP_MAC *mac);
void EVP_MAC_names_do_all(const EVP_MAC *mac,
void (*fn)(const char *name, void *data),
void *data);
@@ -177,6 +178,10 @@ and the given I<arg> as argument.
EVP_MAC_number() returns the internal dynamic number assigned to
I<mac>.
+EVP_MAC_name() return the name of the given MAC. For fetched MACs
+with multiple names, only one of them is returned; it's
+recommended to use EVP_MAC_names_do_all() instead.
+
EVP_MAC_names_do_all() traverses all names for I<mac>, and calls
I<fn> with each name and I<data>.
@@ -282,6 +287,8 @@ EVP_MAC_free() returns nothing at all.
EVP_MAC_is_a() returns 1 if the given method can be identified with
the given name, otherwise 0.
+EVP_MAC_name() returns a name of the MAC, or NULL on error.
+
EVP_MAC_provider() returns a pointer to the provider for the MAC, or
NULL on error.
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
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index ff3234a914..e843a48b22 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1104,6 +1104,7 @@ EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm,
int EVP_MAC_up_ref(EVP_MAC *mac);
void EVP_MAC_free(EVP_MAC *mac);
int EVP_MAC_number(const EVP_MAC *mac);
+const char *EVP_MAC_name(const EVP_MAC *mac);
int EVP_MAC_is_a(const EVP_MAC *mac, const char *name);
const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac);
int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]);
diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h
index b761113956..5bef72da52 100644
--- a/include/openssl/kdf.h
+++ b/include/openssl/kdf.h
@@ -35,6 +35,7 @@ void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx);
EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src);
int EVP_KDF_number(const EVP_KDF *kdf);
int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name);
+const char *EVP_KDF_name(const EVP_KDF *kdf);
const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf);
const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx);
diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c
index 609981b9e8..fdb3d46f1f 100644
--- a/providers/implementations/rands/drbg_ctr.c
+++ b/providers/implementations/rands/drbg_ctr.c
@@ -631,6 +631,19 @@ static void drbg_ctr_free(void *vdrbg)
static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
{
PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
+ PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)drbg->data;
+ OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_USE_DF);
+ if (p != NULL && !OSSL_PARAM_set_int(p, ctr->use_df))
+ return 0;
+
+ p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_CIPHER);
+ if (p != NULL) {
+ if (ctr->cipher_ctr == NULL
+ || !OSSL_PARAM_set_utf8_string(p, EVP_CIPHER_name(ctr->cipher_ctr)))
+ return 0;
+ }
return drbg_get_ctx_params(drbg, params);
}
@@ -638,6 +651,8 @@ static int drbg_ctr_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
static const OSSL_PARAM *drbg_ctr_gettable_ctx_params(ossl_unused void *provctx)
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
+ OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_CIPHER, NULL, 0),
+ OSSL_PARAM_int(OSSL_DRBG_PARAM_USE_DF, NULL),
OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
OSSL_PARAM_END
};
diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c
index ca2f8bb0c6..e5266dbb29 100644
--- a/providers/implementations/rands/drbg_hash.c
+++ b/providers/implementations/rands/drbg_hash.c
@@ -428,6 +428,16 @@ static void drbg_hash_free(void *vdrbg)
static int drbg_hash_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
{
PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
+ PROV_DRBG_HASH *hash = (PROV_DRBG_HASH *)drbg->data;
+ const EVP_MD *md;
+ OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST);
+ if (p != NULL) {
+ md = ossl_prov_digest_md(&hash->digest);
+ if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_name(md)))
+ return 0;
+ }
return drbg_get_ctx_params(drbg, params);
}
@@ -435,6 +445,7 @@ static int drbg_hash_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
static const OSSL_PARAM *drbg_hash_gettable_ctx_params(ossl_unused void *p_ctx)
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
+ OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
OSSL_PARAM_END
};
diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c
index fb232de519..f7ac2926ac 100644
--- a/providers/implementations/rands/drbg_hmac.c
+++ b/providers/implementations/rands/drbg_hmac.c
@@ -325,6 +325,26 @@ static void drbg_hmac_free(void *vdrbg)
static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
{
PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
+ PROV_DRBG_HMAC *hmac = (PROV_DRBG_HMAC *)drbg->data;
+ const char *name;
+ const EVP_MD *md;
+ OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_MAC);
+ if (p != NULL) {
+ if (hmac->ctx == NULL)
+ return 0;
+ name = EVP_MAC_name(EVP_MAC_CTX_mac(hmac->ctx));
+ if (!OSSL_PARAM_set_utf8_string(p, name))
+ return 0;
+ }
+
+ p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_DIGEST);
+ if (p != NULL) {
+ md = ossl_prov_digest_md(&hmac->digest);
+ if (md == NULL || !OSSL_PARAM_set_utf8_string(p, EVP_MD_name(md)))
+ return 0;
+ }
return drbg_get_ctx_params(drbg, params);
}
@@ -332,6 +352,8 @@ static int drbg_hmac_get_ctx_params(void *vdrbg, OSSL_PARAM params[])
static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *p_ctx)
{
static const OSSL_PARAM known_gettable_ctx_params[] = {
+ OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_MAC, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_DRBG_PARAM_DIGEST, NULL, 0),
OSSL_PARAM_DRBG_GETTABLE_CTX_COMMON,
OSSL_PARAM_END
};
diff --git a/test/recipes/20-test_rand_config.t b/test/recipes/20-test_rand_config.t
new file mode 100644
index 0000000000..5919eef56d
--- /dev/null
+++ b/test/recipes/20-test_rand_config.t
@@ -0,0 +1,103 @@
+#! /usr/bin/env perl
+# Copyright 2019-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
+
+
+use strict;
+use warnings;
+
+use OpenSSL::Test;
+use OpenSSL::Test::Utils;
+
+setup("test_rand_config");
+
+my @rand_tests = (
+ { drbg => 'HASH-DRBG',
+ digest => 'SHA2-512/256',
+ properties => '',
+ expected => ["HASH-DRBG", "digest: 'SHA2-512/256'"],
+ desc => 'HASH-DRBG SHA2-512/256' },
+
+ { drbg => 'HASH-DRBG',
+ digest => 'SHA3-256',
+ properties => '',
+ expected => ["HASH-DRBG", "digest: 'SHA3-512'"],
+ desc => 'HASH-DRBG SHA3/512' },
+
+ { drbg => 'HMAC-DRBG',
+ digest => 'SHA3-256',
+ properties => '',
+ expected => ["HMAC-DRBG", "mac: HMAC", "digest: 'SHA3-256'"],
+ desc => 'HMAC-DRBG SHA3/256' },
+
+ { cipher => 'AES-128-CTR',
+ expected => ["CTR-DRBG", "cipher: 'AES-128-CTR'"],
+ desc => 'CTR-DRBG AES-128 no DRBG' },
+ { expected => ["CTR-DRBG", "cipher: 'AES-256-CTR'"],
+ desc => 'CTR-DRBG AES-256 defaults' },
+);
+
+my @aria_tests = (
+ { drbg => 'CTR-DRBG',
+ cipher => 'ARIA-128-CTR',
+ properties => '',
+ expected => ["CTR-DRBG", "cipher: 'ARIA-128-CTR'"],
+ desc => 'CTR-DRBG ARIA-128' },
+
+ { drbg => 'CTR-DRBG',
+ cipher => 'ARIA-128-CTR',
+ properties => '',
+ expected => ["CTR-DRBG", "cipher: 'ARIA-128-CTR'"],
+ desc => 'CTR-DRBG ARIA-256' },
+);
+
+push @rand_tests, @aria_tests unless disabled("aria");
+
+plan tests => scalar @rand_tests;
+
+my $contents =<<'CONFIGEND';
+openssl_conf = openssl_init
+
+[openssl_init]
+random = random_section
+
+[random_section]
+CONFIGEND
+
+foreach (@rand_tests) {
+ my $tmpfile = 'rand_config.cfg';
+ open(my $cfg, '>', $tmpfile) or die "Could not open file";
+ print $cfg $contents;
+ if ($_->{drbg}) {
+ print $cfg "random = $_->{drbg}\n";
+ }
+ if ($_->{cipher}) {
+ print $cfg "cipher = $_->{cipher}\n";
+ }
+ if ($_->{digest}) {
+ print $cfg "digest = $_->{digest}\n"
+ }
+ close $cfg;
+
+ $ENV{OPENSSL_CONF} = $tmpfile;
+
+ ok(comparelines($_->{expected}), $_->{desc});
+}
+
+# Check that the stdout output contains the expected values.
+sub comparelines {
+ my @lines = run(app(["openssl", "list", "--random-instances"]),
+ capture => 1);
+
+ foreach (@_) {
+ if ( !grep( /$_/, @lines ) ) {
+ print "Cannot find: $_\n";
+ return 0;
+ }
+ }
+ return 1;
+}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 3658d14c29..ceab5d3fd9 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4452,6 +4452,7 @@ EVP_KDF_CTX_free ? 3_0_0 EXIST::FUNCTION:
EVP_KDF_reset ? 3_0_0 EXIST::FUNCTION:
EVP_KDF_size ? 3_0_0 EXIST::FUNCTION:
EVP_KDF_derive ? 3_0_0 EXIST::FUNCTION:
+EVP_KDF_name ? 3_0_0 EXIST::FUNCTION:
EC_GROUP_get0_field ? 3_0_0 EXIST::FUNCTION:EC
CRYPTO_alloc_ex_data ? 3_0_0 EXIST::FUNCTION:
OPENSSL_CTX_new ? 3_0_0 EXIST::FUNCTION:
@@ -4692,6 +4693,7 @@ EVP_MAC_get_params ? 3_0_0 EXIST::FUNCTION:
EVP_MAC_gettable_params ? 3_0_0 EXIST::FUNCTION:
EVP_MAC_provider ? 3_0_0 EXIST::FUNCTION:
EVP_MAC_do_all_provided ? 3_0_0 EXIST::FUNCTION:
+EVP_MAC_name ? 3_0_0 EXIST::FUNCTION:
EVP_MD_free ? 3_0_0 EXIST::FUNCTION:
EVP_CIPHER_free ? 3_0_0 EXIST::FUNCTION:
EVP_KDF_up_ref ? 3_0_0 EXIST::FUNCTION:
@@ -5309,6 +5311,6 @@ OSSL_ENCODER_INSTANCE_get_output_type ? 3_0_0 EXIST::FUNCTION:
OSSL_ENCODER_CTX_set_construct ? 3_0_0 EXIST::FUNCTION:
OSSL_ENCODER_CTX_set_construct_data ? 3_0_0 EXIST::FUNCTION:
OSSL_ENCODER_CTX_set_cleanup ? 3_0_0 EXIST::FUNCTION:
-OSSL_DECODER_INSTANCE_get_input_type ? 3_0_0 EXIST::FUNCTION:
OSSL_ENCODER_CTX_set_passphrase_cb ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_typenames_do_all ? 3_0_0 EXIST::FUNCTION:
+OSSL_DECODER_INSTANCE_get_input_type ? 3_0_0 EXIST::FUNCTION:
More information about the openssl-commits
mailing list