From c05d700debc68a6892e03c63a748f0943f22d16a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20Lowas-Rzechonek?= Date: Thu, 27 Jun 2019 09:40:42 +0200 Subject: [PATCH] mesh: Fixed handling of IVI flag in app layer Since IV Index is used in application nonces, we need to honor IVI flag not only in network layer crypto, but also in application layer. This means that if IVI field of incoming packet is different than in current IV Index, try to decode *both* net and app layers using IV Index decreased by one. Change-Id: Ieaacc703dac4aa8b9a58ea6bf01a92b1893e9b7b Signed-off-by: Anupam Roy --- mesh/net-keys.c | 6 ------ mesh/net.c | 17 ++++++++--------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/mesh/net-keys.c b/mesh/net-keys.c index 25f4cae..5be7e0b 100644 --- a/mesh/net-keys.c +++ b/mesh/net-keys.c @@ -209,12 +209,6 @@ static void decrypt_net_pkt(void *a, void *b) uint32_t net_key_decrypt(uint32_t iv_index, const uint8_t *pkt, size_t len, uint8_t **plain, size_t *plain_len) { - bool iv_flag = !!(iv_index & 1); - bool iv_pkt = !!(pkt[0] & 0x80); - - if (iv_pkt != iv_flag) - iv_index--; - /* If we already successfully decrypted this packet, use cached data */ if (cache_id && cache_len == len && !memcmp(pkt, cache_pkt, len)) { /* IV Index must match what was used to decrypt */ diff --git a/mesh/net.c b/mesh/net.c index 771ae5d..1654152 100644 --- a/mesh/net.c +++ b/mesh/net.c @@ -2487,8 +2487,13 @@ static void net_rx(void *net_ptr, void *user_data) size_t out_size; uint32_t key_id; int8_t rssi = 0; + bool ivi_net = !!(net->iv_index & 1); + bool ivi_pkt = !!(data->data[0] & 0x80); - key_id = net_key_decrypt(net->iv_index, data->data, data->len, + /* if IVI flag differs, use previous IV Index */ + uint32_t iv_index = net->iv_index - (ivi_pkt ^ ivi_net); + + key_id = net_key_decrypt(iv_index, data->data, data->len, &out, &out_size); if (!key_id) @@ -2502,16 +2507,10 @@ static void net_rx(void *net_ptr, void *user_data) rssi = data->info->rssi; } - relay_advice = packet_received(net, key_id, net->iv_index, + relay_advice = packet_received(net, key_id, iv_index, out, out_size, rssi); if (relay_advice > data->relay_advice) { - bool iv_flag = !!(net->iv_index & 1); - bool iv_pkt = !!(data->data[0] & 0x80); - - data->iv_index = net->iv_index; - if (iv_pkt != iv_flag) - data->iv_index--; - + data->iv_index = iv_index; data->relay_advice = relay_advice; data->key_id = key_id; data->net = net; -- 2.7.4