@@ -151,16 +151,23 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
151151
152152 // Try-both decode: AEAD-first for peers known to support it (avoids 1/65536
153153 // ECB false-positive on AEAD packets), ECB-first for unknown/legacy peers.
154- uint8_t assoc[3 ] = { pkt->header , dest_hash, src_hash };
154+ // Mask out route type bits — they are set after encryption and vary per hop.
155+ uint8_t assoc[3 ] = { (uint8_t )(pkt->header & ~PH_ROUTE_MASK ), dest_hash, src_hash };
155156 int len;
157+ bool decoded_aead = false ;
156158 if (getPeerFlags (j) & CONTACT_FLAG_AEAD ) {
157159 len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 3 , dest_hash, src_hash);
158- if (len <= 0 ) len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
160+ if (len > 0 ) decoded_aead = true ;
161+ else len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
159162 } else {
160163 len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
161- if (len <= 0 ) len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 3 , dest_hash, src_hash);
164+ if (len <= 0 ) {
165+ len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 3 , dest_hash, src_hash);
166+ if (len > 0 ) decoded_aead = true ;
167+ }
162168 }
163169 if (len > 0 ) { // success!
170+ if (decoded_aead) onPeerAeadDetected (j);
164171 if (pkt->getPayloadType () == PAYLOAD_TYPE_PATH ) {
165172 int k = 0 ;
166173 uint8_t path_len = data[k++];
@@ -216,7 +223,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
216223 // Phase 2 MUST swap to AEAD-first (see peer message comment above).
217224 int len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
218225 if (len <= 0 ) {
219- uint8_t assoc[2 ] = { pkt->header , dest_hash };
226+ uint8_t assoc[2 ] = { ( uint8_t )( pkt->header & ~ PH_ROUTE_MASK ) , dest_hash };
220227 len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 2 , dest_hash, 0 );
221228 }
222229 if (len > 0 ) { // success!
@@ -252,7 +259,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
252259 // worthwhile for public/hashtag channels where the PSK is already widely known.
253260 int len = Utils::MACThenDecrypt (channels[j].secret , data, macAndData, macAndDataLen);
254261 if (len <= 0 ) {
255- uint8_t assoc[2 ] = { pkt->header , channel_hash };
262+ uint8_t assoc[2 ] = { ( uint8_t )( pkt->header & ~ PH_ROUTE_MASK ) , channel_hash };
256263 len = Utils::aeadDecrypt (channels[j].secret , data, macAndData, macAndDataLen, assoc, 2 , channel_hash, 0 );
257264 }
258265 if (len > 0 ) { // success!
@@ -491,7 +498,7 @@ Packet* Mesh::createPathReturn(const uint8_t* dest_hash, const uint8_t* secret,
491498 if (aead_nonce) {
492499 uint8_t dh = packet->payload [0 ];
493500 uint8_t sh = packet->payload [1 ];
494- uint8_t assoc[3 ] = { packet->header , dh, sh };
501+ uint8_t assoc[3 ] = { ( uint8_t )( packet->header & ~ PH_ROUTE_MASK ) , dh, sh };
495502 len += Utils::aeadEncrypt (secret, &packet->payload [len], data, data_len, assoc, 3 , aead_nonce, dh, sh);
496503 } else {
497504 len += Utils::encryptThenMAC (secret, &packet->payload [len], data, data_len);
@@ -526,7 +533,7 @@ Packet* Mesh::createDatagram(uint8_t type, const Identity& dest, const uint8_t*
526533 if (aead_nonce) {
527534 uint8_t dest_hash = packet->payload [0 ];
528535 uint8_t src_hash = packet->payload [1 ];
529- uint8_t assoc[3 ] = { packet->header , dest_hash, src_hash };
536+ uint8_t assoc[3 ] = { ( uint8_t )( packet->header & ~ PH_ROUTE_MASK ) , dest_hash, src_hash };
530537 len += Utils::aeadEncrypt (secret, &packet->payload [len], data, data_len, assoc, 3 , aead_nonce, dest_hash, src_hash);
531538 } else {
532539 len += Utils::encryptThenMAC (secret, &packet->payload [len], data, data_len);
0 commit comments