Skip to content

Commit 6ca048d

Browse files
committed
tls: fix TLSX_PreSharedKey_GetSize word16 overflow (F-2925)
Both TLSX_PreSharedKey_GetSize and TLSX_PreSharedKey_GetSizeBinders accumulate per-identity bytes into a word16. With enough PSK entries (or large binderLen/identityLen values) the accumulator wraps silently and the caller allocates an undersized extension buffer, which TLSX_PreSharedKey_Write then overflows. Switch both accumulators to word32 and return LENGTH_ERROR when the total would exceed the 16-bit wire length field.
1 parent 246cc90 commit 6ca048d

1 file changed

Lines changed: 48 additions & 15 deletions

File tree

src/tls.c

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11911,14 +11911,22 @@ static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType,
1191111911
{
1191211912
if (msgType == client_hello) {
1191311913
/* Length of identities + Length of binders. */
11914-
word16 len = OPAQUE16_LEN + OPAQUE16_LEN;
11914+
word32 len = OPAQUE16_LEN + OPAQUE16_LEN;
1191511915
while (list != NULL) {
1191611916
/* Each entry has: identity, ticket age and binder. */
1191711917
len += OPAQUE16_LEN + list->identityLen + OPAQUE32_LEN +
11918-
OPAQUE8_LEN + (word16)list->binderLen;
11918+
OPAQUE8_LEN + (word32)list->binderLen;
11919+
if (len > WOLFSSL_MAX_16BIT) {
11920+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11921+
return LENGTH_ERROR;
11922+
}
1191911923
list = list->next;
1192011924
}
11921-
*pSz += len;
11925+
if ((word32)*pSz + len > WOLFSSL_MAX_16BIT) {
11926+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11927+
return LENGTH_ERROR;
11928+
}
11929+
*pSz += (word16)len;
1192211930
return 0;
1192311931
}
1192411932

@@ -11941,7 +11949,7 @@ static int TLSX_PreSharedKey_GetSize(PreSharedKey* list, byte msgType,
1194111949
int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType,
1194211950
word16* pSz)
1194311951
{
11944-
word16 len;
11952+
word32 len;
1194511953

1194611954
if (msgType != client_hello) {
1194711955
WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E);
@@ -11951,11 +11959,15 @@ int TLSX_PreSharedKey_GetSizeBinders(PreSharedKey* list, byte msgType,
1195111959
/* Length of all binders. */
1195211960
len = OPAQUE16_LEN;
1195311961
while (list != NULL) {
11954-
len += OPAQUE8_LEN + (word16)list->binderLen;
11962+
len += OPAQUE8_LEN + (word32)list->binderLen;
11963+
if (len > WOLFSSL_MAX_16BIT) {
11964+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
11965+
return LENGTH_ERROR;
11966+
}
1195511967
list = list->next;
1195611968
}
1195711969

11958-
*pSz = len;
11970+
*pSz = (word16)len;
1195911971
return 0;
1196011972
}
1196111973

@@ -14858,7 +14870,10 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1485814870
{
1485914871
int ret = 0;
1486014872
TLSX* extension;
14861-
word16 length = 0;
14873+
/* Accumulate in word32 so per-extension additions can't silently wrap
14874+
* a word16 total - the final 16-bit bound is enforced once at the end. */
14875+
word32 length = 0;
14876+
word16 hsz;
1486214877
byte isRequest = (msgType == client_hello ||
1486314878
msgType == certificate_request);
1486414879

@@ -14958,19 +14973,25 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1495814973
#endif
1495914974
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
1496014975
case TLSX_ENCRYPT_THEN_MAC:
14961-
ret = ETM_GET_SIZE(msgType, &length);
14976+
hsz = 0;
14977+
ret = ETM_GET_SIZE(msgType, &hsz);
14978+
length += hsz;
1496214979
break;
1496314980
#endif /* HAVE_ENCRYPT_THEN_MAC */
1496414981

1496514982
#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
1496614983
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
1496714984
case TLSX_PRE_SHARED_KEY:
14985+
hsz = 0;
1496814986
ret = PSK_GET_SIZE((PreSharedKey*)extension->data, msgType,
14969-
&length);
14987+
&hsz);
14988+
length += hsz;
1497014989
break;
1497114990
#ifdef WOLFSSL_TLS13
1497214991
case TLSX_PSK_KEY_EXCHANGE_MODES:
14973-
ret = PKM_GET_SIZE((byte)extension->val, msgType, &length);
14992+
hsz = 0;
14993+
ret = PKM_GET_SIZE((byte)extension->val, msgType, &hsz);
14994+
length += hsz;
1497414995
break;
1497514996
#ifdef WOLFSSL_CERT_WITH_EXTERN_PSK
1497614997
case TLSX_CERT_WITH_EXTERN_PSK:
@@ -14986,22 +15007,30 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1498615007

1498715008
#ifdef WOLFSSL_TLS13
1498815009
case TLSX_SUPPORTED_VERSIONS:
14989-
ret = SV_GET_SIZE(extension->data, msgType, &length);
15010+
hsz = 0;
15011+
ret = SV_GET_SIZE(extension->data, msgType, &hsz);
15012+
length += hsz;
1499015013
break;
1499115014

1499215015
case TLSX_COOKIE:
14993-
ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length);
15016+
hsz = 0;
15017+
ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &hsz);
15018+
length += hsz;
1499415019
break;
1499515020

1499615021
#ifdef WOLFSSL_EARLY_DATA
1499715022
case TLSX_EARLY_DATA:
14998-
ret = EDI_GET_SIZE(msgType, &length);
15023+
hsz = 0;
15024+
ret = EDI_GET_SIZE(msgType, &hsz);
15025+
length += hsz;
1499915026
break;
1500015027
#endif
1500115028

1500215029
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
1500315030
case TLSX_POST_HANDSHAKE_AUTH:
15004-
ret = PHA_GET_SIZE(msgType, &length);
15031+
hsz = 0;
15032+
ret = PHA_GET_SIZE(msgType, &hsz);
15033+
length += hsz;
1500515034
break;
1500615035
#endif
1500715036

@@ -15059,7 +15088,11 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1505915088
TURN_ON(semaphore, TLSX_ToSemaphore((word16)extension->type));
1506015089
}
1506115090

15062-
*pLength += length;
15091+
if (ret == 0 && (word32)*pLength + length > WOLFSSL_MAX_16BIT) {
15092+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
15093+
return LENGTH_ERROR;
15094+
}
15095+
*pLength += (word16)length;
1506315096

1506415097
return ret;
1506515098
}

0 commit comments

Comments
 (0)