From 00cda6ab7200fa3d5de14dfaa30552bb648f6690 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 27 Jun 2012 14:41:16 -0700 Subject: [PATCH] tied SHA-384 into TLSv1.2 as appropriate --- ctaocrypt/src/aes.c | 2 -- cyassl/ctaocrypt/hmac.h | 8 ++--- src/internal.c | 11 ++++-- src/keys.c | 20 +++++------ src/tls.c | 76 ++++++++++++++++++++++++++++++----------- 5 files changed, 79 insertions(+), 38 deletions(-) diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index 6df52836f..ea815bc63 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -1633,8 +1633,6 @@ int AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, c += AES_BLOCK_SIZE; } if (partial != 0) { - byte pPartial[AES_BLOCK_SIZE]; - IncrementGcmCounter(ctr); AesEncrypt(aes, ctr, scratch); xorbuf(scratch, c, partial); diff --git a/cyassl/ctaocrypt/hmac.h b/cyassl/ctaocrypt/hmac.h index 0fa175e89..a927e7ed7 100644 --- a/cyassl/ctaocrypt/hmac.h +++ b/cyassl/ctaocrypt/hmac.h @@ -49,13 +49,13 @@ enum { HMAC_BLOCK_SIZE = SHA384_BLOCK_SIZE #elif !defined(NO_SHA256) INNER_HASH_SIZE = SHA256_DIGEST_SIZE, - HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE - SHA384 = 5, + HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE, + SHA384 = 5 #else INNER_HASH_SIZE = SHA_DIGEST_SIZE, - HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE + HMAC_BLOCK_SIZE = MD5_BLOCK_SIZE, SHA256 = 2, /* hash type unique */ - SHA384 = 5, + SHA384 = 5 #endif }; diff --git a/src/internal.c b/src/internal.c index 9e375a12d..8ea543476 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1631,12 +1631,17 @@ static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) Sha sha = ssl->hashSha; #ifndef NO_SHA256 Sha256 sha256; +#endif +#if CYASSL_SHA384 + Sha384 sha384; +#endif + +#ifndef NO_SHA256 InitSha256(&sha256); if (IsAtLeastTLSv1_2(ssl)) sha256 = ssl->hashSha256; #endif #if CYASSL_SHA384 - Sha384 sha384; InitSha384(&sha384); if (IsAtLeastTLSv1_2(ssl)) sha384 = ssl->hashSha384; @@ -1652,14 +1657,14 @@ static void BuildFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) /* restore */ ssl->hashMd5 = md5; ssl->hashSha = sha; + if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 - if (IsAtLeastTLSv1_2(ssl)) ssl->hashSha256 = sha256; #endif #ifdef CYASSL_SHA384 - if (IsAtLeastTLSv1_2(ssl)) ssl->hashSha384 = sha384; #endif + } } diff --git a/src/keys.c b/src/keys.c index 02266b0d6..84f4deae9 100644 --- a/src/keys.c +++ b/src/keys.c @@ -315,7 +315,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha256_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = rsa_sa_algo; ssl->specs.hash_size = SHA256_DIGEST_SIZE; @@ -332,7 +332,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha384_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = rsa_sa_algo; ssl->specs.hash_size = SHA384_DIGEST_SIZE; @@ -349,7 +349,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha256_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = ecc_dsa_sa_algo; ssl->specs.hash_size = SHA256_DIGEST_SIZE; @@ -366,7 +366,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha384_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = ecc_dsa_sa_algo; ssl->specs.hash_size = SHA384_DIGEST_SIZE; @@ -383,7 +383,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha256_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = rsa_sa_algo; ssl->specs.hash_size = SHA256_DIGEST_SIZE; @@ -400,7 +400,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha384_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = rsa_sa_algo; ssl->specs.hash_size = SHA384_DIGEST_SIZE; @@ -417,7 +417,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha256_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = ecc_dsa_sa_algo; ssl->specs.hash_size = SHA256_DIGEST_SIZE; @@ -434,7 +434,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha384_mac; ssl->specs.kea = ecc_diffie_hellman_kea; ssl->specs.sig_algo = ecc_dsa_sa_algo; ssl->specs.hash_size = SHA384_DIGEST_SIZE; @@ -786,7 +786,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_RSA_WITH_AES_128_GCM_SHA256 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha256_mac; ssl->specs.kea = rsa_kea; ssl->specs.hash_size = SHA256_DIGEST_SIZE; ssl->specs.pad_size = PAD_SHA; @@ -802,7 +802,7 @@ int SetCipherSpecs(CYASSL* ssl) case TLS_RSA_WITH_AES_256_GCM_SHA384 : ssl->specs.bulk_cipher_algorithm = aes_gcm; ssl->specs.cipher_type = aead; - ssl->specs.mac_algorithm = no_mac; + ssl->specs.mac_algorithm = sha384_mac; ssl->specs.kea = rsa_kea; ssl->specs.hash_size = SHA384_DIGEST_SIZE; ssl->specs.pad_size = PAD_SHA; diff --git a/src/tls.c b/src/tls.c index 447f0d819..c14af1e5b 100644 --- a/src/tls.c +++ b/src/tls.c @@ -53,28 +53,52 @@ static INLINE void get_xor(byte *digest, word32 digLen, byte* md5, byte* sha) } +#ifdef CYASSL_SHA384 + #define PHASH_MAX_DIGEST_SIZE SHA384_DIGEST_SIZE +#else + #define PHASH_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE +#endif -/* compute p_hash for MD5, SHA-1, or SHA-256 for TLSv1 PRF */ +/* compute p_hash for MD5, SHA-1, SHA-256, or SHA-384 for TLSv1 PRF */ static void p_hash(byte* result, word32 resLen, const byte* secret, word32 secLen, const byte* seed, word32 seedLen, int hash) { - word32 len = hash == md5_mac ? MD5_DIGEST_SIZE : hash == sha_mac ? - SHA_DIGEST_SIZE : SHA256_DIGEST_SIZE; - word32 times = resLen / len; - word32 lastLen = resLen % len; + word32 len; + word32 times; + word32 lastLen; word32 lastTime; word32 i; word32 idx = 0; - byte previous[SHA256_DIGEST_SIZE]; /* max size */ - byte current[SHA256_DIGEST_SIZE]; /* max size */ + byte previous[PHASH_MAX_DIGEST_SIZE]; /* max size */ + byte current[PHASH_MAX_DIGEST_SIZE]; /* max size */ Hmac hmac; + if (hash == md5_mac) { + len = MD5_DIGEST_SIZE; + hash = MD5; + } + else if (hash == sha_mac) { + len = SHA_DIGEST_SIZE; + hash = SHA; + } else if (hash == sha256_mac) { + len = SHA256_DIGEST_SIZE; + hash = SHA256; + } +#ifdef CYASSL_SHA384 + else if (hash == sha384_mac) + { + len = SHA384_DIGEST_SIZE; + hash = SHA384; + } +#endif + + times = resLen / len; + lastLen = resLen % len; if (lastLen) times += 1; lastTime = times - 1; - HmacSetKey(&hmac, hash == md5_mac ? MD5 : hash == sha_mac ? SHA : SHA256, - secret, secLen); + HmacSetKey(&hmac, hash, secret, secLen); HmacUpdate(&hmac, seed, seedLen); /* A0 = seed */ HmacFinal(&hmac, previous); /* A1 */ @@ -99,7 +123,7 @@ static void p_hash(byte* result, word32 resLen, const byte* secret, /* compute TLSv1 PRF (pseudo random function using HMAC) */ static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, const byte* label, word32 labLen, const byte* seed, word32 seedLen, - int useSha256) + int useAtLeastSha256, int hash_type) { word32 half = (secLen + 1) / 2; @@ -122,9 +146,13 @@ static void PRF(byte* digest, word32 digLen, const byte* secret, word32 secLen, XMEMCPY(labelSeed, label, labLen); XMEMCPY(labelSeed + labLen, seed, seedLen); - if (useSha256) { + if (useAtLeastSha256) { + /* If a cipher suite wants an algorithm better than sha256, it + * should use better. */ + if (hash_type < sha256_mac) + hash_type = sha256_mac; p_hash(digest, digLen, secret, secLen, labelSeed, labLen + seedLen, - sha256_mac); + hash_type); return; } @@ -144,12 +172,20 @@ void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) Md5Final(&ssl->hashMd5, handshake_hash); ShaFinal(&ssl->hashSha, &handshake_hash[MD5_DIGEST_SIZE]); -#ifndef NO_SHA256 if (IsAtLeastTLSv1_2(ssl)) { - Sha256Final(&ssl->hashSha256, handshake_hash); - hashSz = SHA256_DIGEST_SIZE; - } +#ifndef NO_SHA256 + if (ssl->specs.mac_algorithm <= sha256_mac) { + Sha256Final(&ssl->hashSha256, handshake_hash); + hashSz = SHA256_DIGEST_SIZE; + } #endif +#ifdef CYASSL_SHA384 + if (ssl->specs.mac_algorithm == sha384_mac) { + Sha384Final(&ssl->hashSha384, handshake_hash); + hashSz = SHA384_DIGEST_SIZE; + } +#endif + } if ( XSTRNCMP((const char*)sender, (const char*)client, SIZEOF_SENDER) == 0) side = tls_client; @@ -157,7 +193,8 @@ void BuildTlsFinished(CYASSL* ssl, Hashes* hashes, const byte* sender) side = tls_server; PRF(hashes->md5, TLS_FINISHED_SZ, ssl->arrays.masterSecret, SECRET_LEN, - side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl)); + side, FINISHED_LABEL_SZ, handshake_hash, hashSz, IsAtLeastTLSv1_2(ssl), + ssl->specs.mac_algorithm); } @@ -207,7 +244,8 @@ int DeriveTlsKeys(CYASSL* ssl) XMEMCPY(&seed[RAN_LEN], ssl->arrays.clientRandom, RAN_LEN); PRF(key_data, length, ssl->arrays.masterSecret, SECRET_LEN, key_label, - KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl)); + KEY_LABEL_SZ, seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), + ssl->specs.mac_algorithm); return StoreKeys(ssl, key_data); } @@ -223,7 +261,7 @@ int MakeTlsMasterSecret(CYASSL* ssl) PRF(ssl->arrays.masterSecret, SECRET_LEN, ssl->arrays.preMasterSecret, ssl->arrays.preMasterSz, master_label, MASTER_LABEL_SZ, - seed, SEED_LEN, IsAtLeastTLSv1_2(ssl)); + seed, SEED_LEN, IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm); #ifdef SHOW_SECRETS {