Skip to content

fix - security : prevent OOB write in decrypt() for non-multiple-of-16 src_len#2069

Open
9hozt wants to merge 1 commit intomeshcore-dev:mainfrom
9hozt:fix/decrypt-oob
Open

fix - security : prevent OOB write in decrypt() for non-multiple-of-16 src_len#2069
9hozt wants to merge 1 commit intomeshcore-dev:mainfrom
9hozt:fix/decrypt-oob

Conversation

@9hozt
Copy link

@9hozt 9hozt commented Mar 17, 2026

Problem

Utils::decrypt() checks only that the start of the current block is within
bounds, but aes.decryptBlock() always writes 16 bytes. If src_len is not
a multiple of 16, the last partial block causes an out-of-bounds write into
adjacent memory.

By brute-forcing the 2-byte HMAC (65,536 possible values, ~32,768 attempts on average for a 50% success rate), it is possible to craft and inject arbitrary messages outside of the official app.

Example with src_len=182:

  • Block 12 starts at offset 176 → condition 176 < 182 is true
  • decryptBlock() writes dest[176..191]
  • But dest (data[MAX_PACKET_PAYLOAD]) is only 184 bytes → 8 bytes OOB

The header comment in Utils.h:40 states that src_len should be a multiple
of block size, but this precondition was not enforced in the implementation.

Fix

Change the loop condition to verify that a full 16-byte block is available
before attempting to decrypt it:

  • Before: while (sp - src < src_len)
  • After: while (sp - src + 16 <= src_len)

Impact

No behavioral change for legitimate messages — encrypt() always outputs
a multiple of 16, so decrypt() always receives a valid multiple of 16 in
normal operation. The fix only affects malformed inputs.

@9hozt 9hozt changed the title fix: prevent OOB write in decrypt() for non-multiple-of-16 src_len fix - security : prevent OOB write in decrypt() for non-multiple-of-16 src_len Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant