Skip to content

Commit

Permalink
Merge pull request #7951 from julek-wolfssl/dtls13-cid-fixes
Browse files Browse the repository at this point in the history
DTLS 1.3 CID fixes
  • Loading branch information
JacobBarthelmeh authored Sep 18, 2024
2 parents c390047 + 84c80b4 commit fb2144d
Show file tree
Hide file tree
Showing 11 changed files with 491 additions and 271 deletions.
38 changes: 27 additions & 11 deletions src/dtls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,11 @@ int Dtls13HandshakeAddHeader(WOLFSSL* ssl, byte* output,
return 0;
}

int Dtls13MinimumRecordLength(WOLFSSL* ssl)
{
return Dtls13GetRlHeaderLength(ssl, 1) + DTLS13_MIN_CIPHERTEXT;
}

/**
* Dtls13EncryptRecordNumber() - encrypt record number in the header
* @ssl: ssl object
Expand All @@ -1225,9 +1230,15 @@ int Dtls13EncryptRecordNumber(WOLFSSL* ssl, byte* hdr, word16 recordLength)
if (ssl == NULL || hdr == NULL)
return BAD_FUNC_ARG;

#ifdef HAVE_NULL_CIPHER
/* Do not encrypt record numbers with null cipher. See RFC 9150 Sec 9 */
if (ssl->specs.bulk_cipher_algorithm == wolfssl_cipher_null)
return 0;
#endif /*HAVE_NULL_CIPHER */

/* we need at least a 16 bytes of ciphertext to encrypt record number see
4.2.3*/
if (recordLength < Dtls13GetRlHeaderLength(ssl, 1) + DTLS13_MIN_CIPHERTEXT)
if (recordLength < Dtls13MinimumRecordLength(ssl))
return BUFFER_ERROR;

seqLength = (*hdr & DTLS13_LEN_BIT) ? DTLS13_SEQ_16_LEN : DTLS13_SEQ_8_LEN;
Expand Down Expand Up @@ -1453,17 +1464,22 @@ int Dtls13ParseUnifiedRecordLayer(WOLFSSL* ssl, const byte* input,
hdrInfo->recordLength = inputSize - idx;
}

/* minimum size for a dtls1.3 packet is 16 bytes (to have enough ciphertext
to create record number xor mask). (draft 43 - Sec 4.2.3) */
if (hdrInfo->recordLength < DTLS13_RN_MASK_SIZE)
return LENGTH_ERROR;
if (inputSize < idx + DTLS13_RN_MASK_SIZE)
return BUFFER_ERROR;
/* Do not encrypt record numbers with null cipher. See RFC 9150 Sec 9 */
if (ssl->specs.bulk_cipher_algorithm != wolfssl_cipher_null)
{
/* minimum size for a dtls1.3 packet is 16 bytes (to have enough
* ciphertext to create record number xor mask).
* (draft 43 - Sec 4.2.3) */
if (hdrInfo->recordLength < DTLS13_RN_MASK_SIZE)
return LENGTH_ERROR;
if (inputSize < idx + DTLS13_RN_MASK_SIZE)
return BUFFER_ERROR;

ret = Dtls13EncryptDecryptRecordNumber(ssl, seqNum, seqLen, input + idx,
DEPROTECT);
if (ret != 0)
return ret;
ret = Dtls13EncryptDecryptRecordNumber(ssl, seqNum, seqLen, input + idx,
DEPROTECT);
if (ret != 0)
return ret;
}

if (seqLen == DTLS13_SEQ_16_LEN) {
hdrInfo->seqHiPresent = 1;
Expand Down
38 changes: 32 additions & 6 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -11255,6 +11255,11 @@ static int GetDtls13RecordHeader(WOLFSSL* ssl, word32* inOutIdx,
if (ret != 0)
return ret;

if (ssl->dtls13CurRlLength > sizeof(ssl->dtls13CurRL)) {
WOLFSSL_MSG("Record header too long");
return SEQUENCE_ERROR;
}

if (readSize < ssl->dtls13CurRlLength + DTLS13_RN_MASK_SIZE) {
/* when using DTLS over a medium that does not guarantee that a full
* message is received in a single read, we may end up without the full
Expand Down Expand Up @@ -24789,6 +24794,14 @@ int SendData(WOLFSSL* ssl, const void* data, int sz)
if (IsEncryptionOn(ssl, 1) || ssl->options.tls1_3)
outputSz += cipherExtraData(ssl);

#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID)
if (ssl->options.dtls) {
unsigned int cidSz = 0;
if (wolfSSL_dtls_cid_get_tx_size(ssl, &cidSz) == WOLFSSL_SUCCESS)
outputSz += cidSz;
}
#endif

/* check for available size */
if ((ret = CheckAvailableSize(ssl, outputSz)) != 0)
return ssl->error = ret;
Expand Down Expand Up @@ -25935,7 +25948,7 @@ void SetErrorString(int error, char* str)
*/

#ifndef NO_ERROR_STRINGS
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT) || \
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)
#define SUITE_INFO(x,y,z,w,v,u) {(x),(y),(z),(w),(v),(u),WOLFSSL_CIPHER_SUITE_FLAG_NONE}
#define SUITE_ALIAS(x,z,w,v,u) {(x),"",(z),(w),(v),(u),WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS},
Expand All @@ -25944,7 +25957,7 @@ void SetErrorString(int error, char* str)
#define SUITE_ALIAS(x,z,w,v,u) {(x),"",(z),(w),WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS},
#endif
#else
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT) || \
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)
#define SUITE_INFO(x,y,z,w,v,u) {(x),(z),(w),(v),(u),WOLFSSL_CIPHER_SUITE_FLAG_NONE}
#define SUITE_ALIAS(x,z,w,v,u) {(x),(z),(w),(v),(u),WOLFSSL_CIPHER_SUITE_FLAG_NAMEALIAS},
Expand Down Expand Up @@ -26806,13 +26819,16 @@ const char* wolfSSL_get_cipher_name_iana(WOLFSSL* ssl)
}

int GetCipherSuiteFromName(const char* name, byte* cipherSuite0,
byte* cipherSuite, int* flags)
byte* cipherSuite, byte* major, byte* minor, int* flags)
{
int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
int i;
unsigned long len;
const char* nameDelim;

(void)major;
(void)minor;

/* Support trailing : */
nameDelim = XSTRSTR(name, ":");
if (nameDelim)
Expand All @@ -26830,9 +26846,19 @@ int GetCipherSuiteFromName(const char* name, byte* cipherSuite0,
#endif

if (found) {
*cipherSuite0 = cipher_names[i].cipherSuite0;
*cipherSuite = cipher_names[i].cipherSuite;
*flags = cipher_names[i].flags;
if (cipherSuite0 != NULL)
*cipherSuite0 = cipher_names[i].cipherSuite0;
if (cipherSuite != NULL)
*cipherSuite = cipher_names[i].cipherSuite;
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT) || \
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX)
if (major != NULL)
*major = cipher_names[i].major;
if (minor != NULL)
*minor = cipher_names[i].minor;
#endif
if (flags != NULL)
*flags = cipher_names[i].flags;
ret = 0;
break;
}
Expand Down
11 changes: 7 additions & 4 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -8412,6 +8412,8 @@ static int CheckcipherList(const char* list)
char name[MAX_SUITE_NAME + 1];
word32 length = MAX_SUITE_NAME;
word32 current_length;
byte major = INVALID_BYTE;
byte minor = INVALID_BYTE;

next = XSTRSTR(next, ":");

Expand All @@ -8436,10 +8438,10 @@ static int CheckcipherList(const char* list)
break;
}

ret = wolfSSL_get_cipher_suite_from_name(name, &cipherSuite0,
&cipherSuite1, &flags);
ret = GetCipherSuiteFromName(name, &cipherSuite0,
&cipherSuite1, &major, &minor, &flags);
if (ret == 0) {
if (cipherSuite0 == TLS13_BYTE) {
if (cipherSuite0 == TLS13_BYTE || minor == TLSv1_3_MINOR) {
/* TLSv13 suite */
findTLSv13Suites = 1;
}
Expand Down Expand Up @@ -14297,7 +14299,8 @@ int wolfSSL_get_cipher_suite_from_name(const char* name, byte* cipherSuite0,
(cipherSuite == NULL) ||
(flags == NULL))
return BAD_FUNC_ARG;
return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, flags);
return GetCipherSuiteFromName(name, cipherSuite0, cipherSuite, NULL, NULL,
flags);
}


Expand Down
2 changes: 1 addition & 1 deletion src/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -13500,7 +13500,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
ssl->arrays->client_identity, MAX_PSK_ID_LEN,
ssl->arrays->psk_key, MAX_PSK_KEY_LEN, &cipherName);
if (GetCipherSuiteFromName(cipherName, &cipherSuite0,
&cipherSuite, &cipherSuiteFlags) != 0) {
&cipherSuite, NULL, NULL, &cipherSuiteFlags) != 0) {
return PSK_KEY_ERROR;
}
}
Expand Down
20 changes: 16 additions & 4 deletions src/tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -3199,6 +3199,7 @@ typedef struct BuildMsg13Args {
word32 idx;
word32 headerSz;
word16 size;
word32 paddingSz;
} BuildMsg13Args;

static void FreeBuildMsg13Args(WOLFSSL* ssl, void* pArgs)
Expand Down Expand Up @@ -3304,7 +3305,14 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
args->sz++;
/* Authentication data at the end. */
args->sz += ssl->specs.aead_mac_size;

#ifdef WOLFSSL_DTLS13
/* Pad to minimum length */
if (ssl->options.dtls &&
args->sz < (word32)Dtls13MinimumRecordLength(ssl)) {
args->paddingSz = Dtls13MinimumRecordLength(ssl) - args->sz;
args->sz = Dtls13MinimumRecordLength(ssl);
}
#endif
if (sizeOnly)
return (int)args->sz;

Expand Down Expand Up @@ -3348,6 +3356,9 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,

/* The real record content type goes at the end of the data. */
output[args->idx++] = (byte)type;
/* Double check that any necessary padding is zero'd out */
XMEMSET(output + args->idx, 0, args->paddingSz);
args->idx += args->paddingSz;

ssl->options.buildMsgState = BUILD_MSG_ENCRYPT;
}
Expand Down Expand Up @@ -3393,7 +3404,8 @@ int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input,
#ifdef WOLFSSL_DTLS13
if (ret == 0 && ssl->options.dtls) {
/* AAD points to the header. Reuse the variable */
ret = Dtls13EncryptRecordNumber(ssl, (byte*)aad, (word16)args->sz);
ret = Dtls13EncryptRecordNumber(ssl, (byte*)aad,
(word16)args->sz);
}
#endif /* WOLFSSL_DTLS13 */
}
Expand Down Expand Up @@ -3940,7 +3952,7 @@ static int SetupPskKey(WOLFSSL* ssl, PreSharedKey* psk, int clientHello)
MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN,
&cipherName);
if (GetCipherSuiteFromName(cipherName, &cipherSuite0,
&cipherSuite, &cipherSuiteFlags) != 0) {
&cipherSuite, NULL, NULL, &cipherSuiteFlags) != 0) {
WOLFSSL_ERROR_VERBOSE(PSK_KEY_ERROR);
return PSK_KEY_ERROR;
}
Expand Down Expand Up @@ -5852,7 +5864,7 @@ int FindPskSuite(const WOLFSSL* ssl, PreSharedKey* psk, byte* psk_key,
if (*psk_keySz != 0) {
int cipherSuiteFlags = WOLFSSL_CIPHER_SUITE_FLAG_NONE;
*found = (GetCipherSuiteFromName(cipherName, &cipherSuite0,
&cipherSuite, &cipherSuiteFlags) == 0);
&cipherSuite, NULL, NULL, &cipherSuiteFlags) == 0);
(void)cipherSuiteFlags;
}
}
Expand Down
Loading

0 comments on commit fb2144d

Please sign in to comment.