2020-03-26 21:18:40

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: [PATCH BlueZ RESEND] mesh: Remove redundant code from mesh/crypto

- Remove application_encrypt/application_decrypt
- Make mesh_crypto_privacy_counter private, add mesh_crypto_pecb
- Make *_nonce functions private and align their implementation to be
more consistent
- Refactor network_encrypt/network_decrypt to use *_nonce functions and
rename them to packet_encrypt/packet_decrypt
- Refactor packet_encode/packet_decode
---
mesh/crypto.c | 481 ++++++++++++++++------------------------
mesh/crypto.h | 50 +----
mesh/net-keys.c | 2 +-
unit/test-mesh-crypto.c | 205 ++++++++---------
4 files changed, 291 insertions(+), 447 deletions(-)

diff --git a/mesh/crypto.c b/mesh/crypto.c
index 596a289f9..ce335bbec 100644
--- a/mesh/crypto.c
+++ b/mesh/crypto.c
@@ -327,144 +327,59 @@ bool mesh_crypto_beacon_cmac(const uint8_t encryption_key[16],
return true;
}

-bool mesh_crypto_network_nonce(bool ctl, uint8_t ttl, uint32_t seq,
- uint16_t src, uint32_t iv_index,
- uint8_t nonce[13])
+static void mesh_crypto_network_nonce(bool ctl, uint8_t ttl,
+ uint32_t seq, uint16_t src,
+ uint32_t iv_index, uint8_t nonce[13])
{
- nonce[0] = 0;
+ nonce[0] = 0x00;
nonce[1] = (ttl & TTL_MASK) | (ctl ? CTL : 0x00);
nonce[2] = (seq >> 16) & 0xff;
nonce[3] = (seq >> 8) & 0xff;
nonce[4] = seq & 0xff;
-
- /* SRC */
l_put_be16(src, nonce + 5);
-
l_put_be16(0, nonce + 7);
-
- /* IV Index */
l_put_be32(iv_index, nonce + 9);
-
- return true;
-}
-
-bool mesh_crypto_network_encrypt(bool ctl, uint8_t ttl,
- uint32_t seq, uint16_t src,
- uint32_t iv_index,
- const uint8_t net_key[16],
- const uint8_t *enc_msg, uint8_t enc_msg_len,
- uint8_t *out, void *net_mic)
-{
- uint8_t nonce[13];
-
- if (!mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce))
- return false;
-
- return mesh_crypto_aes_ccm_encrypt(nonce, net_key, NULL, 0, enc_msg,
- enc_msg_len, out, net_mic,
- ctl ? 8 : 4);
}

-bool mesh_crypto_network_decrypt(bool ctl, uint8_t ttl,
- uint32_t seq, uint16_t src,
- uint32_t iv_index,
- const uint8_t net_key[16],
- const uint8_t *enc_msg, uint8_t enc_msg_len,
- uint8_t *out, void *net_mic, size_t mic_size)
-{
- uint8_t nonce[13];
-
- if (!mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce))
- return false;
-
- return mesh_crypto_aes_ccm_decrypt(nonce, net_key, NULL, 0,
- enc_msg, enc_msg_len, out,
- net_mic, mic_size);
-}
-
-bool mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
+static void mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
uint16_t dst, uint32_t iv_index,
bool aszmic, uint8_t nonce[13])
{
nonce[0] = 0x01;
nonce[1] = aszmic ? 0x80 : 0x00;
- nonce[2] = (seq & 0x00ff0000) >> 16;
- nonce[3] = (seq & 0x0000ff00) >> 8;
- nonce[4] = (seq & 0x000000ff);
- nonce[5] = (src & 0xff00) >> 8;
- nonce[6] = (src & 0x00ff);
- nonce[7] = (dst & 0xff00) >> 8;
- nonce[8] = (dst & 0x00ff);
+ nonce[2] = (seq >> 16 ) & 0xff;
+ nonce[3] = (seq >> 8) & 0xff;
+ nonce[4] = seq & 0xff;
+ l_put_be16(src, nonce + 5);
+ l_put_be16(dst, nonce + 7);
l_put_be32(iv_index, nonce + 9);
-
- return true;
}

-bool mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
+static void mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
uint16_t dst, uint32_t iv_index,
bool aszmic, uint8_t nonce[13])
{
nonce[0] = 0x02;
nonce[1] = aszmic ? 0x80 : 0x00;
- nonce[2] = (seq & 0x00ff0000) >> 16;
- nonce[3] = (seq & 0x0000ff00) >> 8;
- nonce[4] = (seq & 0x000000ff);
- nonce[5] = (src & 0xff00) >> 8;
- nonce[6] = (src & 0x00ff);
- nonce[7] = (dst & 0xff00) >> 8;
- nonce[8] = (dst & 0x00ff);
+ nonce[2] = (seq >> 16 ) & 0xff;
+ nonce[3] = (seq >> 8) & 0xff;
+ nonce[4] = seq & 0xff;
+ l_put_be16(src, nonce + 5);
+ l_put_be16(dst, nonce + 7);
l_put_be32(iv_index, nonce + 9);
-
- return true;
}

-bool mesh_crypto_application_encrypt(uint8_t key_aid, uint32_t seq,
- uint16_t src, uint16_t dst,
- uint32_t iv_index,
- const uint8_t app_key[16],
- const uint8_t *aad, uint8_t aad_len,
- const uint8_t *msg, uint8_t msg_len,
- uint8_t *out,
- void *app_mic, size_t mic_size)
+static void mesh_crypto_proxy_nonce(uint32_t seq, uint16_t src,
+ uint32_t iv_index, uint8_t nonce[13])
{
- uint8_t nonce[13];
- bool aszmic = (mic_size == 8) ? true : false;
-
- if (!key_aid && !mesh_crypto_device_nonce(seq, src, dst,
- iv_index, aszmic, nonce))
- return false;
-
- if (key_aid && !mesh_crypto_application_nonce(seq, src, dst,
- iv_index, aszmic, nonce))
- return false;
-
- return mesh_crypto_aes_ccm_encrypt(nonce, app_key, aad, aad_len,
- msg, msg_len,
- out, app_mic, mic_size);
-}
-
-bool mesh_crypto_application_decrypt(uint8_t key_aid, uint32_t seq,
- uint16_t src, uint16_t dst, uint32_t iv_index,
- const uint8_t app_key[16],
- const uint8_t *aad, uint8_t aad_len,
- const uint8_t *enc_msg, uint8_t enc_msg_len,
- uint8_t *out, void *app_mic, size_t mic_size)
-{
- uint8_t nonce[13];
- bool aszmic = (mic_size == 8) ? true : false;
-
- if (!key_aid && !mesh_crypto_device_nonce(seq, src, dst,
- iv_index, aszmic, nonce))
- return false;
-
- if (key_aid && !mesh_crypto_application_nonce(seq, src, dst,
- iv_index, aszmic, nonce))
- return false;
-
- return mesh_crypto_aes_ccm_decrypt(nonce, app_key,
- aad, aad_len, enc_msg,
- enc_msg_len, out,
- app_mic, mic_size);
+ nonce[0] = 0x03;
+ nonce[1] = 0;
+ nonce[2] = (seq >> 16) & 0xff;
+ nonce[3] = (seq >> 8) & 0xff;
+ nonce[4] = seq & 0xff;
+ l_put_be16(src, nonce + 5);
+ l_put_be16(0, nonce + 7);
+ l_put_be32(iv_index, nonce + 9);
}

bool mesh_crypto_session_key(const uint8_t secret[32],
@@ -557,69 +472,67 @@ bool mesh_crypto_virtual_addr(const uint8_t virtual_label[16],
return true;
}

-bool mesh_crypto_privacy_counter(uint32_t iv_index,
+static void mesh_crypto_privacy_counter(uint32_t iv_index,
const uint8_t *payload,
uint8_t privacy_counter[16])
{
memset(privacy_counter, 0, 5);
l_put_be32(iv_index, privacy_counter + 5);
memcpy(privacy_counter + 9, payload, 7);
+}

- return true;
+static bool mesh_crypto_pecb(const uint8_t privacy_key[16],
+ uint32_t iv_index,
+ const uint8_t *payload,
+ uint8_t pecb[16])
+{
+ mesh_crypto_privacy_counter(iv_index, payload, pecb);
+ return aes_ecb_one(privacy_key, pecb, pecb);
}

-bool mesh_crypto_network_obfuscate(const uint8_t privacy_key[16],
- const uint8_t privacy_counter[16],
- bool ctl, uint8_t ttl, uint32_t seq,
- uint16_t src, uint8_t *out)
+static bool mesh_crypto_network_obfuscate(uint8_t *packet,
+ const uint8_t privacy_key[16],
+ uint32_t iv_index,
+ bool ctl, uint8_t ttl,
+ uint32_t seq, uint16_t src)
{
- uint8_t ecb[16], tmp[16];
+ uint8_t pecb[16];
+ uint8_t *net_hdr = packet + 1;
int i;

- if (!aes_ecb_one(privacy_key, privacy_counter, ecb))
+ if (!mesh_crypto_pecb(privacy_key, iv_index, packet + 7, pecb))
return false;

- tmp[0] = ((!!ctl) << 7) | (ttl & TTL_MASK);
- tmp[1] = (seq & 0xff0000) >> 16;
- tmp[2] = (seq & 0x00ff00) >> 8;
- tmp[3] = (seq & 0x0000ff);
- tmp[4] = (src & 0xff00) >> 8;
- tmp[5] = (src & 0x00ff);
+ l_put_be16(src, net_hdr + 4);
+ l_put_be32(seq & SEQ_MASK, net_hdr);
+ net_hdr[0] = ((!!ctl) << 7) | (ttl & TTL_MASK);

- if (out) {
- for (i = 0; i < 6; i++)
- out[i] = ecb[i] ^ tmp[i];
- }
+ for (i = 0; i < 6; i++)
+ net_hdr[i] = pecb[i] ^ net_hdr[i];

return true;
}

-bool mesh_crypto_network_clarify(const uint8_t privacy_key[16],
- const uint8_t privacy_counter[16],
- const uint8_t net_hdr[6],
- bool *ctl, uint8_t *ttl,
- uint32_t *seq, uint16_t *src)
+static bool mesh_crypto_network_clarify(uint8_t *packet,
+ const uint8_t privacy_key[16],
+ uint32_t iv_index,
+ bool *ctl, uint8_t *ttl,
+ uint32_t *seq, uint16_t *src)
{
- uint8_t ecb[16], tmp[6];
+ uint8_t pecb[16];
+ uint8_t *net_hdr = packet + 1;
int i;

- if (!aes_ecb_one(privacy_key, privacy_counter, ecb))
+ if (!mesh_crypto_pecb(privacy_key, iv_index, packet + 7, pecb))
return false;

for (i = 0; i < 6; i++)
- tmp[i] = ecb[i] ^ net_hdr[i];
-
- if (ctl)
- *ctl = !!(tmp[0] & CTL);
+ net_hdr[i] = pecb[i] ^ net_hdr[i];

- if (ttl)
- *ttl = tmp[0] & TTL_MASK;
-
- if (seq)
- *seq = l_get_be32(tmp) & SEQ_MASK;
-
- if (src)
- *src = l_get_be16(tmp + 4);
+ *src = l_get_be16(net_hdr + 4);
+ *seq = l_get_be32(net_hdr) & SEQ_MASK;
+ *ttl = net_hdr[0] & TTL_MASK;
+ *ctl = !!(net_hdr[0] & CTL);

return true;
}
@@ -689,24 +602,13 @@ bool mesh_crypto_packet_build(bool ctl, uint8_t ttl,
return true;
}

-bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
+static bool network_header_parse(const uint8_t *packet, uint8_t packet_len,
bool *ctl, uint8_t *ttl, uint32_t *seq,
- uint16_t *src, uint16_t *dst,
- uint32_t *cookie, uint8_t *opcode,
- bool *segmented, uint8_t *key_aid,
- bool *szmic, bool *relay, uint16_t *seqZero,
- uint8_t *segO, uint8_t *segN,
- const uint8_t **payload, uint8_t *payload_len)
+ uint16_t *src, uint16_t *dst)
{
- uint32_t hdr;
- uint16_t this_dst;
- bool is_segmented;
-
if (packet_len < 10)
return false;

- this_dst = l_get_be16(packet + 7);
-
/* Try to keep bits in the order they exist within the packet */
if (ctl)
*ctl = !!(packet[1] & CTL);
@@ -720,6 +622,30 @@ bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
if (src)
*src = l_get_be16(packet + 5);

+ if (dst)
+ *dst = l_get_be16(packet + 7);
+
+ return true;
+
+}
+
+bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
+ bool *ctl, uint8_t *ttl, uint32_t *seq,
+ uint16_t *src, uint16_t *dst,
+ uint32_t *cookie, uint8_t *opcode,
+ bool *segmented, uint8_t *key_aid,
+ bool *szmic, bool *relay, uint16_t *seqZero,
+ uint8_t *segO, uint8_t *segN,
+ const uint8_t **payload, uint8_t *payload_len)
+{
+ uint32_t hdr;
+ uint16_t this_dst;
+ bool is_segmented;
+
+ if (!network_header_parse(packet, packet_len,
+ ctl, ttl, seq, src, &this_dst))
+ return false;
+
if (dst)
*dst = this_dst;

@@ -799,38 +725,27 @@ bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
bool mesh_crypto_payload_encrypt(uint8_t *aad, const uint8_t *payload,
uint8_t *out, uint16_t payload_len,
uint16_t src, uint16_t dst, uint8_t key_aid,
- uint32_t seq_num, uint32_t iv_index,
+ uint32_t seq, uint32_t iv_index,
bool aszmic,
- const uint8_t application_key[16])
+ const uint8_t app_key[16])
{
- uint8_t application_nonce[13] = { 0x01, };
+ uint8_t nonce[13];

if (payload_len < 1)
return false;

if (key_aid == APP_AID_DEV)
- application_nonce[0] = 0x02;
-
- /* Seq Num */
- l_put_be32(seq_num, application_nonce + 1);
-
- /* ASZMIC */
- application_nonce[1] |= aszmic ? 0x80 : 0x00;
-
- /* SRC */
- l_put_be16(src, application_nonce + 5);
-
- /* DST */
- l_put_be16(dst, application_nonce + 7);
-
- /* IV Index */
- l_put_be32(iv_index, application_nonce + 9);
-
- if (!mesh_crypto_aes_ccm_encrypt(application_nonce, application_key,
- aad, aad ? 16 : 0,
- payload, payload_len,
- out, NULL,
- aszmic ? 8 : 4))
+ mesh_crypto_device_nonce(seq, src, dst, iv_index, aszmic,
+ nonce);
+ else
+ mesh_crypto_application_nonce(seq, src, dst, iv_index, aszmic,
+ nonce);
+
+ if (!mesh_crypto_aes_ccm_encrypt(nonce, app_key,
+ aad, aad ? 16 : 0,
+ payload, payload_len,
+ out, NULL,
+ aszmic ? 8 : 4))
return false;

return true;
@@ -838,13 +753,13 @@ bool mesh_crypto_payload_encrypt(uint8_t *aad, const uint8_t *payload,

bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
const uint8_t *payload, uint16_t payload_len,
- bool szmict,
+ bool aszmic,
uint16_t src, uint16_t dst,
- uint8_t key_aid, uint32_t seq_num,
+ uint8_t key_aid, uint32_t seq,
uint32_t iv_index, uint8_t *out,
const uint8_t app_key[16])
{
- uint8_t app_nonce[13] = { 0x01, };
+ uint8_t nonce[13];
uint32_t mic32;
uint64_t mic64;

@@ -852,27 +767,16 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
return false;

if (key_aid == APP_AID_DEV)
- app_nonce[0] = 0x02;
-
- /* Seq Num */
- l_put_be32(seq_num, app_nonce + 1);
-
- /* ASZMIC */
- app_nonce[1] |= szmict ? 0x80 : 0x00;
-
- /* SRC */
- l_put_be16(src, app_nonce + 5);
-
- /* DST */
- l_put_be16(dst, app_nonce + 7);
-
- /* IV Index */
- l_put_be32(iv_index, app_nonce + 9);
+ mesh_crypto_device_nonce(seq, src, dst, iv_index, aszmic,
+ nonce);
+ else
+ mesh_crypto_application_nonce(seq, src, dst, iv_index, aszmic,
+ nonce);

memcpy(out, payload, payload_len);

- if (szmict) {
- if (!mesh_crypto_aes_ccm_decrypt(app_nonce, app_key,
+ if (aszmic) {
+ if (!mesh_crypto_aes_ccm_decrypt(nonce, app_key,
aad, aad_len,
payload, payload_len,
out, &mic64, sizeof(mic64)))
@@ -884,7 +788,7 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
if (mic64)
return false;
} else {
- if (!mesh_crypto_aes_ccm_decrypt(app_nonce, app_key,
+ if (!mesh_crypto_aes_ccm_decrypt(nonce, app_key,
aad, aad_len,
payload, payload_len,
out, &mic32, sizeof(mic32)))
@@ -900,146 +804,107 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
return true;
}

-bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
+static bool mesh_crypto_packet_encrypt(uint8_t *packet, uint8_t packet_len,
const uint8_t network_key[16],
- uint32_t iv_index,
- const uint8_t privacy_key[16])
+ uint32_t iv_index, bool proxy,
+ bool ctl, uint8_t ttl, uint32_t seq,
+ uint16_t src)
{
- uint8_t network_nonce[13] = { 0x00, 0x00 };
- uint8_t privacy_counter[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
- uint8_t tmp[16];
- int i;
-
- if (packet_len < 14)
- return false;
+ uint8_t nonce[13];

/* Detect Proxy packet by CTL == true && DST == 0x0000 */
- if ((packet[1] & CTL) && l_get_be16(packet + 7) == 0)
- network_nonce[0] = 0x03; /* Proxy Nonce */
+ if (ctl && proxy)
+ mesh_crypto_proxy_nonce(seq, src, iv_index, nonce);
else
- /* CTL + TTL */
- network_nonce[1] = packet[1];
-
- /* Seq Num */
- network_nonce[2] = packet[2];
- network_nonce[3] = packet[3];
- network_nonce[4] = packet[4];
-
- /* SRC */
- network_nonce[5] = packet[5];
- network_nonce[6] = packet[6];
-
- /* DST not available */
- network_nonce[7] = 0;
- network_nonce[8] = 0;
-
- /* IV Index */
- l_put_be32(iv_index, network_nonce + 9);
+ mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce);

/* Check for Long net-MIC */
- if (packet[1] & CTL) {
- if (!mesh_crypto_aes_ccm_encrypt(network_nonce, network_key,
+ if (ctl) {
+ if (!mesh_crypto_aes_ccm_encrypt(nonce, network_key,
NULL, 0,
packet + 7, packet_len - 7 - 8,
packet + 7, NULL, 8))
return false;
} else {
- if (!mesh_crypto_aes_ccm_encrypt(network_nonce, network_key,
+ if (!mesh_crypto_aes_ccm_encrypt(nonce, network_key,
NULL, 0,
packet + 7, packet_len - 7 - 4,
packet + 7, NULL, 4))
return false;
}

- l_put_be32(iv_index, privacy_counter + 5);
- memcpy(privacy_counter + 9, packet + 7, 7);
-
- if (!aes_ecb_one(privacy_key, privacy_counter, tmp))
- return false;
-
- for (i = 0; i < 6; i++)
- packet[1 + i] ^= tmp[i];
-
return true;
}

-bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
- bool proxy, uint8_t *out, uint32_t iv_index,
+bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
+ uint32_t iv_index,
const uint8_t network_key[16],
const uint8_t privacy_key[16])
{
- uint8_t privacy_counter[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
- uint8_t network_nonce[13] = { 0x00, 0x00, };
- uint8_t tmp[16];
+ bool ctl;
+ uint8_t ttl;
+ uint32_t seq;
uint16_t src;
- int i;
+ uint16_t dst;

- if (packet_len < 14)
+ if (!network_header_parse(packet, packet_len,
+ &ctl, &ttl, &seq, &src, &dst))
return false;

- l_put_be32(iv_index, privacy_counter + 5);
- memcpy(privacy_counter + 9, packet + 7, 7);
+ if (!mesh_crypto_packet_encrypt(packet, packet_len, network_key,
+ iv_index, !dst,
+ ctl, ttl, seq, src))

- if (!aes_ecb_one(privacy_key, privacy_counter, tmp))
return false;

- memcpy(out, packet, packet_len);
- for (i = 0; i < 6; i++)
- out[1 + i] ^= tmp[i];
+ return mesh_crypto_network_obfuscate(packet, privacy_key, iv_index,
+ ctl, ttl, seq, src);
+}

- src = l_get_be16(out + 5);
+static bool mesh_crypto_packet_decrypt(uint8_t *packet, uint8_t packet_len,
+ const uint8_t network_key[16],
+ uint32_t iv_index, bool proxy,
+ bool ctl, uint8_t ttl, uint32_t seq,
+ uint16_t src)
+{
+ uint8_t nonce[13];

/* Pre-check SRC address for illegal values */
- if (!src || src >= 0x8000)
+ if (!IS_UNICAST(src))
return false;

/* Detect Proxy packet by CTL == true && proxy == true */
- if ((out[1] & CTL) && proxy)
- network_nonce[0] = 0x03; /* Proxy Nonce */
+ if (ctl & proxy)
+ mesh_crypto_proxy_nonce(seq, src, iv_index, nonce);
else
- /* CTL + TTL */
- network_nonce[1] = out[1];
-
- /* Seq Num */
- network_nonce[2] = out[2];
- network_nonce[3] = out[3];
- network_nonce[4] = out[4];
-
- /* SRC */
- network_nonce[5] = out[5];
- network_nonce[6] = out[6];
-
- /* DST not available */
- network_nonce[7] = 0;
- network_nonce[8] = 0;
-
- /* IV Index */
- l_put_be32(iv_index, network_nonce + 9);
+ mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce);

/* Check for Long MIC */
- if (out[1] & CTL) {
+ if (ctl) {
uint64_t mic;

- if (!mesh_crypto_aes_ccm_decrypt(network_nonce, network_key,
- NULL, 0, packet + 7, packet_len - 7,
- out + 7, &mic, sizeof(mic)))
+ if (!mesh_crypto_aes_ccm_decrypt(nonce, network_key,
+ NULL, 0,
+ packet + 7, packet_len - 7,
+ packet + 7, &mic, sizeof(mic)))
return false;

- mic ^= l_get_be64(out + packet_len - 8);
- l_put_be64(mic, out + packet_len - 8);
+ mic ^= l_get_be64(packet + packet_len - 8);
+ l_put_be64(mic, packet + packet_len - 8);

if (mic)
return false;
} else {
uint32_t mic;

- if (!mesh_crypto_aes_ccm_decrypt(network_nonce, network_key,
- NULL, 0, packet + 7, packet_len - 7,
- out + 7, &mic, sizeof(mic)))
+ if (!mesh_crypto_aes_ccm_decrypt(nonce, network_key,
+ NULL, 0,
+ packet + 7, packet_len - 7,
+ packet + 7, &mic, sizeof(mic)))
return false;

- mic ^= l_get_be32(out + packet_len - 4);
- l_put_be32(mic, out + packet_len - 4);
+ mic ^= l_get_be32(packet + packet_len - 4);
+ l_put_be32(mic, packet + packet_len - 4);

if (mic)
return false;
@@ -1048,6 +913,30 @@ bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
return true;
}

+bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
+ bool proxy, uint8_t *out, uint32_t iv_index,
+ const uint8_t network_key[16],
+ const uint8_t privacy_key[16])
+{
+ bool ctl;
+ uint8_t ttl;
+ uint32_t seq;
+ uint16_t src;
+
+ if (packet_len < 14)
+ return false;
+
+ memcpy(out, packet, packet_len);
+
+ if (!mesh_crypto_network_clarify(out, privacy_key, iv_index,
+ &ctl, &ttl, &seq, &src))
+ return false;
+
+ return mesh_crypto_packet_decrypt(out, packet_len, network_key,
+ iv_index, proxy,
+ ctl, ttl, seq, src);
+}
+
bool mesh_crypto_packet_label(uint8_t *packet, uint8_t packet_len,
uint16_t iv_index, uint8_t network_id)
{
diff --git a/mesh/crypto.h b/mesh/crypto.h
index e5ce840b4..7d3f89cde 100644
--- a/mesh/crypto.h
+++ b/mesh/crypto.h
@@ -19,6 +19,7 @@

#include <stdbool.h>
#include <stdint.h>
+#include <stdlib.h>

bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
const uint8_t *aad, uint16_t aad_len,
@@ -41,40 +42,6 @@ bool mesh_crypto_beacon_cmac(const uint8_t encryption_key[16],
const uint8_t network_id[16],
uint32_t iv_index, bool kr,
bool iu, uint64_t *cmac);
-bool mesh_crypto_network_nonce(bool frnd, uint8_t ttl, uint32_t seq,
- uint16_t src, uint32_t iv_index,
- uint8_t nonce[13]);
-bool mesh_crypto_network_encrypt(bool ctl, uint8_t ttl,
- uint32_t seq, uint16_t src,
- uint32_t iv_index,
- const uint8_t net_key[16],
- const uint8_t *enc_msg, uint8_t enc_msg_len,
- uint8_t *out, void *net_mic);
-bool mesh_crypto_network_decrypt(bool frnd, uint8_t ttl,
- uint32_t seq, uint16_t src,
- uint32_t iv_index,
- const uint8_t net_key[16],
- const uint8_t *enc_msg, uint8_t enc_msg_len,
- uint8_t *out, void *net_mic, size_t mic_size);
-bool mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
- uint16_t dst, uint32_t iv_index,
- bool aszmic, uint8_t nonce[13]);
-bool mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
- uint16_t dst, uint32_t iv_index,
- bool aszmic, uint8_t nonce[13]);
-bool mesh_crypto_application_encrypt(uint8_t akf, uint32_t seq, uint16_t src,
- uint16_t dst, uint32_t iv_index,
- const uint8_t app_key[16],
- const uint8_t *aad, uint8_t aad_len,
- const uint8_t *msg, uint8_t msg_len,
- uint8_t *out,
- void *app_mic, size_t mic_size);
-bool mesh_crypto_application_decrypt(uint8_t akf, uint32_t seq, uint16_t src,
- uint16_t dst, uint32_t iv_index,
- const uint8_t app_key[16],
- const uint8_t *aad, uint8_t aad_len,
- const uint8_t *enc_msg, uint8_t enc_msg_len,
- uint8_t *out, void *app_mic, size_t mic_size);
bool mesh_crypto_device_key(const uint8_t secret[32],
const uint8_t salt[16],
uint8_t device_key[16]);
@@ -102,19 +69,6 @@ bool mesh_crypto_prov_conf_key(const uint8_t secret[32],
bool mesh_crypto_session_key(const uint8_t secret[32],
const uint8_t salt[16],
uint8_t session_key[16]);
-bool mesh_crypto_privacy_counter(uint32_t iv_index,
- const uint8_t *payload,
- uint8_t privacy_counter[16]);
-bool mesh_crypto_network_obfuscate(const uint8_t privacy_key[16],
- const uint8_t privacy_counter[16],
- bool ctl, uint8_t ttl, uint32_t seq,
- uint16_t src, uint8_t *out);
-bool mesh_crypto_network_clarify(const uint8_t privacy_key[16],
- const uint8_t privacy_counter[16],
- const uint8_t net_hdr[6],
- bool *ctl, uint8_t *ttl,
- uint32_t *seq, uint16_t *src);
-
bool mesh_crypto_packet_build(bool ctl, uint8_t ttl,
uint32_t seq,
uint16_t src, uint16_t dst,
@@ -146,8 +100,8 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
uint8_t *out,
const uint8_t application_key[16]);
bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
- const uint8_t network_key[16],
uint32_t iv_index,
+ const uint8_t network_key[16],
const uint8_t privacy_key[16]);
bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
bool proxy, uint8_t *out, uint32_t iv_index,
diff --git a/mesh/net-keys.c b/mesh/net-keys.c
index 683a924c4..f7eb2ca68 100644
--- a/mesh/net-keys.c
+++ b/mesh/net-keys.c
@@ -263,7 +263,7 @@ bool net_key_encrypt(uint32_t id, uint32_t iv_index, uint8_t *pkt, size_t len)
if (!key)
return false;

- result = mesh_crypto_packet_encode(pkt, len, key->encrypt, iv_index,
+ result = mesh_crypto_packet_encode(pkt, len, iv_index, key->encrypt,
key->privacy);

if (!result)
diff --git a/unit/test-mesh-crypto.c b/unit/test-mesh-crypto.c
index 0043b0b10..3ecb3d026 100644
--- a/unit/test-mesh-crypto.c
+++ b/unit/test-mesh-crypto.c
@@ -780,8 +780,8 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
uint8_t priv_rand[16];
uint8_t packet[29];
uint8_t packet_len;
- uint64_t net_mic64;
- uint32_t hdr, net_mic32;
+ uint32_t hdr;
+ uint64_t net_mic64, net_mic32;
size_t net_msg_len;
uint8_t key_aid = keys->key_aid | (keys->akf ? KEY_ID_AKF : 0x00);

@@ -857,13 +857,12 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
net_msg_len = len + 2;
show_data("TransportPayload", 7, packet + 7, net_msg_len);

- mesh_crypto_network_encrypt(keys->ctl,
- keys->net_ttl, keys->net_seq[0],
- keys->net_src,
- keys->iv_index, enc_key,
- packet + 7, len + 2, packet + 7,
- keys->ctl ? (void *)&net_mic64 :
- (void *)&net_mic32);
+ mesh_crypto_packet_encrypt(packet, packet_len,
+ enc_key,
+ keys->iv_index, false,
+ keys->ctl, keys->net_ttl,
+ keys->net_seq[0],
+ keys->net_src);

mesh_crypto_privacy_counter(keys->iv_index, packet + 7, priv_rand);

@@ -883,20 +882,22 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
verify_data("EncNetworkPayload", 7, keys->net_msg[0],
packet + 7, net_msg_len);
if (keys->ctl) {
+ net_mic64 = l_get_be64(packet + 7 + net_msg_len);
verify_uint64("NetworkMIC", 7 + net_msg_len,
- keys->net_mic64, net_mic64);
+ keys->net_mic64, net_mic64);
net_msg_len += 8;
} else {
+ net_mic32 = l_get_be32(packet + 7 + net_msg_len);
verify_uint32("NetworkMIC", 7 + net_msg_len,
- keys->net_mic32[0], net_mic32);
+ keys->net_mic32[0], net_mic32);
net_msg_len += 4;
}

show_data("PreObsPayload", 1, packet + 1, 6 + net_msg_len);
- mesh_crypto_network_obfuscate(priv_key, priv_rand,
- keys->ctl,
- keys->net_ttl, keys->net_seq[0],
- keys->net_src, packet + 1);
+ mesh_crypto_network_obfuscate(packet, priv_key,
+ keys->iv_index,
+ keys->ctl, keys->net_ttl,
+ keys->net_seq[0], keys->net_src);
show_data("PostObsPayload", 1, packet + 1, 6 + net_msg_len);

packet[0] = (keys->iv_index & 0x01) << 7 | nid;
@@ -1019,25 +1020,23 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
if (keys->szmic) {
seg_max = SEG_MAX(keys->segmented, app_msg_len + 8);
enc_msg = l_malloc(app_msg_len + 8);
- mesh_crypto_application_encrypt(key_aid, keys->app_seq,
- keys->net_src, keys->net_dst,
- keys->iv_index,
- keys->akf ? app_key : dev_key,
- aad, aad_len,
- app_msg, app_msg_len,
- enc_msg, &app_mic64, sizeof(app_mic64));
- l_put_be64(app_mic64, enc_msg + app_msg_len);
+
+ mesh_crypto_payload_encrypt(aad, app_msg,
+ enc_msg, app_msg_len,
+ keys->net_src, keys->net_dst, key_aid,
+ keys->app_seq, keys->iv_index,
+ keys->szmic,
+ keys->akf ? app_key : dev_key);
} else {
seg_max = SEG_MAX(keys->segmented, app_msg_len + 4);
enc_msg = l_malloc(app_msg_len + 4);
- mesh_crypto_application_encrypt(key_aid, keys->app_seq,
- keys->net_src, keys->net_dst,
- keys->iv_index,
- keys->akf ? app_key : dev_key,
- aad, aad_len,
- app_msg, app_msg_len,
- enc_msg, &app_mic32, sizeof(app_mic32));
- l_put_be32(app_mic32, enc_msg + app_msg_len);
+
+ mesh_crypto_payload_encrypt(aad, app_msg,
+ enc_msg, app_msg_len,
+ keys->net_src, keys->net_dst, key_aid,
+ keys->app_seq, keys->iv_index,
+ keys->szmic,
+ keys->akf ? app_key : dev_key);
}

if (keys->dev_key && !keys->akf)
@@ -1057,10 +1056,12 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
verify_data("EncryptedAppPayload", 0, keys->enc_msg, enc_msg,
app_msg_len);
if (keys->szmic) {
+ app_mic64 = l_get_be64(enc_msg + app_msg_len);
verify_uint64("ApplicationMIC", app_msg_len,
keys->app_mic64, app_mic64);
app_msg_len += 8;
} else {
+ app_mic32 = l_get_be32(enc_msg + app_msg_len);
verify_uint32("ApplicationMIC", app_msg_len,
keys->app_mic32, app_mic32);
app_msg_len += 4;
@@ -1172,20 +1173,18 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
keys->net_seq[i], keys->net_src,
keys->iv_index, net_nonce);

- verify_data("TransportData", 9, keys->trans_pkt[i],
+ verify_data("TransportData", 9, keys->trans_pkt[i],
packet + 9, seg_len);

verify_uint16("DST", 7, keys->net_dst, l_get_be16(packet + 7));
net_msg_len = seg_len + 2;
show_data("TransportPayload", 7, packet + 7, net_msg_len);

- mesh_crypto_network_encrypt(keys->ctl,
- keys->net_ttl, keys->net_seq[i],
- keys->net_src,
- keys->iv_index, enc_key,
- packet + 7, seg_len + 2, packet + 7,
- keys->ctl ? (void *)&net_mic64 :
- (void *)&net_mic32);
+ mesh_crypto_packet_encrypt(packet, packet_len, enc_key,
+ keys->iv_index, false,
+ keys->ctl, keys->net_ttl,
+ keys->net_seq[i],
+ keys->net_src);

mesh_crypto_privacy_counter(keys->iv_index, packet + 7,
priv_rand);
@@ -1208,20 +1207,23 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
verify_data("EncNetworkPayload", 7, keys->net_msg[i],
packet + 7, net_msg_len);
if (keys->ctl) {
+ net_mic64 = l_get_be64(packet + packet_len - 8);
verify_uint64("NetworkMIC", 7 + net_msg_len,
keys->net_mic64, net_mic64);
net_msg_len += 8;
} else {
+ net_mic32 = l_get_be32(packet + packet_len - 4);
verify_uint32("NetworkMIC", 7 + net_msg_len,
keys->net_mic32[i], net_mic32);
net_msg_len += 4;
}

show_data("PreObsPayload", 1, packet + 1, 6 + net_msg_len);
- mesh_crypto_network_obfuscate(priv_key, priv_rand,
- keys->ctl,
- keys->net_ttl, keys->net_seq[i],
- keys->net_src, packet + 1);
+ mesh_crypto_network_obfuscate(packet, priv_key,
+ keys->iv_index,
+ keys->ctl, keys->net_ttl,
+ keys->net_seq[i], keys->net_src);
+
show_data("PostObsPayload", 1, packet + 1, 6 + net_msg_len);

packet[0] = (keys->iv_index & 0x01) << 7 | nid;
@@ -1242,7 +1244,7 @@ done:

static void check_decrypt_segment(const struct mesh_crypto_test *keys,
uint16_t seg, uint16_t seg_max,
- const uint8_t *pkt, uint8_t pkt_len,
+ uint8_t *pkt, uint8_t pkt_len,
const uint8_t *msg, uint8_t msg_len,
uint8_t *enc_key, uint8_t *priv_key,
uint8_t nid)
@@ -1274,26 +1276,30 @@ static void check_decrypt_segment(const struct mesh_crypto_test *keys,
if (ctl) {
net_mic64 = l_get_be64(pkt + pkt_len - 8);
show_data("EncryptedPayload", 7, pkt + 7, pkt_len - 7 - 8);
- mesh_crypto_network_decrypt(ctl, ttl, seq,
- src, keys->iv_index, enc_key,
- pkt + 7, pkt_len - 7, net_clr + 7,
- &calc_net_mic64,
- sizeof(calc_net_mic64));
+
+ mesh_crypto_packet_decrypt(pkt, pkt_len,
+ enc_key,
+ keys->iv_index, false,
+ ctl, ttl, seq,
+ src);
+ calc_net_mic64 = l_get_be64(pkt + pkt_len - 8);
+
verify_uint64("NetworkMIC", pkt_len - 8, net_mic64,
- calc_net_mic64);
+ net_mic64 ^ calc_net_mic64);
show_data("DecryptedPayload", 7, net_clr + 7, pkt_len - 7 - 8);
} else {
net_mic32 = l_get_be32(pkt + pkt_len - 4);
show_data("EncryptedPayload", 7, pkt + 7, pkt_len - 7 - 4);

- mesh_crypto_network_decrypt(ctl, ttl, seq,
- src, keys->iv_index, enc_key,
- pkt + 7, pkt_len - 7, net_clr + 7,
- &calc_net_mic32,
- sizeof(calc_net_mic32));
+ mesh_crypto_packet_decrypt(pkt, pkt_len,
+ enc_key,
+ keys->iv_index, false,
+ ctl, ttl, seq,
+ src);
+ calc_net_mic32 = l_get_be32(pkt + pkt_len - 4);

verify_uint32("NetworkMIC", pkt_len - 4, net_mic32,
- calc_net_mic32);
+ net_mic32 ^ calc_net_mic32);
show_data("DecryptedPayload", 7, net_clr + 7, pkt_len - 7 - 4);
}

@@ -1387,15 +1393,11 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
uint8_t *app_key;
uint8_t *net_key;
uint8_t enc_key[16];
- uint8_t net_nonce[13];
- uint8_t app_nonce[13];
uint8_t priv_key[16];
- uint8_t priv_rand[16];
uint8_t p[9];
size_t p_len;
uint8_t *packet = NULL;
size_t packet_len;
- const uint8_t *net_hdr;
uint8_t *net_msg;
uint8_t net_msg_len;
uint16_t app_msg_len = 0;
@@ -1469,9 +1471,6 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
goto done;
}

- mesh_crypto_application_nonce(keys->app_seq, keys->net_src,
- keys->net_dst, keys->iv_index,
- keys->szmic, app_nonce);
app_msg = l_malloc(384);

seg_max = (sizeof(keys->packet) / sizeof(keys->packet[0])) - 1;
@@ -1483,19 +1482,13 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
if (keys->segmented)
l_info(COLOR_YELLOW "Segment-%d" COLOR_OFF, i);

- mesh_crypto_network_nonce(keys->frnd, keys->net_ttl,
- keys->net_seq[i], keys->net_src, keys->iv_index,
- net_nonce);
l_free(packet);
packet = l_util_from_hexstring(keys->packet[i], &packet_len);

- net_hdr = packet + 1;
net_msg = packet + 7;
net_msg_len = packet_len - 7;

- mesh_crypto_privacy_counter(keys->iv_index, net_msg, priv_rand);
-
- mesh_crypto_network_clarify(priv_key, priv_rand, net_hdr,
+ mesh_crypto_network_clarify(packet, priv_key, keys->iv_index,
&net_ctl, &net_ttl, &net_seq, &net_src);

show_str("Packet", 0, keys->packet[i]);
@@ -1504,29 +1497,31 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
net_mic64 = l_get_be64(packet + packet_len - 8);
show_data("NetworkMessage", 7, net_msg,
net_msg_len - 8);
- mesh_crypto_network_decrypt(net_ctl, net_ttl, net_seq,
- net_src, keys->iv_index, enc_key,
- net_msg, net_msg_len, net_msg,
- &calc_net_mic64,
- sizeof(calc_net_mic64));
+ mesh_crypto_packet_decrypt(packet, packet_len,
+ enc_key,
+ keys->iv_index, false,
+ net_ctl, net_ttl,
+ net_seq,
+ net_src);
+ calc_net_mic64 = l_get_be64(packet + packet_len - 8);
net_msg_len -= 8;
verify_uint64("NetworkMIC", 7 + net_msg_len, net_mic64,
- calc_net_mic64);
+ net_mic64 ^ calc_net_mic64);
show_data("DecryptedNetwork", 7, net_msg, net_msg_len);
} else {
net_mic32 = l_get_be32(packet + packet_len - 4);
show_data("NetworkMessage", 7, net_msg,
net_msg_len - 4);
-
- mesh_crypto_network_decrypt(net_ctl, net_ttl, net_seq,
- net_src, keys->iv_index, enc_key,
- net_msg, net_msg_len, net_msg,
- &calc_net_mic32,
- sizeof(calc_net_mic32));
-
+ mesh_crypto_packet_decrypt(packet, packet_len,
+ enc_key,
+ keys->iv_index, false,
+ net_ctl, net_ttl,
+ net_seq,
+ net_src);
+ calc_net_mic32 = l_get_be32(packet + packet_len - 4);
net_msg_len -= 4;
verify_uint32("NetworkMIC", 7 + net_msg_len, net_mic32,
- calc_net_mic32);
+ net_mic32 ^ calc_net_mic32);
show_data("DecryptedNetwork", 7, net_msg, net_msg_len);
}

@@ -1645,8 +1640,8 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
packet, &pkt_len);
verify_data("TransportData", 9, keys->trans_pkt[i], packet + 9,
payload_len);
- mesh_crypto_packet_encode(packet, pkt_len, enc_key,
- keys->iv_index, priv_key);
+ mesh_crypto_packet_encode(packet, pkt_len, keys->iv_index,
+ enc_key, priv_key);
mesh_crypto_packet_label(packet, pkt_len, keys->iv_index, nid);

verify_data("Encoded-Packet", 0, keys->packet[i], packet,
@@ -1666,39 +1661,45 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
app_msg_len - 8);
app_mic64 = l_get_be64(app_msg + app_msg_len - 8);

- mesh_crypto_application_decrypt(
- keys_aid | (keys->akf ? KEY_ID_AKF : 0),
- seqZero, net_src,
- net_dst, keys->iv_index,
- keys->akf ? app_key : dev_key,
+ mesh_crypto_payload_decrypt(
aad, aad_len,
app_msg, app_msg_len,
- app_msg, &calc_app_mic64,
- sizeof(calc_app_mic64));
+ true,
+ net_src, net_dst,
+ keys->akf ? keys_aid | KEY_ID_AKF : APP_AID_DEV,
+ seqZero,
+ keys->iv_index,
+ app_msg,
+ keys->akf ? app_key : dev_key);
+
+ calc_app_mic64 = l_get_be64(app_msg + app_msg_len - 8);

verify_data("Payload", 0, keys->app_msg, app_msg,
app_msg_len - 8);
verify_uint64("ApplicationMIC", app_msg_len - 8, app_mic64,
- calc_app_mic64);
+ app_mic64 ^ calc_app_mic64);
} else if (!keys->ctl) {
verify_data("EncryptedPayload", 0, keys->enc_msg, app_msg,
app_msg_len - 4);
app_mic32 = l_get_be32(app_msg + app_msg_len - 4);

- mesh_crypto_application_decrypt(
- keys_aid | (keys->akf ? KEY_ID_AKF : 0),
- seqZero, net_src,
- net_dst, keys->iv_index,
- keys->akf ? app_key : dev_key,
+ mesh_crypto_payload_decrypt(
aad, aad_len,
app_msg, app_msg_len,
- app_msg, &calc_app_mic32,
- sizeof(calc_app_mic32));
+ false,
+ net_src, net_dst,
+ keys->akf ? keys_aid | KEY_ID_AKF : APP_AID_DEV,
+ seqZero,
+ keys->iv_index,
+ app_msg,
+ keys->akf ? app_key : dev_key);
+
+ calc_app_mic32 = l_get_be64(app_msg + app_msg_len - 4);

verify_data("Payload", 0, keys->app_msg, app_msg,
app_msg_len - 4);
verify_uint32("ApplicationMIC", app_msg_len - 4, app_mic32,
- calc_app_mic32);
+ app_mic32 ^ calc_app_mic32);
}

done:
--
2.25.0


2020-04-03 17:55:22

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: Re: [PATCH BlueZ RESEND] mesh: Remove redundant code from mesh/crypto

Brian,

On 03/26, Michał Lowas-Rzechonek wrote:
> - Remove application_encrypt/application_decrypt
> - Make mesh_crypto_privacy_counter private, add mesh_crypto_pecb
> - Make *_nonce functions private and align their implementation to be
> more consistent
> - Refactor network_encrypt/network_decrypt to use *_nonce functions and
> rename them to packet_encrypt/packet_decrypt
> - Refactor packet_encode/packet_decode

Ping...

This version of the patch passes unit tests. I'd really like to get this
applied. Or at least tell me straight in the face that I should bugger
off ;)

regards
--
Michał Lowas-Rzechonek <[email protected]>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND

2020-04-05 18:48:32

by Gix, Brian

[permalink] [raw]
Subject: Re: [PATCH BlueZ RESEND] mesh: Remove redundant code from mesh/crypto

Hi Michał,

I think this needs some more work, in that it no longer correctly fails the mesh-test-crypto test when running:

make distcheck

It *almost* does in that it flags an error in red if a "verify" step fails, but it does not exit with a fail
code. This is an important step, particularily with the dependance on kernel based crypto functions.

My test methodology was to flip a bit in one of the test payloads (i.e., make it "not perfectly match" the
specification sample data).

As best I can tell, it is otherwise functional, but the unit tests are important.

On Thu, 2020-03-26 at 22:17 +0100, Michał Lowas-Rzechonek wrote:
> - Remove application_encrypt/application_decrypt
> - Make mesh_crypto_privacy_counter private, add mesh_crypto_pecb
> - Make *_nonce functions private and align their implementation to be
> more consistent
> - Refactor network_encrypt/network_decrypt to use *_nonce functions and
> rename them to packet_encrypt/packet_decrypt
> - Refactor packet_encode/packet_decode
> ---
> mesh/crypto.c | 481 ++++++++++++++++------------------------
> mesh/crypto.h | 50 +----
> mesh/net-keys.c | 2 +-
> unit/test-mesh-crypto.c | 205 ++++++++---------
> 4 files changed, 291 insertions(+), 447 deletions(-)
>
> diff --git a/mesh/crypto.c b/mesh/crypto.c
> index 596a289f9..ce335bbec 100644
> --- a/mesh/crypto.c
> +++ b/mesh/crypto.c
> @@ -327,144 +327,59 @@ bool mesh_crypto_beacon_cmac(const uint8_t encryption_key[16],
> return true;
> }
>
> -bool mesh_crypto_network_nonce(bool ctl, uint8_t ttl, uint32_t seq,
> - uint16_t src, uint32_t iv_index,
> - uint8_t nonce[13])
> +static void mesh_crypto_network_nonce(bool ctl, uint8_t ttl,
> + uint32_t seq, uint16_t src,
> + uint32_t iv_index, uint8_t nonce[13])
> {
> - nonce[0] = 0;
> + nonce[0] = 0x00;
> nonce[1] = (ttl & TTL_MASK) | (ctl ? CTL : 0x00);
> nonce[2] = (seq >> 16) & 0xff;
> nonce[3] = (seq >> 8) & 0xff;
> nonce[4] = seq & 0xff;
> -
> - /* SRC */
> l_put_be16(src, nonce + 5);
> -
> l_put_be16(0, nonce + 7);
> -
> - /* IV Index */
> l_put_be32(iv_index, nonce + 9);
> -
> - return true;
> -}
> -
> -bool mesh_crypto_network_encrypt(bool ctl, uint8_t ttl,
> - uint32_t seq, uint16_t src,
> - uint32_t iv_index,
> - const uint8_t net_key[16],
> - const uint8_t *enc_msg, uint8_t enc_msg_len,
> - uint8_t *out, void *net_mic)
> -{
> - uint8_t nonce[13];
> -
> - if (!mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce))
> - return false;
> -
> - return mesh_crypto_aes_ccm_encrypt(nonce, net_key, NULL, 0, enc_msg,
> - enc_msg_len, out, net_mic,
> - ctl ? 8 : 4);
> }
>
> -bool mesh_crypto_network_decrypt(bool ctl, uint8_t ttl,
> - uint32_t seq, uint16_t src,
> - uint32_t iv_index,
> - const uint8_t net_key[16],
> - const uint8_t *enc_msg, uint8_t enc_msg_len,
> - uint8_t *out, void *net_mic, size_t mic_size)
> -{
> - uint8_t nonce[13];
> -
> - if (!mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce))
> - return false;
> -
> - return mesh_crypto_aes_ccm_decrypt(nonce, net_key, NULL, 0,
> - enc_msg, enc_msg_len, out,
> - net_mic, mic_size);
> -}
> -
> -bool mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
> +static void mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
> uint16_t dst, uint32_t iv_index,
> bool aszmic, uint8_t nonce[13])
> {
> nonce[0] = 0x01;
> nonce[1] = aszmic ? 0x80 : 0x00;
> - nonce[2] = (seq & 0x00ff0000) >> 16;
> - nonce[3] = (seq & 0x0000ff00) >> 8;
> - nonce[4] = (seq & 0x000000ff);
> - nonce[5] = (src & 0xff00) >> 8;
> - nonce[6] = (src & 0x00ff);
> - nonce[7] = (dst & 0xff00) >> 8;
> - nonce[8] = (dst & 0x00ff);
> + nonce[2] = (seq >> 16 ) & 0xff;
> + nonce[3] = (seq >> 8) & 0xff;
> + nonce[4] = seq & 0xff;
> + l_put_be16(src, nonce + 5);
> + l_put_be16(dst, nonce + 7);
> l_put_be32(iv_index, nonce + 9);
> -
> - return true;
> }
>
> -bool mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
> +static void mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
> uint16_t dst, uint32_t iv_index,
> bool aszmic, uint8_t nonce[13])
> {
> nonce[0] = 0x02;
> nonce[1] = aszmic ? 0x80 : 0x00;
> - nonce[2] = (seq & 0x00ff0000) >> 16;
> - nonce[3] = (seq & 0x0000ff00) >> 8;
> - nonce[4] = (seq & 0x000000ff);
> - nonce[5] = (src & 0xff00) >> 8;
> - nonce[6] = (src & 0x00ff);
> - nonce[7] = (dst & 0xff00) >> 8;
> - nonce[8] = (dst & 0x00ff);
> + nonce[2] = (seq >> 16 ) & 0xff;
> + nonce[3] = (seq >> 8) & 0xff;
> + nonce[4] = seq & 0xff;
> + l_put_be16(src, nonce + 5);
> + l_put_be16(dst, nonce + 7);
> l_put_be32(iv_index, nonce + 9);
> -
> - return true;
> }
>
> -bool mesh_crypto_application_encrypt(uint8_t key_aid, uint32_t seq,
> - uint16_t src, uint16_t dst,
> - uint32_t iv_index,
> - const uint8_t app_key[16],
> - const uint8_t *aad, uint8_t aad_len,
> - const uint8_t *msg, uint8_t msg_len,
> - uint8_t *out,
> - void *app_mic, size_t mic_size)
> +static void mesh_crypto_proxy_nonce(uint32_t seq, uint16_t src,
> + uint32_t iv_index, uint8_t nonce[13])
> {
> - uint8_t nonce[13];
> - bool aszmic = (mic_size == 8) ? true : false;
> -
> - if (!key_aid && !mesh_crypto_device_nonce(seq, src, dst,
> - iv_index, aszmic, nonce))
> - return false;
> -
> - if (key_aid && !mesh_crypto_application_nonce(seq, src, dst,
> - iv_index, aszmic, nonce))
> - return false;
> -
> - return mesh_crypto_aes_ccm_encrypt(nonce, app_key, aad, aad_len,
> - msg, msg_len,
> - out, app_mic, mic_size);
> -}
> -
> -bool mesh_crypto_application_decrypt(uint8_t key_aid, uint32_t seq,
> - uint16_t src, uint16_t dst, uint32_t iv_index,
> - const uint8_t app_key[16],
> - const uint8_t *aad, uint8_t aad_len,
> - const uint8_t *enc_msg, uint8_t enc_msg_len,
> - uint8_t *out, void *app_mic, size_t mic_size)
> -{
> - uint8_t nonce[13];
> - bool aszmic = (mic_size == 8) ? true : false;
> -
> - if (!key_aid && !mesh_crypto_device_nonce(seq, src, dst,
> - iv_index, aszmic, nonce))
> - return false;
> -
> - if (key_aid && !mesh_crypto_application_nonce(seq, src, dst,
> - iv_index, aszmic, nonce))
> - return false;
> -
> - return mesh_crypto_aes_ccm_decrypt(nonce, app_key,
> - aad, aad_len, enc_msg,
> - enc_msg_len, out,
> - app_mic, mic_size);
> + nonce[0] = 0x03;
> + nonce[1] = 0;
> + nonce[2] = (seq >> 16) & 0xff;
> + nonce[3] = (seq >> 8) & 0xff;
> + nonce[4] = seq & 0xff;
> + l_put_be16(src, nonce + 5);
> + l_put_be16(0, nonce + 7);
> + l_put_be32(iv_index, nonce + 9);
> }
>
> bool mesh_crypto_session_key(const uint8_t secret[32],
> @@ -557,69 +472,67 @@ bool mesh_crypto_virtual_addr(const uint8_t virtual_label[16],
> return true;
> }
>
> -bool mesh_crypto_privacy_counter(uint32_t iv_index,
> +static void mesh_crypto_privacy_counter(uint32_t iv_index,
> const uint8_t *payload,
> uint8_t privacy_counter[16])
> {
> memset(privacy_counter, 0, 5);
> l_put_be32(iv_index, privacy_counter + 5);
> memcpy(privacy_counter + 9, payload, 7);
> +}
>
> - return true;
> +static bool mesh_crypto_pecb(const uint8_t privacy_key[16],
> + uint32_t iv_index,
> + const uint8_t *payload,
> + uint8_t pecb[16])
> +{
> + mesh_crypto_privacy_counter(iv_index, payload, pecb);
> + return aes_ecb_one(privacy_key, pecb, pecb);
> }
>
> -bool mesh_crypto_network_obfuscate(const uint8_t privacy_key[16],
> - const uint8_t privacy_counter[16],
> - bool ctl, uint8_t ttl, uint32_t seq,
> - uint16_t src, uint8_t *out)
> +static bool mesh_crypto_network_obfuscate(uint8_t *packet,
> + const uint8_t privacy_key[16],
> + uint32_t iv_index,
> + bool ctl, uint8_t ttl,
> + uint32_t seq, uint16_t src)
> {
> - uint8_t ecb[16], tmp[16];
> + uint8_t pecb[16];
> + uint8_t *net_hdr = packet + 1;
> int i;
>
> - if (!aes_ecb_one(privacy_key, privacy_counter, ecb))
> + if (!mesh_crypto_pecb(privacy_key, iv_index, packet + 7, pecb))
> return false;
>
> - tmp[0] = ((!!ctl) << 7) | (ttl & TTL_MASK);
> - tmp[1] = (seq & 0xff0000) >> 16;
> - tmp[2] = (seq & 0x00ff00) >> 8;
> - tmp[3] = (seq & 0x0000ff);
> - tmp[4] = (src & 0xff00) >> 8;
> - tmp[5] = (src & 0x00ff);
> + l_put_be16(src, net_hdr + 4);
> + l_put_be32(seq & SEQ_MASK, net_hdr);
> + net_hdr[0] = ((!!ctl) << 7) | (ttl & TTL_MASK);
>
> - if (out) {
> - for (i = 0; i < 6; i++)
> - out[i] = ecb[i] ^ tmp[i];
> - }
> + for (i = 0; i < 6; i++)
> + net_hdr[i] = pecb[i] ^ net_hdr[i];
>
> return true;
> }
>
> -bool mesh_crypto_network_clarify(const uint8_t privacy_key[16],
> - const uint8_t privacy_counter[16],
> - const uint8_t net_hdr[6],
> - bool *ctl, uint8_t *ttl,
> - uint32_t *seq, uint16_t *src)
> +static bool mesh_crypto_network_clarify(uint8_t *packet,
> + const uint8_t privacy_key[16],
> + uint32_t iv_index,
> + bool *ctl, uint8_t *ttl,
> + uint32_t *seq, uint16_t *src)
> {
> - uint8_t ecb[16], tmp[6];
> + uint8_t pecb[16];
> + uint8_t *net_hdr = packet + 1;
> int i;
>
> - if (!aes_ecb_one(privacy_key, privacy_counter, ecb))
> + if (!mesh_crypto_pecb(privacy_key, iv_index, packet + 7, pecb))
> return false;
>
> for (i = 0; i < 6; i++)
> - tmp[i] = ecb[i] ^ net_hdr[i];
> -
> - if (ctl)
> - *ctl = !!(tmp[0] & CTL);
> + net_hdr[i] = pecb[i] ^ net_hdr[i];
>
> - if (ttl)
> - *ttl = tmp[0] & TTL_MASK;
> -
> - if (seq)
> - *seq = l_get_be32(tmp) & SEQ_MASK;
> -
> - if (src)
> - *src = l_get_be16(tmp + 4);
> + *src = l_get_be16(net_hdr + 4);
> + *seq = l_get_be32(net_hdr) & SEQ_MASK;
> + *ttl = net_hdr[0] & TTL_MASK;
> + *ctl = !!(net_hdr[0] & CTL);
>
> return true;
> }
> @@ -689,24 +602,13 @@ bool mesh_crypto_packet_build(bool ctl, uint8_t ttl,
> return true;
> }
>
> -bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> +static bool network_header_parse(const uint8_t *packet, uint8_t packet_len,
> bool *ctl, uint8_t *ttl, uint32_t *seq,
> - uint16_t *src, uint16_t *dst,
> - uint32_t *cookie, uint8_t *opcode,
> - bool *segmented, uint8_t *key_aid,
> - bool *szmic, bool *relay, uint16_t *seqZero,
> - uint8_t *segO, uint8_t *segN,
> - const uint8_t **payload, uint8_t *payload_len)
> + uint16_t *src, uint16_t *dst)
> {
> - uint32_t hdr;
> - uint16_t this_dst;
> - bool is_segmented;
> -
> if (packet_len < 10)
> return false;
>
> - this_dst = l_get_be16(packet + 7);
> -
> /* Try to keep bits in the order they exist within the packet */
> if (ctl)
> *ctl = !!(packet[1] & CTL);
> @@ -720,6 +622,30 @@ bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> if (src)
> *src = l_get_be16(packet + 5);
>
> + if (dst)
> + *dst = l_get_be16(packet + 7);
> +
> + return true;
> +
> +}
> +
> +bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> + bool *ctl, uint8_t *ttl, uint32_t *seq,
> + uint16_t *src, uint16_t *dst,
> + uint32_t *cookie, uint8_t *opcode,
> + bool *segmented, uint8_t *key_aid,
> + bool *szmic, bool *relay, uint16_t *seqZero,
> + uint8_t *segO, uint8_t *segN,
> + const uint8_t **payload, uint8_t *payload_len)
> +{
> + uint32_t hdr;
> + uint16_t this_dst;
> + bool is_segmented;
> +
> + if (!network_header_parse(packet, packet_len,
> + ctl, ttl, seq, src, &this_dst))
> + return false;
> +
> if (dst)
> *dst = this_dst;
>
> @@ -799,38 +725,27 @@ bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> bool mesh_crypto_payload_encrypt(uint8_t *aad, const uint8_t *payload,
> uint8_t *out, uint16_t payload_len,
> uint16_t src, uint16_t dst, uint8_t key_aid,
> - uint32_t seq_num, uint32_t iv_index,
> + uint32_t seq, uint32_t iv_index,
> bool aszmic,
> - const uint8_t application_key[16])
> + const uint8_t app_key[16])
> {
> - uint8_t application_nonce[13] = { 0x01, };
> + uint8_t nonce[13];
>
> if (payload_len < 1)
> return false;
>
> if (key_aid == APP_AID_DEV)
> - application_nonce[0] = 0x02;
> -
> - /* Seq Num */
> - l_put_be32(seq_num, application_nonce + 1);
> -
> - /* ASZMIC */
> - application_nonce[1] |= aszmic ? 0x80 : 0x00;
> -
> - /* SRC */
> - l_put_be16(src, application_nonce + 5);
> -
> - /* DST */
> - l_put_be16(dst, application_nonce + 7);
> -
> - /* IV Index */
> - l_put_be32(iv_index, application_nonce + 9);
> -
> - if (!mesh_crypto_aes_ccm_encrypt(application_nonce, application_key,
> - aad, aad ? 16 : 0,
> - payload, payload_len,
> - out, NULL,
> - aszmic ? 8 : 4))
> + mesh_crypto_device_nonce(seq, src, dst, iv_index, aszmic,
> + nonce);
> + else
> + mesh_crypto_application_nonce(seq, src, dst, iv_index, aszmic,
> + nonce);
> +
> + if (!mesh_crypto_aes_ccm_encrypt(nonce, app_key,
> + aad, aad ? 16 : 0,
> + payload, payload_len,
> + out, NULL,
> + aszmic ? 8 : 4))
> return false;
>
> return true;
> @@ -838,13 +753,13 @@ bool mesh_crypto_payload_encrypt(uint8_t *aad, const uint8_t *payload,
>
> bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> const uint8_t *payload, uint16_t payload_len,
> - bool szmict,
> + bool aszmic,
> uint16_t src, uint16_t dst,
> - uint8_t key_aid, uint32_t seq_num,
> + uint8_t key_aid, uint32_t seq,
> uint32_t iv_index, uint8_t *out,
> const uint8_t app_key[16])
> {
> - uint8_t app_nonce[13] = { 0x01, };
> + uint8_t nonce[13];
> uint32_t mic32;
> uint64_t mic64;
>
> @@ -852,27 +767,16 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> return false;
>
> if (key_aid == APP_AID_DEV)
> - app_nonce[0] = 0x02;
> -
> - /* Seq Num */
> - l_put_be32(seq_num, app_nonce + 1);
> -
> - /* ASZMIC */
> - app_nonce[1] |= szmict ? 0x80 : 0x00;
> -
> - /* SRC */
> - l_put_be16(src, app_nonce + 5);
> -
> - /* DST */
> - l_put_be16(dst, app_nonce + 7);
> -
> - /* IV Index */
> - l_put_be32(iv_index, app_nonce + 9);
> + mesh_crypto_device_nonce(seq, src, dst, iv_index, aszmic,
> + nonce);
> + else
> + mesh_crypto_application_nonce(seq, src, dst, iv_index, aszmic,
> + nonce);
>
> memcpy(out, payload, payload_len);
>
> - if (szmict) {
> - if (!mesh_crypto_aes_ccm_decrypt(app_nonce, app_key,
> + if (aszmic) {
> + if (!mesh_crypto_aes_ccm_decrypt(nonce, app_key,
> aad, aad_len,
> payload, payload_len,
> out, &mic64, sizeof(mic64)))
> @@ -884,7 +788,7 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> if (mic64)
> return false;
> } else {
> - if (!mesh_crypto_aes_ccm_decrypt(app_nonce, app_key,
> + if (!mesh_crypto_aes_ccm_decrypt(nonce, app_key,
> aad, aad_len,
> payload, payload_len,
> out, &mic32, sizeof(mic32)))
> @@ -900,146 +804,107 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> return true;
> }
>
> -bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
> +static bool mesh_crypto_packet_encrypt(uint8_t *packet, uint8_t packet_len,
> const uint8_t network_key[16],
> - uint32_t iv_index,
> - const uint8_t privacy_key[16])
> + uint32_t iv_index, bool proxy,
> + bool ctl, uint8_t ttl, uint32_t seq,
> + uint16_t src)
> {
> - uint8_t network_nonce[13] = { 0x00, 0x00 };
> - uint8_t privacy_counter[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
> - uint8_t tmp[16];
> - int i;
> -
> - if (packet_len < 14)
> - return false;
> + uint8_t nonce[13];
>
> /* Detect Proxy packet by CTL == true && DST == 0x0000 */
> - if ((packet[1] & CTL) && l_get_be16(packet + 7) == 0)
> - network_nonce[0] = 0x03; /* Proxy Nonce */
> + if (ctl && proxy)
> + mesh_crypto_proxy_nonce(seq, src, iv_index, nonce);
> else
> - /* CTL + TTL */
> - network_nonce[1] = packet[1];
> -
> - /* Seq Num */
> - network_nonce[2] = packet[2];
> - network_nonce[3] = packet[3];
> - network_nonce[4] = packet[4];
> -
> - /* SRC */
> - network_nonce[5] = packet[5];
> - network_nonce[6] = packet[6];
> -
> - /* DST not available */
> - network_nonce[7] = 0;
> - network_nonce[8] = 0;
> -
> - /* IV Index */
> - l_put_be32(iv_index, network_nonce + 9);
> + mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce);
>
> /* Check for Long net-MIC */
> - if (packet[1] & CTL) {
> - if (!mesh_crypto_aes_ccm_encrypt(network_nonce, network_key,
> + if (ctl) {
> + if (!mesh_crypto_aes_ccm_encrypt(nonce, network_key,
> NULL, 0,
> packet + 7, packet_len - 7 - 8,
> packet + 7, NULL, 8))
> return false;
> } else {
> - if (!mesh_crypto_aes_ccm_encrypt(network_nonce, network_key,
> + if (!mesh_crypto_aes_ccm_encrypt(nonce, network_key,
> NULL, 0,
> packet + 7, packet_len - 7 - 4,
> packet + 7, NULL, 4))
> return false;
> }
>
> - l_put_be32(iv_index, privacy_counter + 5);
> - memcpy(privacy_counter + 9, packet + 7, 7);
> -
> - if (!aes_ecb_one(privacy_key, privacy_counter, tmp))
> - return false;
> -
> - for (i = 0; i < 6; i++)
> - packet[1 + i] ^= tmp[i];
> -
> return true;
> }
>
> -bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> - bool proxy, uint8_t *out, uint32_t iv_index,
> +bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
> + uint32_t iv_index,
> const uint8_t network_key[16],
> const uint8_t privacy_key[16])
> {
> - uint8_t privacy_counter[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
> - uint8_t network_nonce[13] = { 0x00, 0x00, };
> - uint8_t tmp[16];
> + bool ctl;
> + uint8_t ttl;
> + uint32_t seq;
> uint16_t src;
> - int i;
> + uint16_t dst;
>
> - if (packet_len < 14)
> + if (!network_header_parse(packet, packet_len,
> + &ctl, &ttl, &seq, &src, &dst))
> return false;
>
> - l_put_be32(iv_index, privacy_counter + 5);
> - memcpy(privacy_counter + 9, packet + 7, 7);
> + if (!mesh_crypto_packet_encrypt(packet, packet_len, network_key,
> + iv_index, !dst,
> + ctl, ttl, seq, src))
>
> - if (!aes_ecb_one(privacy_key, privacy_counter, tmp))
> return false;
>
> - memcpy(out, packet, packet_len);
> - for (i = 0; i < 6; i++)
> - out[1 + i] ^= tmp[i];
> + return mesh_crypto_network_obfuscate(packet, privacy_key, iv_index,
> + ctl, ttl, seq, src);
> +}
>
> - src = l_get_be16(out + 5);
> +static bool mesh_crypto_packet_decrypt(uint8_t *packet, uint8_t packet_len,
> + const uint8_t network_key[16],
> + uint32_t iv_index, bool proxy,
> + bool ctl, uint8_t ttl, uint32_t seq,
> + uint16_t src)
> +{
> + uint8_t nonce[13];
>
> /* Pre-check SRC address for illegal values */
> - if (!src || src >= 0x8000)
> + if (!IS_UNICAST(src))
> return false;
>
> /* Detect Proxy packet by CTL == true && proxy == true */
> - if ((out[1] & CTL) && proxy)
> - network_nonce[0] = 0x03; /* Proxy Nonce */
> + if (ctl & proxy)
> + mesh_crypto_proxy_nonce(seq, src, iv_index, nonce);
> else
> - /* CTL + TTL */
> - network_nonce[1] = out[1];
> -
> - /* Seq Num */
> - network_nonce[2] = out[2];
> - network_nonce[3] = out[3];
> - network_nonce[4] = out[4];
> -
> - /* SRC */
> - network_nonce[5] = out[5];
> - network_nonce[6] = out[6];
> -
> - /* DST not available */
> - network_nonce[7] = 0;
> - network_nonce[8] = 0;
> -
> - /* IV Index */
> - l_put_be32(iv_index, network_nonce + 9);
> + mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce);
>
> /* Check for Long MIC */
> - if (out[1] & CTL) {
> + if (ctl) {
> uint64_t mic;
>
> - if (!mesh_crypto_aes_ccm_decrypt(network_nonce, network_key,
> - NULL, 0, packet + 7, packet_len - 7,
> - out + 7, &mic, sizeof(mic)))
> + if (!mesh_crypto_aes_ccm_decrypt(nonce, network_key,
> + NULL, 0,
> + packet + 7, packet_len - 7,
> + packet + 7, &mic, sizeof(mic)))
> return false;
>
> - mic ^= l_get_be64(out + packet_len - 8);
> - l_put_be64(mic, out + packet_len - 8);
> + mic ^= l_get_be64(packet + packet_len - 8);
> + l_put_be64(mic, packet + packet_len - 8);
>
> if (mic)
> return false;
> } else {
> uint32_t mic;
>
> - if (!mesh_crypto_aes_ccm_decrypt(network_nonce, network_key,
> - NULL, 0, packet + 7, packet_len - 7,
> - out + 7, &mic, sizeof(mic)))
> + if (!mesh_crypto_aes_ccm_decrypt(nonce, network_key,
> + NULL, 0,
> + packet + 7, packet_len - 7,
> + packet + 7, &mic, sizeof(mic)))
> return false;
>
> - mic ^= l_get_be32(out + packet_len - 4);
> - l_put_be32(mic, out + packet_len - 4);
> + mic ^= l_get_be32(packet + packet_len - 4);
> + l_put_be32(mic, packet + packet_len - 4);
>
> if (mic)
> return false;
> @@ -1048,6 +913,30 @@ bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> return true;
> }
>
> +bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> + bool proxy, uint8_t *out, uint32_t iv_index,
> + const uint8_t network_key[16],
> + const uint8_t privacy_key[16])
> +{
> + bool ctl;
> + uint8_t ttl;
> + uint32_t seq;
> + uint16_t src;
> +
> + if (packet_len < 14)
> + return false;
> +
> + memcpy(out, packet, packet_len);
> +
> + if (!mesh_crypto_network_clarify(out, privacy_key, iv_index,
> + &ctl, &ttl, &seq, &src))
> + return false;
> +
> + return mesh_crypto_packet_decrypt(out, packet_len, network_key,
> + iv_index, proxy,
> + ctl, ttl, seq, src);
> +}
> +
> bool mesh_crypto_packet_label(uint8_t *packet, uint8_t packet_len,
> uint16_t iv_index, uint8_t network_id)
> {
> diff --git a/mesh/crypto.h b/mesh/crypto.h
> index e5ce840b4..7d3f89cde 100644
> --- a/mesh/crypto.h
> +++ b/mesh/crypto.h
> @@ -19,6 +19,7 @@
>
> #include <stdbool.h>
> #include <stdint.h>
> +#include <stdlib.h>
>
> bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
> const uint8_t *aad, uint16_t aad_len,
> @@ -41,40 +42,6 @@ bool mesh_crypto_beacon_cmac(const uint8_t encryption_key[16],
> const uint8_t network_id[16],
> uint32_t iv_index, bool kr,
> bool iu, uint64_t *cmac);
> -bool mesh_crypto_network_nonce(bool frnd, uint8_t ttl, uint32_t seq,
> - uint16_t src, uint32_t iv_index,
> - uint8_t nonce[13]);
> -bool mesh_crypto_network_encrypt(bool ctl, uint8_t ttl,
> - uint32_t seq, uint16_t src,
> - uint32_t iv_index,
> - const uint8_t net_key[16],
> - const uint8_t *enc_msg, uint8_t enc_msg_len,
> - uint8_t *out, void *net_mic);
> -bool mesh_crypto_network_decrypt(bool frnd, uint8_t ttl,
> - uint32_t seq, uint16_t src,
> - uint32_t iv_index,
> - const uint8_t net_key[16],
> - const uint8_t *enc_msg, uint8_t enc_msg_len,
> - uint8_t *out, void *net_mic, size_t mic_size);
> -bool mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
> - uint16_t dst, uint32_t iv_index,
> - bool aszmic, uint8_t nonce[13]);
> -bool mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
> - uint16_t dst, uint32_t iv_index,
> - bool aszmic, uint8_t nonce[13]);
> -bool mesh_crypto_application_encrypt(uint8_t akf, uint32_t seq, uint16_t src,
> - uint16_t dst, uint32_t iv_index,
> - const uint8_t app_key[16],
> - const uint8_t *aad, uint8_t aad_len,
> - const uint8_t *msg, uint8_t msg_len,
> - uint8_t *out,
> - void *app_mic, size_t mic_size);
> -bool mesh_crypto_application_decrypt(uint8_t akf, uint32_t seq, uint16_t src,
> - uint16_t dst, uint32_t iv_index,
> - const uint8_t app_key[16],
> - const uint8_t *aad, uint8_t aad_len,
> - const uint8_t *enc_msg, uint8_t enc_msg_len,
> - uint8_t *out, void *app_mic, size_t mic_size);
> bool mesh_crypto_device_key(const uint8_t secret[32],
> const uint8_t salt[16],
> uint8_t device_key[16]);
> @@ -102,19 +69,6 @@ bool mesh_crypto_prov_conf_key(const uint8_t secret[32],
> bool mesh_crypto_session_key(const uint8_t secret[32],
> const uint8_t salt[16],
> uint8_t session_key[16]);
> -bool mesh_crypto_privacy_counter(uint32_t iv_index,
> - const uint8_t *payload,
> - uint8_t privacy_counter[16]);
> -bool mesh_crypto_network_obfuscate(const uint8_t privacy_key[16],
> - const uint8_t privacy_counter[16],
> - bool ctl, uint8_t ttl, uint32_t seq,
> - uint16_t src, uint8_t *out);
> -bool mesh_crypto_network_clarify(const uint8_t privacy_key[16],
> - const uint8_t privacy_counter[16],
> - const uint8_t net_hdr[6],
> - bool *ctl, uint8_t *ttl,
> - uint32_t *seq, uint16_t *src);
> -
> bool mesh_crypto_packet_build(bool ctl, uint8_t ttl,
> uint32_t seq,
> uint16_t src, uint16_t dst,
> @@ -146,8 +100,8 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> uint8_t *out,
> const uint8_t application_key[16]);
> bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
> - const uint8_t network_key[16],
> uint32_t iv_index,
> + const uint8_t network_key[16],
> const uint8_t privacy_key[16]);
> bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> bool proxy, uint8_t *out, uint32_t iv_index,
> diff --git a/mesh/net-keys.c b/mesh/net-keys.c
> index 683a924c4..f7eb2ca68 100644
> --- a/mesh/net-keys.c
> +++ b/mesh/net-keys.c
> @@ -263,7 +263,7 @@ bool net_key_encrypt(uint32_t id, uint32_t iv_index, uint8_t *pkt, size_t len)
> if (!key)
> return false;
>
> - result = mesh_crypto_packet_encode(pkt, len, key->encrypt, iv_index,
> + result = mesh_crypto_packet_encode(pkt, len, iv_index, key->encrypt,
> key->privacy);
>
> if (!result)
> diff --git a/unit/test-mesh-crypto.c b/unit/test-mesh-crypto.c
> index 0043b0b10..3ecb3d026 100644
> --- a/unit/test-mesh-crypto.c
> +++ b/unit/test-mesh-crypto.c
> @@ -780,8 +780,8 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
> uint8_t priv_rand[16];
> uint8_t packet[29];
> uint8_t packet_len;
> - uint64_t net_mic64;
> - uint32_t hdr, net_mic32;
> + uint32_t hdr;
> + uint64_t net_mic64, net_mic32;
> size_t net_msg_len;
> uint8_t key_aid = keys->key_aid | (keys->akf ? KEY_ID_AKF : 0x00);
>
> @@ -857,13 +857,12 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
> net_msg_len = len + 2;
> show_data("TransportPayload", 7, packet + 7, net_msg_len);
>
> - mesh_crypto_network_encrypt(keys->ctl,
> - keys->net_ttl, keys->net_seq[0],
> - keys->net_src,
> - keys->iv_index, enc_key,
> - packet + 7, len + 2, packet + 7,
> - keys->ctl ? (void *)&net_mic64 :
> - (void *)&net_mic32);
> + mesh_crypto_packet_encrypt(packet, packet_len,
> + enc_key,
> + keys->iv_index, false,
> + keys->ctl, keys->net_ttl,
> + keys->net_seq[0],
> + keys->net_src);
>
> mesh_crypto_privacy_counter(keys->iv_index, packet + 7, priv_rand);
>
> @@ -883,20 +882,22 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
> verify_data("EncNetworkPayload", 7, keys->net_msg[0],
> packet + 7, net_msg_len);
> if (keys->ctl) {
> + net_mic64 = l_get_be64(packet + 7 + net_msg_len);
> verify_uint64("NetworkMIC", 7 + net_msg_len,
> - keys->net_mic64, net_mic64);
> + keys->net_mic64, net_mic64);
> net_msg_len += 8;
> } else {
> + net_mic32 = l_get_be32(packet + 7 + net_msg_len);
> verify_uint32("NetworkMIC", 7 + net_msg_len,
> - keys->net_mic32[0], net_mic32);
> + keys->net_mic32[0], net_mic32);
> net_msg_len += 4;
> }
>
> show_data("PreObsPayload", 1, packet + 1, 6 + net_msg_len);
> - mesh_crypto_network_obfuscate(priv_key, priv_rand,
> - keys->ctl,
> - keys->net_ttl, keys->net_seq[0],
> - keys->net_src, packet + 1);
> + mesh_crypto_network_obfuscate(packet, priv_key,
> + keys->iv_index,
> + keys->ctl, keys->net_ttl,
> + keys->net_seq[0], keys->net_src);
> show_data("PostObsPayload", 1, packet + 1, 6 + net_msg_len);
>
> packet[0] = (keys->iv_index & 0x01) << 7 | nid;
> @@ -1019,25 +1020,23 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> if (keys->szmic) {
> seg_max = SEG_MAX(keys->segmented, app_msg_len + 8);
> enc_msg = l_malloc(app_msg_len + 8);
> - mesh_crypto_application_encrypt(key_aid, keys->app_seq,
> - keys->net_src, keys->net_dst,
> - keys->iv_index,
> - keys->akf ? app_key : dev_key,
> - aad, aad_len,
> - app_msg, app_msg_len,
> - enc_msg, &app_mic64, sizeof(app_mic64));
> - l_put_be64(app_mic64, enc_msg + app_msg_len);
> +
> + mesh_crypto_payload_encrypt(aad, app_msg,
> + enc_msg, app_msg_len,
> + keys->net_src, keys->net_dst, key_aid,
> + keys->app_seq, keys->iv_index,
> + keys->szmic,
> + keys->akf ? app_key : dev_key);
> } else {
> seg_max = SEG_MAX(keys->segmented, app_msg_len + 4);
> enc_msg = l_malloc(app_msg_len + 4);
> - mesh_crypto_application_encrypt(key_aid, keys->app_seq,
> - keys->net_src, keys->net_dst,
> - keys->iv_index,
> - keys->akf ? app_key : dev_key,
> - aad, aad_len,
> - app_msg, app_msg_len,
> - enc_msg, &app_mic32, sizeof(app_mic32));
> - l_put_be32(app_mic32, enc_msg + app_msg_len);
> +
> + mesh_crypto_payload_encrypt(aad, app_msg,
> + enc_msg, app_msg_len,
> + keys->net_src, keys->net_dst, key_aid,
> + keys->app_seq, keys->iv_index,
> + keys->szmic,
> + keys->akf ? app_key : dev_key);
> }
>
> if (keys->dev_key && !keys->akf)
> @@ -1057,10 +1056,12 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> verify_data("EncryptedAppPayload", 0, keys->enc_msg, enc_msg,
> app_msg_len);
> if (keys->szmic) {
> + app_mic64 = l_get_be64(enc_msg + app_msg_len);
> verify_uint64("ApplicationMIC", app_msg_len,
> keys->app_mic64, app_mic64);
> app_msg_len += 8;
> } else {
> + app_mic32 = l_get_be32(enc_msg + app_msg_len);
> verify_uint32("ApplicationMIC", app_msg_len,
> keys->app_mic32, app_mic32);
> app_msg_len += 4;
> @@ -1172,20 +1173,18 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> keys->net_seq[i], keys->net_src,
> keys->iv_index, net_nonce);
>
> - verify_data("TransportData", 9, keys->trans_pkt[i],
> + verify_data("TransportData", 9, keys->trans_pkt[i],
> packet + 9, seg_len);
>
> verify_uint16("DST", 7, keys->net_dst, l_get_be16(packet + 7));
> net_msg_len = seg_len + 2;
> show_data("TransportPayload", 7, packet + 7, net_msg_len);
>
> - mesh_crypto_network_encrypt(keys->ctl,
> - keys->net_ttl, keys->net_seq[i],
> - keys->net_src,
> - keys->iv_index, enc_key,
> - packet + 7, seg_len + 2, packet + 7,
> - keys->ctl ? (void *)&net_mic64 :
> - (void *)&net_mic32);
> + mesh_crypto_packet_encrypt(packet, packet_len, enc_key,
> + keys->iv_index, false,
> + keys->ctl, keys->net_ttl,
> + keys->net_seq[i],
> + keys->net_src);
>
> mesh_crypto_privacy_counter(keys->iv_index, packet + 7,
> priv_rand);
> @@ -1208,20 +1207,23 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> verify_data("EncNetworkPayload", 7, keys->net_msg[i],
> packet + 7, net_msg_len);
> if (keys->ctl) {
> + net_mic64 = l_get_be64(packet + packet_len - 8);
> verify_uint64("NetworkMIC", 7 + net_msg_len,
> keys->net_mic64, net_mic64);
> net_msg_len += 8;
> } else {
> + net_mic32 = l_get_be32(packet + packet_len - 4);
> verify_uint32("NetworkMIC", 7 + net_msg_len,
> keys->net_mic32[i], net_mic32);
> net_msg_len += 4;
> }
>
> show_data("PreObsPayload", 1, packet + 1, 6 + net_msg_len);
> - mesh_crypto_network_obfuscate(priv_key, priv_rand,
> - keys->ctl,
> - keys->net_ttl, keys->net_seq[i],
> - keys->net_src, packet + 1);
> + mesh_crypto_network_obfuscate(packet, priv_key,
> + keys->iv_index,
> + keys->ctl, keys->net_ttl,
> + keys->net_seq[i], keys->net_src);
> +
> show_data("PostObsPayload", 1, packet + 1, 6 + net_msg_len);
>
> packet[0] = (keys->iv_index & 0x01) << 7 | nid;
> @@ -1242,7 +1244,7 @@ done:
>
> static void check_decrypt_segment(const struct mesh_crypto_test *keys,
> uint16_t seg, uint16_t seg_max,
> - const uint8_t *pkt, uint8_t pkt_len,
> + uint8_t *pkt, uint8_t pkt_len,
> const uint8_t *msg, uint8_t msg_len,
> uint8_t *enc_key, uint8_t *priv_key,
> uint8_t nid)
> @@ -1274,26 +1276,30 @@ static void check_decrypt_segment(const struct mesh_crypto_test *keys,
> if (ctl) {
> net_mic64 = l_get_be64(pkt + pkt_len - 8);
> show_data("EncryptedPayload", 7, pkt + 7, pkt_len - 7 - 8);
> - mesh_crypto_network_decrypt(ctl, ttl, seq,
> - src, keys->iv_index, enc_key,
> - pkt + 7, pkt_len - 7, net_clr + 7,
> - &calc_net_mic64,
> - sizeof(calc_net_mic64));
> +
> + mesh_crypto_packet_decrypt(pkt, pkt_len,
> + enc_key,
> + keys->iv_index, false,
> + ctl, ttl, seq,
> + src);
> + calc_net_mic64 = l_get_be64(pkt + pkt_len - 8);
> +
> verify_uint64("NetworkMIC", pkt_len - 8, net_mic64,
> - calc_net_mic64);
> + net_mic64 ^ calc_net_mic64);
> show_data("DecryptedPayload", 7, net_clr + 7, pkt_len - 7 - 8);
> } else {
> net_mic32 = l_get_be32(pkt + pkt_len - 4);
> show_data("EncryptedPayload", 7, pkt + 7, pkt_len - 7 - 4);
>
> - mesh_crypto_network_decrypt(ctl, ttl, seq,
> - src, keys->iv_index, enc_key,
> - pkt + 7, pkt_len - 7, net_clr + 7,
> - &calc_net_mic32,
> - sizeof(calc_net_mic32));
> + mesh_crypto_packet_decrypt(pkt, pkt_len,
> + enc_key,
> + keys->iv_index, false,
> + ctl, ttl, seq,
> + src);
> + calc_net_mic32 = l_get_be32(pkt + pkt_len - 4);
>
> verify_uint32("NetworkMIC", pkt_len - 4, net_mic32,
> - calc_net_mic32);
> + net_mic32 ^ calc_net_mic32);
> show_data("DecryptedPayload", 7, net_clr + 7, pkt_len - 7 - 4);
> }
>
> @@ -1387,15 +1393,11 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> uint8_t *app_key;
> uint8_t *net_key;
> uint8_t enc_key[16];
> - uint8_t net_nonce[13];
> - uint8_t app_nonce[13];
> uint8_t priv_key[16];
> - uint8_t priv_rand[16];
> uint8_t p[9];
> size_t p_len;
> uint8_t *packet = NULL;
> size_t packet_len;
> - const uint8_t *net_hdr;
> uint8_t *net_msg;
> uint8_t net_msg_len;
> uint16_t app_msg_len = 0;
> @@ -1469,9 +1471,6 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> goto done;
> }
>
> - mesh_crypto_application_nonce(keys->app_seq, keys->net_src,
> - keys->net_dst, keys->iv_index,
> - keys->szmic, app_nonce);
> app_msg = l_malloc(384);
>
> seg_max = (sizeof(keys->packet) / sizeof(keys->packet[0])) - 1;
> @@ -1483,19 +1482,13 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> if (keys->segmented)
> l_info(COLOR_YELLOW "Segment-%d" COLOR_OFF, i);
>
> - mesh_crypto_network_nonce(keys->frnd, keys->net_ttl,
> - keys->net_seq[i], keys->net_src, keys->iv_index,
> - net_nonce);
> l_free(packet);
> packet = l_util_from_hexstring(keys->packet[i], &packet_len);
>
> - net_hdr = packet + 1;
> net_msg = packet + 7;
> net_msg_len = packet_len - 7;
>
> - mesh_crypto_privacy_counter(keys->iv_index, net_msg, priv_rand);
> -
> - mesh_crypto_network_clarify(priv_key, priv_rand, net_hdr,
> + mesh_crypto_network_clarify(packet, priv_key, keys->iv_index,
> &net_ctl, &net_ttl, &net_seq, &net_src);
>
> show_str("Packet", 0, keys->packet[i]);
> @@ -1504,29 +1497,31 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> net_mic64 = l_get_be64(packet + packet_len - 8);
> show_data("NetworkMessage", 7, net_msg,
> net_msg_len - 8);
> - mesh_crypto_network_decrypt(net_ctl, net_ttl, net_seq,
> - net_src, keys->iv_index, enc_key,
> - net_msg, net_msg_len, net_msg,
> - &calc_net_mic64,
> - sizeof(calc_net_mic64));
> + mesh_crypto_packet_decrypt(packet, packet_len,
> + enc_key,
> + keys->iv_index, false,
> + net_ctl, net_ttl,
> + net_seq,
> + net_src);
> + calc_net_mic64 = l_get_be64(packet + packet_len - 8);
> net_msg_len -= 8;
> verify_uint64("NetworkMIC", 7 + net_msg_len, net_mic64,
> - calc_net_mic64);
> + net_mic64 ^ calc_net_mic64);
> show_data("DecryptedNetwork", 7, net_msg, net_msg_len);
> } else {
> net_mic32 = l_get_be32(packet + packet_len - 4);
> show_data("NetworkMessage", 7, net_msg,
> net_msg_len - 4);
> -
> - mesh_crypto_network_decrypt(net_ctl, net_ttl, net_seq,
> - net_src, keys->iv_index, enc_key,
> - net_msg, net_msg_len, net_msg,
> - &calc_net_mic32,
> - sizeof(calc_net_mic32));
> -
> + mesh_crypto_packet_decrypt(packet, packet_len,
> + enc_key,
> + keys->iv_index, false,
> + net_ctl, net_ttl,
> + net_seq,
> + net_src);
> + calc_net_mic32 = l_get_be32(packet + packet_len - 4);
> net_msg_len -= 4;
> verify_uint32("NetworkMIC", 7 + net_msg_len, net_mic32,
> - calc_net_mic32);
> + net_mic32 ^ calc_net_mic32);
> show_data("DecryptedNetwork", 7, net_msg, net_msg_len);
> }
>
> @@ -1645,8 +1640,8 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> packet, &pkt_len);
> verify_data("TransportData", 9, keys->trans_pkt[i], packet + 9,
> payload_len);
> - mesh_crypto_packet_encode(packet, pkt_len, enc_key,
> - keys->iv_index, priv_key);
> + mesh_crypto_packet_encode(packet, pkt_len, keys->iv_index,
> + enc_key, priv_key);
> mesh_crypto_packet_label(packet, pkt_len, keys->iv_index, nid);
>
> verify_data("Encoded-Packet", 0, keys->packet[i], packet,
> @@ -1666,39 +1661,45 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> app_msg_len - 8);
> app_mic64 = l_get_be64(app_msg + app_msg_len - 8);
>
> - mesh_crypto_application_decrypt(
> - keys_aid | (keys->akf ? KEY_ID_AKF : 0),
> - seqZero, net_src,
> - net_dst, keys->iv_index,
> - keys->akf ? app_key : dev_key,
> + mesh_crypto_payload_decrypt(
> aad, aad_len,
> app_msg, app_msg_len,
> - app_msg, &calc_app_mic64,
> - sizeof(calc_app_mic64));
> + true,
> + net_src, net_dst,
> + keys->akf ? keys_aid | KEY_ID_AKF : APP_AID_DEV,
> + seqZero,
> + keys->iv_index,
> + app_msg,
> + keys->akf ? app_key : dev_key);
> +
> + calc_app_mic64 = l_get_be64(app_msg + app_msg_len - 8);
>
> verify_data("Payload", 0, keys->app_msg, app_msg,
> app_msg_len - 8);
> verify_uint64("ApplicationMIC", app_msg_len - 8, app_mic64,
> - calc_app_mic64);
> + app_mic64 ^ calc_app_mic64);
> } else if (!keys->ctl) {
> verify_data("EncryptedPayload", 0, keys->enc_msg, app_msg,
> app_msg_len - 4);
> app_mic32 = l_get_be32(app_msg + app_msg_len - 4);
>
> - mesh_crypto_application_decrypt(
> - keys_aid | (keys->akf ? KEY_ID_AKF : 0),
> - seqZero, net_src,
> - net_dst, keys->iv_index,
> - keys->akf ? app_key : dev_key,
> + mesh_crypto_payload_decrypt(
> aad, aad_len,
> app_msg, app_msg_len,
> - app_msg, &calc_app_mic32,
> - sizeof(calc_app_mic32));
> + false,
> + net_src, net_dst,
> + keys->akf ? keys_aid | KEY_ID_AKF : APP_AID_DEV,
> + seqZero,
> + keys->iv_index,
> + app_msg,
> + keys->akf ? app_key : dev_key);
> +
> + calc_app_mic32 = l_get_be64(app_msg + app_msg_len - 4);
>
> verify_data("Payload", 0, keys->app_msg, app_msg,
> app_msg_len - 4);
> verify_uint32("ApplicationMIC", app_msg_len - 4, app_mic32,
> - calc_app_mic32);
> + app_mic32 ^ calc_app_mic32);
> }
>
> done:

2020-04-05 19:52:08

by Gix, Brian

[permalink] [raw]
Subject: Re: [PATCH BlueZ RESEND] mesh: Remove redundant code from mesh/crypto

On Sun, 2020-04-05 at 11:45 -0700, Brian Gix wrote:
> Hi Michał,
>
> I think this needs some more work, in that it no longer correctly fails the mesh-test-crypto test when
> running:
>
> make distcheck
>
> It *almost* does in that it flags an error in red if a "verify" step fails, but it does not exit with a fail
> code. This is an important step, particularily with the dependance on kernel based crypto functions.
>
> My test methodology was to flip a bit in one of the test payloads (i.e., make it "not perfectly match" the
> specification sample data).
>
> As best I can tell, it is otherwise functional, but the unit tests are important.

I'm not sure what exactly is happening yet, but running:

"make check"

is failing for me with your patch, on unit/test-mesh-crypto


>
> On Thu, 2020-03-26 at 22:17 +0100, Michał Lowas-Rzechonek wrote:
> > - Remove application_encrypt/application_decrypt
> > - Make mesh_crypto_privacy_counter private, add mesh_crypto_pecb
> > - Make *_nonce functions private and align their implementation to be
> > more consistent
> > - Refactor network_encrypt/network_decrypt to use *_nonce functions and
> > rename them to packet_encrypt/packet_decrypt
> > - Refactor packet_encode/packet_decode
> > ---
> > mesh/crypto.c | 481 ++++++++++++++++------------------------
> > mesh/crypto.h | 50 +----
> > mesh/net-keys.c | 2 +-
> > unit/test-mesh-crypto.c | 205 ++++++++---------
> > 4 files changed, 291 insertions(+), 447 deletions(-)
> >
> > diff --git a/mesh/crypto.c b/mesh/crypto.c
> > index 596a289f9..ce335bbec 100644
> > --- a/mesh/crypto.c
> > +++ b/mesh/crypto.c
> > @@ -327,144 +327,59 @@ bool mesh_crypto_beacon_cmac(const uint8_t encryption_key[16],
> > return true;
> > }
> >
> > -bool mesh_crypto_network_nonce(bool ctl, uint8_t ttl, uint32_t seq,
> > - uint16_t src, uint32_t iv_index,
> > - uint8_t nonce[13])
> > +static void mesh_crypto_network_nonce(bool ctl, uint8_t ttl,
> > + uint32_t seq, uint16_t src,
> > + uint32_t iv_index, uint8_t nonce[13])
> > {
> > - nonce[0] = 0;
> > + nonce[0] = 0x00;
> > nonce[1] = (ttl & TTL_MASK) | (ctl ? CTL : 0x00);
> > nonce[2] = (seq >> 16) & 0xff;
> > nonce[3] = (seq >> 8) & 0xff;
> > nonce[4] = seq & 0xff;
> > -
> > - /* SRC */
> > l_put_be16(src, nonce + 5);
> > -
> > l_put_be16(0, nonce + 7);
> > -
> > - /* IV Index */
> > l_put_be32(iv_index, nonce + 9);
> > -
> > - return true;
> > -}
> > -
> > -bool mesh_crypto_network_encrypt(bool ctl, uint8_t ttl,
> > - uint32_t seq, uint16_t src,
> > - uint32_t iv_index,
> > - const uint8_t net_key[16],
> > - const uint8_t *enc_msg, uint8_t enc_msg_len,
> > - uint8_t *out, void *net_mic)
> > -{
> > - uint8_t nonce[13];
> > -
> > - if (!mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce))
> > - return false;
> > -
> > - return mesh_crypto_aes_ccm_encrypt(nonce, net_key, NULL, 0, enc_msg,
> > - enc_msg_len, out, net_mic,
> > - ctl ? 8 : 4);
> > }
> >
> > -bool mesh_crypto_network_decrypt(bool ctl, uint8_t ttl,
> > - uint32_t seq, uint16_t src,
> > - uint32_t iv_index,
> > - const uint8_t net_key[16],
> > - const uint8_t *enc_msg, uint8_t enc_msg_len,
> > - uint8_t *out, void *net_mic, size_t mic_size)
> > -{
> > - uint8_t nonce[13];
> > -
> > - if (!mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce))
> > - return false;
> > -
> > - return mesh_crypto_aes_ccm_decrypt(nonce, net_key, NULL, 0,
> > - enc_msg, enc_msg_len, out,
> > - net_mic, mic_size);
> > -}
> > -
> > -bool mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
> > +static void mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
> > uint16_t dst, uint32_t iv_index,
> > bool aszmic, uint8_t nonce[13])
> > {
> > nonce[0] = 0x01;
> > nonce[1] = aszmic ? 0x80 : 0x00;
> > - nonce[2] = (seq & 0x00ff0000) >> 16;
> > - nonce[3] = (seq & 0x0000ff00) >> 8;
> > - nonce[4] = (seq & 0x000000ff);
> > - nonce[5] = (src & 0xff00) >> 8;
> > - nonce[6] = (src & 0x00ff);
> > - nonce[7] = (dst & 0xff00) >> 8;
> > - nonce[8] = (dst & 0x00ff);
> > + nonce[2] = (seq >> 16 ) & 0xff;
> > + nonce[3] = (seq >> 8) & 0xff;
> > + nonce[4] = seq & 0xff;
> > + l_put_be16(src, nonce + 5);
> > + l_put_be16(dst, nonce + 7);
> > l_put_be32(iv_index, nonce + 9);
> > -
> > - return true;
> > }
> >
> > -bool mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
> > +static void mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
> > uint16_t dst, uint32_t iv_index,
> > bool aszmic, uint8_t nonce[13])
> > {
> > nonce[0] = 0x02;
> > nonce[1] = aszmic ? 0x80 : 0x00;
> > - nonce[2] = (seq & 0x00ff0000) >> 16;
> > - nonce[3] = (seq & 0x0000ff00) >> 8;
> > - nonce[4] = (seq & 0x000000ff);
> > - nonce[5] = (src & 0xff00) >> 8;
> > - nonce[6] = (src & 0x00ff);
> > - nonce[7] = (dst & 0xff00) >> 8;
> > - nonce[8] = (dst & 0x00ff);
> > + nonce[2] = (seq >> 16 ) & 0xff;
> > + nonce[3] = (seq >> 8) & 0xff;
> > + nonce[4] = seq & 0xff;
> > + l_put_be16(src, nonce + 5);
> > + l_put_be16(dst, nonce + 7);
> > l_put_be32(iv_index, nonce + 9);
> > -
> > - return true;
> > }
> >
> > -bool mesh_crypto_application_encrypt(uint8_t key_aid, uint32_t seq,
> > - uint16_t src, uint16_t dst,
> > - uint32_t iv_index,
> > - const uint8_t app_key[16],
> > - const uint8_t *aad, uint8_t aad_len,
> > - const uint8_t *msg, uint8_t msg_len,
> > - uint8_t *out,
> > - void *app_mic, size_t mic_size)
> > +static void mesh_crypto_proxy_nonce(uint32_t seq, uint16_t src,
> > + uint32_t iv_index, uint8_t nonce[13])
> > {
> > - uint8_t nonce[13];
> > - bool aszmic = (mic_size == 8) ? true : false;
> > -
> > - if (!key_aid && !mesh_crypto_device_nonce(seq, src, dst,
> > - iv_index, aszmic, nonce))
> > - return false;
> > -
> > - if (key_aid && !mesh_crypto_application_nonce(seq, src, dst,
> > - iv_index, aszmic, nonce))
> > - return false;
> > -
> > - return mesh_crypto_aes_ccm_encrypt(nonce, app_key, aad, aad_len,
> > - msg, msg_len,
> > - out, app_mic, mic_size);
> > -}
> > -
> > -bool mesh_crypto_application_decrypt(uint8_t key_aid, uint32_t seq,
> > - uint16_t src, uint16_t dst, uint32_t iv_index,
> > - const uint8_t app_key[16],
> > - const uint8_t *aad, uint8_t aad_len,
> > - const uint8_t *enc_msg, uint8_t enc_msg_len,
> > - uint8_t *out, void *app_mic, size_t mic_size)
> > -{
> > - uint8_t nonce[13];
> > - bool aszmic = (mic_size == 8) ? true : false;
> > -
> > - if (!key_aid && !mesh_crypto_device_nonce(seq, src, dst,
> > - iv_index, aszmic, nonce))
> > - return false;
> > -
> > - if (key_aid && !mesh_crypto_application_nonce(seq, src, dst,
> > - iv_index, aszmic, nonce))
> > - return false;
> > -
> > - return mesh_crypto_aes_ccm_decrypt(nonce, app_key,
> > - aad, aad_len, enc_msg,
> > - enc_msg_len, out,
> > - app_mic, mic_size);
> > + nonce[0] = 0x03;
> > + nonce[1] = 0;
> > + nonce[2] = (seq >> 16) & 0xff;
> > + nonce[3] = (seq >> 8) & 0xff;
> > + nonce[4] = seq & 0xff;
> > + l_put_be16(src, nonce + 5);
> > + l_put_be16(0, nonce + 7);
> > + l_put_be32(iv_index, nonce + 9);
> > }
> >
> > bool mesh_crypto_session_key(const uint8_t secret[32],
> > @@ -557,69 +472,67 @@ bool mesh_crypto_virtual_addr(const uint8_t virtual_label[16],
> > return true;
> > }
> >
> > -bool mesh_crypto_privacy_counter(uint32_t iv_index,
> > +static void mesh_crypto_privacy_counter(uint32_t iv_index,
> > const uint8_t *payload,
> > uint8_t privacy_counter[16])
> > {
> > memset(privacy_counter, 0, 5);
> > l_put_be32(iv_index, privacy_counter + 5);
> > memcpy(privacy_counter + 9, payload, 7);
> > +}
> >
> > - return true;
> > +static bool mesh_crypto_pecb(const uint8_t privacy_key[16],
> > + uint32_t iv_index,
> > + const uint8_t *payload,
> > + uint8_t pecb[16])
> > +{
> > + mesh_crypto_privacy_counter(iv_index, payload, pecb);
> > + return aes_ecb_one(privacy_key, pecb, pecb);
> > }
> >
> > -bool mesh_crypto_network_obfuscate(const uint8_t privacy_key[16],
> > - const uint8_t privacy_counter[16],
> > - bool ctl, uint8_t ttl, uint32_t seq,
> > - uint16_t src, uint8_t *out)
> > +static bool mesh_crypto_network_obfuscate(uint8_t *packet,
> > + const uint8_t privacy_key[16],
> > + uint32_t iv_index,
> > + bool ctl, uint8_t ttl,
> > + uint32_t seq, uint16_t src)
> > {
> > - uint8_t ecb[16], tmp[16];
> > + uint8_t pecb[16];
> > + uint8_t *net_hdr = packet + 1;
> > int i;
> >
> > - if (!aes_ecb_one(privacy_key, privacy_counter, ecb))
> > + if (!mesh_crypto_pecb(privacy_key, iv_index, packet + 7, pecb))
> > return false;
> >
> > - tmp[0] = ((!!ctl) << 7) | (ttl & TTL_MASK);
> > - tmp[1] = (seq & 0xff0000) >> 16;
> > - tmp[2] = (seq & 0x00ff00) >> 8;
> > - tmp[3] = (seq & 0x0000ff);
> > - tmp[4] = (src & 0xff00) >> 8;
> > - tmp[5] = (src & 0x00ff);
> > + l_put_be16(src, net_hdr + 4);
> > + l_put_be32(seq & SEQ_MASK, net_hdr);
> > + net_hdr[0] = ((!!ctl) << 7) | (ttl & TTL_MASK);
> >
> > - if (out) {
> > - for (i = 0; i < 6; i++)
> > - out[i] = ecb[i] ^ tmp[i];
> > - }
> > + for (i = 0; i < 6; i++)
> > + net_hdr[i] = pecb[i] ^ net_hdr[i];
> >
> > return true;
> > }
> >
> > -bool mesh_crypto_network_clarify(const uint8_t privacy_key[16],
> > - const uint8_t privacy_counter[16],
> > - const uint8_t net_hdr[6],
> > - bool *ctl, uint8_t *ttl,
> > - uint32_t *seq, uint16_t *src)
> > +static bool mesh_crypto_network_clarify(uint8_t *packet,
> > + const uint8_t privacy_key[16],
> > + uint32_t iv_index,
> > + bool *ctl, uint8_t *ttl,
> > + uint32_t *seq, uint16_t *src)
> > {
> > - uint8_t ecb[16], tmp[6];
> > + uint8_t pecb[16];
> > + uint8_t *net_hdr = packet + 1;
> > int i;
> >
> > - if (!aes_ecb_one(privacy_key, privacy_counter, ecb))
> > + if (!mesh_crypto_pecb(privacy_key, iv_index, packet + 7, pecb))
> > return false;
> >
> > for (i = 0; i < 6; i++)
> > - tmp[i] = ecb[i] ^ net_hdr[i];
> > -
> > - if (ctl)
> > - *ctl = !!(tmp[0] & CTL);
> > + net_hdr[i] = pecb[i] ^ net_hdr[i];
> >
> > - if (ttl)
> > - *ttl = tmp[0] & TTL_MASK;
> > -
> > - if (seq)
> > - *seq = l_get_be32(tmp) & SEQ_MASK;
> > -
> > - if (src)
> > - *src = l_get_be16(tmp + 4);
> > + *src = l_get_be16(net_hdr + 4);
> > + *seq = l_get_be32(net_hdr) & SEQ_MASK;
> > + *ttl = net_hdr[0] & TTL_MASK;
> > + *ctl = !!(net_hdr[0] & CTL);
> >
> > return true;
> > }
> > @@ -689,24 +602,13 @@ bool mesh_crypto_packet_build(bool ctl, uint8_t ttl,
> > return true;
> > }
> >
> > -bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> > +static bool network_header_parse(const uint8_t *packet, uint8_t packet_len,
> > bool *ctl, uint8_t *ttl, uint32_t *seq,
> > - uint16_t *src, uint16_t *dst,
> > - uint32_t *cookie, uint8_t *opcode,
> > - bool *segmented, uint8_t *key_aid,
> > - bool *szmic, bool *relay, uint16_t *seqZero,
> > - uint8_t *segO, uint8_t *segN,
> > - const uint8_t **payload, uint8_t *payload_len)
> > + uint16_t *src, uint16_t *dst)
> > {
> > - uint32_t hdr;
> > - uint16_t this_dst;
> > - bool is_segmented;
> > -
> > if (packet_len < 10)
> > return false;
> >
> > - this_dst = l_get_be16(packet + 7);
> > -
> > /* Try to keep bits in the order they exist within the packet */
> > if (ctl)
> > *ctl = !!(packet[1] & CTL);
> > @@ -720,6 +622,30 @@ bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> > if (src)
> > *src = l_get_be16(packet + 5);
> >
> > + if (dst)
> > + *dst = l_get_be16(packet + 7);
> > +
> > + return true;
> > +
> > +}
> > +
> > +bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> > + bool *ctl, uint8_t *ttl, uint32_t *seq,
> > + uint16_t *src, uint16_t *dst,
> > + uint32_t *cookie, uint8_t *opcode,
> > + bool *segmented, uint8_t *key_aid,
> > + bool *szmic, bool *relay, uint16_t *seqZero,
> > + uint8_t *segO, uint8_t *segN,
> > + const uint8_t **payload, uint8_t *payload_len)
> > +{
> > + uint32_t hdr;
> > + uint16_t this_dst;
> > + bool is_segmented;
> > +
> > + if (!network_header_parse(packet, packet_len,
> > + ctl, ttl, seq, src, &this_dst))
> > + return false;
> > +
> > if (dst)
> > *dst = this_dst;
> >
> > @@ -799,38 +725,27 @@ bool mesh_crypto_packet_parse(const uint8_t *packet, uint8_t packet_len,
> > bool mesh_crypto_payload_encrypt(uint8_t *aad, const uint8_t *payload,
> > uint8_t *out, uint16_t payload_len,
> > uint16_t src, uint16_t dst, uint8_t key_aid,
> > - uint32_t seq_num, uint32_t iv_index,
> > + uint32_t seq, uint32_t iv_index,
> > bool aszmic,
> > - const uint8_t application_key[16])
> > + const uint8_t app_key[16])
> > {
> > - uint8_t application_nonce[13] = { 0x01, };
> > + uint8_t nonce[13];
> >
> > if (payload_len < 1)
> > return false;
> >
> > if (key_aid == APP_AID_DEV)
> > - application_nonce[0] = 0x02;
> > -
> > - /* Seq Num */
> > - l_put_be32(seq_num, application_nonce + 1);
> > -
> > - /* ASZMIC */
> > - application_nonce[1] |= aszmic ? 0x80 : 0x00;
> > -
> > - /* SRC */
> > - l_put_be16(src, application_nonce + 5);
> > -
> > - /* DST */
> > - l_put_be16(dst, application_nonce + 7);
> > -
> > - /* IV Index */
> > - l_put_be32(iv_index, application_nonce + 9);
> > -
> > - if (!mesh_crypto_aes_ccm_encrypt(application_nonce, application_key,
> > - aad, aad ? 16 : 0,
> > - payload, payload_len,
> > - out, NULL,
> > - aszmic ? 8 : 4))
> > + mesh_crypto_device_nonce(seq, src, dst, iv_index, aszmic,
> > + nonce);
> > + else
> > + mesh_crypto_application_nonce(seq, src, dst, iv_index, aszmic,
> > + nonce);
> > +
> > + if (!mesh_crypto_aes_ccm_encrypt(nonce, app_key,
> > + aad, aad ? 16 : 0,
> > + payload, payload_len,
> > + out, NULL,
> > + aszmic ? 8 : 4))
> > return false;
> >
> > return true;
> > @@ -838,13 +753,13 @@ bool mesh_crypto_payload_encrypt(uint8_t *aad, const uint8_t *payload,
> >
> > bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> > const uint8_t *payload, uint16_t payload_len,
> > - bool szmict,
> > + bool aszmic,
> > uint16_t src, uint16_t dst,
> > - uint8_t key_aid, uint32_t seq_num,
> > + uint8_t key_aid, uint32_t seq,
> > uint32_t iv_index, uint8_t *out,
> > const uint8_t app_key[16])
> > {
> > - uint8_t app_nonce[13] = { 0x01, };
> > + uint8_t nonce[13];
> > uint32_t mic32;
> > uint64_t mic64;
> >
> > @@ -852,27 +767,16 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> > return false;
> >
> > if (key_aid == APP_AID_DEV)
> > - app_nonce[0] = 0x02;
> > -
> > - /* Seq Num */
> > - l_put_be32(seq_num, app_nonce + 1);
> > -
> > - /* ASZMIC */
> > - app_nonce[1] |= szmict ? 0x80 : 0x00;
> > -
> > - /* SRC */
> > - l_put_be16(src, app_nonce + 5);
> > -
> > - /* DST */
> > - l_put_be16(dst, app_nonce + 7);
> > -
> > - /* IV Index */
> > - l_put_be32(iv_index, app_nonce + 9);
> > + mesh_crypto_device_nonce(seq, src, dst, iv_index, aszmic,
> > + nonce);
> > + else
> > + mesh_crypto_application_nonce(seq, src, dst, iv_index, aszmic,
> > + nonce);
> >
> > memcpy(out, payload, payload_len);
> >
> > - if (szmict) {
> > - if (!mesh_crypto_aes_ccm_decrypt(app_nonce, app_key,
> > + if (aszmic) {
> > + if (!mesh_crypto_aes_ccm_decrypt(nonce, app_key,
> > aad, aad_len,
> > payload, payload_len,
> > out, &mic64, sizeof(mic64)))
> > @@ -884,7 +788,7 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> > if (mic64)
> > return false;
> > } else {
> > - if (!mesh_crypto_aes_ccm_decrypt(app_nonce, app_key,
> > + if (!mesh_crypto_aes_ccm_decrypt(nonce, app_key,
> > aad, aad_len,
> > payload, payload_len,
> > out, &mic32, sizeof(mic32)))
> > @@ -900,146 +804,107 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> > return true;
> > }
> >
> > -bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
> > +static bool mesh_crypto_packet_encrypt(uint8_t *packet, uint8_t packet_len,
> > const uint8_t network_key[16],
> > - uint32_t iv_index,
> > - const uint8_t privacy_key[16])
> > + uint32_t iv_index, bool proxy,
> > + bool ctl, uint8_t ttl, uint32_t seq,
> > + uint16_t src)
> > {
> > - uint8_t network_nonce[13] = { 0x00, 0x00 };
> > - uint8_t privacy_counter[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
> > - uint8_t tmp[16];
> > - int i;
> > -
> > - if (packet_len < 14)
> > - return false;
> > + uint8_t nonce[13];
> >
> > /* Detect Proxy packet by CTL == true && DST == 0x0000 */
> > - if ((packet[1] & CTL) && l_get_be16(packet + 7) == 0)
> > - network_nonce[0] = 0x03; /* Proxy Nonce */
> > + if (ctl && proxy)
> > + mesh_crypto_proxy_nonce(seq, src, iv_index, nonce);
> > else
> > - /* CTL + TTL */
> > - network_nonce[1] = packet[1];
> > -
> > - /* Seq Num */
> > - network_nonce[2] = packet[2];
> > - network_nonce[3] = packet[3];
> > - network_nonce[4] = packet[4];
> > -
> > - /* SRC */
> > - network_nonce[5] = packet[5];
> > - network_nonce[6] = packet[6];
> > -
> > - /* DST not available */
> > - network_nonce[7] = 0;
> > - network_nonce[8] = 0;
> > -
> > - /* IV Index */
> > - l_put_be32(iv_index, network_nonce + 9);
> > + mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce);
> >
> > /* Check for Long net-MIC */
> > - if (packet[1] & CTL) {
> > - if (!mesh_crypto_aes_ccm_encrypt(network_nonce, network_key,
> > + if (ctl) {
> > + if (!mesh_crypto_aes_ccm_encrypt(nonce, network_key,
> > NULL, 0,
> > packet + 7, packet_len - 7 - 8,
> > packet + 7, NULL, 8))
> > return false;
> > } else {
> > - if (!mesh_crypto_aes_ccm_encrypt(network_nonce, network_key,
> > + if (!mesh_crypto_aes_ccm_encrypt(nonce, network_key,
> > NULL, 0,
> > packet + 7, packet_len - 7 - 4,
> > packet + 7, NULL, 4))
> > return false;
> > }
> >
> > - l_put_be32(iv_index, privacy_counter + 5);
> > - memcpy(privacy_counter + 9, packet + 7, 7);
> > -
> > - if (!aes_ecb_one(privacy_key, privacy_counter, tmp))
> > - return false;
> > -
> > - for (i = 0; i < 6; i++)
> > - packet[1 + i] ^= tmp[i];
> > -
> > return true;
> > }
> >
> > -bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> > - bool proxy, uint8_t *out, uint32_t iv_index,
> > +bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
> > + uint32_t iv_index,
> > const uint8_t network_key[16],
> > const uint8_t privacy_key[16])
> > {
> > - uint8_t privacy_counter[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, };
> > - uint8_t network_nonce[13] = { 0x00, 0x00, };
> > - uint8_t tmp[16];
> > + bool ctl;
> > + uint8_t ttl;
> > + uint32_t seq;
> > uint16_t src;
> > - int i;
> > + uint16_t dst;
> >
> > - if (packet_len < 14)
> > + if (!network_header_parse(packet, packet_len,
> > + &ctl, &ttl, &seq, &src, &dst))
> > return false;
> >
> > - l_put_be32(iv_index, privacy_counter + 5);
> > - memcpy(privacy_counter + 9, packet + 7, 7);
> > + if (!mesh_crypto_packet_encrypt(packet, packet_len, network_key,
> > + iv_index, !dst,
> > + ctl, ttl, seq, src))
> >
> > - if (!aes_ecb_one(privacy_key, privacy_counter, tmp))
> > return false;
> >
> > - memcpy(out, packet, packet_len);
> > - for (i = 0; i < 6; i++)
> > - out[1 + i] ^= tmp[i];
> > + return mesh_crypto_network_obfuscate(packet, privacy_key, iv_index,
> > + ctl, ttl, seq, src);
> > +}
> >
> > - src = l_get_be16(out + 5);
> > +static bool mesh_crypto_packet_decrypt(uint8_t *packet, uint8_t packet_len,
> > + const uint8_t network_key[16],
> > + uint32_t iv_index, bool proxy,
> > + bool ctl, uint8_t ttl, uint32_t seq,
> > + uint16_t src)
> > +{
> > + uint8_t nonce[13];
> >
> > /* Pre-check SRC address for illegal values */
> > - if (!src || src >= 0x8000)
> > + if (!IS_UNICAST(src))
> > return false;
> >
> > /* Detect Proxy packet by CTL == true && proxy == true */
> > - if ((out[1] & CTL) && proxy)
> > - network_nonce[0] = 0x03; /* Proxy Nonce */
> > + if (ctl & proxy)
> > + mesh_crypto_proxy_nonce(seq, src, iv_index, nonce);
> > else
> > - /* CTL + TTL */
> > - network_nonce[1] = out[1];
> > -
> > - /* Seq Num */
> > - network_nonce[2] = out[2];
> > - network_nonce[3] = out[3];
> > - network_nonce[4] = out[4];
> > -
> > - /* SRC */
> > - network_nonce[5] = out[5];
> > - network_nonce[6] = out[6];
> > -
> > - /* DST not available */
> > - network_nonce[7] = 0;
> > - network_nonce[8] = 0;
> > -
> > - /* IV Index */
> > - l_put_be32(iv_index, network_nonce + 9);
> > + mesh_crypto_network_nonce(ctl, ttl, seq, src, iv_index, nonce);
> >
> > /* Check for Long MIC */
> > - if (out[1] & CTL) {
> > + if (ctl) {
> > uint64_t mic;
> >
> > - if (!mesh_crypto_aes_ccm_decrypt(network_nonce, network_key,
> > - NULL, 0, packet + 7, packet_len - 7,
> > - out + 7, &mic, sizeof(mic)))
> > + if (!mesh_crypto_aes_ccm_decrypt(nonce, network_key,
> > + NULL, 0,
> > + packet + 7, packet_len - 7,
> > + packet + 7, &mic, sizeof(mic)))
> > return false;
> >
> > - mic ^= l_get_be64(out + packet_len - 8);
> > - l_put_be64(mic, out + packet_len - 8);
> > + mic ^= l_get_be64(packet + packet_len - 8);
> > + l_put_be64(mic, packet + packet_len - 8);
> >
> > if (mic)
> > return false;
> > } else {
> > uint32_t mic;
> >
> > - if (!mesh_crypto_aes_ccm_decrypt(network_nonce, network_key,
> > - NULL, 0, packet + 7, packet_len - 7,
> > - out + 7, &mic, sizeof(mic)))
> > + if (!mesh_crypto_aes_ccm_decrypt(nonce, network_key,
> > + NULL, 0,
> > + packet + 7, packet_len - 7,
> > + packet + 7, &mic, sizeof(mic)))
> > return false;
> >
> > - mic ^= l_get_be32(out + packet_len - 4);
> > - l_put_be32(mic, out + packet_len - 4);
> > + mic ^= l_get_be32(packet + packet_len - 4);
> > + l_put_be32(mic, packet + packet_len - 4);
> >
> > if (mic)
> > return false;
> > @@ -1048,6 +913,30 @@ bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> > return true;
> > }
> >
> > +bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> > + bool proxy, uint8_t *out, uint32_t iv_index,
> > + const uint8_t network_key[16],
> > + const uint8_t privacy_key[16])
> > +{
> > + bool ctl;
> > + uint8_t ttl;
> > + uint32_t seq;
> > + uint16_t src;
> > +
> > + if (packet_len < 14)
> > + return false;
> > +
> > + memcpy(out, packet, packet_len);
> > +
> > + if (!mesh_crypto_network_clarify(out, privacy_key, iv_index,
> > + &ctl, &ttl, &seq, &src))
> > + return false;
> > +
> > + return mesh_crypto_packet_decrypt(out, packet_len, network_key,
> > + iv_index, proxy,
> > + ctl, ttl, seq, src);
> > +}
> > +
> > bool mesh_crypto_packet_label(uint8_t *packet, uint8_t packet_len,
> > uint16_t iv_index, uint8_t network_id)
> > {
> > diff --git a/mesh/crypto.h b/mesh/crypto.h
> > index e5ce840b4..7d3f89cde 100644
> > --- a/mesh/crypto.h
> > +++ b/mesh/crypto.h
> > @@ -19,6 +19,7 @@
> >
> > #include <stdbool.h>
> > #include <stdint.h>
> > +#include <stdlib.h>
> >
> > bool mesh_crypto_aes_ccm_encrypt(const uint8_t nonce[13], const uint8_t key[16],
> > const uint8_t *aad, uint16_t aad_len,
> > @@ -41,40 +42,6 @@ bool mesh_crypto_beacon_cmac(const uint8_t encryption_key[16],
> > const uint8_t network_id[16],
> > uint32_t iv_index, bool kr,
> > bool iu, uint64_t *cmac);
> > -bool mesh_crypto_network_nonce(bool frnd, uint8_t ttl, uint32_t seq,
> > - uint16_t src, uint32_t iv_index,
> > - uint8_t nonce[13]);
> > -bool mesh_crypto_network_encrypt(bool ctl, uint8_t ttl,
> > - uint32_t seq, uint16_t src,
> > - uint32_t iv_index,
> > - const uint8_t net_key[16],
> > - const uint8_t *enc_msg, uint8_t enc_msg_len,
> > - uint8_t *out, void *net_mic);
> > -bool mesh_crypto_network_decrypt(bool frnd, uint8_t ttl,
> > - uint32_t seq, uint16_t src,
> > - uint32_t iv_index,
> > - const uint8_t net_key[16],
> > - const uint8_t *enc_msg, uint8_t enc_msg_len,
> > - uint8_t *out, void *net_mic, size_t mic_size);
> > -bool mesh_crypto_application_nonce(uint32_t seq, uint16_t src,
> > - uint16_t dst, uint32_t iv_index,
> > - bool aszmic, uint8_t nonce[13]);
> > -bool mesh_crypto_device_nonce(uint32_t seq, uint16_t src,
> > - uint16_t dst, uint32_t iv_index,
> > - bool aszmic, uint8_t nonce[13]);
> > -bool mesh_crypto_application_encrypt(uint8_t akf, uint32_t seq, uint16_t src,
> > - uint16_t dst, uint32_t iv_index,
> > - const uint8_t app_key[16],
> > - const uint8_t *aad, uint8_t aad_len,
> > - const uint8_t *msg, uint8_t msg_len,
> > - uint8_t *out,
> > - void *app_mic, size_t mic_size);
> > -bool mesh_crypto_application_decrypt(uint8_t akf, uint32_t seq, uint16_t src,
> > - uint16_t dst, uint32_t iv_index,
> > - const uint8_t app_key[16],
> > - const uint8_t *aad, uint8_t aad_len,
> > - const uint8_t *enc_msg, uint8_t enc_msg_len,
> > - uint8_t *out, void *app_mic, size_t mic_size);
> > bool mesh_crypto_device_key(const uint8_t secret[32],
> > const uint8_t salt[16],
> > uint8_t device_key[16]);
> > @@ -102,19 +69,6 @@ bool mesh_crypto_prov_conf_key(const uint8_t secret[32],
> > bool mesh_crypto_session_key(const uint8_t secret[32],
> > const uint8_t salt[16],
> > uint8_t session_key[16]);
> > -bool mesh_crypto_privacy_counter(uint32_t iv_index,
> > - const uint8_t *payload,
> > - uint8_t privacy_counter[16]);
> > -bool mesh_crypto_network_obfuscate(const uint8_t privacy_key[16],
> > - const uint8_t privacy_counter[16],
> > - bool ctl, uint8_t ttl, uint32_t seq,
> > - uint16_t src, uint8_t *out);
> > -bool mesh_crypto_network_clarify(const uint8_t privacy_key[16],
> > - const uint8_t privacy_counter[16],
> > - const uint8_t net_hdr[6],
> > - bool *ctl, uint8_t *ttl,
> > - uint32_t *seq, uint16_t *src);
> > -
> > bool mesh_crypto_packet_build(bool ctl, uint8_t ttl,
> > uint32_t seq,
> > uint16_t src, uint16_t dst,
> > @@ -146,8 +100,8 @@ bool mesh_crypto_payload_decrypt(uint8_t *aad, uint16_t aad_len,
> > uint8_t *out,
> > const uint8_t application_key[16]);
> > bool mesh_crypto_packet_encode(uint8_t *packet, uint8_t packet_len,
> > - const uint8_t network_key[16],
> > uint32_t iv_index,
> > + const uint8_t network_key[16],
> > const uint8_t privacy_key[16]);
> > bool mesh_crypto_packet_decode(const uint8_t *packet, uint8_t packet_len,
> > bool proxy, uint8_t *out, uint32_t iv_index,
> > diff --git a/mesh/net-keys.c b/mesh/net-keys.c
> > index 683a924c4..f7eb2ca68 100644
> > --- a/mesh/net-keys.c
> > +++ b/mesh/net-keys.c
> > @@ -263,7 +263,7 @@ bool net_key_encrypt(uint32_t id, uint32_t iv_index, uint8_t *pkt, size_t len)
> > if (!key)
> > return false;
> >
> > - result = mesh_crypto_packet_encode(pkt, len, key->encrypt, iv_index,
> > + result = mesh_crypto_packet_encode(pkt, len, iv_index, key->encrypt,
> > key->privacy);
> >
> > if (!result)
> > diff --git a/unit/test-mesh-crypto.c b/unit/test-mesh-crypto.c
> > index 0043b0b10..3ecb3d026 100644
> > --- a/unit/test-mesh-crypto.c
> > +++ b/unit/test-mesh-crypto.c
> > @@ -780,8 +780,8 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
> > uint8_t priv_rand[16];
> > uint8_t packet[29];
> > uint8_t packet_len;
> > - uint64_t net_mic64;
> > - uint32_t hdr, net_mic32;
> > + uint32_t hdr;
> > + uint64_t net_mic64, net_mic32;
> > size_t net_msg_len;
> > uint8_t key_aid = keys->key_aid | (keys->akf ? KEY_ID_AKF : 0x00);
> >
> > @@ -857,13 +857,12 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
> > net_msg_len = len + 2;
> > show_data("TransportPayload", 7, packet + 7, net_msg_len);
> >
> > - mesh_crypto_network_encrypt(keys->ctl,
> > - keys->net_ttl, keys->net_seq[0],
> > - keys->net_src,
> > - keys->iv_index, enc_key,
> > - packet + 7, len + 2, packet + 7,
> > - keys->ctl ? (void *)&net_mic64 :
> > - (void *)&net_mic32);
> > + mesh_crypto_packet_encrypt(packet, packet_len,
> > + enc_key,
> > + keys->iv_index, false,
> > + keys->ctl, keys->net_ttl,
> > + keys->net_seq[0],
> > + keys->net_src);
> >
> > mesh_crypto_privacy_counter(keys->iv_index, packet + 7, priv_rand);
> >
> > @@ -883,20 +882,22 @@ static void check_encrypt_segment(const struct mesh_crypto_test *keys,
> > verify_data("EncNetworkPayload", 7, keys->net_msg[0],
> > packet + 7, net_msg_len);
> > if (keys->ctl) {
> > + net_mic64 = l_get_be64(packet + 7 + net_msg_len);
> > verify_uint64("NetworkMIC", 7 + net_msg_len,
> > - keys->net_mic64, net_mic64);
> > + keys->net_mic64, net_mic64);
> > net_msg_len += 8;
> > } else {
> > + net_mic32 = l_get_be32(packet + 7 + net_msg_len);
> > verify_uint32("NetworkMIC", 7 + net_msg_len,
> > - keys->net_mic32[0], net_mic32);
> > + keys->net_mic32[0], net_mic32);
> > net_msg_len += 4;
> > }
> >
> > show_data("PreObsPayload", 1, packet + 1, 6 + net_msg_len);
> > - mesh_crypto_network_obfuscate(priv_key, priv_rand,
> > - keys->ctl,
> > - keys->net_ttl, keys->net_seq[0],
> > - keys->net_src, packet + 1);
> > + mesh_crypto_network_obfuscate(packet, priv_key,
> > + keys->iv_index,
> > + keys->ctl, keys->net_ttl,
> > + keys->net_seq[0], keys->net_src);
> > show_data("PostObsPayload", 1, packet + 1, 6 + net_msg_len);
> >
> > packet[0] = (keys->iv_index & 0x01) << 7 | nid;
> > @@ -1019,25 +1020,23 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> > if (keys->szmic) {
> > seg_max = SEG_MAX(keys->segmented, app_msg_len + 8);
> > enc_msg = l_malloc(app_msg_len + 8);
> > - mesh_crypto_application_encrypt(key_aid, keys->app_seq,
> > - keys->net_src, keys->net_dst,
> > - keys->iv_index,
> > - keys->akf ? app_key : dev_key,
> > - aad, aad_len,
> > - app_msg, app_msg_len,
> > - enc_msg, &app_mic64, sizeof(app_mic64));
> > - l_put_be64(app_mic64, enc_msg + app_msg_len);
> > +
> > + mesh_crypto_payload_encrypt(aad, app_msg,
> > + enc_msg, app_msg_len,
> > + keys->net_src, keys->net_dst, key_aid,
> > + keys->app_seq, keys->iv_index,
> > + keys->szmic,
> > + keys->akf ? app_key : dev_key);
> > } else {
> > seg_max = SEG_MAX(keys->segmented, app_msg_len + 4);
> > enc_msg = l_malloc(app_msg_len + 4);
> > - mesh_crypto_application_encrypt(key_aid, keys->app_seq,
> > - keys->net_src, keys->net_dst,
> > - keys->iv_index,
> > - keys->akf ? app_key : dev_key,
> > - aad, aad_len,
> > - app_msg, app_msg_len,
> > - enc_msg, &app_mic32, sizeof(app_mic32));
> > - l_put_be32(app_mic32, enc_msg + app_msg_len);
> > +
> > + mesh_crypto_payload_encrypt(aad, app_msg,
> > + enc_msg, app_msg_len,
> > + keys->net_src, keys->net_dst, key_aid,
> > + keys->app_seq, keys->iv_index,
> > + keys->szmic,
> > + keys->akf ? app_key : dev_key);
> > }
> >
> > if (keys->dev_key && !keys->akf)
> > @@ -1057,10 +1056,12 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> > verify_data("EncryptedAppPayload", 0, keys->enc_msg, enc_msg,
> > app_msg_len);
> > if (keys->szmic) {
> > + app_mic64 = l_get_be64(enc_msg + app_msg_len);
> > verify_uint64("ApplicationMIC", app_msg_len,
> > keys->app_mic64, app_mic64);
> > app_msg_len += 8;
> > } else {
> > + app_mic32 = l_get_be32(enc_msg + app_msg_len);
> > verify_uint32("ApplicationMIC", app_msg_len,
> > keys->app_mic32, app_mic32);
> > app_msg_len += 4;
> > @@ -1172,20 +1173,18 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> > keys->net_seq[i], keys->net_src,
> > keys->iv_index, net_nonce);
> >
> > - verify_data("TransportData", 9, keys->trans_pkt[i],
> > + verify_data("TransportData", 9, keys->trans_pkt[i],
> > packet + 9, seg_len);
> >
> > verify_uint16("DST", 7, keys->net_dst, l_get_be16(packet + 7));
> > net_msg_len = seg_len + 2;
> > show_data("TransportPayload", 7, packet + 7, net_msg_len);
> >
> > - mesh_crypto_network_encrypt(keys->ctl,
> > - keys->net_ttl, keys->net_seq[i],
> > - keys->net_src,
> > - keys->iv_index, enc_key,
> > - packet + 7, seg_len + 2, packet + 7,
> > - keys->ctl ? (void *)&net_mic64 :
> > - (void *)&net_mic32);
> > + mesh_crypto_packet_encrypt(packet, packet_len, enc_key,
> > + keys->iv_index, false,
> > + keys->ctl, keys->net_ttl,
> > + keys->net_seq[i],
> > + keys->net_src);
> >
> > mesh_crypto_privacy_counter(keys->iv_index, packet + 7,
> > priv_rand);
> > @@ -1208,20 +1207,23 @@ static void check_encrypt(const struct mesh_crypto_test *keys)
> > verify_data("EncNetworkPayload", 7, keys->net_msg[i],
> > packet + 7, net_msg_len);
> > if (keys->ctl) {
> > + net_mic64 = l_get_be64(packet + packet_len - 8);
> > verify_uint64("NetworkMIC", 7 + net_msg_len,
> > keys->net_mic64, net_mic64);
> > net_msg_len += 8;
> > } else {
> > + net_mic32 = l_get_be32(packet + packet_len - 4);
> > verify_uint32("NetworkMIC", 7 + net_msg_len,
> > keys->net_mic32[i], net_mic32);
> > net_msg_len += 4;
> > }
> >
> > show_data("PreObsPayload", 1, packet + 1, 6 + net_msg_len);
> > - mesh_crypto_network_obfuscate(priv_key, priv_rand,
> > - keys->ctl,
> > - keys->net_ttl, keys->net_seq[i],
> > - keys->net_src, packet + 1);
> > + mesh_crypto_network_obfuscate(packet, priv_key,
> > + keys->iv_index,
> > + keys->ctl, keys->net_ttl,
> > + keys->net_seq[i], keys->net_src);
> > +
> > show_data("PostObsPayload", 1, packet + 1, 6 + net_msg_len);
> >
> > packet[0] = (keys->iv_index & 0x01) << 7 | nid;
> > @@ -1242,7 +1244,7 @@ done:
> >
> > static void check_decrypt_segment(const struct mesh_crypto_test *keys,
> > uint16_t seg, uint16_t seg_max,
> > - const uint8_t *pkt, uint8_t pkt_len,
> > + uint8_t *pkt, uint8_t pkt_len,
> > const uint8_t *msg, uint8_t msg_len,
> > uint8_t *enc_key, uint8_t *priv_key,
> > uint8_t nid)
> > @@ -1274,26 +1276,30 @@ static void check_decrypt_segment(const struct mesh_crypto_test *keys,
> > if (ctl) {
> > net_mic64 = l_get_be64(pkt + pkt_len - 8);
> > show_data("EncryptedPayload", 7, pkt + 7, pkt_len - 7 - 8);
> > - mesh_crypto_network_decrypt(ctl, ttl, seq,
> > - src, keys->iv_index, enc_key,
> > - pkt + 7, pkt_len - 7, net_clr + 7,
> > - &calc_net_mic64,
> > - sizeof(calc_net_mic64));
> > +
> > + mesh_crypto_packet_decrypt(pkt, pkt_len,
> > + enc_key,
> > + keys->iv_index, false,
> > + ctl, ttl, seq,
> > + src);
> > + calc_net_mic64 = l_get_be64(pkt + pkt_len - 8);
> > +
> > verify_uint64("NetworkMIC", pkt_len - 8, net_mic64,
> > - calc_net_mic64);
> > + net_mic64 ^ calc_net_mic64);
> > show_data("DecryptedPayload", 7, net_clr + 7, pkt_len - 7 - 8);
> > } else {
> > net_mic32 = l_get_be32(pkt + pkt_len - 4);
> > show_data("EncryptedPayload", 7, pkt + 7, pkt_len - 7 - 4);
> >
> > - mesh_crypto_network_decrypt(ctl, ttl, seq,
> > - src, keys->iv_index, enc_key,
> > - pkt + 7, pkt_len - 7, net_clr + 7,
> > - &calc_net_mic32,
> > - sizeof(calc_net_mic32));
> > + mesh_crypto_packet_decrypt(pkt, pkt_len,
> > + enc_key,
> > + keys->iv_index, false,
> > + ctl, ttl, seq,
> > + src);
> > + calc_net_mic32 = l_get_be32(pkt + pkt_len - 4);
> >
> > verify_uint32("NetworkMIC", pkt_len - 4, net_mic32,
> > - calc_net_mic32);
> > + net_mic32 ^ calc_net_mic32);
> > show_data("DecryptedPayload", 7, net_clr + 7, pkt_len - 7 - 4);
> > }
> >
> > @@ -1387,15 +1393,11 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> > uint8_t *app_key;
> > uint8_t *net_key;
> > uint8_t enc_key[16];
> > - uint8_t net_nonce[13];
> > - uint8_t app_nonce[13];
> > uint8_t priv_key[16];
> > - uint8_t priv_rand[16];
> > uint8_t p[9];
> > size_t p_len;
> > uint8_t *packet = NULL;
> > size_t packet_len;
> > - const uint8_t *net_hdr;
> > uint8_t *net_msg;
> > uint8_t net_msg_len;
> > uint16_t app_msg_len = 0;
> > @@ -1469,9 +1471,6 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> > goto done;
> > }
> >
> > - mesh_crypto_application_nonce(keys->app_seq, keys->net_src,
> > - keys->net_dst, keys->iv_index,
> > - keys->szmic, app_nonce);
> > app_msg = l_malloc(384);
> >
> > seg_max = (sizeof(keys->packet) / sizeof(keys->packet[0])) - 1;
> > @@ -1483,19 +1482,13 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> > if (keys->segmented)
> > l_info(COLOR_YELLOW "Segment-%d" COLOR_OFF, i);
> >
> > - mesh_crypto_network_nonce(keys->frnd, keys->net_ttl,
> > - keys->net_seq[i], keys->net_src, keys->iv_index,
> > - net_nonce);
> > l_free(packet);
> > packet = l_util_from_hexstring(keys->packet[i], &packet_len);
> >
> > - net_hdr = packet + 1;
> > net_msg = packet + 7;
> > net_msg_len = packet_len - 7;
> >
> > - mesh_crypto_privacy_counter(keys->iv_index, net_msg, priv_rand);
> > -
> > - mesh_crypto_network_clarify(priv_key, priv_rand, net_hdr,
> > + mesh_crypto_network_clarify(packet, priv_key, keys->iv_index,
> > &net_ctl, &net_ttl, &net_seq, &net_src);
> >
> > show_str("Packet", 0, keys->packet[i]);
> > @@ -1504,29 +1497,31 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> > net_mic64 = l_get_be64(packet + packet_len - 8);
> > show_data("NetworkMessage", 7, net_msg,
> > net_msg_len - 8);
> > - mesh_crypto_network_decrypt(net_ctl, net_ttl, net_seq,
> > - net_src, keys->iv_index, enc_key,
> > - net_msg, net_msg_len, net_msg,
> > - &calc_net_mic64,
> > - sizeof(calc_net_mic64));
> > + mesh_crypto_packet_decrypt(packet, packet_len,
> > + enc_key,
> > + keys->iv_index, false,
> > + net_ctl, net_ttl,
> > + net_seq,
> > + net_src);
> > + calc_net_mic64 = l_get_be64(packet + packet_len - 8);
> > net_msg_len -= 8;
> > verify_uint64("NetworkMIC", 7 + net_msg_len, net_mic64,
> > - calc_net_mic64);
> > + net_mic64 ^ calc_net_mic64);
> > show_data("DecryptedNetwork", 7, net_msg, net_msg_len);
> > } else {
> > net_mic32 = l_get_be32(packet + packet_len - 4);
> > show_data("NetworkMessage", 7, net_msg,
> > net_msg_len - 4);
> > -
> > - mesh_crypto_network_decrypt(net_ctl, net_ttl, net_seq,
> > - net_src, keys->iv_index, enc_key,
> > - net_msg, net_msg_len, net_msg,
> > - &calc_net_mic32,
> > - sizeof(calc_net_mic32));
> > -
> > + mesh_crypto_packet_decrypt(packet, packet_len,
> > + enc_key,
> > + keys->iv_index, false,
> > + net_ctl, net_ttl,
> > + net_seq,
> > + net_src);
> > + calc_net_mic32 = l_get_be32(packet + packet_len - 4);
> > net_msg_len -= 4;
> > verify_uint32("NetworkMIC", 7 + net_msg_len, net_mic32,
> > - calc_net_mic32);
> > + net_mic32 ^ calc_net_mic32);
> > show_data("DecryptedNetwork", 7, net_msg, net_msg_len);
> > }
> >
> > @@ -1645,8 +1640,8 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> > packet, &pkt_len);
> > verify_data("TransportData", 9, keys->trans_pkt[i], packet + 9,
> > payload_len);
> > - mesh_crypto_packet_encode(packet, pkt_len, enc_key,
> > - keys->iv_index, priv_key);
> > + mesh_crypto_packet_encode(packet, pkt_len, keys->iv_index,
> > + enc_key, priv_key);
> > mesh_crypto_packet_label(packet, pkt_len, keys->iv_index, nid);
> >
> > verify_data("Encoded-Packet", 0, keys->packet[i], packet,
> > @@ -1666,39 +1661,45 @@ static void check_decrypt(const struct mesh_crypto_test *keys)
> > app_msg_len - 8);
> > app_mic64 = l_get_be64(app_msg + app_msg_len - 8);
> >
> > - mesh_crypto_application_decrypt(
> > - keys_aid | (keys->akf ? KEY_ID_AKF : 0),
> > - seqZero, net_src,
> > - net_dst, keys->iv_index,
> > - keys->akf ? app_key : dev_key,
> > + mesh_crypto_payload_decrypt(
> > aad, aad_len,
> > app_msg, app_msg_len,
> > - app_msg, &calc_app_mic64,
> > - sizeof(calc_app_mic64));
> > + true,
> > + net_src, net_dst,
> > + keys->akf ? keys_aid | KEY_ID_AKF : APP_AID_DEV,
> > + seqZero,
> > + keys->iv_index,
> > + app_msg,
> > + keys->akf ? app_key : dev_key);
> > +
> > + calc_app_mic64 = l_get_be64(app_msg + app_msg_len - 8);
> >
> > verify_data("Payload", 0, keys->app_msg, app_msg,
> > app_msg_len - 8);
> > verify_uint64("ApplicationMIC", app_msg_len - 8, app_mic64,
> > - calc_app_mic64);
> > + app_mic64 ^ calc_app_mic64);
> > } else if (!keys->ctl) {
> > verify_data("EncryptedPayload", 0, keys->enc_msg, app_msg,
> > app_msg_len - 4);
> > app_mic32 = l_get_be32(app_msg + app_msg_len - 4);
> >
> > - mesh_crypto_application_decrypt(
> > - keys_aid | (keys->akf ? KEY_ID_AKF : 0),
> > - seqZero, net_src,
> > - net_dst, keys->iv_index,
> > - keys->akf ? app_key : dev_key,
> > + mesh_crypto_payload_decrypt(
> > aad, aad_len,
> > app_msg, app_msg_len,
> > - app_msg, &calc_app_mic32,
> > - sizeof(calc_app_mic32));
> > + false,
> > + net_src, net_dst,
> > + keys->akf ? keys_aid | KEY_ID_AKF : APP_AID_DEV,
> > + seqZero,
> > + keys->iv_index,
> > + app_msg,
> > + keys->akf ? app_key : dev_key);
> > +
> > + calc_app_mic32 = l_get_be64(app_msg + app_msg_len - 4);
> >
> > verify_data("Payload", 0, keys->app_msg, app_msg,
> > app_msg_len - 4);
> > verify_uint32("ApplicationMIC", app_msg_len - 4, app_mic32,
> > - calc_app_mic32);
> > + app_mic32 ^ calc_app_mic32);
> > }
> >
> > done:

2020-04-06 19:38:09

by Michał Lowas-Rzechonek

[permalink] [raw]
Subject: Re: [PATCH BlueZ RESEND] mesh: Remove redundant code from mesh/crypto

Hi Brian,

On 04/05, Gix, Brian wrote:
> I think this needs some more work, in that it no longer correctly
> fails the mesh-test-crypto test when running:
>
> make distcheck
>
> It *almost* does in that it flags an error in red if a "verify" step
> fails, but it does not exit with a fail code. This is an important
> step, particularily with the dependance on kernel based crypto
> functions.
>
> My test methodology was to flip a bit in one of the test payloads
> (i.e., make it "not perfectly match" the specification sample data).
>
> As best I can tell, it is otherwise functional, but the unit tests are
> important.

Agreed, but as of 14301cf0d42ba3fc4de99c3bdf183045be733e0c running
unit/test-mesh-crypto with modified payloads, e.g.

diff --git a/unit/test-mesh-crypto.c b/unit/test-mesh-crypto.c
index 0043b0b10..a832b2000 100644
--- a/unit/test-mesh-crypto.c
+++ b/unit/test-mesh-crypto.c
@@ -591,7 +591,7 @@ static const struct mesh_crypto_test s8_3_11 = {
static const struct mesh_crypto_test s8_3_22 = {
.name = "8.3.22 Message #22",

- .app_key = "63964771734fbd76e3b40519d1d94a48",
+ .app_key = "63964771735fbd76e3b40519d1d94a48",
.net_key = "7dd7364cd842ad18c17c2b820c84c3d6",
.dev_key = "9d6dd0e96eb25dc19a40ed9914f8f03f",
.iv_index = 0x12345677,

also does not cause it to exit non-zero return code, it just prints red
"FAIL"s...

I thought it was done on purpose, as mesh tests don't seem to use the
src/shared/tester.h.

Also, after applying the patch onto the mentioned commit, I'm getting
all green runs. What system are you using? I'd like to try reproducing
your results.

regards
--
Michał Lowas-Rzechonek <[email protected]>
Silvair http://silvair.com
Jasnogórska 44, 31-358 Krakow, POLAND

2020-04-07 17:14:56

by Gix, Brian

[permalink] [raw]
Subject: Re: [PATCH BlueZ RESEND] mesh: Remove redundant code from mesh/crypto

Patch applied with agreed upon adjustments

On Fri, 2020-04-03 at 19:54 +0200, Michał Lowas-Rzechonek wrote:
> Brian,
>
> On 03/26, Michał Lowas-Rzechonek wrote:
> > - Remove application_encrypt/application_decrypt
> > - Make mesh_crypto_privacy_counter private, add mesh_crypto_pecb
> > - Make *_nonce functions private and align their implementation to be
> > more consistent
> > - Refactor network_encrypt/network_decrypt to use *_nonce functions and
> > rename them to packet_encrypt/packet_decrypt
> > - Refactor packet_encode/packet_decode
>
> Ping...
>
> This version of the patch passes unit tests. I'd really like to get this
> applied. Or at least tell me straight in the face that I should bugger
> off ;)
>
> regards