TLS v1.3 support for Draft 23 and Draft 27

Draft 24: Second ClientHello usees version 0x0303 - no change.
Draft 25: The record layer header is now additional authentication data to
encryption.
Draft 26: Disallow SupportedVersion being used in ServerHello for
negotiating below TLS v1.3.
Draft 27: Older versions can be negotiated (by exclusion of 0x0304) in
SupportedVersion - no change.
This commit is contained in:
Sean Parkinson
2018-03-07 17:05:53 +10:00
parent f70351242b
commit bd53d7ba59
5 changed files with 81 additions and 27 deletions

View File

@ -307,6 +307,18 @@ then
fi
# TLS v1.3 Draft 23
AC_ARG_ENABLE([tls13-draft23],
[AS_HELP_STRING([--enable-tls13-draft23],[Enable wolfSSL TLS v1.3 Draft 23 (default: disabled)])],
[ ENABLED_TLS13_DRAFT23=$enableval ],
[ ENABLED_TLS13_DRAFT23=no ]
)
if test "$ENABLED_TLS13_DRAFT23" = "yes"
then
AM_CFLAGS="-DWOLFSSL_TLS13_DRAFT_23 $AM_CFLAGS"
fi
# TLS v1.3
AC_ARG_ENABLE([tls13],
[AS_HELP_STRING([--enable-tls13],[Enable wolfSSL TLS v1.3 (default: disabled)])],
@ -314,7 +326,7 @@ AC_ARG_ENABLE([tls13],
[ ENABLED_TLS13=no ]
)
if test "$ENABLED_TLS13_DRAFT18" = "yes" || test "$ENABLED_TLS13_DRAFT22" = "yes"
if test "$ENABLED_TLS13_DRAFT18" = "yes" || test "$ENABLED_TLS13_DRAFT22" = "yes" || test "$ENABLED_TLS13_DRAFT23" = "yes"
then
ENABLED_TLS13="yes"
fi
@ -4311,6 +4323,8 @@ echo " * SSL version 3.0: $ENABLED_SSLV3"
echo " * TLS v1.0: $ENABLED_TLSV10"
echo " * TLS v1.3: $ENABLED_TLS13"
echo " * TLS v1.3 Draft 18: $ENABLED_TLS13_DRAFT18"
echo " * TLS v1.3 Draft 22: $ENABLED_TLS13_DRAFT22"
echo " * TLS v1.3 Draft 23: $ENABLED_TLS13_DRAFT23"
echo " * Post-handshake Auth: $ENABLED_TLS13_POST_AUTH"
echo " * Early Data: $ENABLED_TLS13_EARLY_DATA"
echo " * Send State in HRR Cookie: $ENABLED_SEND_HRR_COOKIE"

View File

@ -12244,10 +12244,20 @@ int ProcessReply(WOLFSSL* ssl)
}
else {
#ifdef WOLFSSL_TLS13
#if defined(WOLFSSL_TLS13_DRAFT_18) || \
defined(WOLFSSL_TLS13_DRAFT_22) || \
defined(WOLFSSL_TLS13_DRAFT_23)
ret = DecryptTls13(ssl,
in->buffer + in->idx,
in->buffer + in->idx,
ssl->curSize);
ssl->curSize, NULL, 0);
#else
ret = DecryptTls13(ssl,
in->buffer + in->idx,
in->buffer + in->idx,
ssl->curSize,
(byte*)&ssl->curRL, RECORD_HEADER_SZ);
#endif
#else
ret = DECRYPT_ERROR;
#endif /* WOLFSSL_TLS13 */

View File

@ -4606,7 +4606,6 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
{
ProtocolVersion pv = ssl->ctx->method->version;
int i;
int ret = VERSION_ERROR;
int len;
byte major, minor;
@ -4660,7 +4659,6 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
TLSX_SetResponse(ssl, TLSX_SUPPORTED_VERSIONS);
#endif
}
ret = 0;
break;
}
}
@ -4682,9 +4680,12 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
if (major != pv.major)
return VERSION_ERROR;
/* Can't downgrade with this extension below TLS v1.3. */
if (minor < TLSv1_3_MINOR)
return VERSION_ERROR;
/* Version is TLS v1.2 to handle downgrading from TLS v1.3+. */
if (ssl->options.downgrade && ssl->version.minor == TLSv1_2_MINOR &&
minor >= TLSv1_3_MINOR) {
if (ssl->options.downgrade && ssl->version.minor == TLSv1_2_MINOR) {
/* Set minor version back to TLS v1.3+ */
ssl->version.minor = ssl->ctx->method->version.minor;
}
@ -4704,14 +4705,12 @@ static int TLSX_SupportedVersions_Parse(WOLFSSL *ssl, byte* input,
/* Downgrade the version. */
ssl->version.minor = minor;
}
ret = 0;
}
#endif
else
return SANITY_MSG_E;
return ret;
return 0;
}
/* Sets a new SupportedVersions extension into the extension list.

View File

@ -1500,12 +1500,14 @@ static INLINE void BuildTls13Nonce(WOLFSSL* ssl, byte* nonce, const byte* iv,
* input The data to encrypt.
* sz The number of bytes to encrypt.
* nonce The nonce to use with ChaCha20.
* 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 ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output,
const byte* input, word16 sz, byte* nonce,
byte* tag)
const byte* aad, word16 aadSz, byte* tag)
{
int ret = 0;
byte poly[CHACHA20_256_KEY_SIZE];
@ -1534,8 +1536,8 @@ static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output,
if (ret != 0)
return ret;
/* Add authentication code of encrypted data to end. */
ret = wc_Poly1305_MAC(ssl->auth.poly1305, NULL, 0, output, sz, tag,
POLY1305_AUTH_SZ);
ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz, output, sz,
tag, POLY1305_AUTH_SZ);
return ret;
}
@ -1546,13 +1548,15 @@ static int ChaCha20Poly1305_Encrypt(WOLFSSL* ssl, byte* output,
* ssl The SSL/TLS object.
* output The buffer to write encrypted data and authentication tag into.
* May be the same pointer as input.
* input The data to encrypt.
* input The record header and data to encrypt.
* sz The number of bytes to encrypt.
* aad The additional authentication data.
* aadSz The size of the addition authentication data.
* asyncOkay If non-zero can return WC_PENDING_E, otherwise blocks on crypto
* returns 0 on success, otherwise failure.
*/
static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
word16 sz, int asyncOkay)
word16 sz, const byte* aad, word16 aadSz, int asyncOkay)
{
int ret = 0;
word16 dataSz = sz - ssl->specs.aead_mac_size;
@ -1585,6 +1589,11 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Data to encrypt");
WOLFSSL_BUFFER(input, dataSz);
#if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \
!defined(WOLFSSL_TLS13_DRAFT_23)
WOLFSSL_MSG("Addition Authentication Data");
WOLFSSL_BUFFER(aad, aadSz);
#endif
#endif
if (ssl->encrypt.nonce == NULL)
@ -1617,7 +1626,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
nonceSz = AESGCM_NONCE_SZ;
ret = wc_AesGcmEncrypt(ssl->encrypt.aes, output, input,
dataSz, ssl->encrypt.nonce, nonceSz,
output + dataSz, macSz, NULL, 0);
output + dataSz, macSz, aad, aadSz);
break;
#endif
@ -1634,14 +1643,14 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
nonceSz = AESCCM_NONCE_SZ;
ret = wc_AesCcmEncrypt(ssl->encrypt.aes, output, input,
dataSz, ssl->encrypt.nonce, nonceSz,
output + dataSz, macSz, NULL, 0);
output + dataSz, macSz, aad, aadSz);
break;
#endif
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
case wolfssl_chacha:
ret = ChaCha20Poly1305_Encrypt(ssl, output, input, dataSz,
ssl->encrypt.nonce, output + dataSz);
ssl->encrypt.nonce, aad, aadSz, output + dataSz);
break;
#endif
@ -1700,11 +1709,14 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
* input The data to decrypt.
* sz The number of bytes to decrypt.
* nonce The nonce to use with ChaCha20.
* 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 ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
const byte* input, word16 sz, byte* nonce,
const byte* aad, word16 aadSz,
const byte* tagIn)
{
int ret;
@ -1729,8 +1741,8 @@ static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
if (ret != 0)
return ret;
/* Generate authentication tag for encrypted data. */
if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, NULL, 0, (byte*)input, sz,
tag, sizeof(tag))) != 0) {
if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, (byte*)aad, aadSz,
(byte*)input, sz, tag, sizeof(tag))) != 0) {
return ret;
}
@ -1752,11 +1764,14 @@ static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
* ssl The SSL/TLS object.
* output The buffer to write decrypted data into.
* May be the same pointer as input.
* input The data to encrypt and authentication tag.
* input The data to decrypt and authentication tag.
* sz The length of the encrypted data plus authentication tag.
* aad The additional authentication data.
* aadSz The size of the addition authentication data.
* returns 0 on success, otherwise failure.
*/
int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz)
int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz,
const byte* aad, word16 aadSz)
{
int ret = 0;
word16 dataSz = sz - ssl->specs.aead_mac_size;
@ -1797,6 +1812,11 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz)
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Data to decrypt");
WOLFSSL_BUFFER(input, dataSz);
#if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) && \
!defined(WOLFSSL_TLS13_DRAFT_23)
WOLFSSL_MSG("Addition Authentication Data");
WOLFSSL_BUFFER(aad, aadSz);
#endif
WOLFSSL_MSG("Authentication tag");
WOLFSSL_BUFFER(input + dataSz, macSz);
#endif
@ -1831,7 +1851,7 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz)
nonceSz = AESGCM_NONCE_SZ;
ret = wc_AesGcmDecrypt(ssl->decrypt.aes, output, input,
dataSz, ssl->decrypt.nonce, nonceSz,
input + dataSz, macSz, NULL, 0);
input + dataSz, macSz, aad, aadSz);
#ifdef WOLFSSL_ASYNC_CRYPT
if (ret == WC_PENDING_E) {
ret = wolfSSL_AsyncPush(ssl,
@ -1854,7 +1874,7 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz)
nonceSz = AESCCM_NONCE_SZ;
ret = wc_AesCcmDecrypt(ssl->decrypt.aes, output, input,
dataSz, ssl->decrypt.nonce, nonceSz,
input + dataSz, macSz, NULL, 0);
input + dataSz, macSz, aad, aadSz);
#ifdef WOLFSSL_ASYNC_CRYPT
if (ret == WC_PENDING_E) {
ret = wolfSSL_AsyncPush(ssl,
@ -1867,7 +1887,7 @@ int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input, word16 sz)
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
case wolfssl_chacha:
ret = ChaCha20Poly1305_Decrypt(ssl, output, input, dataSz,
ssl->decrypt.nonce, input + dataSz);
ssl->decrypt.nonce, aad, aadSz, input + dataSz);
break;
#endif
@ -2060,8 +2080,17 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
else
#endif
{
#if defined(WOLFSSL_TLS13_DRAFT_18) || defined(WOLFSSL_TLS13_DRAFT_22) || \
defined(WOLFSSL_TLS13_DRAFT_23)
output += args->headerSz;
ret = EncryptTls13(ssl, output, output, args->size, asyncOkay);
ret = EncryptTls13(ssl, output, output, args->size, NULL, 0,
asyncOkay);
#else
const byte* aad = output;
output += args->headerSz;
ret = EncryptTls13(ssl, output, output, args->size, aad,
RECORD_HEADER_SZ, asyncOkay);
#endif
}
break;
}

View File

@ -1030,8 +1030,10 @@ enum Misc {
TLS_DRAFT_MINOR = 0x12, /* Minor version number of TLS draft */
#elif defined(WOLFSSL_TLS13_DRAFT_22)
TLS_DRAFT_MINOR = 0x16, /* Minor version number of TLS draft */
#else
#elif defined(WOLFSSL_TLS13_DRAFT_23)
TLS_DRAFT_MINOR = 0x17, /* Minor version number of TLS draft */
#else
TLS_DRAFT_MINOR = 0x1b, /* Minor version number of TLS draft */
#endif
OLD_HELLO_ID = 0x01, /* SSLv2 Client Hello Indicator */
INVALID_BYTE = 0xff, /* Used to initialize cipher specs values */
@ -1506,7 +1508,7 @@ WOLFSSL_LOCAL int SNI_Callback(WOLFSSL* ssl);
#endif
#ifdef WOLFSSL_TLS13
WOLFSSL_LOCAL int DecryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
word16 sz);
word16 sz, const byte* aad, word16 aadSz);
WOLFSSL_LOCAL int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input,
word32* inOutIdx, byte type,
word32 size, word32 totalSz);