From 9b0dd1ae04bb4bb3bf86fe8dd629f84a07bf5cbf Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 13 Dec 2018 16:59:04 -0500 Subject: [PATCH] Add a function to compute an XOF in one shot. Motivation: 1. It's convenient. 2. It's all that openssl supports. Part of 28837. --- src/lib/crypt_ops/crypto_digest.c | 24 ++++++++++++++++++++++++ src/lib/crypt_ops/crypto_digest.h | 2 ++ src/test/test_crypto.c | 5 +++++ 3 files changed, 31 insertions(+) diff --git a/src/lib/crypt_ops/crypto_digest.c b/src/lib/crypt_ops/crypto_digest.c index 2cbd3d1124..1e64100f2f 100644 --- a/src/lib/crypt_ops/crypto_digest.c +++ b/src/lib/crypt_ops/crypto_digest.c @@ -955,3 +955,27 @@ crypto_xof_free_(crypto_xof_t *xof) memwipe(xof, 0, sizeof(crypto_xof_t)); tor_free(xof); } + +/** Compute the XOF (SHAKE256) of a input_len bytes at input, + * putting output_len bytes at output. */ +void +crypto_xof(uint8_t *output, size_t output_len, + const uint8_t *input, size_t input_len) +{ +#ifdef OPENSSL_HAS_SHA3 + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); + tor_assert(ctx); + int r = EVP_DigestInit(ctx, EVP_shake256()); + tor_assert(r == 1); + r = EVP_DigestUpdate(ctx, input, input_len); + tor_assert(r == 1); + r = EVP_DigestFinalXOF(ctx, output, output_len); + tor_assert(r == 1); + EVP_MD_CTX_free(ctx); +#else + crypto_xof_t *xof = crypto_xof_new(); + crypto_xof_add_bytes(xof, input, input_len); + crypto_xof_squeeze_bytes(xof, output, output_len); + crypto_xof_free(xof); +#endif +} diff --git a/src/lib/crypt_ops/crypto_digest.h b/src/lib/crypt_ops/crypto_digest.h index 47e60ce617..5869db7800 100644 --- a/src/lib/crypt_ops/crypto_digest.h +++ b/src/lib/crypt_ops/crypto_digest.h @@ -124,6 +124,8 @@ void crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len); void crypto_xof_free_(crypto_xof_t *xof); #define crypto_xof_free(xof) \ FREE_AND_NULL(crypto_xof_t, crypto_xof_free_, (xof)) +void crypto_xof(uint8_t *output, size_t output_len, + const uint8_t *input, size_t input_len); #ifdef TOR_UNIT_TESTS digest_algorithm_t crypto_digest_get_algorithm(crypto_digest_t *digest); diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index ec0c3cae64..556666df8d 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -1173,6 +1173,11 @@ test_crypto_sha3_xof(void *arg) crypto_xof_free(xof); memset(out, 0, sizeof(out)); + /* Test one-function absorb/squeeze. */ + crypto_xof(out, sizeof(out), msg, sizeof(msg)); + test_memeq_hex(out, squeezed_hex); + memset(out, 0, sizeof(out)); + /* Test incremental absorb/squeeze. */ xof = crypto_xof_new(); tt_assert(xof);