From ac2dc0510f168345d4272ee7ac3b38fb68a8e3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Tvrd=C3=ADk?= Date: Tue, 28 Apr 2015 12:43:03 +0200 Subject: [PATCH] Add HMAC-SHA224 (but it does not work yet!) Unit Tests for HMAC-SHA224 not passed --- lib/sha256.c | 39 ++++++++++++ lib/sha256.h | 16 ++++- lib/sha256_test.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 2 deletions(-) diff --git a/lib/sha256.c b/lib/sha256.c index 85880a97..e262227b 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -392,6 +392,45 @@ sha256_hmac_init(sha256_hmac_context *ctx, const void *key, size_t keylen) } } +void sha224_hmac_init(sha224_hmac_context *ctx, const void *key, size_t keylen) +{ + sha224_init(&ctx->ctx); + + ctx->finalized = 0; + ctx->use_hmac = 0; + + if (key) + { + int i; + unsigned char ipad[64]; + + memset(ipad, 0, 64); + memset(ctx->opad, 0, 64); + if (keylen <= 64) + { + memcpy(ipad, key, keylen); + memcpy(ctx->opad, key, keylen); + } + else + { + sha224_hmac_context tmp_ctx; + + sha224_hmac_init(&tmp_ctx, NULL, 0); + sha224_hmac_update(&tmp_ctx, key, keylen); + sha224_final(&tmp_ctx.ctx); + memcpy(ipad, tmp_ctx.ctx.buf, 32); + memcpy(ctx->opad, tmp_ctx.ctx.buf, 32); + } + for(i=0; i < 64; i++) + { + ipad[i] ^= 0x36; + ctx->opad[i] ^= 0x5c; + } + ctx->use_hmac = 1; + sha224_hmac_update(ctx, ipad, 64); + } +} + /* Update the message digest with the contents of BUFFER containing LENGTH bytes. */ void diff --git a/lib/sha256.h b/lib/sha256.h index c6ffd7c3..a054ff90 100644 --- a/lib/sha256.h +++ b/lib/sha256.h @@ -42,8 +42,8 @@ byte* sha224_final(sha224_context *ctx) return sha256_final(ctx); } -/* - * HMAC-SHA256 +/** + * HMAC-SHA256 & HMAC-SHA224 */ typedef struct { @@ -52,9 +52,21 @@ typedef struct int use_hmac:1; byte opad[64]; } sha256_hmac_context; +typedef sha256_hmac_context sha224_hmac_context; void sha256_hmac_init(sha256_hmac_context *ctx, const void *key, size_t keylen); +void sha224_hmac_init(sha224_hmac_context *ctx, const void *key, size_t keylen); + void sha256_hmac_update(sha256_hmac_context *ctx, const void *buf, size_t buflen); +void sha224_hmac_update(sha224_hmac_context *ctx, const void *buf, size_t buflen) +{ + sha256_hmac_update(ctx, buf, buflen); +} + const byte *sha256_hmac_final(sha256_hmac_context *ctx); +const byte *sha224_hmac_final(sha224_hmac_context *ctx) +{ + return sha256_hmac_final(ctx); +} #endif /* _BIRD_SHA256_H_ */ diff --git a/lib/sha256_test.c b/lib/sha256_test.c index f9976d13..f7b93f0a 100644 --- a/lib/sha256_test.c +++ b/lib/sha256_test.c @@ -171,6 +171,20 @@ get_sha256_hmac(const struct hmac_data_in in, char (*out_hash)[SHA256_HEX_SIZE]) sprintf(*out_hash + i*2, "%02x", hash_byte[i]); } +static void +get_sha224_hmac(const struct hmac_data_in in, char (*out_hash)[SHA256_HEX_SIZE]) +{ + sha224_hmac_context ctx; + sha224_hmac_init(&ctx, in.key, in.key_len); + sha224_hmac_update(&ctx, in.data, in.data_len); + byte *hash_byte = sha224_hmac_final(&ctx); + + int i; + for (i = 0; i < SHA224_SIZE; i++) + sprintf(*out_hash + i*2, "%02x", hash_byte[i]); +} + + static int t_sha256_hmac(void) { @@ -303,6 +317,139 @@ t_sha256_hmac(void) return BT_SUCCESS; } + +static int +t_sha224_hmac(void) +{ + struct in_out { + struct hmac_data_in in; + char out[SHA256_HEX_SIZE]; + } in_out[] = { + { + .in = { + .key = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + }, + .key_len = 20, + .data = "Hi There", + .data_len = 8, + }, + .out = "896fb1128abbdf196832107cd49df33f47b4b1169912ba4f53684b22", + }, + { + .in = { + .key = "Jefe", + .key_len = 4, + .data = "what do ya want for nothing?", + .data_len = 28, + }, + .out = "a30e01098bc6dbbf45690f3a7e9e6d0f8bbea2a39e6148008fd05e44", + }, + { + .in = { + .key = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + }, + .key_len = 20, + .data = { + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + }, + .data_len = 50, + }, + .out = "7fb3cb3588c6c1f6ffa9694d7d6ad2649365b0c1f65d69d1ec8333ea", + }, + { + .in = { + .key = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, + }, + .key_len = 25, + .data = { + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + }, + .data_len = 50, + }, + .out = "6c11506874013cac6a2abc1bb382627cec6a90d86efc012de7afec5a", + }, + { + .in = { + .key = { + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, + }, + .key_len = 20, + .data = "Test With Truncation", + .data_len = 20, + }, + .out = "0e2aea68a90c8d37c988bcdb9fca6fa8", + }, + { + .in = { + .key = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, + }, + .key_len = 131, + .data = "Test Using Larger Than Block-Size Key - Hash Key First", + .data_len = 54, + }, + .out = "95e9a0db962095adaebe9b2d6f0dbce2d499f112f2d2b7273fa6870e", + }, + { + .in = { + .key = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, + }, + .key_len = 131, + .data = "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + .data_len = 152, + }, + .out = "3a854166ac5d9f023f54d517d0b39dbd946770db9c2b95c9f6f565d1", + }, + }; + + bt_assert_fn_in_out(get_sha224_hmac, in_out, NULL, "'%s'"); + + return BT_SUCCESS; +} + int main(int argc, char *argv[]) { @@ -313,6 +460,7 @@ main(int argc, char *argv[]) bt_test_suite(t_sha256_concating, "Testing concating input string to hash process via sha256_update"); bt_test_suite(t_sha256_hmac, "Test Suite by RFC 4231"); + bt_test_suite(t_sha224_hmac, "Test Suite by RFC 4231"); return bt_end(); }