Browse Source

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
pull/1677/head
Wessel Nieboer 6 months ago
parent
commit
7682782405
No known key found for this signature in database GPG Key ID: 929C8E45E33B5FD2
  1. 3
      src/Mesh.cpp
  2. 6
      src/Utils.cpp
  3. 5
      src/helpers/ContactInfo.h

3
src/Mesh.cpp

@ -531,7 +531,8 @@ Packet* Mesh::createDatagram(uint8_t type, const Identity& dest, const uint8_t*
if (type == PAYLOAD_TYPE_TXT_MSG || type == PAYLOAD_TYPE_REQ || type == PAYLOAD_TYPE_RESPONSE) {
size_t hash_prefix = PATH_HASH_SIZE * 2; // dest_hash + src_hash
size_t max_overhead = aead_nonce ? (AEAD_NONCE_SIZE + AEAD_TAG_SIZE) : (CIPHER_MAC_SIZE + CIPHER_BLOCK_SIZE-1);
if (data_len + hash_prefix + max_overhead > MAX_PACKET_PAYLOAD) return NULL;
size_t max_payload_data = MAX_PACKET_PAYLOAD - hash_prefix - max_overhead;
if (data_len > max_payload_data) return NULL;
} else {
return NULL; // invalid type
}

6
src/Utils.cpp

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

5
src/helpers/ContactInfo.h

@ -23,7 +23,10 @@ struct ContactInfo {
// When 0, callers use ECB encryption.
uint16_t nextAeadNonce() const {
if (flags & CONTACT_FLAG_AEAD) {
if (++aead_nonce == 0) ++aead_nonce; // skip 0 (sentinel for ECB)
if (++aead_nonce == 0) {
++aead_nonce; // skip 0 (sentinel for ECB)
MESH_DEBUG_PRINTLN("AEAD nonce wrapped for peer: %s", name);
}
return aead_nonce;
}
return 0;

Loading…
Cancel
Save