Move appkey_packet_decrypt to mesh/model, rename it to app_packet_decrypt, make it private and change arguments to be aligned with other decryption functions. Also, simplify the implementation using an inline loop, removing the need of mod_decrypt struct. --- mesh/appkey.c | 111 +++++++++----------------------------------------- mesh/appkey.h | 10 ++--- mesh/model.c | 73 +++++++++++++++++++++++++++++---- 3 files changed, 89 insertions(+), 105 deletions(-) diff --git a/mesh/appkey.c b/mesh/appkey.c index 6c65454c1..e96d5228a 100644 --- a/mesh/appkey.c +++ b/mesh/appkey.c @@ -50,23 +50,6 @@ struct mesh_msg { uint16_t src; }; -struct mod_decrypt { - const uint8_t *data; - uint8_t *out; - struct mesh_app_key *key; - uint8_t *virt; - uint32_t seq; - uint32_t iv_idx; - uint16_t src; - uint16_t dst; - uint16_t idx; - uint16_t size; - uint16_t virt_size; - uint8_t key_aid; - bool szmict; - bool decrypted; -}; - static bool match_key_index(const void *a, const void *b) { const struct mesh_app_key *key = a; @@ -99,80 +82,6 @@ static bool clean_old_iv_index(void *a, void *b) return false; } -static void packet_decrypt(void *a, void *b) -{ - struct mesh_app_key *key = a; - struct mod_decrypt *dec = b; - - l_debug("model.c - app_packet_decrypt"); - if (dec->decrypted) - return; - - if (key->key_aid != dec->key_aid && - key->new_key_aid != dec->key_aid) - return; - - dec->key = key; - - if (key->key_aid == dec->key_aid) { - dec->decrypted = mesh_crypto_payload_decrypt(dec->virt, - dec->virt_size, dec->data, dec->size, - dec->szmict, dec->src, dec->dst, dec->key_aid, - dec->seq, dec->iv_idx, dec->out, key->key); - if (dec->decrypted) - print_packet("Used App Key", dec->key->key, 16); - else - print_packet("Failed with App Key", dec->key->key, 16); - } - - if (!dec->decrypted && key->new_key_aid == dec->key_aid) { - dec->decrypted = mesh_crypto_payload_decrypt(dec->virt, - dec->virt_size, dec->data, dec->size, - dec->szmict, dec->src, dec->dst, dec->key_aid, - dec->seq, dec->iv_idx, dec->out, key->new_key); - if (dec->decrypted) - print_packet("Used App Key", dec->key->new_key, 16); - else - print_packet("Failed with App Key", - dec->key->new_key, 16); - } - - if (dec->decrypted) - dec->idx = key->app_idx; -} - -int appkey_packet_decrypt(struct mesh_net *net, bool szmict, uint32_t seq, - uint32_t iv_index, uint16_t src, - uint16_t dst, uint8_t *virt, uint16_t virt_size, - uint8_t key_aid, const uint8_t *data, - uint16_t data_size, uint8_t *out) -{ - struct l_queue *app_keys; - - struct mod_decrypt decrypt = { - .src = src, - .dst = dst, - .seq = seq, - .data = data, - .out = out, - .size = data_size, - .key_aid = key_aid, - .iv_idx = iv_index, - .virt = virt, - .virt_size = virt_size, - .szmict = szmict, - .decrypted = false, - }; - - app_keys = mesh_net_get_app_keys(net); - if (!app_keys) - return -1; - - l_queue_foreach(app_keys, packet_decrypt, &decrypt); - - return decrypt.decrypted ? decrypt.idx : -1; -} - bool appkey_msg_in_replay_cache(struct mesh_net *net, uint16_t idx, uint16_t src, uint16_t crpl, uint32_t seq, uint32_t iv_index) @@ -345,6 +254,26 @@ const uint8_t *appkey_get_key(struct mesh_net *net, uint16_t app_idx, return app_key->new_key; } +int appkey_get_key_idx(struct mesh_app_key *app_key, + const uint8_t **key, uint8_t *key_aid, + const uint8_t **new_key, uint8_t *new_key_aid) +{ + if (!app_key) + return -1; + + if (key && key_aid) { + *key = app_key->key; + *key_aid = app_key->key_aid; + } + + if (new_key && new_key_aid) { + *new_key = app_key->new_key; + *new_key_aid = app_key->new_key_aid; + } + + return app_key->app_idx; +} + bool appkey_have_key(struct mesh_net *net, uint16_t app_idx) { struct mesh_app_key *key; diff --git a/mesh/appkey.h b/mesh/appkey.h index 4c135580a..b3e548071 100644 --- a/mesh/appkey.h +++ b/mesh/appkey.h @@ -20,19 +20,19 @@ /* TODO: get this number from configuration */ #define MAX_APP_KEYS 32 +struct mesh_app_key; + bool appkey_key_init(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx, uint8_t *key_value, uint8_t *new_key_value); void appkey_key_free(void *data); -int appkey_packet_decrypt(struct mesh_net *net, bool szmict, uint32_t seq, - uint32_t iv_index, uint16_t src, uint16_t dst, - uint8_t *virt, uint16_t virt_size, - uint8_t key_id, const uint8_t *data, - uint16_t data_size, uint8_t *out); bool appkey_msg_in_replay_cache(struct mesh_net *net, uint16_t idx, uint16_t src, uint16_t crpl, uint32_t seq, uint32_t iv_index); const uint8_t *appkey_get_key(struct mesh_net *net, uint16_t app_idx, uint8_t *key_id); +int appkey_get_key_idx(struct mesh_app_key *app_key, + const uint8_t **key, uint8_t *key_aid, + const uint8_t **new_key, uint8_t *new_key_aid); bool appkey_have_key(struct mesh_net *net, uint16_t app_idx); uint16_t appkey_net_idx(struct mesh_net *net, uint16_t app_idx); int appkey_key_add(struct mesh_net *net, uint16_t net_idx, uint16_t app_idx, diff --git a/mesh/model.c b/mesh/model.c index 2ecaf00e9..52cb57429 100644 --- a/mesh/model.c +++ b/mesh/model.c @@ -353,6 +353,62 @@ static void forward_model(void *a, void *b) fwd->done = true; } +static int app_packet_decrypt(struct mesh_net *net, const uint8_t *data, + uint16_t size, bool szmict, uint16_t src, + uint16_t dst, uint8_t *virt, uint16_t virt_size, + uint8_t key_aid, uint32_t seq, + uint32_t iv_idx, uint8_t *out) +{ + struct l_queue *app_keys = mesh_net_get_app_keys(net); + const struct l_queue_entry *entry; + + if (!app_keys) + return -1; + + for (entry = l_queue_get_entries(app_keys); entry; + entry = entry->next) { + const uint8_t *old_key = NULL, *new_key = NULL; + uint8_t old_key_aid, new_key_aid; + int app_idx; + bool decrypted; + + app_idx = appkey_get_key_idx(entry->data, + &old_key, &old_key_aid, + &new_key, &new_key_aid); + + if (app_idx < 0) + continue; + + if (old_key && old_key_aid == key_aid) { + decrypted = mesh_crypto_payload_decrypt(NULL, 0, data, + size, szmict, src, dst, key_aid, + seq, iv_idx, out, old_key); + + if (decrypted) { + print_packet("Used App Key", old_key, 16); + return app_idx; + } + + print_packet("Failed App Key", old_key, 16); + } + + if (new_key && new_key_aid == key_aid) { + decrypted = mesh_crypto_payload_decrypt(NULL, 0, data, + size, szmict, src, dst, key_aid, + seq, iv_idx, out, new_key); + + if (decrypted) { + print_packet("Used App Key", new_key, 16); + return app_idx; + } + + print_packet("Failed App Key", new_key, 16); + } + } + + return -1; +} + static int dev_packet_decrypt(struct mesh_node *node, const uint8_t *data, uint16_t size, bool szmict, uint16_t src, uint16_t dst, uint8_t key_aid, uint32_t seq, @@ -395,11 +451,10 @@ static int virt_packet_decrypt(struct mesh_net *net, const uint8_t *data, if (virt->addr != dst) continue; - decrypt_idx = appkey_packet_decrypt(net, szmict, seq, - iv_idx, src, dst, - virt->label, 16, - key_aid, - data, size, out); + decrypt_idx = app_packet_decrypt(net, data, size, szmict, src, + dst, virt->label, 16, + key_aid, seq, iv_idx, + out); if (decrypt_idx >= 0) { *decrypt_virt = virt; @@ -853,10 +908,10 @@ bool mesh_model_rx(struct mesh_node *node, bool szmict, uint32_t seq0, iv_index, clear_text, &decrypt_virt); else - decrypt_idx = appkey_packet_decrypt(net, szmict, seq0, - iv_index, src, dst, - NULL, 0, key_aid, data, - size, clear_text); + decrypt_idx = app_packet_decrypt(net, data, size, szmict, src, + dst, NULL, 0, + key_aid, seq0, iv_index, + clear_text); if (decrypt_idx < 0) { l_error("model.c - Failed to decrypt application payload"); -- 2.19.1