prop224 prepwork: Introduce HMAC-SHA3 function.

This commit is contained in:
George Kadianakis 2016-09-05 17:21:44 +02:00 committed by Nick Mathewson
parent 0980787f91
commit b9010c8bf5
3 changed files with 68 additions and 0 deletions

View File

@ -2109,6 +2109,28 @@ crypto_hmac_sha256(char *hmac_out,
tor_assert(rv);
}
/** Compute an SHA3 MAC of <b>msg</b> using <b>key</b> as the key. The format
* used for our MAC is SHA3(k | m). Write the DIGEST256_LEN-byte result into
* <b>mac_out</b> of size <b>mac_out_len</b>. */
void
crypto_mac_sha3_256(char *mac_out, size_t mac_out_len,
const char *key, size_t key_len,
const char *msg, size_t msg_len)
{
crypto_digest_t *digest;
tor_assert(mac_out);
tor_assert(key);
tor_assert(msg);
digest = crypto_digest256_new(DIGEST_SHA3_256);
crypto_digest_add_bytes(digest, key, key_len);
crypto_digest_add_bytes(digest, msg, msg_len);
crypto_digest_get_digest(digest, mac_out, mac_out_len);
crypto_digest_free(digest);
}
/** Internal state for a eXtendable-Output Function (XOF). */
struct crypto_xof_t {
keccak_state s;

View File

@ -255,6 +255,9 @@ 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);
void crypto_mac_sha3_256(char *mac_out, size_t mac_out_len,
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);

View File

@ -1135,6 +1135,48 @@ test_crypto_sha3_xof(void *arg)
tor_free(mem_op_hex_tmp);
}
/* Test our MAC-SHA3 function. There are not actually any MAC-SHA3 test
* vectors out there for our H(len(k) || k || m) construction. Hence what we
* are gonna do is test our crypto_mac_sha3_256() function against manually
* doing H(len(k) || k||m). If in the future the Keccak group decides to
* standarize an MAC construction and make test vectors, we should
* incorporate them here. */
static void
test_crypto_mac_sha3(void *arg)
{
const char msg[] = "i am in a library somewhere using my computer";
const char key[] = "i'm from the past talking to the future.";
char hmac_test[DIGEST256_LEN];
char hmac_manual[DIGEST256_LEN];
(void) arg;
/* First let's use our nice HMAC-SHA3 function */
crypto_mac_sha3_256(hmac_test, sizeof(hmac_test),
key, strlen(key),
msg, strlen(msg));
/* Now let's try a manual H(k || m) construction */
{
char *key_msg_concat = NULL;
int result;
tor_asprintf(&key_msg_concat, "%s%s", key, msg);
result = crypto_digest256(hmac_manual,
key_msg_concat, strlen(key_msg_concat),
DIGEST_SHA3_256);
tt_int_op(result, ==, 0);
tor_free(key_msg_concat);
}
/* Now compare the two results */
tt_mem_op(hmac_test, OP_EQ, hmac_manual, DIGEST256_LEN);
done: ;
}
/** Run unit tests for our public key crypto functions */
static void
test_crypto_pk(void *arg)
@ -2918,6 +2960,7 @@ struct testcase_t crypto_tests[] = {
{ "digest_names", test_crypto_digest_names, 0, NULL, NULL },
{ "sha3", test_crypto_sha3, TT_FORK, NULL, NULL},
{ "sha3_xof", test_crypto_sha3_xof, TT_FORK, NULL, NULL},
{ "mac_sha3", test_crypto_mac_sha3, TT_FORK, NULL, NULL},
CRYPTO_LEGACY(dh),
{ "aes_iv_AES", test_crypto_aes_iv, TT_FORK, &passthrough_setup,
(void*)"aes" },