From c2cf1fb708119fe7ff4afb30159513aa0395b47b Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 27 Jun 2012 10:34:43 -0700 Subject: [PATCH] added HMAC-SHA-384 --- ctaocrypt/src/hmac.c | 85 ++++++++++++++++++++++++++++++++--------- cyassl/ctaocrypt/hmac.h | 19 +++++++-- 2 files changed, 82 insertions(+), 22 deletions(-) diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 1f777ab5b..298a4461a 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -34,7 +34,7 @@ static int InitHmac(Hmac* hmac, int type) hmac->innerHashKeyed = 0; hmac->macType = (byte)type; - if (!(type == MD5 || type == SHA || type == SHA256)) + if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384)) return BAD_FUNC_ARG; if (type == MD5) @@ -45,6 +45,10 @@ static int InitHmac(Hmac* hmac, int type) else if (type == SHA256) InitSha256(&hmac->hash.sha256); #endif +#ifdef CYASSL_SHA384 + else if (type == SHA384) + InitSha384(&hmac->hash.sha384); +#endif return 0; } @@ -54,34 +58,58 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) { byte* ip = (byte*) hmac->ipad; byte* op = (byte*) hmac->opad; - word32 i; + word32 i, hmac_block_size = MD5_BLOCK_SIZE; InitHmac(hmac, type); - if (length <= HMAC_BLOCK_SIZE) - XMEMCPY(ip, key, length); - else { - if (hmac->macType == MD5) { + if (hmac->macType == MD5) { + if (length <= MD5_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { Md5Update(&hmac->hash.md5, key, length); Md5Final(&hmac->hash.md5, ip); length = MD5_DIGEST_SIZE; } - else if (hmac->macType == SHA) { + } + else if (hmac->macType == SHA) { + if (length <= MD5_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { ShaUpdate(&hmac->hash.sha, key, length); ShaFinal(&hmac->hash.sha, ip); length = SHA_DIGEST_SIZE; } + } #ifndef NO_SHA256 - else if (hmac->macType == SHA256) { + else if (hmac->macType == SHA256) { + if (length <= MD5_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { Sha256Update(&hmac->hash.sha256, key, length); Sha256Final(&hmac->hash.sha256, ip); length = SHA256_DIGEST_SIZE; } -#endif } - XMEMSET(ip + length, 0, HMAC_BLOCK_SIZE - length); +#endif +#ifdef CYASSL_SHA384 + else if (hmac->macType == SHA384) { + hmac_block_size = SHA384_BLOCK_SIZE; + if (length <= SHA384_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { + Sha384Update(&hmac->hash.sha384, key, length); + Sha384Final(&hmac->hash.sha384, ip); + length = SHA384_DIGEST_SIZE; + } + } +#endif + XMEMSET(ip + length, 0, hmac_block_size - length); - for(i = 0; i < HMAC_BLOCK_SIZE; i++) { + for(i = 0; i < hmac_block_size; i++) { op[i] = ip[i] ^ OPAD; ip[i] ^= IPAD; } @@ -91,12 +119,16 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) static void HmacKeyInnerHash(Hmac* hmac) { if (hmac->macType == MD5) - Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); + Md5Update(&hmac->hash.md5, (byte*) hmac->ipad, MD5_BLOCK_SIZE); else if (hmac->macType == SHA) - ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); + ShaUpdate(&hmac->hash.sha, (byte*) hmac->ipad, MD5_BLOCK_SIZE); #ifndef NO_SHA256 else if (hmac->macType == SHA256) - Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, HMAC_BLOCK_SIZE); + Sha256Update(&hmac->hash.sha256, (byte*) hmac->ipad, MD5_BLOCK_SIZE); +#endif +#ifdef CYASSL_SHA384 + else if (hmac->macType == SHA384) + Sha384Update(&hmac->hash.sha384, (byte*) hmac->ipad, SHA384_BLOCK_SIZE); #endif hmac->innerHashKeyed = 1; @@ -116,6 +148,10 @@ void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) else if (hmac->macType == SHA256) Sha256Update(&hmac->hash.sha256, msg, length); #endif +#ifdef CYASSL_SHA384 + else if (hmac->macType == SHA384) + Sha384Update(&hmac->hash.sha384, msg, length); +#endif } @@ -128,30 +164,41 @@ void HmacFinal(Hmac* hmac, byte* hash) if (hmac->macType == MD5) { Md5Final(&hmac->hash.md5, (byte*) hmac->innerHash); - Md5Update(&hmac->hash.md5, (byte*) hmac->opad, HMAC_BLOCK_SIZE); + Md5Update(&hmac->hash.md5, (byte*) hmac->opad, MD5_BLOCK_SIZE); Md5Update(&hmac->hash.md5, (byte*) hmac->innerHash, MD5_DIGEST_SIZE); Md5Final(&hmac->hash.md5, hash); } - else if (hmac->macType ==SHA) { + else if (hmac->macType == SHA) { ShaFinal(&hmac->hash.sha, (byte*) hmac->innerHash); - ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, HMAC_BLOCK_SIZE); + ShaUpdate(&hmac->hash.sha, (byte*) hmac->opad, MD5_BLOCK_SIZE); ShaUpdate(&hmac->hash.sha, (byte*) hmac->innerHash, SHA_DIGEST_SIZE); ShaFinal(&hmac->hash.sha, hash); } #ifndef NO_SHA256 - else if (hmac->macType ==SHA256) { + else if (hmac->macType == SHA256) { Sha256Final(&hmac->hash.sha256, (byte*) hmac->innerHash); - Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, HMAC_BLOCK_SIZE); + Sha256Update(&hmac->hash.sha256, (byte*) hmac->opad, MD5_BLOCK_SIZE); Sha256Update(&hmac->hash.sha256, (byte*) hmac->innerHash, SHA256_DIGEST_SIZE); Sha256Final(&hmac->hash.sha256, hash); } #endif +#ifdef CYASSL_SHA384 + else if (hmac->macType == SHA384) { + Sha384Final(&hmac->hash.sha384, (byte*) hmac->innerHash); + + Sha384Update(&hmac->hash.sha384, (byte*) hmac->opad, SHA384_BLOCK_SIZE); + Sha384Update(&hmac->hash.sha384, (byte*) hmac->innerHash, + SHA384_DIGEST_SIZE); + + Sha384Final(&hmac->hash.sha384, hash); + } +#endif hmac->innerHashKeyed = 0; } diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index 6f022748b..0fa175e89 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -32,6 +32,10 @@ #include #endif +#ifdef CYASSL_SHA384 + #include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -40,13 +44,19 @@ enum { IPAD = 0x36, OPAD = 0x5C, -#ifndef NO_SHA256 +#if defined(CYASSL_SHA384) + INNER_HASH_SIZE = SHA384_DIGEST_SIZE, + HMAC_BLOCK_SIZE = SHA384_BLOCK_SIZE +#elif !defined(NO_SHA256) INNER_HASH_SIZE = SHA256_DIGEST_SIZE, + HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE + SHA384 = 5, #else INNER_HASH_SIZE = SHA_DIGEST_SIZE, - SHA256 = 2, /* hash type unique */ -#endif HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE + SHA256 = 2, /* hash type unique */ + SHA384 = 5, +#endif }; @@ -57,6 +67,9 @@ typedef union { #ifndef NO_SHA256 Sha256 sha256; #endif + #ifdef CYASSL_SHA384 + Sha384 sha384; + #endif } Hash; /* Hmac digest */