////////////////////
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,
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);
}
} crypto_sha512_ctx;
typedef struct {
- uint8_t key[64];
+ uint8_t key[128];
crypto_sha512_ctx ctx;
} crypto_hmac_ctx;
--- /dev/null
+#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;
+}
.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
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
--- /dev/null
+0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b:
+4869205468657265:
+87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854:
+
+4a656665:
+7768617420646f2079612077616e7420666f72206e6f7468696e673f:
+164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:
+fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb:
+
+0102030405060708090a0b0c0d0e0f10111213141516171819:
+cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd:
+b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374:
+80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e:
+e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58:
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);
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);