summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorYawning Angel <yawning@schwanenlied.me>2015-12-18 22:31:12 +0000
committerYawning Angel <yawning@schwanenlied.me>2015-12-19 22:45:21 +0000
commit9467485517b69a99fb42e71416b856a2ef18a729 (patch)
treef4548bf9596832181db5af526f0c892200374528 /src/common
parent687f9b3bd7b55bcf4d984d745e978c2a03aeb4e1 (diff)
downloadtor-9467485517b69a99fb42e71416b856a2ef18a729.tar.gz
tor-9467485517b69a99fb42e71416b856a2ef18a729.zip
Add `crypto_xof_t` and assorted routines, backed by SHAKE256.
This is an eXtendable-Output Function with the following claimed security strengths against *all* adversaries: Collision: min(d/2, 256) Preimage: >= min(d, 256) 2nd Preimage: min(d, 256) where d is the amount of output used, in bits.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/crypto.c50
-rw-r--r--src/common/crypto.h5
2 files changed, 55 insertions, 0 deletions
diff --git a/src/common/crypto.c b/src/common/crypto.c
index f66ae9ee50..b39f9c16e3 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1986,6 +1986,56 @@ crypto_hmac_sha256(char *hmac_out,
tor_assert(rv);
}
+/** Internal state for a eXtendable-Output Function (XOF). */
+struct crypto_xof_t {
+ keccak_state s;
+};
+
+/** Allocate a new XOF object backed by SHAKE-256. The security level
+ * provided is a function of the length of the output used. Read and
+ * understand FIPS-202 A.2 "Additional Consideration for Extendable-Output
+ * Functions" before using this construct.
+ */
+crypto_xof_t *
+crypto_xof_new(void)
+{
+ crypto_xof_t *xof;
+ xof = tor_malloc(sizeof(crypto_xof_t));
+ keccak_xof_init(&xof->s, 256);
+ return xof;
+}
+
+/** Absorb bytes into a XOF object. Must not be called after a call to
+ * crypto_xof_squeeze_bytes() for the same instance, and will assert
+ * if attempted.
+ */
+void
+crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len)
+{
+ int i = keccak_xof_absorb(&xof->s, data, len);
+ tor_assert(i == 0);
+}
+
+/** Squeeze bytes out of a XOF object. Calling this routine will render
+ * the XOF instance ineligible to absorb further data.
+ */
+void
+crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len)
+{
+ int i = keccak_xof_squeeze(&xof->s, out, len);
+ tor_assert(i == 0);
+}
+
+/** Cleanse and deallocate a XOF object. */
+void
+crypto_xof_free(crypto_xof_t *xof)
+{
+ if (!xof)
+ return;
+ memwipe(xof, 0, sizeof(crypto_xof_t));
+ tor_free(xof);
+}
+
/* DH */
/** Our DH 'g' parameter */
diff --git a/src/common/crypto.h b/src/common/crypto.h
index ff640ced0e..cf7b9ee408 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -117,6 +117,7 @@ typedef struct {
typedef struct crypto_pk_t crypto_pk_t;
typedef struct crypto_cipher_t crypto_cipher_t;
typedef struct crypto_digest_t crypto_digest_t;
+typedef struct crypto_xof_t crypto_xof_t;
typedef struct crypto_dh_t crypto_dh_t;
/* global state */
@@ -246,6 +247,10 @@ void crypto_digest_assign(crypto_digest_t *into,
void crypto_hmac_sha256(char *hmac_out,
const char *key, size_t key_len,
const char *msg, size_t msg_len);
+crypto_xof_t *crypto_xof_new(void);
+void crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len);
+void crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len);
+void crypto_xof_free(crypto_xof_t *xof);
/* Key negotiation */
#define DH_TYPE_CIRCUIT 1