summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2020-01-26 22:18:23 +0100
committerDr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>2020-02-07 11:38:02 +0100
commit30a9d5d1a72149c4eb2b8e5aa83f509344c80232 (patch)
treec8ae072771a45fa23ad49b0cc0a3ffe740623392
parentb03de7a9207645c72e22627b10709f15eed211bf (diff)
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@oracle.com> (Merged from https://github.com/openssl/openssl/pull/10950)
-rw-r--r--crypto/rand/drbg_lib.c28
-rw-r--r--crypto/rand/rand_local.h2
-rw-r--r--doc/man3/RAND_DRBG_set_callbacks.pod31
-rw-r--r--doc/man3/SSL_CTX_set_ct_validation_callback.pod2
-rw-r--r--include/openssl/rand_drbg.h4
-rw-r--r--util/libcrypto.num2
6 files changed, 66 insertions, 3 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
@@ -305,6 +305,34 @@ void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
}
/*
+ * 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|.
*
* If |type| and |flags| are zero, use the defaults
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..c899a1adcb 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 need 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 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/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: