From c039b0106a75cdf102d22c4397ddc06006ca9bb2 Mon Sep 17 00:00:00 2001 From: toddouska Date: Wed, 23 Oct 2013 17:13:54 -0700 Subject: [PATCH] add HC-128 Blake2b 256 cipher suite for speed test --- ctaocrypt/src/hmac.c | 53 ++++++++++++++++++++++- ctaocrypt/test/test.c | 90 +++++++++++++++++++++++++++++++++++++++ cyassl/ctaocrypt/blake2.h | 3 +- cyassl/ctaocrypt/hmac.h | 13 ++++++ cyassl/internal.h | 10 ++++- src/internal.c | 20 +++++++++ src/keys.c | 17 ++++++++ src/ssl.c | 4 ++ src/tls.c | 7 +++ tests/test.conf | 24 +++++++++++ 10 files changed, 236 insertions(+), 5 deletions(-) diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 9b03087f4..44de41e64 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -43,8 +43,8 @@ static int InitHmac(Hmac* hmac, int type) hmac->innerHashKeyed = 0; hmac->macType = (byte)type; - if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 - || type == SHA512)) + if (!(type == MD5 || type == SHA || type == SHA256 || type == SHA384 + || type == SHA512 || type == BLAKE2B_ID)) return BAD_FUNC_ARG; switch (type) { @@ -78,6 +78,12 @@ static int InitHmac(Hmac* hmac, int type) break; #endif + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); + break; + #endif + default: break; } @@ -180,6 +186,22 @@ void HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) break; #endif + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + { + hmac_block_size = BLAKE2B_BLOCKBYTES; + if (length <= BLAKE2B_BLOCKBYTES) { + XMEMCPY(ip, key, length); + } + else { + Blake2bUpdate(&hmac->hash.blake2b, key, length); + Blake2bFinal(&hmac->hash.blake2b, ip, BLAKE2B_256); + length = BLAKE2B_256; + } + } + break; + #endif + default: break; } @@ -229,6 +251,13 @@ static void HmacKeyInnerHash(Hmac* hmac) break; #endif + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + Blake2bUpdate(&hmac->hash.blake2b, + (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES); + break; + #endif + default: break; } @@ -278,6 +307,12 @@ void HmacUpdate(Hmac* hmac, const byte* msg, word32 length) break; #endif + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + Blake2bUpdate(&hmac->hash.blake2b, msg, length); + break; + #endif + default: break; } @@ -369,6 +404,20 @@ void HmacFinal(Hmac* hmac, byte* hash) break; #endif + #ifdef HAVE_BLAKE2 + case BLAKE2B_ID: + { + Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, + BLAKE2B_256); + Blake2bUpdate(&hmac->hash.blake2b, + (byte*) hmac->opad, BLAKE2B_BLOCKBYTES); + Blake2bUpdate(&hmac->hash.blake2b, + (byte*) hmac->innerHash, BLAKE2B_256); + Blake2bFinal(&hmac->hash.blake2b, hash, BLAKE2B_256); + } + break; + #endif + default: break; } diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index e049ff546..4cf89c5cb 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -134,6 +134,7 @@ int hmac_sha_test(void); int hmac_sha256_test(void); int hmac_sha384_test(void); int hmac_sha512_test(void); +int hmac_blake2b_test(void); int arc4_test(void); int hc128_test(void); int rabbit_test(void); @@ -301,6 +302,13 @@ void ctaocrypt_test(void* args) printf( "HMAC-SHA512 test passed!\n"); #endif + #ifdef HAVE_BLAKE2 + if ( (ret = hmac_blake2b_test()) != 0) + err_sys("HMAC-BLAKE2 test failed!\n", ret); + else + printf( "HMAC-BLAKE2 test passed!\n"); + #endif + #endif #ifdef HAVE_AESGCM @@ -1223,6 +1231,88 @@ int hmac_sha256_test(void) #endif +#if !defined(NO_HMAC) && defined(HAVE_BLAKE2) +int hmac_blake2b_test(void) +{ + Hmac hmac; + byte hash[BLAKE2B_256]; + + 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 = "\x72\x93\x0d\xdd\xf5\xf7\xe1\x78\x38\x07\x44\x18\x0b\x3f\x51" + "\x37\x25\xb5\x82\xc2\x08\x83\x2f\x1c\x99\xfd\x03\xa0\x16\x75" + "\xac\xfd"; + a.inLen = strlen(a.input); + a.outLen = BLAKE2B_256; + + b.input = "what do ya want for nothing?"; + b.output = "\x3d\x20\x50\x71\x05\xc0\x8c\x0c\x38\x44\x1e\xf7\xf9\xd1\x67" + "\x21\xff\x64\xf5\x94\x00\xcf\xf9\x75\x41\xda\x88\x61\x9d\x7c" + "\xda\x2b"; + b.inLen = strlen(b.input); + b.outLen = BLAKE2B_256; + + 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 = "\xda\xfe\x2a\x24\xfc\xe7\xea\x36\x34\xbe\x41\x92\xc7\x11\xa7" + "\x00\xae\x53\x9c\x11\x9c\x80\x74\x55\x22\x25\x4a\xb9\x55\xd3" + "\x0f\x87"; + c.inLen = strlen(c.input); + c.outLen = BLAKE2B_256; + + test_hmac[0] = a; + test_hmac[1] = b; + test_hmac[2] = c; + + for (i = 0; i < times; ++i) { +#ifdef HAVE_CAVIUM + if (i == 1) + continue; /* driver can't handle keys <= bytes */ + if (HmacInitCavium(&hmac, CAVIUM_DEV_ID) != 0) + return -20011; +#endif + HmacSetKey(&hmac, BLAKE2B_ID, (byte*)keys[i], (word32)strlen(keys[i])); + HmacUpdate(&hmac, (byte*)test_hmac[i].input, + (word32)test_hmac[i].inLen); + HmacFinal(&hmac, hash); + + { + int z; + for (z = 0; z < 32; z ++) { + printf("%02x ", hash[z]); + if ( (z%16) == 15) + printf("\n"); + } + printf("\n"); + } + + if (memcmp(hash, test_hmac[i].output, BLAKE2B_256) != 0) + return -20 - i; +#ifdef HAVE_CAVIUM + HmacFreeCavium(&hmac); +#endif + } + + return 0; +} +#endif + + #if !defined(NO_HMAC) && defined(CYASSL_SHA384) int hmac_sha384_test(void) { diff --git a/cyassl/ctaocrypt/blake2.h b/cyassl/ctaocrypt/blake2.h index a506b83da..381471a9c 100644 --- a/cyassl/ctaocrypt/blake2.h +++ b/cyassl/ctaocrypt/blake2.h @@ -33,7 +33,8 @@ /* in bytes, variable digest size up to 512 bits (64 bytes) */ enum { - BLAKE2B_ID = 7 /* hash type unique */ + BLAKE2B_ID = 7, /* hash type unique */ + BLAKE2B_256 = 32 /* 256 bit type, SSL default */ }; diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index 8a71450a7..47daf2794 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -43,6 +43,10 @@ #include #endif +#ifdef HAVE_BLAKE2 + #include +#endif + #ifdef HAVE_CAVIUM #include #include "cavium_common.h" @@ -75,11 +79,17 @@ enum { #ifndef CYASSL_SHA384 SHA384 = 5, #endif +#ifndef HAVE_BLAKE2 + BLAKE2B_ID = 7, +#endif /* Select the largest available hash for the buffer size. */ #if defined(CYASSL_SHA512) MAX_DIGEST_SIZE = SHA512_DIGEST_SIZE, HMAC_BLOCK_SIZE = SHA512_BLOCK_SIZE +#elif defined(HAVE_BLAKE2) + MAX_DIGEST_SIZE = BLAKE2B_OUTBYTES, + HMAC_BLOCK_SIZE = BLAKE2B_BLOCKBYTES, #elif defined(CYASSL_SHA384) MAX_DIGEST_SIZE = SHA384_DIGEST_SIZE, HMAC_BLOCK_SIZE = SHA384_BLOCK_SIZE @@ -115,6 +125,9 @@ typedef union { #ifdef CYASSL_SHA512 Sha512 sha512; #endif + #ifdef HAVE_BLAKE2 + Blake2b blake2b; + #endif } Hash; /* Hmac digest */ diff --git a/cyassl/internal.h b/cyassl/internal.h index 35bea43bb..231cc03b1 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -255,6 +255,9 @@ void c32to24(word32 in, word24 out); #if !defined(NO_SHA) #define BUILD_TLS_RSA_WITH_HC_128_CBC_SHA #endif + #if defined(HAVE_BLAKE2) + #define BUILD_TLS_RSA_WITH_HC_128_CBC_B2B256 + #endif #endif #if !defined(NO_RABBIT) && !defined(NO_TLS) && !defined(NO_RSA) @@ -383,7 +386,8 @@ void c32to24(word32 in, word24 out); #endif #if defined(BUILD_TLS_RSA_WITH_HC_128_CBC_SHA) || \ - defined(BUILD_TLS_RSA_WITH_HC_128_CBC_MD5) + defined(BUILD_TLS_RSA_WITH_HC_128_CBC_MD5) || \ + defined(BUILD_TLS_RSA_WITH_HC_128_CBC_B2B256) #define BUILD_HC128 #endif @@ -462,6 +466,7 @@ enum { TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0x26, /* CyaSSL extension - eSTREAM */ + TLS_RSA_WITH_HC_128_CBC_B2B256 = 0xFA, TLS_RSA_WITH_HC_128_CBC_MD5 = 0xFB, TLS_RSA_WITH_HC_128_CBC_SHA = 0xFC, TLS_RSA_WITH_RABBIT_CBC_SHA = 0xFD, @@ -1282,7 +1287,8 @@ enum MACAlgorithm { sha256_mac, sha384_mac, sha512_mac, - rmd_mac + rmd_mac, + blake2b_mac }; diff --git a/src/internal.c b/src/internal.c index 7d5cb9d8e..6a4357544 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1105,6 +1105,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, } #endif +#ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_B2B256 + if (tls && haveRSA) { + suites->suites[idx++] = 0; + suites->suites[idx++] = TLS_RSA_WITH_HC_128_CBC_B2B256; + } +#endif + #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA if (tls && haveRSA) { suites->suites[idx++] = 0; @@ -6142,6 +6149,10 @@ const char* const cipher_names[] = "HC128-SHA", #endif +#ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_B2B256 + "HC128-B2B256", +#endif + #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA "RABBIT-SHA", #endif @@ -6450,6 +6461,10 @@ int cipher_name_idx[] = TLS_RSA_WITH_HC_128_CBC_SHA, #endif +#ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_B2B256 + TLS_RSA_WITH_HC_128_CBC_B2B256, +#endif + #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA TLS_RSA_WITH_RABBIT_CBC_SHA, #endif @@ -9305,6 +9320,11 @@ static void PickHashSigAlgo(CYASSL* ssl, return 1; break; + case TLS_RSA_WITH_HC_128_CBC_B2B256: + if (requirement == REQUIRES_RSA) + return 1; + break; + case TLS_RSA_WITH_RABBIT_CBC_SHA : if (requirement == REQUIRES_RSA) return 1; diff --git a/src/keys.c b/src/keys.c index f19cb8620..0ccec8498 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1122,6 +1122,23 @@ int SetCipherSpecs(CYASSL* ssl) break; #endif +#ifdef BUILD_TLS_RSA_WITH_HC_128_CBC_B2B256 + case TLS_RSA_WITH_HC_128_CBC_B2B256: + ssl->specs.bulk_cipher_algorithm = cyassl_hc128; + ssl->specs.cipher_type = stream; + ssl->specs.mac_algorithm = blake2b_mac; + ssl->specs.kea = rsa_kea; + ssl->specs.sig_algo = rsa_sa_algo; + ssl->specs.hash_size = BLAKE2B_256; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = HC_128_KEY_SIZE; + ssl->specs.block_size = 0; + ssl->specs.iv_size = HC_128_IV_SIZE; + + break; +#endif + #ifdef BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA case TLS_RSA_WITH_RABBIT_CBC_SHA : ssl->specs.bulk_cipher_algorithm = cyassl_rabbit; diff --git a/src/ssl.c b/src/ssl.c index 39875ffb8..3397c9f2c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -7581,6 +7581,10 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format) case TLS_RSA_WITH_HC_128_CBC_SHA : return "TLS_RSA_WITH_HC_128_CBC_SHA"; #endif + #ifdef HAVE_BLAKE2 + case TLS_RSA_WITH_HC_128_CBC_B2B256: + return "TLS_RSA_WITH_HC_128_CBC_B2B256"; + #endif #endif /* NO_HC128 */ #ifndef NO_SHA #ifndef NO_RABBIT diff --git a/src/tls.c b/src/tls.c index 805ae45b4..ab139c7ff 100644 --- a/src/tls.c +++ b/src/tls.c @@ -455,6 +455,13 @@ int CyaSSL_GetHmacType(CYASSL* ssl) } break; #endif + #ifdef HAVE_BLAKE2 + case blake2b_mac: + { + return BLAKE2B_ID; + } + break; + #endif default: { return SSL_FATAL_ERROR; diff --git a/tests/test.conf b/tests/test.conf index 987786308..87f73211f 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -766,6 +766,14 @@ -v 1 -l HC128-MD5 +# server TLSv1 HC128-B2B256 +-v 1 +-l HC128-B2B256 + +# client TLSv1 HC128-B2B256 +-v 1 +-l HC128-B2B256 + # server TLSv1.1 HC128-SHA -v 2 -l HC128-SHA @@ -782,6 +790,14 @@ -v 2 -l HC128-MD5 +# server TLSv1.1 HC128-B2B256 +-v 2 +-l HC128-B2B256 + +# client TLSv1.1 HC128-B2B256 +-v 2 +-l HC128-B2B256 + # server TLSv1.2 HC128-SHA -v 3 -l HC128-SHA @@ -798,6 +814,14 @@ -v 3 -l HC128-MD5 +# server TLSv1.2 HC128-B2B256 +-v 3 +-l HC128-B2B256 + +# client TLSv1.2 HC128-B2B256 +-v 3 +-l HC128-B2B256 + # server TLSv1 RABBIT-SHA -v 1 -l RABBIT-SHA