Skip to content

Commit

Permalink
Fix MIC calculation in LoRaWAN 1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
rvolosatovs authored and paul-szczepanek-arm committed Jun 25, 2021
1 parent f8a7adf commit 8e0c49d
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 33 deletions.
2 changes: 1 addition & 1 deletion UNITTESTS/stubs/connectivity/LoRaMacCrypto_stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ lorawan_status_t LoRaMacCrypto::set_keys(uint8_t *, uint8_t *, uint8_t *, uint8_
}

int LoRaMacCrypto::compute_mic(const uint8_t *, uint16_t, uint32_t, uint32_t,
uint8_t, uint32_t, uint32_t *)
uint8_t, uint32_t, uint8_t, uint32_t *)
{
return LoRaMacCrypto_stub::int_table[LoRaMacCrypto_stub::int_table_idx_value++];
}
Expand Down
6 changes: 3 additions & 3 deletions connectivity/lorawan/lorastack/mac/LoRaMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ bool LoRaMac::message_integrity_check(const uint8_t *const payload,

_lora_crypto.compute_mic(payload, size - LORAMAC_MFR_LEN,
args, address, DOWN_LINK, *downlink_counter,
&mic);
0, &mic);

if (mic_rx != mic) {
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_MIC_FAIL;
Expand Down Expand Up @@ -2482,7 +2482,7 @@ lorawan_status_t LoRaMac::calculate_userdata_mic()

if (0 != _lora_crypto.compute_mic(_params.tx_buffer, _params.tx_buffer_len,
args, _params.dev_addr, UP_LINK,
_params.ul_frame_counter, &mic)) {
_params.ul_frame_counter, 0, &mic)) {
status = LORAWAN_STATUS_CRYPTO_FAIL;
}

Expand All @@ -2495,7 +2495,7 @@ lorawan_status_t LoRaMac::calculate_userdata_mic()

if (0 != _lora_crypto.compute_mic(_params.tx_buffer, _params.tx_buffer_len,
args, _params.dev_addr, UP_LINK,
_params.ul_frame_counter, &mic2)) {
_params.ul_frame_counter, 1, &mic2)) {
status = LORAWAN_STATUS_CRYPTO_FAIL;
}

Expand Down
67 changes: 46 additions & 21 deletions connectivity/lorawan/lorastack/mac/LoRaMacCrypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,40 +82,65 @@ lorawan_status_t LoRaMacCrypto::set_keys(uint8_t *nwk_key, uint8_t *app_key, uin
int LoRaMacCrypto::compute_mic(const uint8_t *buffer, uint16_t size,
uint32_t args, uint32_t address,
uint8_t dir, uint32_t seq_counter,
uint32_t *mic)
uint8_t block, uint32_t *mic)
{
uint8_t computed_mic[16] = {};
uint8_t mic_block_b0[16] = {};
uint8_t mic_block[16] = {};
int ret = 0;

//In case of LW_1_0_2 this is same as nwk_skey
uint8_t *key = _keys.snwk_sintkey;
uint8_t *key;
switch (dir) {
case 0:
switch (block) {
case 0:
key = _keys.nwk_skey;
break;

case 1:
key = _keys.snwk_sintkey;
break;

default:
MBED_ASSERT(false);
break;
}
break;

case 1:
MBED_ASSERT(block == 0);
key = _keys.snwk_sintkey;
break;

default:
MBED_ASSERT(false);
break;
}

//TODO: handle multicast based on address
//_dev_addr

mic_block_b0[0] = 0x49;
mic_block[0] = 0x49;

mic_block_b0[1] = (args) & 0xFF;
mic_block_b0[2] = (args >> 8) & 0xFF;
mic_block_b0[3] = (args >> 16) & 0xFF;
mic_block_b0[4] = (args >> 24) & 0xFF;
mic_block[1] = (args) & 0xFF;
mic_block[2] = (args >> 8) & 0xFF;
mic_block[3] = (args >> 16) & 0xFF;
mic_block[4] = (args >> 24) & 0xFF;

mic_block_b0[5] = dir;
mic_block[5] = dir;

mic_block_b0[6] = (address) & 0xFF;
mic_block_b0[7] = (address >> 8) & 0xFF;
mic_block_b0[8] = (address >> 16) & 0xFF;
mic_block_b0[9] = (address >> 24) & 0xFF;
mic_block[6] = (address) & 0xFF;
mic_block[7] = (address >> 8) & 0xFF;
mic_block[8] = (address >> 16) & 0xFF;
mic_block[9] = (address >> 24) & 0xFF;

mic_block_b0[10] = (seq_counter) & 0xFF;
mic_block_b0[11] = (seq_counter >> 8) & 0xFF;
mic_block_b0[12] = (seq_counter >> 16) & 0xFF;
mic_block_b0[13] = (seq_counter >> 24) & 0xFF;
mic_block[10] = (seq_counter) & 0xFF;
mic_block[11] = (seq_counter >> 8) & 0xFF;
mic_block[12] = (seq_counter >> 16) & 0xFF;
mic_block[13] = (seq_counter >> 24) & 0xFF;

mic_block_b0[14] = 0;
mic_block[14] = 0;

mic_block_b0[15] = size & 0xFF;
mic_block[15] = size & 0xFF;

mbedtls_cipher_init(aes_cmac_ctx);

Expand All @@ -132,7 +157,7 @@ int LoRaMacCrypto::compute_mic(const uint8_t *buffer, uint16_t size,
goto exit;
}

ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0, sizeof(mic_block_b0));
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block, sizeof(mic_block));
if (0 != ret) {
goto exit;
}
Expand Down
3 changes: 2 additions & 1 deletion connectivity/lorawan/lorastack/mac/LoRaMacCrypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ class LoRaMacCrypto {
* @param [in] address - Frame address
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
* @param [in] seq_counter - Frame sequence counter
* @param [in] block - Block number [0, 1]
* @param [out] mic - Computed MIC field
*
* @return 0 if successful, or a cipher specific error code
*/
int compute_mic(const uint8_t *buffer, uint16_t size,
uint32_t args, uint32_t address,
uint8_t dir, uint32_t seq_counter,
uint32_t *mic);
uint8_t block, uint32_t *mic);

/**
* Performs payload encryption
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,35 +52,35 @@ TEST_F(Test_LoRaMacCrypto, constructor)

TEST_F(Test_LoRaMacCrypto, compute_mic)
{
EXPECT_TRUE(MBEDTLS_ERR_CIPHER_ALLOC_FAILED == object->compute_mic(NULL, 0, 0, 0, 0, 0, NULL));
EXPECT_TRUE(MBEDTLS_ERR_CIPHER_ALLOC_FAILED == object->compute_mic(NULL, 0, 0, 0, 0, 0, 0, NULL));

mbedtls_cipher_info_t info;
cipher_stub.info_value = &info;
cipher_stub.int_zero_counter = 0;
cipher_stub.int_value = -1;
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, NULL));
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, 0, NULL));

cipher_stub.int_value = 0;
cmac_stub.int_zero_counter = 0;
cmac_stub.int_value = -1;
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, NULL));
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, 0, NULL));

cmac_stub.int_zero_counter = 1;
cmac_stub.int_value = -1;
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, NULL));
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, 0, NULL));

cmac_stub.int_zero_counter = 2;
cmac_stub.int_value = -1;
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, NULL));
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, 0, NULL));

cmac_stub.int_zero_counter = 3;
cmac_stub.int_value = -1;
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, NULL));
EXPECT_TRUE(-1 == object->compute_mic(NULL, 0, 0, 0, 0, 0, 0, NULL));

uint32_t mic[16];
cmac_stub.int_zero_counter = 3;
cmac_stub.int_value = 0;
EXPECT_TRUE(0 == object->compute_mic(NULL, 0, 0, 0, 0, 0, mic));
EXPECT_TRUE(0 == object->compute_mic(NULL, 0, 0, 0, 0, 0, 0, mic));

}

Expand Down

0 comments on commit 8e0c49d

Please sign in to comment.