@@ -156,16 +156,23 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
156156
157157 // Try-both decode: AEAD-first for peers known to support it (avoids 1/65536
158158 // ECB false-positive on AEAD packets), ECB-first for unknown/legacy peers.
159- uint8_t assoc[3 ] = { pkt->header , dest_hash, src_hash };
159+ // Mask out route type bits — they are set after encryption and vary per hop.
160+ uint8_t assoc[3 ] = { (uint8_t )(pkt->header & ~PH_ROUTE_MASK ), dest_hash, src_hash };
160161 int len;
162+ bool decoded_aead = false ;
161163 if (getPeerFlags (j) & CONTACT_FLAG_AEAD ) {
162164 len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 3 , dest_hash, src_hash);
163- if (len <= 0 ) len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
165+ if (len > 0 ) decoded_aead = true ;
166+ else len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
164167 } else {
165168 len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
166- if (len <= 0 ) len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 3 , dest_hash, src_hash);
169+ if (len <= 0 ) {
170+ len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 3 , dest_hash, src_hash);
171+ if (len > 0 ) decoded_aead = true ;
172+ }
167173 }
168174 if (len > 0 ) { // success!
175+ if (decoded_aead) onPeerAeadDetected (j);
169176 if (pkt->getPayloadType () == PAYLOAD_TYPE_PATH ) {
170177 int k = 0 ;
171178 uint8_t path_len = data[k++];
@@ -219,7 +226,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
219226 // Phase 2 MUST swap to AEAD-first (see peer message comment above).
220227 int len = Utils::MACThenDecrypt (secret, data, macAndData, macAndDataLen);
221228 if (len <= 0 ) {
222- uint8_t assoc[2 ] = { pkt->header , dest_hash };
229+ uint8_t assoc[2 ] = { ( uint8_t )( pkt->header & ~ PH_ROUTE_MASK ) , dest_hash };
223230 len = Utils::aeadDecrypt (secret, data, macAndData, macAndDataLen, assoc, 2 , dest_hash, 0 );
224231 }
225232 if (len > 0 ) { // success!
@@ -255,7 +262,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
255262 // worthwhile for public/hashtag channels where the PSK is already widely known.
256263 int len = Utils::MACThenDecrypt (channels[j].secret , data, macAndData, macAndDataLen);
257264 if (len <= 0 ) {
258- uint8_t assoc[2 ] = { pkt->header , channel_hash };
265+ uint8_t assoc[2 ] = { ( uint8_t )( pkt->header & ~ PH_ROUTE_MASK ) , channel_hash };
259266 len = Utils::aeadDecrypt (channels[j].secret , data, macAndData, macAndDataLen, assoc, 2 , channel_hash, 0 );
260267 }
261268 if (len > 0 ) { // success!
@@ -498,7 +505,7 @@ Packet* Mesh::createPathReturn(const uint8_t* dest_hash, const uint8_t* secret,
498505 if (aead_nonce) {
499506 uint8_t dh = packet->payload [0 ];
500507 uint8_t sh = packet->payload [1 ];
501- uint8_t assoc[3 ] = { packet->header , dh, sh };
508+ uint8_t assoc[3 ] = { ( uint8_t )( packet->header & ~ PH_ROUTE_MASK ) , dh, sh };
502509 len += Utils::aeadEncrypt (secret, &packet->payload [len], data, data_len, assoc, 3 , aead_nonce, dh, sh);
503510 } else {
504511 len += Utils::encryptThenMAC (secret, &packet->payload [len], data, data_len);
@@ -533,7 +540,7 @@ Packet* Mesh::createDatagram(uint8_t type, const Identity& dest, const uint8_t*
533540 if (aead_nonce) {
534541 uint8_t dest_hash = packet->payload [0 ];
535542 uint8_t src_hash = packet->payload [1 ];
536- uint8_t assoc[3 ] = { packet->header , dest_hash, src_hash };
543+ uint8_t assoc[3 ] = { ( uint8_t )( packet->header & ~ PH_ROUTE_MASK ) , dest_hash, src_hash };
537544 len += Utils::aeadEncrypt (secret, &packet->payload [len], data, data_len, assoc, 3 , aead_nonce, dest_hash, src_hash);
538545 } else {
539546 len += Utils::encryptThenMAC (secret, &packet->payload [len], data, data_len);
0 commit comments