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
No known key found for this signature in database
GPG Key ID: 929C8E45E33B5FD2
3 changed files with
10 additions and
4 deletions
src/Mesh.cpp
src/Utils.cpp
src/helpers/ContactInfo.h
@ -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
}
@ -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 ;
@ -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 ;