mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6692 from kivaisan/remove_singleton
Lora: Remove singleton patternpull/6735/head
commit
0e86fa2529
|
@ -23,14 +23,9 @@
|
|||
|
||||
using namespace events;
|
||||
|
||||
inline LoRaWANStack& stk_obj()
|
||||
{
|
||||
return LoRaWANStack::get_lorawan_stack();
|
||||
}
|
||||
|
||||
LoRaWANInterface::LoRaWANInterface(LoRaRadio& radio)
|
||||
{
|
||||
stk_obj().bind_radio_driver(radio);
|
||||
_lw_stack.bind_radio_driver(radio);
|
||||
}
|
||||
|
||||
LoRaWANInterface::~LoRaWANInterface()
|
||||
|
@ -39,95 +34,95 @@ LoRaWANInterface::~LoRaWANInterface()
|
|||
|
||||
lorawan_status_t LoRaWANInterface::initialize(EventQueue *queue)
|
||||
{
|
||||
return stk_obj().initialize_mac_layer(queue);
|
||||
return _lw_stack.initialize_mac_layer(queue);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::connect()
|
||||
{
|
||||
return stk_obj().connect();
|
||||
return _lw_stack.connect();
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::connect(const lorawan_connect_t &connect)
|
||||
{
|
||||
return stk_obj().connect(connect);
|
||||
return _lw_stack.connect(connect);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::disconnect()
|
||||
{
|
||||
return stk_obj().shutdown();
|
||||
return _lw_stack.shutdown();
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::add_link_check_request()
|
||||
{
|
||||
return stk_obj().set_link_check_request();
|
||||
return _lw_stack.set_link_check_request();
|
||||
}
|
||||
|
||||
void LoRaWANInterface::remove_link_check_request()
|
||||
{
|
||||
stk_obj().remove_link_check_request();
|
||||
_lw_stack.remove_link_check_request();
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::set_datarate(uint8_t data_rate)
|
||||
{
|
||||
return stk_obj().set_channel_data_rate(data_rate);
|
||||
return _lw_stack.set_channel_data_rate(data_rate);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::set_confirmed_msg_retries(uint8_t count)
|
||||
{
|
||||
return stk_obj().set_confirmed_msg_retry(count);
|
||||
return _lw_stack.set_confirmed_msg_retry(count);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::enable_adaptive_datarate()
|
||||
{
|
||||
return stk_obj().enable_adaptive_datarate(true);
|
||||
return _lw_stack.enable_adaptive_datarate(true);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::disable_adaptive_datarate()
|
||||
{
|
||||
return stk_obj().enable_adaptive_datarate(false);
|
||||
return _lw_stack.enable_adaptive_datarate(false);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::set_channel_plan(const lorawan_channelplan_t &channel_plan)
|
||||
{
|
||||
return stk_obj().add_channels(channel_plan);
|
||||
return _lw_stack.add_channels(channel_plan);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::get_channel_plan(lorawan_channelplan_t &channel_plan)
|
||||
{
|
||||
return stk_obj().get_enabled_channels(channel_plan);
|
||||
return _lw_stack.get_enabled_channels(channel_plan);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::remove_channel(uint8_t id)
|
||||
{
|
||||
return stk_obj().remove_a_channel(id);
|
||||
return _lw_stack.remove_a_channel(id);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::remove_channel_plan()
|
||||
{
|
||||
return stk_obj().drop_channel_list();
|
||||
return _lw_stack.drop_channel_list();
|
||||
}
|
||||
|
||||
int16_t LoRaWANInterface::send(uint8_t port, const uint8_t* data, uint16_t length, int flags)
|
||||
{
|
||||
return stk_obj().handle_tx(port, data, length, flags);
|
||||
return _lw_stack.handle_tx(port, data, length, flags);
|
||||
}
|
||||
|
||||
int16_t LoRaWANInterface::receive(uint8_t port, uint8_t* data, uint16_t length, int flags)
|
||||
{
|
||||
return stk_obj().handle_rx(data, length, port, flags, true);
|
||||
return _lw_stack.handle_rx(data, length, port, flags, true);
|
||||
}
|
||||
|
||||
int16_t LoRaWANInterface::receive(uint8_t* data, uint16_t length, uint8_t& port, int& flags)
|
||||
{
|
||||
return stk_obj().handle_rx(data, length, port, flags, false);
|
||||
return _lw_stack.handle_rx(data, length, port, flags, false);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::add_app_callbacks(lorawan_app_callbacks_t *callbacks)
|
||||
{
|
||||
return stk_obj().set_lora_callbacks(callbacks);
|
||||
return _lw_stack.set_lora_callbacks(callbacks);
|
||||
}
|
||||
|
||||
lorawan_status_t LoRaWANInterface::set_device_class(const device_class_t device_class)
|
||||
{
|
||||
return stk_obj().set_device_class(device_class);
|
||||
return _lw_stack.set_device_class(device_class);
|
||||
}
|
||||
|
|
|
@ -434,6 +434,9 @@ public:
|
|||
* or other negative error code if request failed.
|
||||
*/
|
||||
virtual lorawan_status_t set_device_class(const device_class_t device_class);
|
||||
|
||||
private:
|
||||
LoRaWANStack _lw_stack;
|
||||
};
|
||||
|
||||
#endif /* LORAWANINTERFACE_H_ */
|
||||
|
|
|
@ -103,19 +103,9 @@ LoRaWANStack::LoRaWANStack()
|
|||
LoRaMacPrimitives.mlme_indication = callback(this, &LoRaWANStack::mlme_indication_handler);
|
||||
}
|
||||
|
||||
LoRaWANStack::~LoRaWANStack()
|
||||
{
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Public member functions *
|
||||
****************************************************************************/
|
||||
LoRaWANStack& LoRaWANStack::get_lorawan_stack()
|
||||
{
|
||||
static LoRaWANStack _lw_stack;
|
||||
return _lw_stack;
|
||||
}
|
||||
|
||||
void LoRaWANStack::bind_radio_driver(LoRaRadio& radio)
|
||||
{
|
||||
_loramac.bind_radio_driver(radio);
|
||||
|
|
|
@ -70,7 +70,7 @@ private:
|
|||
} device_states_t;
|
||||
|
||||
public:
|
||||
static LoRaWANStack& get_lorawan_stack();
|
||||
LoRaWANStack();
|
||||
|
||||
/** Binds radio driver to PHY layer.
|
||||
*
|
||||
|
@ -396,9 +396,6 @@ public:
|
|||
lorawan_status_t set_device_class(const device_class_t& device_class);
|
||||
|
||||
private:
|
||||
LoRaWANStack();
|
||||
~LoRaWANStack();
|
||||
|
||||
/**
|
||||
* Checks if the user provided port is valid or not
|
||||
*/
|
||||
|
@ -465,7 +462,6 @@ private:
|
|||
void send_automatic_uplink_message(const uint8_t port);
|
||||
|
||||
private:
|
||||
|
||||
LoRaMac _loramac;
|
||||
loramac_primitives_t LoRaMacPrimitives;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "LoRaMac.h"
|
||||
#include "LoRaMacCrypto.h"
|
||||
|
||||
#if defined(FEATURE_COMMON_PAL)
|
||||
#include "mbed_trace.h"
|
||||
|
@ -37,6 +36,13 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
|
||||
using namespace events;
|
||||
|
||||
|
||||
/*
|
||||
* LoRaWAN spec 6.2: AppKey is AES-128 key
|
||||
*/
|
||||
#define APPKEY_KEY_LENGTH 128
|
||||
|
||||
|
||||
/*!
|
||||
* Maximum length of the fOpts field
|
||||
*/
|
||||
|
@ -311,17 +317,22 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
return;
|
||||
}
|
||||
|
||||
if (0 != decrypt_join_frame(payload + 1, size - 1,
|
||||
_params.keys.app_key,
|
||||
_params.payload + 1)) {
|
||||
if (0 != _lora_crypto.decrypt_join_frame(payload + 1,
|
||||
size - 1,
|
||||
_params.keys.app_key,
|
||||
APPKEY_KEY_LENGTH,
|
||||
_params.payload + 1)) {
|
||||
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
_params.payload[0] = mac_hdr.value;
|
||||
|
||||
if (0 != compute_join_frame_mic(_params.payload, size - LORAMAC_MFR_LEN,
|
||||
_params.keys.app_key, &mic)) {
|
||||
if (0 != _lora_crypto.compute_join_frame_mic(_params.payload,
|
||||
size - LORAMAC_MFR_LEN,
|
||||
_params.keys.app_key,
|
||||
APPKEY_KEY_LENGTH,
|
||||
&mic)) {
|
||||
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
|
||||
return;
|
||||
}
|
||||
|
@ -333,11 +344,12 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
|
||||
if (mic_rx == mic) {
|
||||
|
||||
if (0 != compute_skeys_for_join_frame(_params.keys.app_key,
|
||||
_params.payload + 1,
|
||||
_params.dev_nonce,
|
||||
_params.keys.nwk_skey,
|
||||
_params.keys.app_skey)) {
|
||||
if (0 != _lora_crypto.compute_skeys_for_join_frame(_params.keys.app_key,
|
||||
APPKEY_KEY_LENGTH,
|
||||
_params.payload + 1,
|
||||
_params.dev_nonce,
|
||||
_params.keys.nwk_skey,
|
||||
_params.keys.app_skey)) {
|
||||
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
|
||||
return;
|
||||
}
|
||||
|
@ -436,15 +448,17 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
|
||||
if (sequence_counter_diff < (1 << 15)) {
|
||||
downlink_counter += sequence_counter_diff;
|
||||
compute_mic(payload, size - LORAMAC_MFR_LEN, nwk_skey,
|
||||
address, DOWN_LINK, downlink_counter, &mic);
|
||||
_lora_crypto.compute_mic(payload, size - LORAMAC_MFR_LEN,
|
||||
nwk_skey, sizeof(_params.keys.nwk_skey)*8, // sizeof nws_skey must be the same as _params.keys.nwk_skey
|
||||
address, DOWN_LINK, downlink_counter, &mic);
|
||||
if (mic_rx == mic) {
|
||||
is_mic_ok = true;
|
||||
}
|
||||
} else {
|
||||
uint32_t downlink_counter_tmp = downlink_counter + 0x10000 + (int16_t)sequence_counter_diff;
|
||||
compute_mic(payload, size - LORAMAC_MFR_LEN, nwk_skey,
|
||||
address, DOWN_LINK, downlink_counter_tmp, &mic);
|
||||
_lora_crypto.compute_mic(payload, size - LORAMAC_MFR_LEN,
|
||||
nwk_skey, sizeof(_params.keys.nwk_skey)*8, // sizeof nws_skey must be the same as _params.keys.nwk_skey
|
||||
address, DOWN_LINK, downlink_counter_tmp, &mic);
|
||||
|
||||
if (mic_rx == mic ) {
|
||||
is_mic_ok = true;
|
||||
|
@ -539,13 +553,14 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
|
||||
if (port == 0) {
|
||||
if (fctrl.bits.fopts_len == 0) {
|
||||
if (0 != decrypt_payload(payload + app_payload_start_index,
|
||||
frame_len,
|
||||
nwk_skey,
|
||||
address,
|
||||
DOWN_LINK,
|
||||
downlink_counter,
|
||||
_params.payload)) {
|
||||
if (0 != _lora_crypto.decrypt_payload(payload + app_payload_start_index,
|
||||
frame_len,
|
||||
nwk_skey,
|
||||
sizeof(_params.keys.nwk_skey)*8, // sizeof nws_skey must be the same as _params.keys.nwk_skey
|
||||
address,
|
||||
DOWN_LINK,
|
||||
downlink_counter,
|
||||
_params.payload)) {
|
||||
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
|
@ -575,13 +590,14 @@ void LoRaMac::on_radio_rx_done(uint8_t *payload, uint16_t size, int16_t rssi,
|
|||
}
|
||||
}
|
||||
|
||||
if (0 != decrypt_payload(payload + app_payload_start_index,
|
||||
frame_len,
|
||||
app_skey,
|
||||
address,
|
||||
DOWN_LINK,
|
||||
downlink_counter,
|
||||
_params.payload)) {
|
||||
if (0 != _lora_crypto.decrypt_payload(payload + app_payload_start_index,
|
||||
frame_len,
|
||||
app_skey,
|
||||
sizeof(_params.keys.app_skey)*8, // sizeof app_skey must be the same as _params.keys.app_skey
|
||||
address,
|
||||
DOWN_LINK,
|
||||
downlink_counter,
|
||||
_params.payload)) {
|
||||
_mcps_indication.status = LORAMAC_EVENT_INFO_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1563,9 +1579,11 @@ lorawan_status_t LoRaMac::prepare_frame(loramac_mhdr_t *machdr,
|
|||
_params.buffer[_params.buffer_pkt_len++] = _params.dev_nonce & 0xFF;
|
||||
_params.buffer[_params.buffer_pkt_len++] = (_params.dev_nonce >> 8) & 0xFF;
|
||||
|
||||
if (0 != compute_join_frame_mic(_params.buffer,
|
||||
_params.buffer_pkt_len & 0xFF,
|
||||
_params.keys.app_key, &mic)) {
|
||||
if (0 != _lora_crypto.compute_join_frame_mic(_params.buffer,
|
||||
_params.buffer_pkt_len & 0xFF,
|
||||
_params.keys.app_key,
|
||||
APPKEY_KEY_LENGTH,
|
||||
&mic)) {
|
||||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1646,23 +1664,27 @@ lorawan_status_t LoRaMac::prepare_frame(loramac_mhdr_t *machdr,
|
|||
_params.buffer[pkt_header_len++] = frame_port;
|
||||
|
||||
uint8_t *key = _params.keys.app_skey;
|
||||
uint32_t key_length = sizeof(_params.keys.app_skey)*8;
|
||||
if (frame_port == 0) {
|
||||
mac_commands.clear_command_buffer();
|
||||
key = _params.keys.nwk_skey;
|
||||
key_length = sizeof(_params.keys.nwk_skey)*8;
|
||||
}
|
||||
if (0 != encrypt_payload((uint8_t*) payload, _params.payload_length,
|
||||
key, _params.dev_addr, UP_LINK,
|
||||
_params.ul_frame_counter,
|
||||
&_params.buffer[pkt_header_len])) {
|
||||
if (0 != _lora_crypto.encrypt_payload((uint8_t*) payload, _params.payload_length,
|
||||
key, key_length,
|
||||
_params.dev_addr, UP_LINK,
|
||||
_params.ul_frame_counter,
|
||||
&_params.buffer[pkt_header_len])) {
|
||||
status = LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
_params.buffer_pkt_len = pkt_header_len + _params.payload_length;
|
||||
|
||||
if (0 != compute_mic(_params.buffer, _params.buffer_pkt_len,
|
||||
_params.keys.nwk_skey, _params.dev_addr,
|
||||
UP_LINK, _params.ul_frame_counter, &mic)) {
|
||||
if (0 != _lora_crypto.compute_mic(_params.buffer, _params.buffer_pkt_len,
|
||||
_params.keys.nwk_skey, sizeof(_params.keys.nwk_skey)*8,
|
||||
_params.dev_addr,
|
||||
UP_LINK, _params.ul_frame_counter, &mic)) {
|
||||
status = LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
|
||||
#include "LoRaMacChannelPlan.h"
|
||||
#include "LoRaMacCommand.h"
|
||||
#include "LoRaMacCrypto.h"
|
||||
|
||||
|
||||
class LoRaMac {
|
||||
|
||||
|
@ -542,6 +544,11 @@ private:
|
|||
*/
|
||||
LoRaMacChannelPlan channel_plan;
|
||||
|
||||
/**
|
||||
* Crypto handling subsystem
|
||||
*/
|
||||
LoRaMacCrypto _lora_crypto;
|
||||
|
||||
/**
|
||||
* Central MAC layer data storage
|
||||
*/
|
||||
|
|
|
@ -26,59 +26,27 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/cmac.h"
|
||||
|
||||
#include "LoRaMacCrypto.h"
|
||||
#include "system/lorawan_data_structures.h"
|
||||
|
||||
|
||||
#if defined(MBEDTLS_CMAC_C) && defined(MBEDTLS_AES_C) && defined(MBEDTLS_CIPHER_C)
|
||||
|
||||
/**
|
||||
* CMAC/AES Message Integrity Code (MIC) Block B0 size
|
||||
*/
|
||||
#define LORAMAC_MIC_BLOCK_B0_SIZE 16
|
||||
|
||||
/**
|
||||
* MIC field computation initial data
|
||||
*/
|
||||
static uint8_t mic_block_b0[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* Contains the computed MIC field.
|
||||
*
|
||||
* \remark Only the 4 first bytes are used
|
||||
*/
|
||||
static uint8_t computed_mic[16];
|
||||
|
||||
/**
|
||||
* Encryption aBlock and sBlock
|
||||
*/
|
||||
static uint8_t a_block[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static uint8_t s_block[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
/**
|
||||
* AES computation context variable
|
||||
*/
|
||||
static mbedtls_aes_context aes_ctx;
|
||||
|
||||
/**
|
||||
* CMAC computation context variable
|
||||
*/
|
||||
static mbedtls_cipher_context_t aes_cmac_ctx[1];
|
||||
|
||||
#define AES_CMAC_KEY_LENGTH 16
|
||||
|
||||
int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint32_t *mic)
|
||||
LoRaMacCrypto::LoRaMacCrypto()
|
||||
: mic_block_b0(),
|
||||
computed_mic(),
|
||||
a_block(),
|
||||
s_block()
|
||||
{
|
||||
mic_block_b0[0] = 0x49;
|
||||
a_block[0] = 0x01;
|
||||
}
|
||||
|
||||
int LoRaMacCrypto::compute_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, const uint32_t key_length,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint32_t *mic)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mic_block_b0[5] = dir;
|
||||
|
@ -104,13 +72,11 @@ int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
|||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key,
|
||||
AES_CMAC_KEY_LENGTH * 8);
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, key_length);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0,
|
||||
LORAMAC_MIC_BLOCK_B0_SIZE);
|
||||
ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0, sizeof(mic_block_b0));
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -133,9 +99,10 @@ exit: mbedtls_cipher_free(aes_cmac_ctx);
|
|||
return ret;
|
||||
}
|
||||
|
||||
int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer)
|
||||
int LoRaMacCrypto::encrypt_payload(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, const uint32_t key_length,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer)
|
||||
{
|
||||
uint16_t i;
|
||||
uint8_t bufferIndex = 0;
|
||||
|
@ -143,7 +110,7 @@ int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
|||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, key_length);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -190,16 +157,18 @@ exit: mbedtls_aes_free(&aes_ctx);
|
|||
return ret;
|
||||
}
|
||||
|
||||
int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer)
|
||||
int LoRaMacCrypto::decrypt_payload(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer)
|
||||
{
|
||||
return encrypt_payload(buffer, size, key, address, dir, seq_counter,
|
||||
return encrypt_payload(buffer, size, key, key_length, address, dir, seq_counter,
|
||||
dec_buffer);
|
||||
}
|
||||
|
||||
int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t *mic)
|
||||
int LoRaMacCrypto::compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint32_t *mic)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -211,8 +180,7 @@ int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
|||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key,
|
||||
AES_CMAC_KEY_LENGTH * 8);
|
||||
ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, key_length);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -235,14 +203,15 @@ exit: mbedtls_cipher_free(aes_cmac_ctx);
|
|||
return ret;
|
||||
}
|
||||
|
||||
int decrypt_join_frame(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint8_t *dec_buffer)
|
||||
int LoRaMacCrypto::decrypt_join_frame(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint8_t *dec_buffer)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, key_length);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -261,9 +230,9 @@ exit: mbedtls_aes_free(&aes_ctx);
|
|||
return ret;
|
||||
}
|
||||
|
||||
int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
||||
uint16_t dev_nonce, uint8_t *nwk_skey,
|
||||
uint8_t *app_skey)
|
||||
int LoRaMacCrypto::compute_skeys_for_join_frame(const uint8_t *key, uint32_t key_length,
|
||||
const uint8_t *app_nonce, uint16_t dev_nonce,
|
||||
uint8_t *nwk_skey, uint8_t *app_skey)
|
||||
{
|
||||
uint8_t nonce[16];
|
||||
uint8_t *p_dev_nonce = (uint8_t *) &dev_nonce;
|
||||
|
@ -271,7 +240,7 @@ int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
|||
|
||||
mbedtls_aes_init(&aes_ctx);
|
||||
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8);
|
||||
ret = mbedtls_aes_setkey_enc(&aes_ctx, key, key_length);
|
||||
if (0 != ret)
|
||||
goto exit;
|
||||
|
||||
|
@ -294,12 +263,17 @@ int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
|||
}
|
||||
#else
|
||||
|
||||
LoRaMacCrypto::LoRaMacCrypto()
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
}
|
||||
|
||||
// If mbedTLS is not configured properly, these dummies will ensure that
|
||||
// user knows what is wrong and in addition to that these ensure that
|
||||
// Mbed-OS compiles properly under normal conditions where LoRaWAN in conjunction
|
||||
// with mbedTLS is not being used.
|
||||
int compute_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t dir, uint32_t, uint32_t *)
|
||||
int LoRaMacCrypto::compute_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t, uint32_t,
|
||||
uint8_t dir, uint32_t, uint32_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -307,8 +281,8 @@ int compute_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int encrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
int LoRaMacCrypto::encrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -316,8 +290,8 @@ int encrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int decrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
int LoRaMacCrypto::decrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t, uint32_t,
|
||||
uint8_t , uint32_t , uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -325,7 +299,7 @@ int decrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t,
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int compute_join_frame_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t *)
|
||||
int LoRaMacCrypto::compute_join_frame_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t, uint32_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -333,7 +307,7 @@ int compute_join_frame_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int decrypt_join_frame(const uint8_t *, uint16_t , const uint8_t *, uint8_t *)
|
||||
int LoRaMacCrypto::decrypt_join_frame(const uint8_t *, uint16_t , const uint8_t *, uint32_t, uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
@ -341,8 +315,8 @@ int decrypt_join_frame(const uint8_t *, uint16_t , const uint8_t *, uint8_t *)
|
|||
return LORAWAN_STATUS_CRYPTO_FAIL;
|
||||
}
|
||||
|
||||
int compute_skeys_for_join_frame(const uint8_t *, const uint8_t *, uint16_t ,
|
||||
uint8_t *, uint8_t *)
|
||||
int LoRaMacCrypto::compute_skeys_for_join_frame(const uint8_t *, uint32_t, const uint8_t *, uint16_t ,
|
||||
uint8_t *, uint8_t *)
|
||||
{
|
||||
MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS");
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/**
|
||||
\code
|
||||
|
||||
/ _____) _ | |
|
||||
( (____ _____ ____ _| |_ _____ ____| |__
|
||||
\____ \| ___ | (_ _) ___ |/ ___) _ \
|
||||
|
@ -11,6 +13,8 @@
|
|||
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
|
||||
embedded.connectivity.solutions===============
|
||||
|
||||
\endcode
|
||||
|
||||
Description: LoRa MAC Crypto implementation
|
||||
|
||||
License: Revised BSD License, see LICENSE.TXT file include in the project
|
||||
|
@ -26,97 +30,150 @@ SPDX-License-Identifier: BSD-3-Clause
|
|||
#ifndef MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__
|
||||
#define MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC frame MIC field
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @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, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint32_t *mic);
|
||||
#include "mbedtls/aes.h"
|
||||
#include "mbedtls/cmac.h"
|
||||
|
||||
/**
|
||||
* Performs payload encryption
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] enc_buffer - Encrypted buffer
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
|
||||
class LoRaMacCrypto
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
LoRaMacCrypto();
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC frame MIC field
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] key_length - Length of the key (bits)
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @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,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer);
|
||||
uint32_t *mic);
|
||||
|
||||
/**
|
||||
* Performs payload decryption
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer);
|
||||
/**
|
||||
* Performs payload encryption
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] key_length - Length of the key (bits)
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] enc_buffer - Encrypted buffer
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int encrypt_payload(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *enc_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC Join Request frame MIC field
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [out] mic - Computed MIC field
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*
|
||||
*/
|
||||
int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t *mic);
|
||||
/**
|
||||
* Performs payload decryption
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] key_length - Length of the key (bits)
|
||||
* @param [in] address - Frame address
|
||||
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
|
||||
* @param [in] seq_counter - Frame sequence counter
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int decrypt_payload(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint32_t address, uint8_t dir, uint32_t seq_counter,
|
||||
uint8_t *dec_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int decrypt_join_frame(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint8_t *dec_buffer);
|
||||
/**
|
||||
* Computes the LoRaMAC Join Request frame MIC field
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] key_length - Length of the key (bits)
|
||||
* @param [out] mic - Computed MIC field
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*
|
||||
*/
|
||||
int compute_join_frame_mic(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint32_t *mic);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] app_nonce - Application nonce
|
||||
* @param [in] dev_nonce - Device nonce
|
||||
* @param [out] nwk_skey - Network session key
|
||||
* @param [out] app_skey - Application session key
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce,
|
||||
uint16_t dev_nonce, uint8_t *nwk_skey,
|
||||
uint8_t *app_skey );
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* @param [in] buffer - Data buffer
|
||||
* @param [in] size - Data buffer size
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] key_length - Length of the key (bits)
|
||||
* @param [out] dec_buffer - Decrypted buffer
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int decrypt_join_frame(const uint8_t *buffer, uint16_t size,
|
||||
const uint8_t *key, uint32_t key_length,
|
||||
uint8_t *dec_buffer);
|
||||
|
||||
/**
|
||||
* Computes the LoRaMAC join frame decryption
|
||||
*
|
||||
* @param [in] key - AES key to be used
|
||||
* @param [in] key_length - Length of the key (bits)
|
||||
* @param [in] app_nonce - Application nonce
|
||||
* @param [in] dev_nonce - Device nonce
|
||||
* @param [out] nwk_skey - Network session key
|
||||
* @param [out] app_skey - Application session key
|
||||
*
|
||||
* @return 0 if successful, or a cipher specific error code
|
||||
*/
|
||||
int compute_skeys_for_join_frame(const uint8_t *key, uint32_t key_length,
|
||||
const uint8_t *app_nonce, uint16_t dev_nonce,
|
||||
uint8_t *nwk_skey, uint8_t *app_skey);
|
||||
|
||||
private:
|
||||
/**
|
||||
* MIC field computation initial data
|
||||
*/
|
||||
uint8_t mic_block_b0[16];
|
||||
|
||||
/**
|
||||
* Contains the computed MIC field.
|
||||
*
|
||||
* \remark Only the 4 first bytes are used
|
||||
*/
|
||||
uint8_t computed_mic[16];
|
||||
|
||||
/**
|
||||
* Encryption aBlock and sBlock
|
||||
*/
|
||||
uint8_t a_block[16];
|
||||
uint8_t s_block[16];
|
||||
|
||||
/**
|
||||
* AES computation context variable
|
||||
*/
|
||||
mbedtls_aes_context aes_ctx;
|
||||
|
||||
/**
|
||||
* CMAC computation context variable
|
||||
*/
|
||||
mbedtls_cipher_context_t aes_cmac_ctx[1];
|
||||
};
|
||||
|
||||
#endif // MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__
|
||||
|
|
|
@ -1244,11 +1244,13 @@ typedef struct {
|
|||
|
||||
/*!
|
||||
* AES encryption/decryption cipher network session key
|
||||
* NOTE! LoRaMac determines the length of the key based on sizeof this variable
|
||||
*/
|
||||
uint8_t nwk_skey[16];
|
||||
|
||||
/*!
|
||||
* AES encryption/decryption cipher application session key
|
||||
* NOTE! LoRaMac determines the length of the key based on sizeof this variable
|
||||
*/
|
||||
uint8_t app_skey[16];
|
||||
|
||||
|
|
Loading…
Reference in New Issue