Check the channel packet overhead literal against its expression

CHANNEL_PACKET_OVERHEAD_MAX is a hand-computed copy of
CHANNEL_PACKET_OVERHEAD_SZ, needed because the expression bottoms out in
wolfCrypt enum constants that #if reads as zero. Nothing tied the two
together, so a term added to the expression would leave the #error
guarding DEFAULT_MAX_PACKET_SZ silently ineffective.

Assert the bound in internal.c, where both are ordinary constant
expressions, with a negative-array-size typedef.
pull/1171/head
John Safranek 2026-08-18 08:58:52 -07:00 committed by philljj
parent 245baf01f0
commit ffe7b1cfee
2 changed files with 17 additions and 15 deletions

View File

@ -98,6 +98,14 @@
#include <wolfssl/wolfcrypt/coding.h>
/* The #error in internal.h can't compare the two: the expression's terms are
* enum constants that #if reads as zero. Here both are ordinary constant
* expressions, so a term added without bumping the literal fails the build. */
typedef char wolfSSH_channel_overhead_check[
(CHANNEL_PACKET_OVERHEAD_SZ <= CHANNEL_PACKET_OVERHEAD_MAX) ? 1 : -1];
/*
Flags:
HAVE_WC_ECC_SET_RNG

View File

@ -741,14 +741,11 @@ WOLFSSH_LOCAL int CheckAlgoList(const char* list, byte type);
* block size first to decrypt to find the size of
* the rest of the data. */
/* What a channel data packet carries besides its payload: the transport
* framing, the larger of the two channel data headers (CHANNEL_EXTENDED_DATA),
* the worst-case padding BundlePacket() can pick, and the largest MAC.
* The MAC term is the one that varies, so it is spelled twice: once with
* MAX_HMAC_SZ for the compiler, and once as a literal 64, the largest
* wolfCrypt digest, for the preprocessor. AES_BLOCK_SIZE and MAX_HMAC_SZ are
* wolfCrypt enum constants, which #if reads as zero, so the #error below
* cannot use the macro form. Both come to 4+1+1+8+4+19+64 = 101. */
/* Channel data packet overhead: transport framing, the larger channel data
* header (CHANNEL_EXTENDED_DATA), worst-case BundlePacket() padding, and the
* largest MAC. Spelled twice because AES_BLOCK_SIZE and MAX_HMAC_SZ are enum
* constants that #if reads as zero. The literal is a ceiling: 101 with a
* 64-byte MAC, less with a smaller digest. */
#define CHANNEL_PACKET_OVERHEAD_SZ \
(LENGTH_SZ + PAD_LENGTH_SZ \
+ MSG_ID_SZ + (UINT32_SZ * 2) + LENGTH_SZ \
@ -757,15 +754,12 @@ WOLFSSH_LOCAL int CheckAlgoList(const char* list, byte type);
#define CHANNEL_PACKET_OVERHEAD_MAX 101
/* Largest channel payload that still fits MAX_PACKET_SZ on the wire, which
* bounds the whole binary packet. Comes to 35000 - 101 = 34899. Derived, not
* a tunable, so it is deliberately not overridable. */
* bounds the whole binary packet. At most 35000 - 101 = 34899. Derived, not
* a tunable, so deliberately not overridable. */
#define MAX_CHANNEL_PACKET_SZ (MAX_PACKET_SZ - CHANNEL_PACKET_OVERHEAD_SZ)
/* wolfSSH_CTX_SetWindowPacketSize() bounds an explicit size by
* MAX_CHANNEL_PACKET_SZ, but a zero there and CtxInit() both take
* DEFAULT_MAX_PACKET_SZ unchecked, so assert the default holds too. Both
* MAX_PACKET_SZ and DEFAULT_MAX_PACKET_SZ are overridable and the default
* path is the common one. */
/* Both sizes are overridable, and CtxInit() takes DEFAULT_MAX_PACKET_SZ
* unchecked, so assert the default frames too. */
#if DEFAULT_MAX_PACKET_SZ > (MAX_PACKET_SZ - CHANNEL_PACKET_OVERHEAD_MAX)
#error "DEFAULT_MAX_PACKET_SZ too large to frame inside MAX_PACKET_SZ"
#endif