Skip to content

Commit 7595a95

Browse files
yosuke-wolfsslejohnstown
authored andcommitted
internal: reject inbound packets that are not block aligned
- DoReceive() validates the peeked packet_length in PROCESS_PACKET_LENGTH: UINT32_SZ plus curSz for non-AEAD, curSz alone for AEAD, against peerBlockSz floored at MIN_BLOCK_SZ. A non-zero remainder sets ssh->error to WS_BUFFER_E and returns WS_FATAL_ERROR. - BuildMacTestPacketPrefix() in unit.c takes padLen from the caller and pads to a block-aligned total; test_DoReceive_VerifyMacFailure, test_DoReceive_AeadTagFailure, and test_DoReceive_RejectsShortPadding follow. - BuildPacket() in regress.c pads to 16. - test_DoReceive_RejectsMisalignedPacket, test_DoReceive_RejectsMisalignedCtr, and test_DoReceive_RejectsMisalignedAead cover the cleartext, AES-CTR, and AES-GCM paths. Issue: F-8834
1 parent f494688 commit 7595a95

3 files changed

Lines changed: 336 additions & 20 deletions

File tree

src/internal.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12810,10 +12810,12 @@ int DoReceive(WOLFSSH* ssh)
1281012810
int ret = WS_SUCCESS;
1281112811
int verifyResult;
1281212812
word32 readSz;
12813+
word32 alignSz;
1281312814
byte peerBlockSz = ssh->peerBlockSz;
1281412815
byte peerMacSz = ssh->peerMacSz;
1281512816
byte aeadMode = ssh->peerAeadMode;
1281612817
byte bufferConsumed = 0;
12818+
byte alignBlockSz;
1281712819

1281812820
switch (ssh->processReplyState) {
1281912821
case PROCESS_INIT:
@@ -12852,6 +12854,21 @@ int DoReceive(WOLFSSH* ssh)
1285212854
ssh->error = WS_OVERFLOW_E;
1285312855
return WS_FATAL_ERROR;
1285412856
}
12857+
12858+
/* RFC 4253 section 6 aligns packet_length through the padding
12859+
* on the block size, or 8, whichever is larger. Under AES-GCM
12860+
* the length is AAD, so RFC 5647 section 7.2 aligns the body. */
12861+
alignBlockSz = peerBlockSz < MIN_BLOCK_SZ ?
12862+
MIN_BLOCK_SZ : peerBlockSz;
12863+
alignSz = aeadMode ? ssh->curSz : UINT32_SZ + ssh->curSz;
12864+
if (alignSz % alignBlockSz != 0) {
12865+
WLOG(WS_LOG_DEBUG,
12866+
"Packet not block aligned: aligned size = %u, "
12867+
"block = %u, aead = %u",
12868+
alignSz, (word32)alignBlockSz, (word32)aeadMode);
12869+
ssh->error = WS_BUFFER_E;
12870+
return WS_FATAL_ERROR;
12871+
}
1285512872
ssh->processReplyState = PROCESS_PACKET_FINISH;
1285612873
FALL_THROUGH;
1285712874

tests/regress.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,10 @@ static HandshakeInfo* AllocHandshake(WOLFSSH* ssh)
107107
}
108108

109109
/* Build a minimal SSH binary packet carrying only a message ID.
110-
* Layout: uint32 packetLen, byte padLen, payload[msgId], pad[padLen].
111-
* Choose padLen so total is 8-byte aligned for the clear transport case. */
110+
* Layout: uint32 packetLen, byte padLen, payload[msgId], pad[padLen]. */
112111
static word32 BuildPacket(byte msgId, byte* out, word32 outSz)
113112
{
114-
byte padLen = 6; /* 1 (msgId) +1 (padLen) +6 = 8 */
113+
byte padLen = 10; /* 4 (len) +1 (padLen) +1 (msgId) +10 = 16 */
115114
word32 packetLen = 1 + 1 + padLen; /* payload + padLen field + pad */
116115
word32 need = 4 + packetLen;
117116

0 commit comments

Comments
 (0)