RAND_DRBG: add a function for setting the default DRBG type and flags
authorDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Thu, 15 Mar 2018 18:48:43 +0000 (19:48 +0100)
committerDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Fri, 16 Mar 2018 17:31:30 +0000 (18:31 +0100)
This commit adds a new api RAND_DRBG_set_defaults() which sets the
default type and flags for new DRBG instances. See also #5576.

Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5632)

crypto/err/openssl.txt
crypto/rand/drbg_ctr.c
crypto/rand/drbg_lib.c
crypto/rand/rand_err.c
crypto/rand/rand_lcl.h
include/openssl/rand_drbg.h
include/openssl/randerr.h
ssl/ssl_lib.c
util/libcrypto.num

index 176a82b156329ec8ef3a28614d071f60becddcde..728013ba84a898040672ef1f0f79d0d71812bc25 100644 (file)
@@ -916,6 +916,7 @@ RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new
 RAND_F_RAND_DRBG_RESEED:110:RAND_DRBG_reseed
 RAND_F_RAND_DRBG_RESTART:102:rand_drbg_restart
 RAND_F_RAND_DRBG_SET:104:RAND_DRBG_set
+RAND_F_RAND_DRBG_SET_DEFAULTS:121:RAND_DRBG_set_defaults
 RAND_F_RAND_DRBG_UNINSTANTIATE:118:RAND_DRBG_uninstantiate
 RAND_F_RAND_LOAD_FILE:111:RAND_load_file
 RAND_F_RAND_POOL_ADD:103:rand_pool_add
@@ -2314,6 +2315,7 @@ RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow
 RAND_R_REQUEST_TOO_LARGE_FOR_DRBG:117:request too large for drbg
 RAND_R_RESEED_ERROR:118:reseed error
 RAND_R_SELFTEST_FAILURE:119:selftest failure
+RAND_R_UNSUPPORTED_DRBG_FLAGS:132:unsupported drbg flags
 RAND_R_UNSUPPORTED_DRBG_TYPE:120:unsupported drbg type
 RSA_R_ALGORITHM_MISMATCH:100:algorithm mismatch
 RSA_R_BAD_E_VALUE:101:bad e value
index 84425dc4e099b3af464fda1a8246096fe35de831..ac4af331d706f67d051428095c552d81a67aab2b 100644 (file)
@@ -317,7 +317,7 @@ int drbg_ctr_init(RAND_DRBG *drbg)
     RAND_DRBG_CTR *ctr = &drbg->data.ctr;
     size_t keylen;
 
-    switch (drbg->nid) {
+    switch (drbg->type) {
     default:
         /* This can't happen, but silence the compiler warning. */
         return 0;
index 93092c86a9526f76dd54fa9aadad84f8555b037d..360e77565c0e4b0ada4b434e3b0cc99aa7debff1 100644 (file)
@@ -113,6 +113,11 @@ static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG";
 
 static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;
 
+
+
+static int rand_drbg_type = RAND_DRBG_TYPE;
+static unsigned int rand_drbg_flags = RAND_DRBG_FLAGS;
+
 static unsigned int master_reseed_interval = MASTER_RESEED_INTERVAL;
 static unsigned int slave_reseed_interval  = SLAVE_RESEED_INTERVAL;
 
@@ -127,19 +132,26 @@ static RAND_DRBG *rand_drbg_new(int secure,
                                 RAND_DRBG *parent);
 
 /*
- * Set/initialize |drbg| to be of type |nid|, with optional |flags|.
+ * Set/initialize |drbg| to be of type |type|, with optional |flags|.
+ *
+ * If |type| and |flags| are zero, use the defaults
  *
  * Returns 1 on success, 0 on failure.
  */
-int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags)
+int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags)
 {
     int ret = 1;
 
+    if (type == 0 && flags == 0) {
+        type = rand_drbg_type;
+        flags = rand_drbg_flags;
+    }
+
     drbg->state = DRBG_UNINITIALISED;
     drbg->flags = flags;
-    drbg->nid = nid;
+    drbg->type = type;
 
-    switch (nid) {
+    switch (type) {
     default:
         RANDerr(RAND_F_RAND_DRBG_SET, RAND_R_UNSUPPORTED_DRBG_TYPE);
         return 0;
@@ -158,6 +170,37 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags)
     return ret;
 }
 
+/*
+ * Set/initialize default |type| and |flag| for new drbg instances.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+int RAND_DRBG_set_defaults(int type, unsigned int flags)
+{
+    int ret = 1;
+
+    switch (type) {
+    default:
+        RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_TYPE);
+        return 0;
+    case NID_aes_128_ctr:
+    case NID_aes_192_ctr:
+    case NID_aes_256_ctr:
+        break;
+    }
+
+    if ((flags & ~RAND_DRBG_USED_FLAGS) != 0) {
+        RANDerr(RAND_F_RAND_DRBG_SET_DEFAULTS, RAND_R_UNSUPPORTED_DRBG_FLAGS);
+        return 0;
+    }
+
+    rand_drbg_type  = type;
+    rand_drbg_flags = flags;
+
+    return ret;
+}
+
+
 /*
  * Allocate memory and initialize a new DRBG. The DRBG is allocated on
  * the secure heap if |secure| is nonzero and the secure heap is enabled.
@@ -357,7 +400,7 @@ int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
      * initial values.
      */
     drbg->meth->uninstantiate(drbg);
-    return RAND_DRBG_set(drbg, drbg->nid, drbg->flags);
+    return RAND_DRBG_set(drbg, drbg->type, drbg->flags);
 }
 
 /*
@@ -849,7 +892,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent)
 {
     RAND_DRBG *drbg;
 
-    drbg = RAND_DRBG_secure_new(RAND_DRBG_NID, 0, parent);
+    drbg = RAND_DRBG_secure_new(rand_drbg_type, rand_drbg_flags, parent);
     if (drbg == NULL)
         return NULL;
 
index 542499f1a7d1f7924e182b04117fb5711ded5234..36d484c726f075c7d59a918e21df756d84a336ee 100644 (file)
@@ -31,6 +31,8 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESEED, 0), "RAND_DRBG_reseed"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_RESTART, 0), "rand_drbg_restart"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET, 0), "RAND_DRBG_set"},
+    {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_SET_DEFAULTS, 0),
+     "RAND_DRBG_set_defaults"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_UNINSTANTIATE, 0),
      "RAND_DRBG_uninstantiate"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_LOAD_FILE, 0), "RAND_load_file"},
@@ -99,6 +101,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
     "request too large for drbg"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RESEED_ERROR), "reseed error"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_SELFTEST_FAILURE), "selftest failure"},
+    {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_FLAGS),
+    "unsupported drbg flags"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_TYPE),
     "unsupported drbg type"},
     {0, NULL}
index 2f1a52bb5903cc0a7da858cf26d80f999de2fd39..32526fbb54e6165bd32e778451030402e741f11a 100644 (file)
@@ -116,7 +116,7 @@ struct rand_drbg_st {
     CRYPTO_RWLOCK *lock;
     RAND_DRBG *parent;
     int secure; /* 1: allocated on the secure heap, 0: otherwise */
-    int nid; /* the underlying algorithm */
+    int type; /* the nid of the underlying algorithm */
     int fork_count;
     unsigned short flags; /* various external flags */
 
index 667a8ab2fd251b90049e6ac0b1a8a96fa4c29891..17ca979da25b42168ad16408a1dd41dccdca0b14 100644 (file)
 /* In CTR mode, disable derivation function ctr_df */
 # define RAND_DRBG_FLAG_CTR_NO_DF            0x1
 
+/* A logical OR of all used flag bits (currently there is only one) */
+# define RAND_DRBG_USED_FLAGS  ( \
+    RAND_DRBG_FLAG_CTR_NO_DF \
+                                 )
+
 /*
  * Default security strength (in the sense of [NIST SP 800-90Ar1])
  *
  *
  * Currently supported ciphers are: NID_aes_128_ctr, NID_aes_192_ctr and
  * NID_aes_256_ctr
- *
- * TODO(DRBG): would be nice to have the NID and strength configurable
  */
 # define RAND_DRBG_STRENGTH             256
-# define RAND_DRBG_NID                  NID_aes_256_ctr
+# define RAND_DRBG_TYPE                 NID_aes_256_ctr
+# define RAND_DRBG_FLAGS                0
 
 
 # ifdef  __cplusplus
@@ -47,6 +51,7 @@ extern "C" {
 RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent);
 RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent);
 int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags);
+int RAND_DRBG_set_defaults(int type, unsigned int flags);
 int RAND_DRBG_instantiate(RAND_DRBG *drbg,
                           const unsigned char *pers, size_t perslen);
 int RAND_DRBG_uninstantiate(RAND_DRBG *drbg);
index 81bda4ba51eb24e64ccfd68a2a3aadeced4c5088..afc8213927503fca98e5e078868c378666696dda 100644 (file)
@@ -32,6 +32,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_F_RAND_DRBG_RESEED                          110
 # define RAND_F_RAND_DRBG_RESTART                         102
 # define RAND_F_RAND_DRBG_SET                             104
+# define RAND_F_RAND_DRBG_SET_DEFAULTS                    121
 # define RAND_F_RAND_DRBG_UNINSTANTIATE                   118
 # define RAND_F_RAND_LOAD_FILE                            111
 # define RAND_F_RAND_POOL_ADD                             103
@@ -75,6 +76,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG                117
 # define RAND_R_RESEED_ERROR                              118
 # define RAND_R_SELFTEST_FAILURE                          119
+# define RAND_R_UNSUPPORTED_DRBG_FLAGS                    132
 # define RAND_R_UNSUPPORTED_DRBG_TYPE                     120
 
 #endif
index 298588cd3d455a8d3005ed5849551f91afc0a723..cd972ae63febb0a2388680da43905b02f04b0c08 100644 (file)
@@ -696,7 +696,7 @@ SSL *SSL_new(SSL_CTX *ctx)
      */
     if (RAND_get_rand_method() == RAND_OpenSSL()) {
         s->drbg =
-            RAND_DRBG_new(RAND_DRBG_NID, 0, RAND_DRBG_get0_public());
+            RAND_DRBG_new(0, 0, RAND_DRBG_get0_public());
         if (s->drbg == NULL
             || RAND_DRBG_instantiate(s->drbg,
                                      (const unsigned char *) SSL_version_str,
index 38c902c9c0f79e801912f32c0cb333419a9c93c6..16d19526bb563d07a691d519081fe96b5f65a345 100644 (file)
@@ -4513,3 +4513,4 @@ EVP_PKEY_new_raw_public_key             4454      1_1_1   EXIST::FUNCTION:
 EVP_PKEY_new_CMAC_key                   4455   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_set_priv_key          4456   1_1_1   EXIST::FUNCTION:
 EVP_PKEY_asn1_set_set_pub_key           4457   1_1_1   EXIST::FUNCTION:
+RAND_DRBG_set_defaults                  4458   1_1_1   EXIST::FUNCTION: