diff --git a/UNITTESTS/features/lorawan/loramaccrypto/Test_LoRaMacCrypto.cpp b/UNITTESTS/features/lorawan/loramaccrypto/Test_LoRaMacCrypto.cpp index 01e481711c..2fc66f48eb 100644 --- a/UNITTESTS/features/lorawan/loramaccrypto/Test_LoRaMacCrypto.cpp +++ b/UNITTESTS/features/lorawan/loramaccrypto/Test_LoRaMacCrypto.cpp @@ -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)); } diff --git a/UNITTESTS/stubs/LoRaMacCrypto_stub.cpp b/UNITTESTS/stubs/LoRaMacCrypto_stub.cpp index 26721303a5..27e6f14e20 100644 --- a/UNITTESTS/stubs/LoRaMacCrypto_stub.cpp +++ b/UNITTESTS/stubs/LoRaMacCrypto_stub.cpp @@ -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++]; } diff --git a/features/lorawan/lorastack/mac/LoRaMac.cpp b/features/lorawan/lorastack/mac/LoRaMac.cpp index 689a9851b5..fc1c37e674 100644 --- a/features/lorawan/lorastack/mac/LoRaMac.cpp +++ b/features/lorawan/lorastack/mac/LoRaMac.cpp @@ -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; @@ -2456,7 +2456,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; } @@ -2469,7 +2469,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; } diff --git a/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp b/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp index ec742ddb3e..dcc351e4b0 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp +++ b/features/lorawan/lorastack/mac/LoRaMacCrypto.cpp @@ -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); @@ -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; } diff --git a/features/lorawan/lorastack/mac/LoRaMacCrypto.h b/features/lorawan/lorastack/mac/LoRaMacCrypto.h index eaedebbd3c..484d58a563 100644 --- a/features/lorawan/lorastack/mac/LoRaMacCrypto.h +++ b/features/lorawan/lorastack/mac/LoRaMacCrypto.h @@ -68,6 +68,7 @@ public: * @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 @@ -75,7 +76,7 @@ public: 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