]> git.codecow.com Git - Monocypher.git/commitdiff
Fixed HMAC SHA-512 (and added tests)
authorLoup Vaillant <loup@loup-vaillant.fr>
Mon, 2 Dec 2019 22:49:25 +0000 (23:49 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Mon, 2 Dec 2019 22:49:25 +0000 (23:49 +0100)
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).

src/optional/ed25519.c
src/optional/ed25519.h
tests/gen/hmac_sha512.c [new file with mode: 0644]
tests/gen/makefile
tests/gen/vectors/hmac_sha512 [new file with mode: 0644]
tests/test.c

index 6818e8c5ecee2189cde3cf7203f1fec46345fe05..2bb45458599138f3609c5f4a86b0a592e2859629 100644 (file)
@@ -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);
 }
 
index c5e4f726fc4499b9ba15769b516d826bb822331a..3f5bff9b2070d70d1695a298a8e7be37c09e9de3 100644 (file)
@@ -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 (file)
index 0000000..f70b2d5
--- /dev/null
@@ -0,0 +1,28 @@
+#include <sodium.h>
+#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;
+}
index d0bbd7de6eed345ec1344438473f81541ffeca5d..d567cf3094354f0079490cd53193391e984c0cc5 100644 (file)
@@ -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 (file)
index 0000000..0306411
--- /dev/null
@@ -0,0 +1,23 @@
+0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b:
+4869205468657265:
+87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854:
+
+4a656665:
+7768617420646f2079612077616e7420666f72206e6f7468696e673f:
+164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:
+fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb:
+
+0102030405060708090a0b0c0d0e0f10111213141516171819:
+cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd:
+b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374:
+80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e:
+e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58:
index 8214c581956d2daa7e91953082c5652e5c660b0f..8ccb5c737f0359e2ed23a4b7826088b7bab01349 100644 (file)
@@ -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);