Merge pull request #953 from SparkiDev/tls13_psk

External PSK working in TLS13
This commit is contained in:
toddouska 2017-06-07 13:58:03 -07:00 committed by GitHub
commit 1be0b2aa30
7 changed files with 268 additions and 101 deletions

View File

@ -1280,13 +1280,18 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args)
wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
if (cipherList == NULL) {
const char *defaultCipherList;
#if defined(HAVE_AESGCM) && !defined(NO_DH)
defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
#elif defined(HAVE_NULL_CIPHER)
defaultCipherList = "PSK-NULL-SHA256";
#if defined(HAVE_AESGCM) && !defined(NO_DH)
#ifdef WOLFSSL_TLS13
defaultCipherList = "DHE-PSK-AES128-GCM-SHA256:"
"TLS13-AES128-GCM-SHA256";
#else
defaultCipherList = "PSK-AES128-CBC-SHA256";
defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
#endif
#elif defined(HAVE_NULL_CIPHER)
defaultCipherList = "PSK-NULL-SHA256";
#else
defaultCipherList = "PSK-AES128-CBC-SHA256";
#endif
if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList)
!=SSL_SUCCESS) {
wolfSSL_CTX_free(ctx);

View File

@ -866,14 +866,19 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
if (cipherList == NULL && !usePskPlus) {
const char *defaultCipherList;
#if defined(HAVE_AESGCM) && !defined(NO_DH)
defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
needDH = 1;
#elif defined(HAVE_NULL_CIPHER)
defaultCipherList = "PSK-NULL-SHA256";
#if defined(HAVE_AESGCM) && !defined(NO_DH)
#ifdef WOLFSSL_TLS13
defaultCipherList = "DHE-PSK-AES128-GCM-SHA256:"
"TLS13-AES128-GCM-SHA256";
#else
defaultCipherList = "PSK-AES128-CBC-SHA256";
defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
#endif
needDH = 1;
#elif defined(HAVE_NULL_CIPHER)
defaultCipherList = "PSK-NULL-SHA256";
#else
defaultCipherList = "PSK-AES128-CBC-SHA256";
#endif
if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
err_sys("server can't set cipher list 2");
}

View File

@ -9128,7 +9128,7 @@ int SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session)
ssl->options.resuming = 1;
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
defined(HAVE_SESSION_TICKET) && !defined(NO_PSK))
defined(HAVE_SESSION_TICKET))
ssl->version = session->version;
ssl->options.cipherSuite0 = session->cipherSuite0;
ssl->options.cipherSuite = session->cipherSuite;
@ -9278,13 +9278,13 @@ int AddSession(WOLFSSL* ssl)
}
#endif /* SESSION_CERTS */
#if defined(SESSION_CERTS) || (defined(WOLFSSL_TLS13) && \
defined(HAVE_SESSION_TICKET) && !defined(NO_PSK))
defined(HAVE_SESSION_TICKET))
if (error == 0) {
session->version = ssl->version;
session->cipherSuite0 = ssl->options.cipherSuite0;
session->cipherSuite = ssl->options.cipherSuite;
}
#endif /* SESSION_CERTS || (WOLFSSL_TLS13 & !NO_PSK) */
#endif /* SESSION_CERTS || (WOLFSSL_TLS13 & HAVE_SESSION_TICKET) */
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
if (error == 0) {
session->namedGroup = ssl->session.namedGroup;

View File

@ -673,7 +673,7 @@ static INLINE void c24to32(const word24 u24, word32* u32)
}
#endif
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK)
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
/* Convert opaque data to a 32-bit unsigned integer.
*
* c The opaque data holding a 32-bit integer.
@ -5207,7 +5207,7 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
{
int ret;
#ifdef HAVE_SESSION_TICKET
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
ssl->session.namedGroup = keyShareEntry->group;
#endif
/* Use Key Share Data from server. */
@ -5434,6 +5434,7 @@ int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
if (extension == NULL)
return MEMORY_E;
}
extension->resp = 0;
/* Try to find the key share entry with this group. */
keyShareEntry = (KeyShareEntry*)extension->data;
@ -5620,6 +5621,9 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl)
if (extension != NULL)
list = (KeyShareEntry*)extension->data;
if (extension && extension->resp == 1)
return 0;
/* TODO: [TLS13] Server's preference and sending back SupportedGroups */
/* Use client's preference. */
for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) {
@ -5695,7 +5699,7 @@ int TLSX_KeyShare_Establish(WOLFSSL *ssl)
/* Pre-Shared Key */
/******************************************************************************/
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
/* Free the pre-shared key dynamic data.
*
* list The linked list of key share entry objects.
@ -5922,8 +5926,8 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length,
ato32(input + idx, &age);
idx += OPAQUE32_LEN;
ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, 0, 1,
NULL);
ret = TLSX_PreSharedKey_Use(ssl, identity, identityLen, age, no_mac,
1, NULL);
if (ret != 0)
return ret;
@ -5990,6 +5994,7 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length,
return PSK_KEY_ERROR;
list->chosen = 1;
#ifdef HAVE_SESSION_TICKET
if (list->resumption) {
/* Check that the session's details are the same as the server's. */
if (ssl->options.cipherSuite0 != ssl->session.cipherSuite0 ||
@ -5999,6 +6004,7 @@ static int TLSX_PreSharedKey_Parse(WOLFSSL* ssl, byte* input, word16 length,
return PSK_KEY_ERROR;
}
}
#endif
/* TODO: [TLS13] More checks of consistency.
* the "key_share", and "signature_algorithms" extensions are
* consistent with the indicated ke_modes and auth_modes values
@ -6147,7 +6153,7 @@ int TLSX_PreSharedKey_Use(WOLFSSL* ssl, byte* identity, word16 len, word32 age,
/* PSK Key Exchange Modes */
/******************************************************************************/
#if defined(WOLFSSL_TLS13) && !defined(NO_PSK)
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
/* Get the size of the encoded PSK KE modes extension.
* Only in ClientHello.
*
@ -6368,7 +6374,7 @@ void TLSX_FreeAll(TLSX* list, void* heap)
KS_FREE_ALL((KeyShareEntry*)extension->data, heap);
break;
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
PSK_FREE_ALL((PreSharedKey*)extension->data, heap);
break;
@ -6475,7 +6481,7 @@ static word16 TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType)
length += KS_GET_SIZE((KeyShareEntry*)extension->data, msgType);
break;
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
length += PSK_GET_SIZE((PreSharedKey*)extension->data, msgType);
break;
@ -6602,7 +6608,7 @@ static word16 TLSX_Write(TLSX* list, byte* output, byte* semaphore,
output + offset, msgType);
break;
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
WOLFSSL_MSG("Pre-Shared Key extension to write");
offset += PSK_WRITE((PreSharedKey*)extension->data,
@ -6826,6 +6832,9 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
int ret = 0;
byte* public_key = NULL;
word16 public_key_len = 0;
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
int usingPSK = 0;
#endif
#ifdef HAVE_QSH
TLSX* extension;
QSHScheme* qsh;
@ -7084,11 +7093,10 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
return ret;
}
#if defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
#if defined(HAVE_SESSION_TICKET)
if (ssl->options.resuming) {
WOLFSSL_SESSION* sess = &ssl->session;
word32 milli;
byte modes;
/* Determine the MAC algorithm for the cipher suite used. */
ssl->options.cipherSuite0 = sess->cipherSuite0;
@ -7103,6 +7111,37 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
if (ret != 0)
return ret;
usingPSK = 1;
}
#endif
#ifndef NO_PSK
if (ssl->options.client_psk_cb != NULL) {
byte mac = sha256_mac;
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
ssl->arrays->server_hint, ssl->arrays->client_identity,
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
if (ssl->arrays->psk_keySz == 0 ||
ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) {
return PSK_KEY_ERROR;
}
ssl->arrays->client_identity[MAX_PSK_ID_LEN] = '\0';
/* Hash algorithm defaults to SHA-256 unless cb specifies. */
ret = TLSX_PreSharedKey_Use(ssl,
(byte*)ssl->arrays->client_identity,
XSTRLEN(ssl->arrays->client_identity),
0, mac, 0, NULL);
if (ret != 0)
return ret;
usingPSK = 1;
}
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (usingPSK) {
byte modes;
/* Pre-shared key modes: mandatory extension for resumption. */
modes = 1 << PSK_KE;
#if !defined(NO_DH) || defined(HAVE_ECC)
@ -7114,7 +7153,6 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
return ret;
}
#endif
/* TODO: [TLS13] Add PSKs */
}
#endif
@ -7152,7 +7190,7 @@ word16 TLSX_GetRequestSize(WOLFSSL* ssl)
if (!IsAtLeastTLSv1_3(ssl->version)) {
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
#endif
@ -7200,11 +7238,11 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
if (!IsAtLeastTLSv1_3(ssl->version)) {
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SUPPORTED_VERSIONS));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PSK_KEY_EXCHANGE_MODES));
#endif
}
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
#endif
@ -7227,8 +7265,8 @@ word16 TLSX_WriteRequest(WOLFSSL* ssl, byte* output)
#endif
#ifdef WOLFSSL_TLS13
if (IsAtLeastTLSv1_3(ssl->version) && ssl->options.resuming) {
#ifndef NO_PSK
if (IsAtLeastTLSv1_3(ssl->version)) {
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
offset += TLSX_Write(ssl->extensions, output + offset, semaphore,
@ -7260,7 +7298,7 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
if (ssl->options.tls1_3) {
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
}
@ -7268,7 +7306,7 @@ word16 TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType)
case encrypted_extensions:
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
break;
@ -7321,7 +7359,7 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
if (ssl->options.tls1_3) {
XMEMSET(semaphore, 0xff, SEMAPHORE_SIZE);
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
}
@ -7329,7 +7367,7 @@ word16 TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType)
case encrypted_extensions:
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_SESSION_TICKET));
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE));
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_PRE_SHARED_KEY));
#endif
break;
@ -7574,7 +7612,7 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType,
ret = KS_PARSE(ssl, input + offset, size, msgType);
break;
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
case TLSX_PRE_SHARED_KEY:
WOLFSSL_MSG("Pre-Shared Key extension received");

View File

@ -26,8 +26,8 @@
#endif
#ifdef WOLFSSL_TLS13
#if defined(HAVE_SESSION_TICKET)
#include <sys/time.h>
#ifdef HAVE_SESSION_TICKET
#include <sys/time.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
@ -462,7 +462,7 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen,
}
#if defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
#ifndef NO_PSK
#ifdef WOLFSSL_TLS13_DRAFT_18
/* The length of the binder key label. */
#define BINDER_KEY_LABEL_SZ 23
@ -489,7 +489,9 @@ static int DeriveBinderKey(WOLFSSL* ssl, byte* key)
binderKeyLabel, BINDER_KEY_LABEL_SZ,
NULL, 0, ssl->specs.mac_algorithm);
}
#endif /* !NO_PSK */
#ifdef HAVE_SESSION_TICKET
#ifdef WOLFSSL_TLS13_DRAFT_18
/* The length of the binder key resume label. */
#define BINDER_KEY_RESUME_LABEL_SZ 25
@ -516,7 +518,7 @@ static int DeriveBinderKeyResume(WOLFSSL* ssl, byte* key)
binderKeyResumeLabel, BINDER_KEY_RESUME_LABEL_SZ,
NULL, 0, ssl->specs.mac_algorithm);
}
#endif
#endif /* HAVE_SESSION_TICKET */
#ifdef TLS13_SUPPORTS_0RTT
#ifdef WOLFSSL_TLS13_DRAFT_18
@ -713,7 +715,7 @@ static int DeriveExporterSecret(WOLFSSL* ssl, byte* key)
}
#endif
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#ifdef WOLFSSL_TLS13_DRAFT_18
/* The length of the resumption master secret label. */
#define RESUME_MASTER_LABEL_SZ 24
@ -794,7 +796,7 @@ static int DeriveTrafficSecret(WOLFSSL* ssl, byte* secret)
static int DeriveEarlySecret(WOLFSSL* ssl)
{
WOLFSSL_MSG("Derive Early Secret");
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
return Tls13_HKDF_Extract(ssl->arrays->secret, NULL, 0,
ssl->arrays->psk_key, ssl->arrays->psk_keySz,
ssl->specs.mac_algorithm);
@ -1073,7 +1075,7 @@ end:
return ret;
}
#if defined(HAVE_SESSION_TICKET)
#ifdef HAVE_SESSION_TICKET
#if defined(USER_TICKS)
#if 0
word32 TimeNowInMilliseconds(void)
@ -1274,10 +1276,10 @@ end:
return (word32)(now.tv_sec * 1000 + now.tv_usec / 1000);
}
#endif
#endif /* HAVE_SESSION_TICKET */
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_SESSION_TICKET) && \
#if !defined(NO_WOLFSSL_SERVER) && (defined(HAVE_SESSION_TICKET) || \
!defined(NO_PSK))
/* Add input to all handshake hashes.
*
@ -1323,6 +1325,55 @@ static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
}
#endif
/* Restart the Hanshake hash with a hash of the previous messages.
*
* ssl The SSL/TLS object.
* returns 0 on success, otherwise failure.
*/
static int RestartHandshakeHash(WOLFSSL* ssl)
{
int ret;
Hashes hashes;
byte header[] = { message_hash, 0, 0, 0 };
byte* hash = NULL;
ret = BuildCertHashes(ssl, &hashes);
if (ret != 0)
return ret;
ret = InitHandshakeHashes(ssl);
if (ret != 0)
return ret;
switch (ssl->specs.mac_algorithm) {
#ifndef NO_SHA256
case sha256_mac:
header[3] = SHA256_DIGEST_SIZE;
hash = hashes.sha256;
break;
#endif
#ifdef WOLFSSL_SHA384
case sha384_mac:
header[3] = SHA384_DIGEST_SIZE;
hash = hashes.sha384;
break;
#endif
#ifdef WOLFSSL_SHA512
case sha512_mac:
header[3] = SHA512_DIGEST_SIZE;
hash = hashes.sha512;
break;
#endif
}
WOLFSSL_MSG("Restart Hash");
WOLFSSL_BUFFER(hash, header[3]);
ret = HashOutputRaw(ssl, header, sizeof(header));
if (ret != 0)
return ret;
return HashOutputRaw(ssl, hash, header[3]);
}
/* Extract the handshake header information.
*
* ssl The SSL/TLS object.
@ -1335,9 +1386,9 @@ static int HashInputRaw(WOLFSSL* ssl, const byte* input, int sz)
* returns BUFFER_E if there is not enough input data and 0 on success.
*/
static int GetHandshakeHeader(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
byte *type, word32 *size, word32 totalSz)
byte* type, word32* size, word32 totalSz)
{
const byte *ptr = input + *inOutIdx;
const byte* ptr = input + *inOutIdx;
(void)ssl;
*inOutIdx += HANDSHAKE_HEADER_SZ;
@ -1471,7 +1522,7 @@ static INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out)
* iv The derived IV.
* order The side on which the message is to be or was sent.
*/
static INLINE void BuildTls13Nonce(WOLFSSL* ssl, byte *nonce, const byte* iv,
static INLINE void BuildTls13Nonce(WOLFSSL* ssl, byte* nonce, const byte* iv,
int order)
{
int i;
@ -1612,7 +1663,7 @@ static int EncryptTls13(WOLFSSL* ssl, byte* output, const byte* input,
* tagIn The authentication tag data from packet.
* returns 0 on success, otherwise failure.
*/
static int ChaCha20Poly1305_Decrypt(WOLFSSL *ssl, byte* output,
static int ChaCha20Poly1305_Decrypt(WOLFSSL* ssl, byte* output,
const byte* input, word16 sz, byte* nonce,
const byte* tagIn)
{
@ -1821,13 +1872,13 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
}
#ifndef NO_WOLFSSL_CLIENT
#if defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
#ifdef HAVE_SESSION_TICKET
/* Get the size of the message hash.
*
* ssl The SSL/TLS object.
* returns the length of the hash.
*/
static int GetMsgHashSize(WOLFSSL *ssl)
static int GetMsgHashSize(WOLFSSL* ssl)
{
switch (ssl->specs.mac_algorithm) {
#ifndef NO_SHA256
@ -1845,7 +1896,9 @@ static int GetMsgHashSize(WOLFSSL *ssl)
}
return 0;
}
#endif
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* Derive and write the binders into the ClientHello in space left when
* writing the Pre-Shared Key extension.
*
@ -1879,6 +1932,7 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
/* Calculate the binder for each identity based on previous handshake data.
*/
while (current != NULL) {
#ifdef HAVE_SESSION_TICKET
if (current->resumption) {
/* Set the HMAC to use based on the one for the session (set into
* the extension data at the start of this function based on the
@ -1899,12 +1953,17 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
if (ret != 0)
return ret;
}
else {
/* TODO: [TLS13] Support non-ticket PSK. */
else
#endif
#ifndef NO_PSK
if (!current->resumption) {
/* Get the pre-shared key. */
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
(char *)current->identity, ssl->arrays->client_identity,
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
/* TODO: Forcing cipher suite to use SHA256 with PSK. */
/* Default to SHA-256 if cb doesn't specify. */
ssl->specs.mac_algorithm = sha256_mac;
/* Derive the early secret using the PSK. */
ret = DeriveEarlySecret(ssl);
if (ret != 0)
@ -1914,6 +1973,12 @@ static int WritePSKBinders(WOLFSSL* ssl, byte* output, word32 idx)
if (ret != 0)
return ret;
}
else
#endif
{
current = current->next;
continue;
}
/* Derive the Finished message secret. */
ret = DeriveFinishedSecret(ssl, binderKey, ssl->keys.client_write_MAC_secret);
@ -1954,7 +2019,7 @@ int SendTls13ClientHello(WOLFSSL* ssl)
int sendSz;
int ret;
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
if (ssl->options.resuming &&
(ssl->session.version.major != ssl->version.major ||
ssl->session.version.minor != ssl->version.minor)) {
@ -2031,11 +2096,11 @@ int SendTls13ClientHello(WOLFSSL* ssl)
/* Write out extensions for a request. */
idx += TLSX_WriteRequest(ssl, output + idx);
#if defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* Resumption has a specific set of extensions and binder is calculated
* for each identity.
*/
if (ssl->options.resuming)
if (TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY))
ret = WritePSKBinders(ssl, output, idx);
else
#endif
@ -2083,7 +2148,7 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
#endif
/* Version info and length field of extension data. */
if (totalSz < i - begin + OPAQUE16_LEN + OPAQUE16_LEN)
if (totalSz < i - begin + OPAQUE16_LEN + OPAQUE16_LEN + OPAQUE16_LEN)
return BUFFER_ERROR;
/* Protocol version. */
@ -2093,6 +2158,14 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
if (ret != 0)
return ret;
/* Set the cipher suite from the message. */
ssl->options.cipherSuite0 = input[i++];
ssl->options.cipherSuite = input[i++];
ret = SetCipherSpecs(ssl);
if (ret != 0)
return ret;
/* Length of extension data. */
ato16(&input[i], &totalExtSz);
i += OPAQUE16_LEN;
@ -2115,7 +2188,7 @@ static int DoTls13HelloRetryRequest(WOLFSSL* ssl, const byte* input,
ssl->options.tls1_3 = 1;
ssl->options.serverState = SERVER_HELLO_RETRY_REQUEST;
return 0;
return RestartHandshakeHash(ssl);
}
/* Handle the ServerHello message from the server.
@ -2199,9 +2272,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (ret != 0)
return ret;
#ifndef NO_PSK
#ifdef HAVE_SESSION_TICKET
if (ssl->options.resuming) {
PreSharedKey *psk = NULL;
PreSharedKey* psk = NULL;
TLSX* ext = TLSX_Find(ssl->extensions, TLSX_PRE_SHARED_KEY);
if (ext != NULL)
psk = (PreSharedKey*)ext->data;
@ -2336,7 +2409,7 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
#endif /* !NO_WOLFSSL_CLIENT */
#ifndef NO_WOLFSSL_SERVER
#if defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* Handle any Pre-Shared Key (PSK) extension.
* Must do this in ClientHello as it requires a hash of the truncated message.
* Don't know size of binders until Pre-Shared Key extension has been parsed.
@ -2347,7 +2420,7 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input,
* usingPSK Indicates handshake is using Pre-Shared Keys.
* returns 0 on success and otherwise failure.
*/
static int DoPreSharedKeys(WOLFSSL *ssl, const byte* input, word32 helloSz,
static int DoPreSharedKeys(WOLFSSL* ssl, const byte* input, word32 helloSz,
int* usingPSK)
{
int ret;
@ -2384,13 +2457,15 @@ static int DoPreSharedKeys(WOLFSSL *ssl, const byte* input, word32 helloSz,
/* Look through all client's pre-shared keys for a match. */
current = (PreSharedKey*)ext->data;
while (current != NULL) {
/* TODO: [TLS13] Support non-ticket PSK. */
/* Decode the identity. */
ret = DoClientTicket(ssl, current->identity, current->identityLen);
if (ret != WOLFSSL_TICKET_RET_OK)
continue;
#ifndef NO_PSK
XMEMCPY(ssl->arrays->client_identity, current->identity,
current->identityLen);
ssl->arrays->client_identity[current->identityLen] = '\0';
#endif
if (current->resumption) {
#ifdef HAVE_SESSION_TICKET
/* Decode the identity. */
if ((ret = DoClientTicket(ssl, current->identity, current->identityLen)) == WOLFSSL_TICKET_RET_OK) {
/* Check the ticket isn't too old or new. */
int diff = TimeNowInMilliseconds() - ssl->session.ticketSeen;
diff -= current->ticketAge - ssl->session.ticketAdd;
@ -2421,15 +2496,25 @@ static int DoPreSharedKeys(WOLFSSL *ssl, const byte* input, word32 helloSz,
if (ret != 0)
return ret;
}
else {
else
#endif
#ifndef NO_PSK
if ((ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl,
ssl->arrays->client_identity, ssl->arrays->psk_key,
MAX_PSK_KEY_LEN)) != 0) {
if (ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN)
return PSK_KEY_ERROR;
ssl->options.resuming = 0;
/* PSK age is always zero. */
if (current->ticketAge != ssl->session.ticketAdd)
return PSK_KEY_ERROR;
/* Get the pre-shared key. */
ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl,
(char*)current->identity, ssl->arrays->client_identity,
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN);
/* TODO: Forcing cipher suite to use SHA256 with PSK. */
/* Default to SHA-256 if cb doesn't specify. */
ssl->specs.mac_algorithm = sha256_mac;
/* Derive the early secret using the PSK. */
ret = DeriveEarlySecret(ssl);
if (ret != 0)
@ -2439,6 +2524,14 @@ static int DoPreSharedKeys(WOLFSSL *ssl, const byte* input, word32 helloSz,
if (ret != 0)
return ret;
}
else
#endif
{
current = current->next;
continue;
}
ssl->options.sendVerify = 0;
/* Derive the Finished message secret. */
ret = DeriveFinishedSecret(ssl, binderKey,
@ -2627,21 +2720,25 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
if (TLSX_Find(ssl->extensions, TLSX_SUPPORTED_VERSIONS) == NULL)
ssl->version.minor = pv.minor;
#if defined(HAVE_SESSION_TICKET) && !defined(NO_PSK)
ssl->options.sendVerify = SEND_CERT;
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* Process the Pre-Shared Key extension if present. */
ret = DoPreSharedKeys(ssl, input + begin, helloSz, &usingPSK);
if (ret != 0)
return ret;
#endif
if (!usingPSK) {
if (!usingPSK || !ssl->options.resuming) {
ret = MatchSuite(ssl, &clSuites);
if (ret < 0) {
WOLFSSL_MSG("Unsupported cipher suite, ClientHello");
return ret;
}
}
#ifndef NO_PSK
if (!usingPSK) {
#ifdef HAVE_SESSION_TICKET
if (ssl->options.resuming) {
ssl->options.resuming = 0;
XMEMSET(ssl->arrays->psk_key, 0, ssl->specs.hash_size);
@ -2655,6 +2752,10 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
ret = HashInput(ssl, input + begin, helloSz);
if (ret != 0)
return ret;
/* Derive early secret for handshake secret. */
if ((ret = DeriveEarlySecret(ssl)) != 0)
return ret;
}
i += totalExtSz;
@ -2672,7 +2773,7 @@ static int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
* ssl The SSL/TLS object.
* returns 0 on success, otherwise failure.
*/
int SendTls13HelloRetryRequest(WOLFSSL *ssl)
int SendTls13HelloRetryRequest(WOLFSSL* ssl)
{
int ret;
byte* output;
@ -2687,8 +2788,8 @@ int SendTls13HelloRetryRequest(WOLFSSL *ssl)
if (len == 0)
return MISSING_HANDSHAKE_DATA;
/* Protocol version + Extensions */
length = OPAQUE16_LEN + len;
/* Protocol version + CipherSuite + Extensions */
length = OPAQUE16_LEN + OPAQUE16_LEN + len;
sendSz = idx + length;
/* Check buffers are big enough and grow if needed. */
@ -2713,6 +2814,10 @@ int SendTls13HelloRetryRequest(WOLFSSL *ssl)
output[idx++] = TLS_DRAFT_MAJOR;
output[idx++] = TLS_DRAFT_MINOR;
/* Chosen cipher suite */
output[idx++] = ssl->options.cipherSuite0;
output[idx++] = ssl->options.cipherSuite;
/* Add TLS extensions. */
TLSX_WriteResponse(ssl, output + idx, hello_retry_request);
idx += len;
@ -2725,6 +2830,10 @@ int SendTls13HelloRetryRequest(WOLFSSL *ssl)
ssl->heap);
#endif
ret = RestartHandshakeHash(ssl);
if (ret < 0)
return ret;
ret = HashOutput(ssl, output, idx, 0);
if (ret != 0)
return ret;
@ -2827,7 +2936,7 @@ int SendTls13ServerHello(WOLFSSL* ssl)
* ssl The SSL/TLS object.
* returns 0 on success, otherwise failure.
*/
int SendTls13EncryptedExtensions(WOLFSSL *ssl)
int SendTls13EncryptedExtensions(WOLFSSL* ssl)
{
int ret;
byte* output;
@ -2837,9 +2946,6 @@ int SendTls13EncryptedExtensions(WOLFSSL *ssl)
ssl->keys.encryptionOn = 1;
/* Derive early secret for handshake secret. */
if ((ret = DeriveEarlySecret(ssl)) != 0)
return ret;
/* Derive the handshake secret now that we are at first message to be
* encrypted under the keys.
*/
@ -2907,7 +3013,7 @@ int SendTls13EncryptedExtensions(WOLFSSL *ssl)
*/
int SendTls13CertificateRequest(WOLFSSL* ssl)
{
byte *output;
byte* output;
int ret;
int sendSz;
int reqCtxLen = 0;
@ -3033,7 +3139,7 @@ static INLINE void DecodeSigAlg(byte* input, byte* hashAlgo, byte* hsType)
* hash The buffer to write the hash to.
* returns the length of the hash.
*/
static INLINE int GetMsgHash(WOLFSSL *ssl, byte* hash)
static INLINE int GetMsgHash(WOLFSSL* ssl, byte* hash)
{
switch (ssl->specs.mac_algorithm) {
#ifndef NO_SHA256
@ -3279,7 +3385,7 @@ static int CheckRSASignature(WOLFSSL* ssl, int sigAlgo, int hashAlgo,
CreateSigData(ssl, sigData, &sigDataSz, 1);
#ifdef WC_RSA_PSS
if (sigAlgo == rsa_pss_sa_algo) {
int hashType = WC_HASH_TYPE_NONE;
enum wc_HashType hashType = WC_HASH_TYPE_NONE;
switch (hashAlgo) {
case sha512_mac:
@ -4392,7 +4498,7 @@ int SendTls13Finished(WOLFSSL* ssl)
if ((ret = SetKeysSide(ssl, ENCRYPT_AND_DECRYPT_SIDE)) != 0)
return ret;
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
ret = DeriveResumptionSecret(ssl, ssl->session.masterSecret);
#endif
}
@ -5011,7 +5117,7 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
return ret;
}
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
if (type == finished && ssl->options.side == WOLFSSL_SERVER_END)
DeriveResumptionSecret(ssl, ssl->session.masterSecret);
#endif
@ -5464,7 +5570,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
errno = 0;
#endif
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
havePSK = ssl->options.havePSK;
#endif
(void)havePSK;
@ -5594,7 +5700,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
case CERT_REQ_SENT :
ssl->options.acceptState = KEY_EXCHANGE_SENT;
#ifndef NO_CERTS
if (!ssl->options.resuming) {
if (!ssl->options.resuming && ssl->options.sendVerify) {
if ((ssl->error = SendTls13Certificate(ssl)) != 0) {
WOLFSSL_ERROR(ssl->error);
return SSL_FATAL_ERROR;
@ -5607,7 +5713,7 @@ int wolfSSL_accept_TLSv13(WOLFSSL* ssl)
case CERT_SENT :
#ifndef NO_CERTS
if (!ssl->options.resuming) {
if (!ssl->options.resuming && ssl->options.sendVerify) {
if ((ssl->error = SendTls13CertificateVerify(ssl)) != 0) {
WOLFSSL_ERROR(ssl->error);
return SSL_FATAL_ERROR;

View File

@ -251,3 +251,13 @@
-v 3
-l PSK-AES256-GCM-SHA384
# server TLSv1.3 AES128-GCM-SHA256
-s
-v 4
-l TLS13-AES128-GCM-SHA256
# client TLSv1.3 AES128-GCM-SHA256
-s
-v 4
-l TLS13-AES128-GCM-SHA256

View File

@ -1771,11 +1771,11 @@ typedef enum {
TLSX_SESSION_TICKET = 0x0023,
#ifdef WOLFSSL_TLS13
TLSX_KEY_SHARE = 0x0028,
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TLSX_PRE_SHARED_KEY = 0x0029,
#endif
TLSX_SUPPORTED_VERSIONS = 0x002b,
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
TLSX_PSK_KEY_EXCHANGE_MODES = 0x002d,
#endif
#endif
@ -2063,7 +2063,7 @@ WOLFSSL_LOCAL int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len,
WOLFSSL_LOCAL int TLSX_KeyShare_Empty(WOLFSSL* ssl);
WOLFSSL_LOCAL int TLSX_KeyShare_Establish(WOLFSSL* ssl);
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
/* The PreSharedKey extension information - entry in a linked list. */
typedef struct PreSharedKey {
word16 identityLen; /* Length of identity */
@ -2092,7 +2092,7 @@ enum PskKeyExchangeMode {
};
WOLFSSL_LOCAL int TLSX_PskKeModes_Use(WOLFSSL* ssl, byte modes);
#endif /* NO_PSK */
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
/* The types of keys to derive for. */
enum DeriveKeyType {
@ -2203,12 +2203,12 @@ struct WOLFSSL_CTX {
word32 ecdhCurveOID; /* curve Ecc_Sum */
word32 pkCurveOID; /* curve Ecc_Sum */
#endif
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
byte havePSK; /* psk key set by user */
wc_psk_client_callback client_psk_cb; /* client callback */
wc_psk_server_callback server_psk_cb; /* server callback */
char server_hint[MAX_PSK_ID_LEN + NULL_TERM_LEN];
#endif /* NO_PSK */
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
#ifdef HAVE_ANON
byte haveAnon; /* User wants to allow Anon suites */
#endif /* HAVE_ANON */
@ -2527,7 +2527,7 @@ struct WOLFSSL_SESSION {
word16 idLen; /* serverID length */
byte serverID[SERVER_ID_LEN]; /* for easier client lookup */
#endif
#ifdef HAVE_SESSION_TICKET
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
#ifdef WOLFSSL_TLS13
byte namedGroup;
word32 ticketSeen; /* Time ticket seen (ms) */
@ -2657,8 +2657,10 @@ typedef struct Options {
#ifndef NO_PSK
wc_psk_client_callback client_psk_cb;
wc_psk_server_callback server_psk_cb;
word16 havePSK:1; /* psk key set by user */
#endif /* NO_PSK */
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
word16 havePSK:1; /* psk key set by user */
#endif /* HAVE_SESSION_TICKET || !NO_PSK */
#ifdef OPENSSL_EXTRA
unsigned long mask; /* store SSL_OP_ flags */
#endif
@ -2767,7 +2769,7 @@ typedef struct Arrays {
word32 preMasterSz; /* differs for DH, actual size */
word32 pendingMsgSz; /* defrag buffer size */
word32 pendingMsgOffset; /* current offset into defrag buffer */
#ifndef NO_PSK
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
word32 psk_keySz; /* actual size */
char client_identity[MAX_PSK_ID_LEN + NULL_TERM_LEN];
char server_hint[MAX_PSK_ID_LEN + NULL_TERM_LEN];
@ -3380,6 +3382,7 @@ enum HandShakeType {
change_cipher_hs = 55, /* simulate unique handshake type for sanity
checks. record layer change_cipher
conflicts with handshake finished */
message_hash = 254, /* synthetic message type for TLS v1.3 */
no_shake = 255 /* used to initialize the DtlsMsg record */
};
@ -3543,7 +3546,7 @@ WOLFSSL_LOCAL int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength);
#endif /* NO_TLS */
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET)
#if defined(WOLFSSL_TLS13) && (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK))
WOLFSSL_LOCAL word32 TimeNowInMilliseconds(void);
#endif
WOLFSSL_LOCAL word32 LowResTimer(void);