Skip to content

Commit 16c61a4

Browse files
committed
Harden AEAD-4 bounds checks and add nonce wrap logging
- Fix potential unsigned overflow in createDatagram size check by subtracting constants from MAX_PACKET_PAYLOAD instead of adding to data_len - Add upper-bound validation on src_len and assoc_len in aeadEncrypt and aeadDecrypt - Log peer name on AEAD nonce wraparound for debug builds
1 parent 0954142 commit 16c61a4

3 files changed

Lines changed: 10 additions & 4 deletions

File tree

src/Mesh.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,8 @@ Packet* Mesh::createDatagram(uint8_t type, const Identity& dest, const uint8_t*
514514
if (type == PAYLOAD_TYPE_TXT_MSG || type == PAYLOAD_TYPE_REQ || type == PAYLOAD_TYPE_RESPONSE) {
515515
size_t hash_prefix = PATH_HASH_SIZE * 2; // dest_hash + src_hash
516516
size_t max_overhead = aead_nonce ? (AEAD_NONCE_SIZE + AEAD_TAG_SIZE) : (CIPHER_MAC_SIZE + CIPHER_BLOCK_SIZE-1);
517-
if (data_len + hash_prefix + max_overhead > MAX_PACKET_PAYLOAD) return NULL;
517+
size_t max_payload_data = MAX_PACKET_PAYLOAD - hash_prefix - max_overhead;
518+
if (data_len > max_payload_data) return NULL;
518519
} else {
519520
return NULL; // invalid type
520521
}

src/Utils.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ int Utils::aeadEncrypt(const uint8_t* shared_secret,
122122
const uint8_t* assoc_data, int assoc_len,
123123
uint16_t nonce_counter,
124124
uint8_t dest_hash, uint8_t src_hash) {
125-
if (src_len <= 0) return 0;
125+
if (src_len <= 0 || src_len > MAX_PACKET_PAYLOAD) return 0;
126+
if (assoc_len < 0 || assoc_len > MAX_PACKET_PAYLOAD) return 0;
126127

127128
// Write nonce to output
128129
dest[0] = (uint8_t)(nonce_counter >> 8);
@@ -166,7 +167,8 @@ int Utils::aeadDecrypt(const uint8_t* shared_secret,
166167
const uint8_t* assoc_data, int assoc_len,
167168
uint8_t dest_hash, uint8_t src_hash) {
168169
// Minimum: nonce(2) + at least 1 byte ciphertext + tag(4)
169-
if (src_len < AEAD_NONCE_SIZE + 1 + AEAD_TAG_SIZE) return 0;
170+
if (src_len < AEAD_NONCE_SIZE + 1 + AEAD_TAG_SIZE || src_len > MAX_PACKET_PAYLOAD) return 0;
171+
if (assoc_len < 0 || assoc_len > MAX_PACKET_PAYLOAD) return 0;
170172

171173
int ct_len = src_len - AEAD_NONCE_SIZE - AEAD_TAG_SIZE;
172174

src/helpers/ContactInfo.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ struct ContactInfo {
2323
// When 0, callers use ECB encryption.
2424
uint16_t nextAeadNonce() const {
2525
if (flags & CONTACT_FLAG_AEAD) {
26-
if (++aead_nonce == 0) ++aead_nonce; // skip 0 (sentinel for ECB)
26+
if (++aead_nonce == 0) {
27+
++aead_nonce; // skip 0 (sentinel for ECB)
28+
MESH_DEBUG_PRINTLN("AEAD nonce wrapped for peer: %s", name);
29+
}
2730
return aead_nonce;
2831
}
2932
return 0;

0 commit comments

Comments
 (0)