From 7d7a72f2a66e6f1df34b271b5c5ad4733cb952f3 Mon Sep 17 00:00:00 2001 From: toddouska Date: Wed, 20 Mar 2013 12:26:55 -0700 Subject: [PATCH] add hmac sha512 --- ctaocrypt/src/hmac.c | 53 +++++++++++++++++++++++++++- ctaocrypt/test/test.c | 77 +++++++++++++++++++++++++++++++++++++++++ cyassl/ctaocrypt/hmac.h | 10 +++++- mcapi/crypto.h | 2 +- 4 files changed, 139 insertions(+), 3 deletions(-) diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 2ed820ee3..30b1badf6 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -42,7 +42,8 @@ static int InitHmac(Hmac* hmac, int type) hmac->innerHashKeyed = 0; hmac->macType = (byte)type; - if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384)) + if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 + || type == SHA512)) return BAD_FUNC_ARG; switch (type) { @@ -70,6 +71,12 @@ static int InitHmac(Hmac* hmac, int type) break; #endif + #ifdef CYASSL_SHA512 + case SHA512: + InitSha512(&hmac->hash.sha512); + break; + #endif + default: break; } @@ -156,6 +163,22 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) break; #endif + #ifdef CYASSL_SHA512 + case SHA512: + { + hmac_block_size = SHA512_BLOCK_SIZE; + if (length <= SHA512_BLOCK_SIZE) { + XMEMCPY(ip, key, length); + } + else { + Sha512Update(&hmac->hash.sha512, key, length); + Sha512Final(&hmac->hash.sha512, ip); + length = SHA512_DIGEST_SIZE; + } + } + break; + #endif + default: break; } @@ -198,6 +221,13 @@ static void HmacKeyInnerHash(Hmac* hmac) break; #endif + #ifdef CYASSL_SHA512 + case SHA512: + Sha512Update(&hmac->hash.sha512, + (byte*) hmac->ipad, SHA512_BLOCK_SIZE); + break; + #endif + default: break; } @@ -241,6 +271,12 @@ void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) break; #endif + #ifdef CYASSL_SHA512 + case SHA512: + Sha512Update(&hmac->hash.sha512, msg, length); + break; + #endif + default: break; } @@ -317,6 +353,21 @@ void HmacFinal(Hmac* hmac, byte* hash) break; #endif + #ifdef CYASSL_SHA512 + case SHA512: + { + Sha512Final(&hmac->hash.sha512, (byte*) hmac->innerHash); + + Sha512Update(&hmac->hash.sha512, + (byte*) hmac->opad, SHA512_BLOCK_SIZE); + Sha512Update(&hmac->hash.sha512, + (byte*) hmac->innerHash, SHA512_DIGEST_SIZE); + + Sha512Final(&hmac->hash.sha512, hash); + } + break; + #endif + default: break; } diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 5f7eba869..7da380252 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -119,6 +119,7 @@ int hmac_md5_test(void); int hmac_sha_test(void); int hmac_sha256_test(void); int hmac_sha384_test(void); +int hmac_sha512_test(void); int arc4_test(void); int hc128_test(void); int rabbit_test(void); @@ -268,6 +269,13 @@ void ctaocrypt_test(void* args) printf( "HMAC-SHA384 test passed!\n"); #endif + #ifdef CYASSL_SHA512 + if ( (ret = hmac_sha512_test()) ) + err_sys("HMAC-SHA512 test failed!\n", ret); + else + printf( "HMAC-SHA512 test passed!\n"); + #endif + #endif #ifndef NO_RC4 @@ -1180,6 +1188,75 @@ int hmac_sha384_test(void) #endif +#if !defined(NO_HMAC) && defined(CYASSL_SHA512) +int hmac_sha512_test(void) +{ + Hmac hmac; + byte hash[SHA512_DIGEST_SIZE]; + + const char* keys[]= + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA" + }; + + testVector a, b, c; + testVector test_hmac[3]; + + int times = sizeof(test_hmac) / sizeof(testVector), i; + + a.input = "Hi There"; + a.output = "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c" + "\xb0\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1" + "\x7c\xde\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae" + "\xa3\xf4\xe4\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20" + "\x3a\x12\x68\x54"; + a.inLen = strlen(a.input); + a.outLen = SHA512_DIGEST_SIZE; + + b.input = "what do ya want for nothing?"; + b.output = "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0" + "\xa3\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25" + "\x05\x54\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8" + "\xf0\xe6\xfd\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a" + "\x38\xbc\xe7\x37"; + b.inLen = strlen(b.input); + b.outLen = SHA512_DIGEST_SIZE; + + c.input = "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" + "\xDD\xDD\xDD\xDD\xDD\xDD"; + c.output = "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b" + "\xe9\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27" + "\x9d\x39\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e" + "\x67\xc8\x07\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59" + "\xe1\x32\x92\xfb"; + c.inLen = strlen(c.input); + c.outLen = SHA512_DIGEST_SIZE; + + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; + + for (i = 0; i < times; ++i) { + HmacSetKey(&hmac, SHA512, (byte*)keys[i], (word32)strlen(keys[i])); + HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + HmacFinal(&hmac, hash); + + if (memcmp(hash, test_hmac[i].output, SHA512_DIGEST_SIZE) != 0) + return -20 - i; + } + + return 0; +} +#endif + + #ifndef NO_RC4 int arc4_test(void) { diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index 89aaa81ca..7b8105a2f 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -57,17 +57,22 @@ enum { #ifdef NO_MD5 MD5 = 0, #endif -#if defined(CYASSL_SHA384) +#if defined(CYASSL_SHA512) + INNER_HASH_SIZE = SHA512_DIGEST_SIZE, + HMAC_BLOCK_SIZE = SHA512_BLOCK_SIZE +#elif 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 = SHA256_BLOCK_SIZE, + SHA512 = 4, SHA384 = 5 #else INNER_HASH_SIZE = SHA_DIGEST_SIZE, HMAC_BLOCK_SIZE = SHA_BLOCK_SIZE, SHA256 = 2, /* hash type unique */ + SHA512 = 4, SHA384 = 5 #endif }; @@ -87,6 +92,9 @@ typedef union { #ifdef CYASSL_SHA384 Sha384 sha384; #endif + #ifdef CYASSL_SHA512 + Sha512 sha512; + #endif } Hash; /* Hmac digest */ diff --git a/mcapi/crypto.h b/mcapi/crypto.h index 89c3f8d75..1cb1654d3 100644 --- a/mcapi/crypto.h +++ b/mcapi/crypto.h @@ -103,7 +103,7 @@ enum { /* HMAC */ typedef struct CRYPT_HMAC_CTX { - long long holder[65]; /* big enough to hold internal, but check on init */ + long long holder[67]; /* big enough to hold internal, but check on init */ } CRYPT_HMAC_CTX; int CRYPT_HMAC_SetKey(CRYPT_HMAC_CTX*, int, const unsigned char*, unsigned int);