[openssl-commits] [openssl] master update

paul.dale at oracle.com paul.dale at oracle.com
Thu Jan 4 01:48:33 UTC 2018


The branch master has been updated
       via  8212d50576147cd5db87b1e2f4607a6d5b5f435f (commit)
       via  4e585e720195788c9546a9ce71d63dafdfd2aaf1 (commit)
      from  767938fae99777c84818bdebae239934b8558a74 (commit)


- Log -----------------------------------------------------------------
commit 8212d50576147cd5db87b1e2f4607a6d5b5f435f
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Thu Dec 28 21:42:14 2017 +0100

    crypto/rand: restore the generic DRBG implementation
    
    The DRGB concept described in NIST SP 800-90A provides for having different
    algorithms to generate random output. In fact, the FIPS object module used to
    implement three of them, CTR DRBG, HASH DRBG and HMAC DRBG.
    
    When the FIPS code was ported to master in #4019, two of the three algorithms
    were dropped, and together with those the entire code that made RAND_DRBG
    generic was removed, since only one concrete implementation was left.
    
    This commit restores the original generic implementation of the DRBG, making it
    possible again to add additional implementations using different algorithms
    (like RAND_DRBG_CHACHA20) in the future.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Tim Hudson <tjh at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4998)

commit 4e585e720195788c9546a9ce71d63dafdfd2aaf1
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Thu Dec 28 02:18:21 2017 +0100

    crypto/rand: rename drbg_rand.c to drbg_ctr.c
    
    The generic part of the FIPS DRBG was implemented in fips_drbg_lib.c and the
    algorithm specific parts in fips_drbg_<alg>.c for <alg> in {ctr, hash, hmac}.
    Additionally, there was the module fips_drbg_rand.c which contained 'gluing'
    code between the RAND_METHOD api and the FIPS DRBG.
    
    When the FIPS code was ported to master in #4019, for some reason the ctr-drbg
    implementation from fips_drbg_ctr.c ended up in drbg_rand.c instead of drbg_ctr.c.
    
    This commit renames the module drbg_rand.c back to drbg_ctr.c, thereby restoring
    a simple relationship between the original fips modules and the drbg modules
    in master:
    
     fips_drbg_lib.c    =>  drbg_lib.c    /* generic part of implementation */
     fips_drbg_<alg>.c  =>  drbg_<alg>.c  /* algorithm specific implementations */
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    Reviewed-by: Tim Hudson <tjh at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/4998)

-----------------------------------------------------------------------

Summary of changes:
 crypto/err/openssl.txt                  |  2 ++
 crypto/rand/build.info                  |  2 +-
 crypto/rand/{drbg_rand.c => drbg_ctr.c} | 43 ++++++++++++++---------
 crypto/rand/drbg_lib.c                  | 30 ++++++++++++----
 crypto/rand/rand_err.c                  |  4 +++
 crypto/rand/rand_lcl.h                  | 62 ++++++++++++++++++++++++---------
 include/openssl/randerr.h               |  2 ++
 test/drbgtest.c                         |  2 +-
 8 files changed, 105 insertions(+), 42 deletions(-)
 rename crypto/rand/{drbg_rand.c => drbg_ctr.c} (89%)

diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 4357cfb..9ec0009 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -893,6 +893,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_UNINSTANTIATE:118:RAND_DRBG_uninstantiate
 RAND_F_RAND_LOAD_FILE:111:RAND_load_file
 RAND_F_RAND_POOL_ADD:103:RAND_POOL_add
 RAND_F_RAND_POOL_ADD_BEGIN:113:RAND_POOL_add_begin
@@ -2258,6 +2259,7 @@ RAND_R_INTERNAL_ERROR:113:internal error
 RAND_R_IN_ERROR_STATE:114:in error state
 RAND_R_NOT_A_REGULAR_FILE:122:Not a regular file
 RAND_R_NOT_INSTANTIATED:115:not instantiated
+RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED:128:no drbg implementation selected
 RAND_R_PERSONALISATION_STRING_TOO_LONG:116:personalisation string too long
 RAND_R_PRNG_NOT_SEEDED:100:PRNG not seeded
 RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow
diff --git a/crypto/rand/build.info b/crypto/rand/build.info
index 2591c01..df9bac6 100644
--- a/crypto/rand/build.info
+++ b/crypto/rand/build.info
@@ -1,4 +1,4 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
         randfile.c rand_lib.c rand_err.c rand_egd.c \
-        rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_rand.c
+        rand_win.c rand_unix.c rand_vms.c drbg_lib.c drbg_ctr.c
diff --git a/crypto/rand/drbg_rand.c b/crypto/rand/drbg_ctr.c
similarity index 89%
rename from crypto/rand/drbg_rand.c
rename to crypto/rand/drbg_ctr.c
index bb3acc8..3130e49 100644
--- a/crypto/rand/drbg_rand.c
+++ b/crypto/rand/drbg_ctr.c
@@ -201,7 +201,7 @@ static void ctr_update(RAND_DRBG *drbg,
                        const unsigned char *in2, size_t in2len,
                        const unsigned char *nonce, size_t noncelen)
 {
-    RAND_DRBG_CTR *ctr = &drbg->ctr;
+    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
 
     /* ks is already setup for correct key */
     inc_128(ctr);
@@ -236,12 +236,12 @@ static void ctr_update(RAND_DRBG *drbg,
     AES_set_encrypt_key(ctr->K, drbg->strength, &ctr->ks);
 }
 
-int ctr_instantiate(RAND_DRBG *drbg,
-                    const unsigned char *entropy, size_t entropylen,
-                    const unsigned char *nonce, size_t noncelen,
-                    const unsigned char *pers, size_t perslen)
+static int drbg_ctr_instantiate(RAND_DRBG *drbg,
+                                const unsigned char *entropy, size_t entropylen,
+                                const unsigned char *nonce, size_t noncelen,
+                                const unsigned char *pers, size_t perslen)
 {
-    RAND_DRBG_CTR *ctr = &drbg->ctr;
+    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
 
     if (entropy == NULL)
         return 0;
@@ -253,9 +253,9 @@ int ctr_instantiate(RAND_DRBG *drbg,
     return 1;
 }
 
-int ctr_reseed(RAND_DRBG *drbg,
-               const unsigned char *entropy, size_t entropylen,
-               const unsigned char *adin, size_t adinlen)
+static int drbg_ctr_reseed(RAND_DRBG *drbg,
+                           const unsigned char *entropy, size_t entropylen,
+                           const unsigned char *adin, size_t adinlen)
 {
     if (entropy == NULL)
         return 0;
@@ -263,11 +263,11 @@ int ctr_reseed(RAND_DRBG *drbg,
     return 1;
 }
 
-int ctr_generate(RAND_DRBG *drbg,
-                 unsigned char *out, size_t outlen,
-                 const unsigned char *adin, size_t adinlen)
+static int drbg_ctr_generate(RAND_DRBG *drbg,
+                             unsigned char *out, size_t outlen,
+                             const unsigned char *adin, size_t adinlen)
 {
-    RAND_DRBG_CTR *ctr = &drbg->ctr;
+    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
 
     if (adin != NULL && adinlen != 0) {
         ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0);
@@ -299,15 +299,22 @@ int ctr_generate(RAND_DRBG *drbg,
     return 1;
 }
 
-int ctr_uninstantiate(RAND_DRBG *drbg)
+static int drbg_ctr_uninstantiate(RAND_DRBG *drbg)
 {
-    OPENSSL_cleanse(&drbg->ctr, sizeof(drbg->ctr));
+    OPENSSL_cleanse(&drbg->data.ctr, sizeof(drbg->data.ctr));
     return 1;
 }
 
-int ctr_init(RAND_DRBG *drbg)
+static RAND_DRBG_METHOD drbg_ctr_meth = {
+    drbg_ctr_instantiate,
+    drbg_ctr_reseed,
+    drbg_ctr_generate,
+    drbg_ctr_uninstantiate
+};
+
+int drbg_ctr_init(RAND_DRBG *drbg)
 {
-    RAND_DRBG_CTR *ctr = &drbg->ctr;
+    RAND_DRBG_CTR *ctr = &drbg->data.ctr;
     size_t keylen;
 
     switch (drbg->nid) {
@@ -325,6 +332,8 @@ int ctr_init(RAND_DRBG *drbg)
         break;
     }
 
+    drbg->meth = &drbg_ctr_meth;
+
     ctr->keylen = keylen;
     drbg->strength = keylen * 8;
     drbg->seedlen = keylen + 16;
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index e33877e..795b098 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -124,7 +124,7 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags)
     case NID_aes_128_ctr:
     case NID_aes_192_ctr:
     case NID_aes_256_ctr:
-        ret = ctr_init(drbg);
+        ret = drbg_ctr_init(drbg);
         break;
     }
 
@@ -172,7 +172,8 @@ void RAND_DRBG_free(RAND_DRBG *drbg)
     if (drbg == NULL)
         return;
 
-    ctr_uninstantiate(drbg);
+    if (drbg->meth != NULL)
+        drbg->meth->uninstantiate(drbg);
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
     OPENSSL_clear_free(drbg, sizeof(*drbg));
 }
@@ -196,6 +197,14 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
                 RAND_R_PERSONALISATION_STRING_TOO_LONG);
         goto end;
     }
+
+    if (drbg->meth == NULL)
+    {
+        RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
+                RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
+        goto end;
+    }
+
     if (drbg->state != DRBG_UNINITIALISED) {
         RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
                 drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE
@@ -223,7 +232,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
         }
     }
 
-    if (!ctr_instantiate(drbg, entropy, entropylen,
+    if (!drbg->meth->instantiate(drbg, entropy, entropylen,
                          nonce, noncelen, pers, perslen)) {
         RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ERROR_INSTANTIATING_DRBG);
         goto end;
@@ -267,11 +276,18 @@ end:
  */
 int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
 {
+    if (drbg->meth == NULL)
+    {
+        RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
+                RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
+        return 0;
+    }
+
     /* Clear the entire drbg->ctr struct, then reset some important
      * members of the drbg->ctr struct (e.g. keysize, df_ks) to their
      * initial values.
      */
-    ctr_uninstantiate(drbg);
+    drbg->meth->uninstantiate(drbg);
     return RAND_DRBG_set(drbg, drbg->nid, drbg->flags);
 }
 
@@ -314,7 +330,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
         goto end;
     }
 
-    if (!ctr_reseed(drbg, entropy, entropylen, adin, adinlen))
+    if (!drbg->meth->reseed(drbg, entropy, entropylen, adin, adinlen))
         goto end;
 
     drbg->state = DRBG_READY;
@@ -420,7 +436,7 @@ int rand_drbg_restart(RAND_DRBG *drbg,
              * entropy from the trusted entropy source using get_entropy().
              * This is not a reseeding in the strict sense of NIST SP 800-90A.
              */
-            ctr_reseed(drbg, adin, adinlen, NULL, 0);
+            drbg->meth->reseed(drbg, adin, adinlen, NULL, 0);
         } else if (reseeded == 0) {
             /* do a full reseeding if it has not been done yet above */
             RAND_DRBG_reseed(drbg, NULL, 0);
@@ -507,7 +523,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
         adinlen = 0;
     }
 
-    if (!ctr_generate(drbg, out, outlen, adin, adinlen)) {
+    if (!drbg->meth->generate(drbg, out, outlen, adin, adinlen)) {
         drbg->state = DRBG_ERROR;
         RANDerr(RAND_F_RAND_DRBG_GENERATE, RAND_R_GENERATE_ERROR);
         return 0;
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index dc6140c..ac70b4a 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -27,6 +27,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_UNINSTANTIATE, 0),
+     "RAND_DRBG_uninstantiate"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_LOAD_FILE, 0), "RAND_load_file"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD, 0), "RAND_POOL_add"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_POOL_ADD_BEGIN, 0),
@@ -76,6 +78,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_A_REGULAR_FILE),
     "Not a regular file"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_INSTANTIATED), "not instantiated"},
+    {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED),
+    "no drbg implementation selected"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PERSONALISATION_STRING_TOO_LONG),
     "personalisation string too long"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index 9044981..1a09118 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -54,6 +54,42 @@ typedef enum drbg_status_e {
 } DRBG_STATUS;
 
 
+/* intantiate */
+typedef int (*RAND_DRBG_instantiate_fn)(RAND_DRBG *ctx,
+                                        const unsigned char *ent,
+                                        size_t entlen,
+                                        const unsigned char *nonce,
+                                        size_t noncelen,
+                                        const unsigned char *pers,
+                                        size_t perslen);
+/* reseed */
+typedef int (*RAND_DRBG_reseed_fn)(RAND_DRBG *ctx,
+                                   const unsigned char *ent,
+                                   size_t entlen,
+                                   const unsigned char *adin,
+                                   size_t adinlen);
+/* generat output */
+typedef int (*RAND_DRBG_generate_fn)(RAND_DRBG *ctx,
+                                     unsigned char *out,
+                                     size_t outlen,
+                                     const unsigned char *adin,
+                                     size_t adinlen);
+/* uninstantiate */
+typedef int (*RAND_DRBG_uninstantiate_fn)(RAND_DRBG *ctx);
+
+
+/*
+ * The DRBG methods
+ */
+
+typedef struct rand_drbg_method_st {
+    RAND_DRBG_instantiate_fn instantiate;
+    RAND_DRBG_reseed_fn reseed;
+    RAND_DRBG_generate_fn generate;
+    RAND_DRBG_uninstantiate_fn uninstantiate;
+} RAND_DRBG_METHOD;
+
+
 /*
  * The state of a DRBG AES-CTR.
  */
@@ -96,7 +132,7 @@ struct rand_drbg_st {
     /*
      * The following parameters are setup by the per-type "init" function.
      *
-     * Currently the only type is CTR_DRBG, its init function is ctr_init().
+     * Currently the only type is CTR_DRBG, its init function is drbg_ctr_init().
      *
      * The parameters are closely related to the ones described in
      * section '10.2.1 CTR_DRBG' of [NIST SP 800-90Ar1], with one
@@ -148,8 +184,13 @@ struct rand_drbg_st {
     /* Application data, mainly used in the KATs. */
     CRYPTO_EX_DATA ex_data;
 
-    /* Implementation specific structures; was a union, but inline for now */
-    RAND_DRBG_CTR ctr;
+    /* Implementation specific data (currently only one implementation) */
+    union {
+        RAND_DRBG_CTR ctr;
+    } data;
+
+    /* Implementation specific methods */
+    RAND_DRBG_METHOD *meth;
 
     /* Callback functions.  See comments in rand_lib.c */
     RAND_DRBG_get_entropy_fn get_entropy;
@@ -179,18 +220,7 @@ void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
 int rand_drbg_restart(RAND_DRBG *drbg,
                       const unsigned char *buffer, size_t len, size_t entropy);
 
-/* DRBG functions implementing AES-CTR */
-int ctr_init(RAND_DRBG *drbg);
-int ctr_uninstantiate(RAND_DRBG *drbg);
-int ctr_instantiate(RAND_DRBG *drbg,
-                    const unsigned char *entropy, size_t entropylen,
-                    const unsigned char *nonce, size_t noncelen,
-                    const unsigned char *pers, size_t perslen);
-int ctr_reseed(RAND_DRBG *drbg,
-               const unsigned char *entropy, size_t entropylen,
-               const unsigned char *adin, size_t adinlen);
-int ctr_generate(RAND_DRBG *drbg,
-                 unsigned char *out, size_t outlen,
-                 const unsigned char *adin, size_t adinlen);
+/* initializes the AES-CTR DRBG implementation */
+int drbg_ctr_init(RAND_DRBG *drbg);
 
 #endif
diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h
index b07ea23..b136ce8 100644
--- a/include/openssl/randerr.h
+++ b/include/openssl/randerr.h
@@ -33,6 +33,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_UNINSTANTIATE                   118
 # define RAND_F_RAND_LOAD_FILE                            111
 # define RAND_F_RAND_POOL_ADD                             103
 # define RAND_F_RAND_POOL_ADD_BEGIN                       113
@@ -65,6 +66,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_R_IN_ERROR_STATE                            114
 # define RAND_R_NOT_A_REGULAR_FILE                        122
 # define RAND_R_NOT_INSTANTIATED                          115
+# define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED           128
 # define RAND_R_PERSONALISATION_STRING_TOO_LONG           116
 # define RAND_R_PRNG_NOT_SEEDED                           100
 # define RAND_R_RANDOM_POOL_OVERFLOW                      125
diff --git a/test/drbgtest.c b/test/drbgtest.c
index 68c1697..fcb4b28 100644
--- a/test/drbgtest.c
+++ b/test/drbgtest.c
@@ -438,7 +438,7 @@ static int error_check(DRBG_SELFTEST_DATA *td)
         goto err;
 
     /* Standard says we have to check uninstantiate really zeroes */
-    if (!TEST_mem_eq(zero, sizeof(drbg->ctr), &drbg->ctr, sizeof(drbg->ctr)))
+    if (!TEST_mem_eq(zero, sizeof(drbg->data), &drbg->data, sizeof(drbg->data)))
         goto err;
 
     ret = 1;


More information about the openssl-commits mailing list