forked from wolfSSL/wolfssl
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:
16
configure.ac
16
configure.ac
@ -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"
|
||||
|
@ -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 */
|
||||
|
13
src/tls.c
13
src/tls.c
@ -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.
|
||||
|
61
src/tls13.c
61
src/tls13.c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user