diff --git a/lib/hmac.c b/lib/hmac.c index 73e2afa0..a88ce410 100644 --- a/lib/hmac.c +++ b/lib/hmac.c @@ -32,45 +32,6 @@ #ifdef HAVE_C_UNIT_TESTS DECLARE_TEST_SUITE(hmac_test, "hmac functions test suite"); #endif -typedef struct { - MD5Context ctx_inside; - MD5Context ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_md5_ctx; - -typedef struct { - SHA1_INFO ctx_inside; - SHA1_INFO ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha1_ctx; - -typedef struct { - SHA256_CTX ctx_inside; - SHA256_CTX ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha256_ctx; - -typedef struct { - SHA384_CTX ctx_inside; - SHA384_CTX ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha384_ctx; - -typedef struct { - SHA512_CTX ctx_inside; - SHA512_CTX ctx_outside; - - unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN]; - unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN]; -} hmac_sha512_ctx; static void pad_init(unsigned char *inner_pad, unsigned char *outer_pad, @@ -97,351 +58,226 @@ pad_init(unsigned char *inner_pad, unsigned char *outer_pad, /* Begin MD5 HMAC functions */ -static void -hmac_md5_init(hmac_md5_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - unsigned char init_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; - - memcpy(init_key, key, final_len); - - if(MD5_BLOCK_LEN < key_len) - { - /* Calculate the digest of the key - */ - md5(final_key, init_key, final_len); - } - else - { - memcpy(final_key, init_key, key_len); - } - - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - MD5Init(&ctx->ctx_inside); - MD5Update(&ctx->ctx_inside, ctx->block_inner_pad, MD5_BLOCK_LEN); - - MD5Init(&ctx->ctx_outside); - MD5Update(&ctx->ctx_outside, ctx->block_outer_pad, MD5_BLOCK_LEN); - - return; -} - -static void -hmac_md5_update(hmac_md5_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - MD5Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} - -static void -hmac_md5_final(hmac_md5_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[MD5_DIGEST_LEN]; - - MD5Final(digest_inside, &ctx->ctx_inside); - MD5Update(&ctx->ctx_outside, digest_inside, MD5_DIGEST_LEN); - MD5Final(hmac, &ctx->ctx_outside); - - return; -} - void hmac_md5(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_md5_ctx ctx; + unsigned char inner_hash[MD5_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[MD5_BLOCK_LEN + MD5_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memset(&ctx, 0, sizeof(ctx)); + int final_len = hmac_key_len; - hmac_md5_init(&ctx, hmac_key, hmac_key_len); - hmac_md5_update(&ctx, msg, msg_len); - hmac_md5_final(&ctx, hmac); + if(MD5_BLOCK_LEN < hmac_key_len) + { + /* Calculate the digest of the key + */ + md5(final_key, (unsigned char *)hmac_key, final_len); + final_len = MD5_DIGEST_LEN; + } + else + { + memcpy(final_key, hmac_key, hmac_key_len); + } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, MD5_BLOCK_LEN); + memcpy(padded_msg + MD5_BLOCK_LEN, msg, msg_len); + //Calculate the inner hash + md5(inner_hash, padded_msg, msg_len + MD5_BLOCK_LEN); + + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, MD5_BLOCK_LEN); + memcpy(padded_hash + MD5_BLOCK_LEN, inner_hash, MD5_DIGEST_LEN); + + //the outer hash is the final hmac + md5(hmac, padded_hash, MD5_BLOCK_LEN + MD5_DIGEST_LEN); + + free(padded_msg); return; } /* Begin SHA1 HMAC functions */ -static void -hmac_sha1_init(hmac_sha1_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - unsigned char init_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; - - memcpy(init_key, key, final_len); - - if(SHA1_BLOCK_LEN < key_len) - { - /* Calculate the digest of the key - */ - sha1(final_key, init_key, final_len); - } - else - { - memcpy(final_key, init_key, key_len); - } - - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - sha1_init(&ctx->ctx_inside); - sha1_update(&ctx->ctx_inside, ctx->block_inner_pad, SHA1_BLOCK_LEN); - - sha1_init(&ctx->ctx_outside); - sha1_update(&ctx->ctx_outside, ctx->block_outer_pad, SHA1_BLOCK_LEN); - - return; -} - -static void -hmac_sha1_update(hmac_sha1_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - sha1_update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} - -static void -hmac_sha1_final(hmac_sha1_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA1_DIGEST_LEN]; - - sha1_final(digest_inside, &ctx->ctx_inside); - sha1_update(&ctx->ctx_outside, digest_inside, SHA1_DIGEST_LEN); - sha1_final(hmac, &ctx->ctx_outside); - - return; -} - void hmac_sha1(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_sha1_ctx ctx; + unsigned char inner_hash[SHA1_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA1_BLOCK_LEN + SHA1_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memset(&ctx, 0, sizeof(ctx)); + int final_len = hmac_key_len; - hmac_sha1_init(&ctx, hmac_key, hmac_key_len); - hmac_sha1_update(&ctx, msg, msg_len); - hmac_sha1_final(&ctx, hmac); + if(SHA1_BLOCK_LEN < hmac_key_len) + { + /* Calculate the digest of the key + */ + sha1(final_key, (unsigned char *)hmac_key, final_len); + final_len = SHA1_DIGEST_LEN; + } + else + { + memcpy(final_key, hmac_key, hmac_key_len); + } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA1_BLOCK_LEN); + memcpy(padded_msg + SHA1_BLOCK_LEN, msg, msg_len); + //Calculate the inner hash + sha1(inner_hash, padded_msg, msg_len + SHA1_BLOCK_LEN); + + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA1_BLOCK_LEN); + memcpy(padded_hash + SHA1_BLOCK_LEN, inner_hash, SHA1_DIGEST_LEN); + + //the outer hash is the final hmac + sha1(hmac, padded_hash, SHA1_BLOCK_LEN + SHA1_DIGEST_LEN); + + free(padded_msg); return; } /* Begin SHA256 HMAC functions */ -static void -hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - unsigned char init_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; - - memcpy(init_key, key, final_len); - - if(SHA256_BLOCK_LEN < key_len) - { - /* Calculate the digest of the key - */ - sha256(final_key, init_key, final_len); - } - else - { - memcpy(final_key, init_key, key_len); - } - - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - SHA256_Init(&ctx->ctx_inside); - SHA256_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA256_BLOCK_LEN); - - SHA256_Init(&ctx->ctx_outside); - SHA256_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA256_BLOCK_LEN); - - return; -} - -static void -hmac_sha256_update(hmac_sha256_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - SHA256_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} - -static void -hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA256_DIGEST_LEN]; - - SHA256_Final(digest_inside, &ctx->ctx_inside); - SHA256_Update(&ctx->ctx_outside, digest_inside, SHA256_DIGEST_LEN); - SHA256_Final(hmac, &ctx->ctx_outside); - - return; -} - void hmac_sha256(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_sha256_ctx ctx; + unsigned char inner_hash[SHA256_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA256_BLOCK_LEN + SHA256_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memset(&ctx, 0, sizeof(ctx)); + int final_len = hmac_key_len; - hmac_sha256_init(&ctx, hmac_key, hmac_key_len); - hmac_sha256_update(&ctx, msg, msg_len); - hmac_sha256_final(&ctx, hmac); + if(SHA256_BLOCK_LEN < hmac_key_len) + { + /* Calculate the digest of the key + */ + sha256(final_key, (unsigned char *)hmac_key, final_len); + final_len = SHA256_DIGEST_LEN; + } + else + { + memcpy(final_key, hmac_key, hmac_key_len); + } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA256_BLOCK_LEN); + memcpy(padded_msg + SHA256_BLOCK_LEN, msg, msg_len); + //Calculate the inner hash + sha256(inner_hash, padded_msg, msg_len + SHA256_BLOCK_LEN); + + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA256_BLOCK_LEN); + memcpy(padded_hash + SHA256_BLOCK_LEN, inner_hash, SHA256_DIGEST_LEN); + + //the outer hash is the final hmac + sha256(hmac, padded_hash, SHA256_BLOCK_LEN + SHA256_DIGEST_LEN); + + free(padded_msg); return; } /* Begin SHA384 HMAC functions */ -static void -hmac_sha384_init(hmac_sha384_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; - - if(SHA384_BLOCK_LEN < key_len) - { - /* Calculate the digest of the key - */ - sha384(final_key, (unsigned char *)key, final_len); - } - else - { - memcpy(final_key, key, key_len); - } - - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - SHA384_Init(&ctx->ctx_inside); - SHA384_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA384_BLOCK_LEN); - - SHA384_Init(&ctx->ctx_outside); - SHA384_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA384_BLOCK_LEN); - - return; -} - -static void -hmac_sha384_update(hmac_sha384_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - SHA384_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} - -static void -hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA384_DIGEST_LEN]; - - SHA384_Final(digest_inside, &ctx->ctx_inside); - SHA384_Update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_LEN); - SHA384_Final(hmac, &ctx->ctx_outside); - - return; -} - void hmac_sha384(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_sha384_ctx ctx; + unsigned char inner_hash[SHA384_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA384_BLOCK_LEN + SHA384_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memset(&ctx, 0, sizeof(ctx)); + int final_len = hmac_key_len; - hmac_sha384_init(&ctx, hmac_key, hmac_key_len); - hmac_sha384_update(&ctx, msg, msg_len); - hmac_sha384_final(&ctx, hmac); + if(SHA384_BLOCK_LEN < hmac_key_len) + { + /* Calculate the digest of the key + */ + sha384(final_key, (unsigned char *)hmac_key, final_len); + final_len = SHA384_DIGEST_LEN; + } + else + { + memcpy(final_key, hmac_key, hmac_key_len); + } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA384_BLOCK_LEN); + memcpy(padded_msg + SHA384_BLOCK_LEN, msg, msg_len); + //Calculate the inner hash + sha384(inner_hash, padded_msg, msg_len + SHA384_BLOCK_LEN); + + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA384_BLOCK_LEN); + memcpy(padded_hash + SHA384_BLOCK_LEN, inner_hash, SHA384_DIGEST_LEN); + + //the outer hash is the final hmac + sha384(hmac, padded_hash, SHA384_BLOCK_LEN + SHA384_DIGEST_LEN); + + free(padded_msg); return; } /* Begin SHA512 HMAC functions */ -static void -hmac_sha512_init(hmac_sha512_ctx *ctx, const char *key, const int key_len) -{ - unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; - int final_len = key_len; - - if(key_len > MAX_DIGEST_BLOCK_LEN) - final_len = MAX_DIGEST_BLOCK_LEN; - - if(SHA512_BLOCK_LEN < key_len) - { - /* Calculate the digest of the key - */ - sha512(final_key, (unsigned char *)key, final_len); - final_len = SHA512_DIGEST_LEN; - } - else - { - memcpy(final_key, key, key_len); - } - - pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len); - - SHA512_Init(&ctx->ctx_inside); - SHA512_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA512_BLOCK_LEN); - - SHA512_Init(&ctx->ctx_outside); - SHA512_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA512_BLOCK_LEN); - - return; -} - -static void -hmac_sha512_update(hmac_sha512_ctx *ctx, const char *msg, - unsigned int msg_len) -{ - SHA512_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len); - return; -} - -static void -hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *hmac) -{ - unsigned char digest_inside[SHA512_DIGEST_LEN]; - - SHA512_Final(digest_inside, &ctx->ctx_inside); - SHA512_Update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_LEN); - SHA512_Final(hmac, &ctx->ctx_outside); - - return; -} - void hmac_sha512(const char *msg, const unsigned int msg_len, unsigned char *hmac, const char *hmac_key, const int hmac_key_len) { - hmac_sha512_ctx ctx; + unsigned char inner_hash[SHA512_DIGEST_LEN] = {0}; + unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char final_key[MAX_DIGEST_BLOCK_LEN] = {0}; + unsigned char padded_hash[SHA512_BLOCK_LEN + SHA512_DIGEST_LEN + 1] = {0}; + unsigned char *padded_msg = malloc(msg_len + MAX_DIGEST_BLOCK_LEN + 1); - memset(&ctx, 0, sizeof(ctx)); + int final_len = hmac_key_len; - hmac_sha512_init(&ctx, hmac_key, hmac_key_len); - hmac_sha512_update(&ctx, msg, msg_len); - hmac_sha512_final(&ctx, hmac); + if(SHA512_BLOCK_LEN < hmac_key_len) + { + /* Calculate the digest of the key + */ + sha512(final_key, (unsigned char *)hmac_key, final_len); + final_len = SHA512_DIGEST_LEN; + } + else + { + memcpy(final_key, hmac_key, hmac_key_len); + } + pad_init(block_inner_pad, block_outer_pad, final_key, final_len); + //The first step is to hash the inner_pad + message + memcpy(padded_msg, block_inner_pad, SHA512_BLOCK_LEN); + memcpy(padded_msg + SHA512_BLOCK_LEN, msg, msg_len); + //Calculate the inner hash + sha512(inner_hash, padded_msg, msg_len + SHA512_BLOCK_LEN); + + //Then hash the outer pad + inner hash + memcpy(padded_hash, block_outer_pad, SHA512_BLOCK_LEN); + memcpy(padded_hash + SHA512_BLOCK_LEN, inner_hash, SHA512_DIGEST_LEN); + + //the outer hash is the final hmac + sha512(hmac, padded_hash, SHA512_BLOCK_LEN + SHA512_DIGEST_LEN); + + free(padded_msg); return; }