Skip to content

Commit b3779da

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 65d0880 commit b3779da

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

@@ -14770,7 +14782,10 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1477014782
{
1477114783
int ret = 0;
1477214784
TLSX* extension;
14773-
word16 length = 0;
14785+
/* Accumulate in word32 so per-extension additions can't silently wrap
14786+
* a word16 total - the final 16-bit bound is enforced once at the end. */
14787+
word32 length = 0;
14788+
word16 hsz;
1477414789
byte isRequest = (msgType == client_hello ||
1477514790
msgType == certificate_request);
1477614791

@@ -14870,19 +14885,25 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1487014885
#endif
1487114886
#if defined(HAVE_ENCRYPT_THEN_MAC) && !defined(WOLFSSL_AEAD_ONLY)
1487214887
case TLSX_ENCRYPT_THEN_MAC:
14873-
ret = ETM_GET_SIZE(msgType, &length);
14888+
hsz = 0;
14889+
ret = ETM_GET_SIZE(msgType, &hsz);
14890+
length += hsz;
1487414891
break;
1487514892
#endif /* HAVE_ENCRYPT_THEN_MAC */
1487614893

1487714894
#if defined(WOLFSSL_TLS13) || !defined(WOLFSSL_NO_TLS12) || !defined(NO_OLD_TLS)
1487814895
#if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)
1487914896
case TLSX_PRE_SHARED_KEY:
14897+
hsz = 0;
1488014898
ret = PSK_GET_SIZE((PreSharedKey*)extension->data, msgType,
14881-
&length);
14899+
&hsz);
14900+
length += hsz;
1488214901
break;
1488314902
#ifdef WOLFSSL_TLS13
1488414903
case TLSX_PSK_KEY_EXCHANGE_MODES:
14885-
ret = PKM_GET_SIZE((byte)extension->val, msgType, &length);
14904+
hsz = 0;
14905+
ret = PKM_GET_SIZE((byte)extension->val, msgType, &hsz);
14906+
length += hsz;
1488614907
break;
1488714908
#endif
1488814909
#endif
@@ -14893,22 +14914,30 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1489314914

1489414915
#ifdef WOLFSSL_TLS13
1489514916
case TLSX_SUPPORTED_VERSIONS:
14896-
ret = SV_GET_SIZE(extension->data, msgType, &length);
14917+
hsz = 0;
14918+
ret = SV_GET_SIZE(extension->data, msgType, &hsz);
14919+
length += hsz;
1489714920
break;
1489814921

1489914922
case TLSX_COOKIE:
14900-
ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &length);
14923+
hsz = 0;
14924+
ret = CKE_GET_SIZE((Cookie*)extension->data, msgType, &hsz);
14925+
length += hsz;
1490114926
break;
1490214927

1490314928
#ifdef WOLFSSL_EARLY_DATA
1490414929
case TLSX_EARLY_DATA:
14905-
ret = EDI_GET_SIZE(msgType, &length);
14930+
hsz = 0;
14931+
ret = EDI_GET_SIZE(msgType, &hsz);
14932+
length += hsz;
1490614933
break;
1490714934
#endif
1490814935

1490914936
#ifdef WOLFSSL_POST_HANDSHAKE_AUTH
1491014937
case TLSX_POST_HANDSHAKE_AUTH:
14911-
ret = PHA_GET_SIZE(msgType, &length);
14938+
hsz = 0;
14939+
ret = PHA_GET_SIZE(msgType, &hsz);
14940+
length += hsz;
1491214941
break;
1491314942
#endif
1491414943

@@ -14966,7 +14995,11 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType,
1496614995
TURN_ON(semaphore, TLSX_ToSemaphore((word16)extension->type));
1496714996
}
1496814997

14969-
*pLength += length;
14998+
if (ret == 0 && (word32)*pLength + length > WOLFSSL_MAX_16BIT) {
14999+
WOLFSSL_ERROR_VERBOSE(LENGTH_ERROR);
15000+
return LENGTH_ERROR;
15001+
}
15002+
*pLength += (word16)length;
1497015003

1497115004
return ret;
1497215005
}

0 commit comments

Comments
 (0)