[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