forked from wolfSSL/wolfssl
TLS 1.3 and Integrity-only ciphersuites
This commit is contained in:
@ -1989,15 +1989,18 @@ void FreeCiphers(WOLFSSL* ssl)
|
||||
#ifdef BUILD_AES
|
||||
wc_AesFree(ssl->encrypt.aes);
|
||||
wc_AesFree(ssl->decrypt.aes);
|
||||
#if defined(BUILD_AESGCM) || defined(HAVE_AESCCM)
|
||||
#if (defined(BUILD_AESGCM) || defined(HAVE_AESCCM)) && \
|
||||
!defined(WOLFSSL_NO_TLS12)
|
||||
XFREE(ssl->decrypt.additional, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
XFREE(ssl->encrypt.additional, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
#endif
|
||||
XFREE(ssl->encrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
XFREE(ssl->decrypt.aes, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
#endif
|
||||
#ifdef CIPHER_NONCE
|
||||
XFREE(ssl->decrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
XFREE(ssl->encrypt.nonce, ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
XFREE(ssl->encrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
XFREE(ssl->decrypt.cam, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
@ -2021,6 +2024,12 @@ void FreeCiphers(WOLFSSL* ssl)
|
||||
XFREE(ssl->encrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
XFREE(ssl->decrypt.idea, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
|
||||
wc_HmacFree(ssl->encrypt.hmac);
|
||||
wc_HmacFree(ssl->decrypt.hmac);
|
||||
XFREE(ssl->encrypt.hmac, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
XFREE(ssl->decrypt.hmac, ssl->heap, DYNAMIC_TYPE_CIPHER);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2249,6 +2258,22 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA,
|
||||
suites->suites[idx++] = TLS_AES_128_CCM_8_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
#ifdef BUILD_TLS_SHA256_SHA256
|
||||
if (tls1_3) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_SHA256_SHA256;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_SHA384_SHA384
|
||||
if (tls1_3) {
|
||||
suites->suites[idx++] = ECC_BYTE;
|
||||
suites->suites[idx++] = TLS_SHA384_SHA384;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* WOLFSSL_TLS13 */
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
@ -8098,6 +8123,14 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender)
|
||||
return 1;
|
||||
break;
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
|
||||
case TLS_SHA256_SHA256:
|
||||
return 0;
|
||||
case TLS_SHA384_SHA384:
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unsupported cipher suite, CipherRequires ECC");
|
||||
return 0;
|
||||
@ -16452,6 +16485,14 @@ static const CipherSuiteInfo cipher_names[] =
|
||||
SUITE_INFO("TLS13-AES128-CCM-8-SHA256","TLS_AES_128_CCM_8_SHA256",TLS13_BYTE,TLS_AES_128_CCM_8_SHA256),
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_SHA256_SHA256
|
||||
SUITE_INFO("TLS13-SHA256-SHA256","TLS_SHA256_SHA256",ECC_BYTE,TLS_SHA256_SHA256),
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_SHA384_SHA384
|
||||
SUITE_INFO("TLS13-SHA384-SHA384","TLS_SHA384_SHA384",ECC_BYTE,TLS_SHA384_SHA384),
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
|
||||
#ifdef BUILD_SSL_RSA_WITH_RC4_128_SHA
|
||||
@ -17235,7 +17276,12 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz)
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
else if (ssl->specs.sig_algo == 0 && !IsAtLeastTLSv1_3(ssl->version)) {
|
||||
#if !defined(WOLFSSL_TLS13) || !defined(HAVE_NULL_CIPHER)
|
||||
else if (ssl->specs.sig_algo == 0 && IsAtLeastTLSv1_3(ssl->version)) {
|
||||
}
|
||||
#endif
|
||||
else if (ssl->specs.sig_algo == 0)
|
||||
{
|
||||
ssl->suites->hashAlgo = ssl->specs.mac_algorithm;
|
||||
ret = 0;
|
||||
}
|
||||
|
137
src/keys.c
137
src/keys.c
@ -239,7 +239,7 @@ int SetCipherSpecs(WOLFSSL* ssl)
|
||||
}
|
||||
}
|
||||
|
||||
/* ECC extensions, or AES-CCM */
|
||||
/* ECC extensions, AES-CCM or TLS 1.3 Integrity-only */
|
||||
if (ssl->options.cipherSuite0 == ECC_BYTE) {
|
||||
|
||||
switch (ssl->options.cipherSuite) {
|
||||
@ -1065,6 +1065,44 @@ int SetCipherSpecs(WOLFSSL* ssl)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
|
||||
#ifdef BUILD_TLS_SHA256_SHA256
|
||||
case TLS_SHA256_SHA256 :
|
||||
ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha256_mac;
|
||||
ssl->specs.kea = 0;
|
||||
ssl->specs.sig_algo = 0;
|
||||
ssl->specs.hash_size = WC_SHA256_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = WC_SHA256_DIGEST_SIZE / 2;
|
||||
ssl->specs.block_size = 0;
|
||||
ssl->specs.iv_size = HMAC_NONCE_SZ;
|
||||
ssl->specs.aead_mac_size = WC_SHA256_DIGEST_SIZE;
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_TLS_SHA384_SHA384
|
||||
case TLS_SHA384_SHA384 :
|
||||
ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null;
|
||||
ssl->specs.cipher_type = aead;
|
||||
ssl->specs.mac_algorithm = sha384_mac;
|
||||
ssl->specs.kea = 0;
|
||||
ssl->specs.sig_algo = 0;
|
||||
ssl->specs.hash_size = WC_SHA384_DIGEST_SIZE;
|
||||
ssl->specs.pad_size = PAD_SHA;
|
||||
ssl->specs.static_ecdh = 0;
|
||||
ssl->specs.key_size = WC_SHA384_DIGEST_SIZE / 2;
|
||||
ssl->specs.block_size = 0;
|
||||
ssl->specs.iv_size = HMAC_NONCE_SZ;
|
||||
ssl->specs.aead_mac_size = WC_SHA384_DIGEST_SIZE;
|
||||
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Unsupported cipher suite, SetCipherSpecs ECC");
|
||||
return UNSUPPORTED_SUITE;
|
||||
@ -2229,10 +2267,10 @@ static int SetPrefix(byte* sha_input, int idx)
|
||||
|
||||
|
||||
static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
int side, void* heap, int devId, WC_RNG* rng, int skipIv)
|
||||
int side, void* heap, int devId, WC_RNG* rng, int tls13)
|
||||
{
|
||||
(void)rng;
|
||||
(void)skipIv;
|
||||
(void)tls13;
|
||||
|
||||
#ifdef BUILD_ARC4
|
||||
if (specs->bulk_cipher_algorithm == wolfssl_rc4) {
|
||||
@ -2631,7 +2669,7 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
#if !defined(NO_PUBLIC_GCM_SET_IV) && \
|
||||
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
|
||||
if (!skipIv) {
|
||||
if (!tls13) {
|
||||
gcmRet = wc_AesGcmSetIV(enc->aes, AESGCM_NONCE_SZ,
|
||||
keys->client_write_IV, AESGCM_IMP_IV_SZ, rng);
|
||||
if (gcmRet != 0) return gcmRet;
|
||||
@ -2656,7 +2694,7 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
#if !defined(NO_PUBLIC_GCM_SET_IV) && \
|
||||
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
|
||||
if (!skipIv) {
|
||||
if (!tls13) {
|
||||
gcmRet = wc_AesGcmSetIV(enc->aes, AESGCM_NONCE_SZ,
|
||||
keys->server_write_IV, AESGCM_IMP_IV_SZ, rng);
|
||||
if (gcmRet != 0) return gcmRet;
|
||||
@ -2733,7 +2771,7 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
#if !defined(NO_PUBLIC_CCM_SET_NONCE) && \
|
||||
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
|
||||
if (!skipIv) {
|
||||
if (!tls13) {
|
||||
CcmRet = wc_AesCcmSetNonce(enc->aes, keys->client_write_IV,
|
||||
AEAD_MAX_IMP_SZ);
|
||||
if (CcmRet != 0) return CcmRet;
|
||||
@ -2762,7 +2800,7 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
#if !defined(NO_PUBLIC_CCM_SET_NONCE) && \
|
||||
((!defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)) || \
|
||||
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)))
|
||||
if (!skipIv) {
|
||||
if (!tls13) {
|
||||
CcmRet = wc_AesCcmSetNonce(enc->aes, keys->server_write_IV,
|
||||
AEAD_MAX_IMP_SZ);
|
||||
if (CcmRet != 0) return CcmRet;
|
||||
@ -2894,6 +2932,75 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
if (specs->bulk_cipher_algorithm == wolfssl_cipher_null) {
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if (tls13) {
|
||||
int hmacRet;
|
||||
int hashType = WC_HASH_TYPE_NONE;
|
||||
|
||||
switch (specs->mac_algorithm) {
|
||||
case sha256_mac:
|
||||
hashType = WC_SHA256;
|
||||
break;
|
||||
case sha384_mac:
|
||||
hashType = WC_SHA384;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (enc && enc->hmac == NULL) {
|
||||
enc->hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap,
|
||||
DYNAMIC_TYPE_CIPHER);
|
||||
}
|
||||
if (enc && enc->hmac == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
if (dec && dec->hmac == NULL) {
|
||||
dec->hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap,
|
||||
DYNAMIC_TYPE_CIPHER);
|
||||
}
|
||||
if (dec && dec->hmac == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
if (enc) {
|
||||
if (wc_HmacInit(enc->hmac, heap, devId) != 0) {
|
||||
WOLFSSL_MSG("HmacInit failed in SetKeys");
|
||||
return ASYNC_INIT_E;
|
||||
}
|
||||
}
|
||||
if (dec) {
|
||||
if (wc_HmacInit(dec->hmac, heap, devId) != 0) {
|
||||
WOLFSSL_MSG("HmacInit failed in SetKeys");
|
||||
return ASYNC_INIT_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (side == WOLFSSL_CLIENT_END) {
|
||||
if (enc) {
|
||||
hmacRet = wc_HmacSetKey(enc->hmac, hashType,
|
||||
keys->client_write_key, specs->key_size);
|
||||
if (hmacRet != 0) return hmacRet;
|
||||
}
|
||||
if (dec) {
|
||||
hmacRet = wc_HmacSetKey(dec->hmac, hashType,
|
||||
keys->server_write_key, specs->key_size);
|
||||
if (hmacRet != 0) return hmacRet;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (enc) {
|
||||
hmacRet = wc_HmacSetKey(enc->hmac, hashType,
|
||||
keys->server_write_key, specs->key_size);
|
||||
if (hmacRet != 0) return hmacRet;
|
||||
}
|
||||
if (dec) {
|
||||
hmacRet = wc_HmacSetKey(dec->hmac, hashType,
|
||||
keys->client_write_key, specs->key_size);
|
||||
if (hmacRet != 0) return hmacRet;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (enc)
|
||||
enc->setup = 1;
|
||||
if (dec)
|
||||
@ -3006,10 +3113,10 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("Provisioning ENCRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
|
||||
}
|
||||
#endif
|
||||
wc_encrypt = &ssl->encrypt;
|
||||
@ -3019,10 +3126,10 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("Provisioning DECRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
|
||||
}
|
||||
#endif
|
||||
wc_decrypt = &ssl->decrypt;
|
||||
@ -3032,17 +3139,17 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side)
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("Provisioning ENCRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
|
||||
}
|
||||
WOLFSSL_MSG("Provisioning DECRYPT key");
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END) {
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.server_write_key, ssl->specs.key_size);
|
||||
}
|
||||
else {
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, AES_256_KEY_SIZE);
|
||||
WOLFSSL_BUFFER(ssl->keys.client_write_key, ssl->specs.key_size);
|
||||
}
|
||||
#endif
|
||||
wc_encrypt = &ssl->encrypt;
|
||||
|
124
src/tls13.c
124
src/tls13.c
@ -1615,6 +1615,43 @@ static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
/* Create authenication tag and copy data over input.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* output The buffer to copy data into.
|
||||
* May be the same pointer as input.
|
||||
* input The data.
|
||||
* sz The number of bytes of data.
|
||||
* nonce The nonce to use with authentication.
|
||||
* aad The additional authentication data.
|
||||
* aadSz The size of the addition authentication data.
|
||||
* tag The authentication tag buffer.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Tls13IntegrityOnly_Encrypt(WOLFSSL* ssl, byte* output,
|
||||
const byte* input, word16 sz,
|
||||
const byte* nonce,
|
||||
const byte* aad, word16 aadSz, byte* tag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* HMAC: nonce | aad | input */
|
||||
ret = wc_HmacUpdate(ssl->encrypt.hmac, nonce, HMAC_NONCE_SZ);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(ssl->encrypt.hmac, aad, aadSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(ssl->encrypt.hmac, input, sz);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacFinal(ssl->encrypt.hmac, tag);
|
||||
/* Copy the input to output if not the same buffer */
|
||||
if (ret == 0 && output != input)
|
||||
XMEMCPY(output, input, sz);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Encrypt data for TLS v1.3.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
@ -1668,6 +1705,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CIPHER_NONCE
|
||||
if (ssl->encrypt.nonce == NULL)
|
||||
ssl->encrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ,
|
||||
ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
@ -1676,6 +1714,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
|
||||
|
||||
BuildTls13Nonce(ssl, ssl->encrypt.nonce, ssl->keys.aead_enc_imp_IV,
|
||||
CUR_ORDER);
|
||||
#endif
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->encrypt.state = CIPHER_STATE_DO;
|
||||
@ -1748,6 +1787,13 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
case wolfssl_cipher_null:
|
||||
ret = Tls13IntegrityOnly_Encrypt(ssl, output, input, dataSz,
|
||||
ssl->encrypt.nonce, aad, aadSz, output + dataSz);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("wolfSSL Encrypt programming error");
|
||||
return ENCRYPT_ERROR;
|
||||
@ -1773,16 +1819,20 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
|
||||
|
||||
case CIPHER_STATE_END:
|
||||
{
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
#ifdef CIPHER_NONCE
|
||||
WOLFSSL_MSG("Nonce");
|
||||
WOLFSSL_BUFFER(ssl->encrypt.nonce, ssl->specs.iv_size);
|
||||
#endif
|
||||
WOLFSSL_MSG("Encrypted data");
|
||||
WOLFSSL_BUFFER(output, dataSz);
|
||||
WOLFSSL_MSG("Authentication Tag");
|
||||
WOLFSSL_BUFFER(output + dataSz, macSz);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CIPHER_NONCE
|
||||
ForceZero(ssl->encrypt.nonce, AEAD_NONCE_SZ);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1853,6 +1903,48 @@ static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
/* Check HMAC tag and copy over input.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
* output The buffer to copy data into.
|
||||
* May be the same pointer as input.
|
||||
* input The data.
|
||||
* sz The number of bytes of data.
|
||||
* nonce The nonce to use with authentication.
|
||||
* aad The additional authentication data.
|
||||
* aadSz The size of the addition authentication data.
|
||||
* tagIn The authentication tag data from packet.
|
||||
* returns 0 on success, otherwise failure.
|
||||
*/
|
||||
static int Tls13IntegrityOnly_Decrypt(WOLFSSL* ssl, byte* output,
|
||||
const byte* input, word16 sz,
|
||||
const byte* nonce,
|
||||
const byte* aad, word16 aadSz,
|
||||
const byte* tagIn)
|
||||
{
|
||||
int ret;
|
||||
byte hmac[WC_MAX_DIGEST_SIZE];
|
||||
|
||||
/* HMAC: nonce | aad | input */
|
||||
ret = wc_HmacUpdate(ssl->decrypt.hmac, nonce, HMAC_NONCE_SZ);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(ssl->decrypt.hmac, aad, aadSz);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacUpdate(ssl->decrypt.hmac, input, sz);
|
||||
if (ret == 0)
|
||||
ret = wc_HmacFinal(ssl->decrypt.hmac, hmac);
|
||||
/* Check authentication tag matches */
|
||||
if (ret == 0 && XMEMCMP(tagIn, hmac, ssl->specs.hash_size) != 0)
|
||||
ret = DECRYPT_ERROR;
|
||||
/* Copy the input to output if not the same buffer */
|
||||
if (ret == 0 && output != input)
|
||||
XMEMCPY(output, input, sz);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Decrypt data for TLS v1.3.
|
||||
*
|
||||
* ssl The SSL/TLS object.
|
||||
@ -1915,6 +2007,7 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
|
||||
WOLFSSL_BUFFER(input + dataSz, macSz);
|
||||
#endif
|
||||
|
||||
#ifdef CIPHER_NONCE
|
||||
if (ssl->decrypt.nonce == NULL)
|
||||
ssl->decrypt.nonce = (byte*)XMALLOC(AEAD_NONCE_SZ,
|
||||
ssl->heap, DYNAMIC_TYPE_AES_BUFFER);
|
||||
@ -1923,6 +2016,7 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
|
||||
|
||||
BuildTls13Nonce(ssl, ssl->decrypt.nonce, ssl->keys.aead_dec_imp_IV,
|
||||
PEER_ORDER);
|
||||
#endif
|
||||
|
||||
/* Advance state and proceed */
|
||||
ssl->decrypt.state = CIPHER_STATE_DO;
|
||||
@ -1985,6 +2079,12 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
case wolfssl_cipher_null:
|
||||
ret = Tls13IntegrityOnly_Decrypt(ssl, output, input, dataSz,
|
||||
ssl->decrypt.nonce, aad, aadSz, input + dataSz);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
WOLFSSL_MSG("wolfSSL Decrypt programming error");
|
||||
return DECRYPT_ERROR;
|
||||
@ -2005,13 +2105,17 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
|
||||
case CIPHER_STATE_END:
|
||||
{
|
||||
#ifdef WOLFSSL_DEBUG_TLS
|
||||
WOLFSSL_MSG("Nonce");
|
||||
WOLFSSL_BUFFER(ssl->decrypt.nonce, ssl->specs.iv_size);
|
||||
WOLFSSL_MSG("Decrypted data");
|
||||
WOLFSSL_BUFFER(output, dataSz);
|
||||
#ifdef CIPHER_NONCE
|
||||
WOLFSSL_MSG("Nonce");
|
||||
WOLFSSL_BUFFER(ssl->decrypt.nonce, ssl->specs.iv_size);
|
||||
#endif
|
||||
WOLFSSL_MSG("Decrypted data");
|
||||
WOLFSSL_BUFFER(output, dataSz);
|
||||
#endif
|
||||
|
||||
#ifdef CIPHER_NONCE
|
||||
ForceZero(ssl->decrypt.nonce, AEAD_NONCE_SZ);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
@ -4168,6 +4272,14 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
if (ssl->options.cipherSuite0 == ECC_BYTE &&
|
||||
(ssl->options.cipherSuite == TLS_SHA256_SHA256 ||
|
||||
ssl->options.cipherSuite == TLS_SHA384_SHA384)) {
|
||||
;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* Check that the negotiated ciphersuite matches protocol version. */
|
||||
if (ssl->options.cipherSuite0 != TLS13_BYTE) {
|
||||
WOLFSSL_MSG("Negotiated ciphersuite from lesser version than "
|
||||
|
@ -648,7 +648,7 @@ static void test_for_double_Free(void)
|
||||
"ES128-CBC-SHA256:PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:DHE-PSK-CHA"
|
||||
"CHA20-POLY1305:EDH-RSA-DES-CBC3-SHA:TLS13-AES128-GCM-SHA256:TLS13-AES256-GCM-S"
|
||||
"HA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES128-CCM-SHA256:TLS13-AES128-CCM-"
|
||||
"8-SHA256";
|
||||
"8-SHA256:TLS13-SHA256-SHA256:TLS13-SHA384-SHA384";
|
||||
#ifndef NO_RSA
|
||||
testCertFile = svrCertFile;
|
||||
testKeyFile = svrKeyFile;
|
||||
|
@ -193,3 +193,19 @@
|
||||
-v 4
|
||||
-l TLS13-AES128-GCM-SHA256
|
||||
-Q
|
||||
|
||||
# server TLSv1.3 Integrity-only SHA256
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# client TLSv1.3 Integrity-only SHA256
|
||||
-v 4
|
||||
-l TLS13-SHA256-SHA256
|
||||
|
||||
# server TLSv1.3 Integrity-only SHA384
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
||||
# client TLSv1.3 Integrity-only SHA384
|
||||
-v 4
|
||||
-l TLS13-SHA384-SHA384
|
||||
|
@ -256,6 +256,8 @@
|
||||
#define BUILD_TLS_QSH
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
|
||||
#ifndef WOLFSSL_MAX_STRENGTH
|
||||
|
||||
#ifdef WOLFSSL_AEAD_ONLY
|
||||
@ -785,6 +787,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_TLS13)
|
||||
#ifdef HAVE_AESGCM
|
||||
#if !defined(NO_SHA256) && defined(WOLFSSL_AES_128)
|
||||
@ -807,6 +811,14 @@
|
||||
#define BUILD_TLS_AES_128_CCM_8_SHA256
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_NULL_CIPHER
|
||||
#ifndef NO_SHA256
|
||||
#define BUILD_TLS_SHA256_SHA256
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
#define BUILD_TLS_SHA384_SHA384
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_MULTICAST
|
||||
@ -841,7 +853,9 @@
|
||||
defined(BUILD_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384) || \
|
||||
defined(BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) || \
|
||||
defined(BUILD_TLS_PSK_WITH_AES_256_GCM_SHA384) || \
|
||||
defined(BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384)
|
||||
defined(BUILD_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384) || \
|
||||
defined(BUILD_TLS_AES_128_GCM_SHA256) || \
|
||||
defined(BUILD_TLS_AES_256_GCM_SHA384)
|
||||
#define BUILD_AESGCM
|
||||
#else
|
||||
/* No AES-GCM cipher suites available with build */
|
||||
@ -901,7 +915,9 @@
|
||||
#if defined(WOLFSSL_MAX_STRENGTH) || \
|
||||
(defined(HAVE_AESGCM) && !defined(NO_AESGCM_AEAD)) || \
|
||||
defined(HAVE_AESCCM) || \
|
||||
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_CHAPOL_AEAD))
|
||||
(defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && \
|
||||
!defined(NO_CHAPOL_AEAD)) || \
|
||||
(defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER))
|
||||
|
||||
#define HAVE_AEAD
|
||||
#endif
|
||||
@ -1070,6 +1086,10 @@ enum {
|
||||
TLS_AES_128_CCM_SHA256 = 0x04,
|
||||
TLS_AES_128_CCM_8_SHA256 = 0x05,
|
||||
|
||||
/* TLS v1.3 Integity only cipher suites - 0xC0 (ECC) first byte */
|
||||
TLS_SHA256_SHA256 = 0xB4,
|
||||
TLS_SHA384_SHA384 = 0xB5,
|
||||
|
||||
/* Fallback SCSV (Signaling Cipher Suite Value) */
|
||||
TLS_FALLBACK_SCSV = 0x56,
|
||||
/* Renegotiation Indication Extension Special Suite */
|
||||
@ -1358,6 +1378,8 @@ enum Misc {
|
||||
|
||||
POLY1305_AUTH_SZ = 16, /* 128 bits */
|
||||
|
||||
HMAC_NONCE_SZ = 12, /* Size of HMAC nonce */
|
||||
|
||||
HC_128_KEY_SIZE = 16, /* 128 bits */
|
||||
HC_128_IV_SIZE = 16, /* also 128 bits */
|
||||
|
||||
@ -2887,8 +2909,10 @@ enum CipherType { aead };
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(BUILD_AES) || defined(BUILD_AESGCM) || (defined(HAVE_CHACHA) && \
|
||||
defined(HAVE_POLY1305)) || defined(WOLFSSL_TLS13)
|
||||
#define CIPHER_NONCE
|
||||
#endif
|
||||
|
||||
|
||||
/* cipher for now */
|
||||
@ -2901,11 +2925,14 @@ typedef struct Ciphers {
|
||||
#endif
|
||||
#if defined(BUILD_AES) || defined(BUILD_AESGCM)
|
||||
Aes* aes;
|
||||
#if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) || defined(WOLFSSL_TLS13)
|
||||
#if (defined(BUILD_AESGCM) || defined(HAVE_AESCCM)) && \
|
||||
!defined(WOLFSSL_NO_TLS12)
|
||||
byte* additional;
|
||||
byte* nonce;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef CIPHER_NONCE
|
||||
byte* nonce;
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
Camellia* cam;
|
||||
#endif
|
||||
@ -2920,6 +2947,9 @@ typedef struct Ciphers {
|
||||
#endif
|
||||
#ifdef HAVE_IDEA
|
||||
Idea* idea;
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER)
|
||||
Hmac* hmac;
|
||||
#endif
|
||||
byte state;
|
||||
byte setup; /* have we set it up flag for detection */
|
||||
|
Reference in New Issue
Block a user