tied SHA-384 into TLSv1.2 as appropriate

This commit is contained in:
John Safranek 2012-06-27 14:41:16 -07:00
parent c2cf1fb708
commit 00cda6ab72
5 changed files with 79 additions and 38 deletions

View File

@ -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);

View File

@ -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
};

View File

@ -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
}
}

View File

@ -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;

View File

@ -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
{