From: Loup Vaillant Date: Mon, 2 Dec 2019 22:49:25 +0000 (+0100) Subject: Fixed HMAC SHA-512 (and added tests) X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=34db5fcd402ad141af47c4bda82cb3aba6025b6f;p=Monocypher.git Fixed HMAC SHA-512 (and added tests) Test vectors were generated with Libsodium, with various key sizes (both shorter and longer than the message), and every message size from 0 to 256 (twice the SHA 512 block size). Also added Test vectors from RFC 4231, except the one with truncated output (we don't support truncated outputs, users will have to do that manually). --- diff --git a/src/optional/ed25519.c b/src/optional/ed25519.c index 6818e8c..2bb4545 100644 --- a/src/optional/ed25519.c +++ b/src/optional/ed25519.c @@ -233,17 +233,18 @@ const crypto_sign_vtable crypto_sha512_vtable = { //////////////////// void crypto_hmac_init(crypto_hmac_ctx *ctx, const u8 *key, size_t key_size) { - if (key_size <= 64) { - FOR (i, 0, key_size) { ctx->key[i] = key[i]; } - FOR (i, key_size, 64) { ctx->key[i] = 0; } - } else { + // hash key if it is too long + if (key_size > 128) { crypto_sha512(ctx->key, key, key_size); + key = ctx->key; + key_size = 64; } - FOR (i, 0, 64) { - ctx->key[i] ^= 0x36; - } + // Compute inner key: padded key XOR 0x36 + FOR (i, 0, key_size) { ctx->key[i] = key[i] ^ 0x36; } + FOR (i, key_size, 128) { ctx->key[i] = 0x36; } + // Start computing inner hash crypto_sha512_init (&ctx->ctx); - crypto_sha512_update(&ctx->ctx, ctx->key, 64); + crypto_sha512_update(&ctx->ctx, ctx->key, 128); } void crypto_hmac_update(crypto_hmac_ctx *ctx, @@ -254,14 +255,17 @@ void crypto_hmac_update(crypto_hmac_ctx *ctx, void crypto_hmac_final(crypto_hmac_ctx *ctx, u8 hmac[64]) { + // Finish computing inner hash crypto_sha512_final(&ctx->ctx, hmac); - FOR (i, 0, 64) { + // Compute outer key: padded key XOR 0x5c + FOR (i, 0, 128) { ctx->key[i] ^= 0x36 ^ 0x5c; } + // Compute outer hash crypto_sha512_init (&ctx->ctx); - crypto_sha512_update(&ctx->ctx, ctx->key , 64); + crypto_sha512_update(&ctx->ctx, ctx->key , 128); crypto_sha512_update(&ctx->ctx, hmac, 64); - crypto_sha512_final (&ctx->ctx, hmac); + crypto_sha512_final (&ctx->ctx, hmac); // outer hash WIPE_CTX(ctx); } diff --git a/src/optional/ed25519.h b/src/optional/ed25519.h index c5e4f72..3f5bff9 100644 --- a/src/optional/ed25519.h +++ b/src/optional/ed25519.h @@ -20,7 +20,7 @@ typedef struct { } crypto_sha512_ctx; typedef struct { - uint8_t key[64]; + uint8_t key[128]; crypto_sha512_ctx ctx; } crypto_hmac_ctx; diff --git a/tests/gen/hmac_sha512.c b/tests/gen/hmac_sha512.c new file mode 100644 index 0000000..f70b2d5 --- /dev/null +++ b/tests/gen/hmac_sha512.c @@ -0,0 +1,28 @@ +#include +#include "utils.h" + +static void test(size_t key_size, size_t msg_size) +{ + RANDOM_INPUT(key, 128); + RANDOM_INPUT(msg, 256); + u8 tag[64]; + + crypto_auth_hmacsha512_state ctx; + crypto_auth_hmacsha512_init (&ctx, key, key_size); + crypto_auth_hmacsha512_update(&ctx, msg, msg_size); + crypto_auth_hmacsha512_final (&ctx, tag); + + print_vector(key, key_size); + print_vector(msg, msg_size); + print_vector(tag, 64); + printf("\n"); +} + +int main(void) +{ + SODIUM_INIT; + FOR (key_size, 0, 32) { test(key_size, 32); } + FOR (key_size, 120, 136) { test(key_size, 32); } + FOR (msg_size, 0, 256) { test(32, msg_size); } + return 0; +} diff --git a/tests/gen/makefile b/tests/gen/makefile index d0bbd7d..d567cf3 100644 --- a/tests/gen/makefile +++ b/tests/gen/makefile @@ -4,7 +4,7 @@ CFLAGS = -pedantic -Wall -Wextra .PHONY: all clean VEC = chacha20 hchacha20 xchacha20 aead_ietf poly1305 \ - blake2b sha512 argon2i \ + blake2b sha512 hmac_sha512 argon2i \ edDSA edDSA_pk ed_25519 ed_25519_check \ x25519 x25519_pk key_exchange # monokex_xk1 monokex_x @@ -59,6 +59,7 @@ xchacha20.all.vec : xchacha20.vec aead_ietf.all.vec : aead_ietf.vec blake2b.all.vec : blake2b.vec sha512.all.vec : sha512.vec +hmac_sha512.all.vec : hmac_sha512.vec vectors/hmac_sha512 argon2i.all.vec : argon2i.vec vectors/argon2i edDSA.all.vec : edDSA.vec edDSA_pk.all.vec : edDSA_pk.vec diff --git a/tests/gen/vectors/hmac_sha512 b/tests/gen/vectors/hmac_sha512 new file mode 100644 index 0000000..0306411 --- /dev/null +++ b/tests/gen/vectors/hmac_sha512 @@ -0,0 +1,23 @@ +0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b: +4869205468657265: +87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854: + +4a656665: +7768617420646f2079612077616e7420666f72206e6f7468696e673f: +164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737: + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd: +fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb: + +0102030405060708090a0b0c0d0e0f10111213141516171819: +cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd: +b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd: + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374: +80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598: + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: +5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e: +e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58: diff --git a/tests/test.c b/tests/test.c index 8214c58..8ccb5c7 100644 --- a/tests/test.c +++ b/tests/test.c @@ -82,6 +82,13 @@ static void sha512(const vector in[], vector *out) crypto_sha512(out->buf, in->buf, in->size); } +static void hmac_sha512(const vector in[], vector *out) +{ + const vector *key = in; + const vector *msg = in +1; + crypto_hmac(out->buf, key->buf, key->size, msg->buf, msg->size); +} + static void argon2i(const vector in[], vector *out) { u64 nb_blocks = load64_le(in[0].buf); @@ -661,6 +668,7 @@ int main(int argc, char *argv[]) status |= TEST(aead_ietf , 4); status |= TEST(blake2b , 2); status |= TEST(sha512 , 1); + status |= TEST(hmac_sha512 , 2); status |= TEST(argon2i , 6); status |= TEST(x25519 , 2); status |= TEST(x25519_pk , 1);