net: l2: ieee802154: decouple frame decryption from upper layer fields

The L2 function `ieee802154_decipher_data_frame()` relied on upper layer
LL address fields which breaks encapsulation.

Also fixes a bug introduced in another fix that went overboard (#53734).

Fixes: #78490

Signed-off-by: Florian Grandel <fgrandel@code-for-humans.de>
This commit is contained in:
Florian Grandel 2024-09-17 16:06:53 +02:00 committed by Fabio Baltieri
parent 766fda06c2
commit da0371accf
2 changed files with 13 additions and 13 deletions

View file

@ -271,11 +271,10 @@ static inline void swap_and_set_pkt_ll_addr(struct net_linkaddr *addr, bool has_
addr->addr = NULL;
}
/* The net stack expects link layer addresses to be in
* big endian format for posix compliance so we must swap it.
* This is ok as the L2 address field comes from the header
* part of the packet buffer which will not be directly accessible
* once the packet reaches the upper layers.
/* The net stack expects big endian link layer addresses for POSIX compliance
* so we must swap it. This is ok as the L2 address field points into the L2
* header of the frame buffer which will no longer be accessible once the
* packet reaches upper layers.
*/
if (addr->len > 0) {
sys_mem_swap(addr->addr, addr->len);
@ -435,9 +434,9 @@ static enum net_verdict ieee802154_recv(struct net_if *iface, struct net_pkt *pk
return NET_DROP;
}
/* Setting L2 addresses must be done after packet authentication and internal
* packet handling as it will mangle the package header to comply with upper
* network layers' (POSIX) requirement to represent network addresses in big endian.
/* Setting LL addresses for upper layers must be done after L2 packet
* handling as it will mangle the L2 frame header to comply with upper
* layers' (POSIX) requirement to represent network addresses in big endian.
*/
swap_and_set_pkt_ll_addr(net_pkt_lladdr_src(pkt), !fs->fc.pan_id_comp,
fs->fc.src_addr_mode, mpdu.mhr.src_addr);

View file

@ -934,8 +934,8 @@ bool ieee802154_decipher_data_frame(struct net_if *iface, struct net_pkt *pkt,
{
struct ieee802154_context *ctx = net_if_l2_data(iface);
uint8_t level, authtag_len, ll_hdr_len, payload_len;
int8_t ext_addr_le[IEEE802154_EXT_ADDR_LENGTH];
struct ieee802154_mhr *mhr = &mpdu->mhr;
struct ieee802154_address *src;
bool ret = false;
k_sem_take(&ctx->ctx_lock, K_FOREVER);
@ -970,14 +970,15 @@ bool ieee802154_decipher_data_frame(struct net_if *iface, struct net_pkt *pkt,
* This will require to look up in nbr cache with short addr
* in order to get the extended address related to it.
*/
if (net_pkt_lladdr_src(pkt)->len != IEEE802154_EXT_ADDR_LENGTH) {
NET_ERR("Decrypting packages with short source addresses is not supported.");
if (mhr->fs->fc.src_addr_mode != IEEE802154_ADDR_MODE_EXTENDED) {
NET_ERR("Only encrypting packages with extended source addresses is supported.");
goto out;
}
sys_memcpy_swap(ext_addr_le, net_pkt_lladdr_src(pkt)->addr, net_pkt_lladdr_src(pkt)->len);
src = mhr->fs->fc.pan_id_comp ? &mhr->src_addr->comp.addr : &mhr->src_addr->plain.addr;
if (!ieee802154_decrypt_auth(&ctx->sec_ctx, net_pkt_data(pkt), ll_hdr_len, payload_len,
authtag_len, ext_addr_le,
authtag_len, src->ext_addr,
sys_le32_to_cpu(mhr->aux_sec->frame_counter))) {
NET_ERR("Could not decipher the frame");
goto out;