[openssl] master update

matthias.st.pierre at ncp-e.com matthias.st.pierre at ncp-e.com
Fri Feb 7 10:40:02 UTC 2020


The branch master has been updated
       via  09066cf2a1f9f3d13ea2898304250f5916d6de70 (commit)
       via  30a9d5d1a72149c4eb2b8e5aa83f509344c80232 (commit)
      from  b03de7a9207645c72e22627b10709f15eed211bf (commit)


- Log -----------------------------------------------------------------
commit 09066cf2a1f9f3d13ea2898304250f5916d6de70
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Fri Jan 31 13:32:11 2020 +0100

    tests/drbgtest: use new RAND_DRBG callback_data API instead of ex_data
    
    It took me a little while to realize why the test_rand_drbg_reseed test
    kept crashing after replacing the RAND_DRBG_{gs}et_ex_data() calls by
    RAND_DRBG_{gs}et_callback_data().
    
    The reason was that the ex_data API prohibits modifying the callbacks
    or callback data of chained DRBGs and returned an error which was
    ignored by the `test_rand_drbg_reseed` test, for good reasons.
    
    The `test_rand_drbg_reseed` test is special in this respect, because
    it needs to install callbacks for all DRBGs, in order to intercept
    and count the reseeding events.
    
    Since the drbgtest module has access to the internal structures of
    the DRBG anyway, the problem could be solved by accessing the members
    directly. I added a warning comment in hook_drbg().
    
    [extended tests]
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/10950)

commit 30a9d5d1a72149c4eb2b8e5aa83f509344c80232
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Sun Jan 26 22:18:23 2020 +0100

    RAND_DRBG: add a callback data for entropy and nonce callbacks
    
    The callback data allows passing context specific data from the
    application of the DRBG to to the entropy callbacks.
    This a rather specialized feature which is useful for implementing
    known answer tests (KATs) or deterministic signatures (RFC6979),
    which require passing a specified entropy and nonce for instantiating
    the DRBG.
    
    Reviewed-by: Shane Lontis <shane.lontis at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/10950)

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

Summary of changes:
 crypto/rand/drbg_lib.c                          | 28 ++++++++++++++++++++++
 crypto/rand/rand_local.h                        |  2 ++
 doc/man3/RAND_DRBG_set_callbacks.pod            | 31 +++++++++++++++++++++++--
 doc/man3/SSL_CTX_set_ct_validation_callback.pod |  2 +-
 include/openssl/rand_drbg.h                     |  4 ++++
 test/drbgtest.c                                 | 31 +++++++++++++------------
 util/libcrypto.num                              |  2 ++
 7 files changed, 82 insertions(+), 18 deletions(-)

diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index a695a5f7dd..029cc6e77c 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -304,6 +304,34 @@ void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
     OPENSSL_clear_free(out, outlen);
 }
 
+/*
+ * Set the |drbg|'s callback data pointer for the entropy and nonce callbacks
+ *
+ * The ownership of the context data remains with the caller,
+ * i.e., it is the caller's responsibility to keep it available as long
+ * as it is need by the callbacks and free it after use.
+ *
+ * Setting the callback data is allowed only if the drbg has not been
+ * initialized yet. Otherwise, the operation will fail.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *data)
+{
+    if (drbg->state != DRBG_UNINITIALISED
+        || drbg->parent != NULL)
+        return 0;
+
+    drbg->callback_data = data;
+    return 1;
+}
+
+/* Retrieve the callback data pointer */
+void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg)
+{
+    return drbg->callback_data;
+}
+
 /*
  * Set/initialize |drbg| to be of type |type|, with optional |flags|.
  *
diff --git a/crypto/rand/rand_local.h b/crypto/rand/rand_local.h
index c0ba3bad03..ce16892531 100644
--- a/crypto/rand/rand_local.h
+++ b/crypto/rand/rand_local.h
@@ -328,6 +328,8 @@ struct rand_drbg_st {
     RAND_DRBG_cleanup_entropy_fn cleanup_entropy;
     RAND_DRBG_get_nonce_fn get_nonce;
     RAND_DRBG_cleanup_nonce_fn cleanup_nonce;
+
+    void *callback_data;
 };
 
 /* The global RAND method, and the global buffer and DRBG instance. */
diff --git a/doc/man3/RAND_DRBG_set_callbacks.pod b/doc/man3/RAND_DRBG_set_callbacks.pod
index 695c1903e9..51414bcfc1 100644
--- a/doc/man3/RAND_DRBG_set_callbacks.pod
+++ b/doc/man3/RAND_DRBG_set_callbacks.pod
@@ -3,6 +3,8 @@
 =head1 NAME
 
 RAND_DRBG_set_callbacks,
+RAND_DRBG_set_callback_data,
+RAND_DRBG_get_callback_data,
 RAND_DRBG_get_entropy_fn,
 RAND_DRBG_cleanup_entropy_fn,
 RAND_DRBG_get_nonce_fn,
@@ -20,6 +22,9 @@ RAND_DRBG_cleanup_nonce_fn
                              RAND_DRBG_get_nonce_fn get_nonce,
                              RAND_DRBG_cleanup_nonce_fn cleanup_nonce);
 
+ int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *ctx);
+
+ void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg);
 
 =head2 Callback Functions
 
@@ -53,7 +58,16 @@ the nonce when reseeding the given B<drbg>.
 The callback functions are implemented and provided by the caller.
 Their parameter lists need to match the function prototypes above.
 
-Setting the callbacks is allowed only if the DRBG has not been initialized yet.
+RAND_DRBG_set_callback_data() can be used to store a pointer to some context
+specific data, which can subsequently be retrieved by the entropy and nonce
+callbacks using RAND_DRBG_get_callback_data().
+The ownership of the context data remains with the caller, i.e., it is the
+caller's responsibility to keep it available as long as it is needed by the
+callbacks and free it after use.
+For more information about the the callback data see the NOTES section.
+
+Setting the callbacks or the callback data is allowed only if the DRBG has
+not been initialized yet.
 Otherwise, the operation will fail.
 To change the settings for one of the three shared DRBGs it is necessary to call
 RAND_DRBG_uninstantiate() first.
@@ -95,7 +109,12 @@ setting them to NULL.
 
 =head1 RETURN VALUES
 
-RAND_DRBG_set_callbacks() return 1 on success, and 0 on failure
+RAND_DRBG_set_callbacks() returns 1 on success, and 0 on failure.
+
+RAND_DRBG_set_callback_data() returns 1 on success, and 0 on failure.
+
+RAND_DRBG_get_callback_data() returns the pointer to the callback data,
+which is NULL if none has been set previously.
 
 =head1 NOTES
 
@@ -121,6 +140,14 @@ In this case the DRBG will automatically request an extra amount of entropy
 utilize for the nonce, following the recommendations of [NIST SP 800-90A Rev. 1],
 section 8.6.7.
 
+The callback data is a rather specialized feature, because in general the
+random sources don't (and in fact, they must not) depend on any state provided
+by the DRBG.
+There are however exceptional cases where this feature is useful, most notably
+for implementing known answer tests (KATs) or deterministic signatures like
+those specified in RFC6979, which require passing a specified entropy and nonce
+for instantiating the DRBG.
+
 =head1 SEE ALSO
 
 L<RAND_DRBG_new(3)>,
diff --git a/doc/man3/SSL_CTX_set_ct_validation_callback.pod b/doc/man3/SSL_CTX_set_ct_validation_callback.pod
index c0a635b9aa..6732ee1135 100644
--- a/doc/man3/SSL_CTX_set_ct_validation_callback.pod
+++ b/doc/man3/SSL_CTX_set_ct_validation_callback.pod
@@ -69,7 +69,7 @@ sufficient to allow the connection to continue.
 The TLS handshake is aborted if the verification mode is not B<SSL_VERIFY_NONE>
 and the callback returns a non-positive result.
 
-An arbitrary callback context argument, B<arg>, can be passed in when setting
+An arbitrary callback data argument, B<arg>, can be passed in when setting
 the callback.
 This will be passed to the callback whenever it is invoked.
 Ownership of this context remains with the caller.
diff --git a/include/openssl/rand_drbg.h b/include/openssl/rand_drbg.h
index e9857ec431..6d8368d43d 100644
--- a/include/openssl/rand_drbg.h
+++ b/include/openssl/rand_drbg.h
@@ -150,6 +150,10 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
                             RAND_DRBG_cleanup_nonce_fn cleanup_nonce);
 
 
+int RAND_DRBG_set_callback_data(RAND_DRBG *drbg, void *data);
+
+void *RAND_DRBG_get_callback_data(RAND_DRBG *drbg);
+
 # ifdef  __cplusplus
 }
 # endif
diff --git a/test/drbgtest.c b/test/drbgtest.c
index b8dcbf7b7b..34a5cc744d 100644
--- a/test/drbgtest.c
+++ b/test/drbgtest.c
@@ -127,8 +127,6 @@ static DRBG_SELFTEST_DATA drbg_test[] = {
     make_drbg_test_data_hash(NID_sha512, sha512, 0),
 };
 
-static int app_data_index;
-
 /*
  * Test context data, attached as EXDATA to the RAND_DRBG
  */
@@ -145,7 +143,7 @@ static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout,
                           int entropy, size_t min_len, size_t max_len,
                           int prediction_resistance)
 {
-    TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
+    TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_callback_data(drbg);
 
     t->entropycnt++;
     *pout = (unsigned char *)t->entropy;
@@ -155,7 +153,7 @@ static size_t kat_entropy(RAND_DRBG *drbg, unsigned char **pout,
 static size_t kat_nonce(RAND_DRBG *drbg, unsigned char **pout,
                         int entropy, size_t min_len, size_t max_len)
 {
-    TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
+    TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_callback_data(drbg);
 
     t->noncecnt++;
     *pout = (unsigned char *)t->nonce;
@@ -213,6 +211,7 @@ static int single_kat(DRBG_SELFTEST_DATA *td)
         return 0;
     if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
                                            kat_nonce, NULL))
+        || !TEST_true(RAND_DRBG_set_callback_data(drbg, &t))
         || !TEST_true(disable_crngt(drbg))) {
         failures++;
         goto err;
@@ -222,7 +221,6 @@ static int single_kat(DRBG_SELFTEST_DATA *td)
     t.entropylen = td->entropylen;
     t.nonce = td->nonce;
     t.noncelen = td->noncelen;
-    RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
 
     if (!TEST_true(RAND_DRBG_instantiate(drbg, td->pers, td->perslen))
             || !TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0,
@@ -246,9 +244,9 @@ static int single_kat(DRBG_SELFTEST_DATA *td)
      */
     if (!TEST_true(RAND_DRBG_set(drbg, td->nid, td->flags))
             || !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
-                                                  kat_nonce, NULL)))
+                                                  kat_nonce, NULL))
+            || !TEST_true(RAND_DRBG_set_callback_data(drbg, &t)))
         failures++;
-    RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
     t.entropy = td->entropy_pr;
     t.entropylen = td->entropylen_pr;
     t.nonce = td->nonce_pr;
@@ -296,7 +294,7 @@ static int init(RAND_DRBG *drbg, DRBG_SELFTEST_DATA *td, TEST_CTX *t)
             || !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
                                                   kat_nonce, NULL)))
         return 0;
-    RAND_DRBG_set_ex_data(drbg, app_data_index, t);
+    RAND_DRBG_set_callback_data(drbg, t);
     t->entropy = td->entropy;
     t->entropylen = td->entropylen;
     t->nonce = td->nonce;
@@ -551,7 +549,7 @@ static HOOK_CTX master_ctx, public_ctx, private_ctx;
 
 static HOOK_CTX *get_hook_ctx(RAND_DRBG *drbg)
 {
-    return (HOOK_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
+    return (HOOK_CTX *)RAND_DRBG_get_callback_data(drbg);
 }
 
 /* Intercepts and counts calls to the get_entropy() callback */
@@ -579,17 +577,22 @@ static void hook_drbg(RAND_DRBG *drbg, HOOK_CTX *ctx)
     memset(ctx, 0, sizeof(*ctx));
     ctx->drbg = drbg;
     ctx->get_entropy = drbg->get_entropy;
+
+    /*
+     * We can't use the public API here, since it prohibits modifying
+     * the callbacks or the callback data of chained DRBGs.
+     */
     drbg->get_entropy = get_entropy_hook;
-    RAND_DRBG_set_ex_data(drbg, app_data_index, ctx);
+    drbg->callback_data = ctx;
 }
 
 /* Installs the hook for the get_entropy() callback of the given drbg */
 static void unhook_drbg(RAND_DRBG *drbg)
 {
-    HOOK_CTX *ctx = get_hook_ctx(drbg);
+    HOOK_CTX *ctx = drbg->callback_data;
 
-    drbg->get_entropy = ctx->get_entropy;
-    CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data);
+    if (ctx != NULL)
+        drbg->get_entropy = ctx->get_entropy;
 }
 
 /* Resets the given hook context */
@@ -1382,8 +1385,6 @@ err:
 
 int setup_tests(void)
 {
-    app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
-
     ADD_ALL_TESTS(test_kats, OSSL_NELEM(drbg_test));
     ADD_ALL_TESTS(test_error_checks, OSSL_NELEM(drbg_test));
     ADD_TEST(test_rand_drbg_reseed);
diff --git a/util/libcrypto.num b/util/libcrypto.num
index dc6515cfc9..777db89d9f 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4918,3 +4918,5 @@ PKCS8_pkey_add1_attr_by_OBJ             ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_private_check                  ?	3_0_0	EXIST::FUNCTION:
 EVP_PKEY_pairwise_check                 ?	3_0_0	EXIST::FUNCTION:
 ASN1_item_verify_ctx                    ?	3_0_0	EXIST::FUNCTION:
+RAND_DRBG_set_callback_data             ?	3_0_0	EXIST::FUNCTION:
+RAND_DRBG_get_callback_data             ?	3_0_0	EXIST::FUNCTION:


More information about the openssl-commits mailing list