mbed-os/features/lorawan/lorastack/mac/LoRaMacCrypto.h

211 lines
7.3 KiB
C++

/**
\code
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(C)2013 Semtech
___ _____ _ ___ _ _____ ___ ___ ___ ___
/ __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
\__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
|___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
embedded.connectivity.solutions===============
\endcode
Description: LoRa MAC Crypto implementation
License: Revised BSD License, see LICENSE.TXT file include in the project
Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
Copyright (c) 2017, Arm Limited and affiliates.
SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__
#define MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__
#include "mbedtls/config.h"
#include "mbedtls/aes.h"
#include "mbedtls/cmac.h"
#include "system/lorawan_data_structures.h"
class LoRaMacCrypto {
public:
/**
* Constructor
*/
LoRaMacCrypto();
/**
* Destructor
*/
~LoRaMacCrypto();
/**
* @brief set_keys Set keys to be used for crypto operations
* @param [in] nwk_key Network key
* @param [in] app_key Application key
*
* @return LORAWAN_STATUS_OK if accepted, LORAWAN_STATUS_CRYPTO_FAIL otherwise
*/
lorawan_status_t set_keys(uint8_t *nwk_key, uint8_t *app_key, uint8_t *nwk_skey = NULL,
uint8_t *app_skey = NULL, uint8_t *snwk_sintkey = NULL, uint8_t *nwk_senckey = NULL);
/**
* Computes the LoRaMAC frame MIC field
*
* @param [in] buffer - Data buffer
* @param [in] size - Data buffer size
* @param [in] args - LW1.1 bytes 1-4 (ConfFCnt, TxDr, TxCh)
* @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,
uint32_t args, uint32_t address,
uint8_t dir, uint32_t seq_counter,
uint32_t *mic);
/**
* Performs payload encryption
*
* @param [in] buffer - Data buffer
* @param [in] size - Data buffer size
* @param [in] address - Frame address
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
* @param [in] seq_counter - Frame sequence counter
* @param [in] s1_block_start - 0 for FOpts field, 1 for FMRPayload
* @param [out] enc_buffer - Encrypted buffer
* @param [in] is_fopts - Specifies whether to use FOpts key or not
*
* @return 0 if successful, or a cipher specific error code
*/
int encrypt_payload(const uint8_t *buffer, uint16_t size,
uint32_t address, uint8_t dir, uint32_t seq_counter,
seq_counter_type_t seq_cnt_type,
payload_type_t pld_type,
uint8_t *enc_buffer,
server_type_t serv_type, bool is_fopts = false);
/**
* Performs payload decryption
*
* @param [in] buffer - Data buffer
* @param [in] size - Data buffer size
* @param [in] address - Frame address
* @param [in] dir - Frame direction [0: uplink, 1: downlink]
* @param [in] seq_counter - Frame sequence counter
* @param [in] s1_block_start - 0 for FOpts field, 1 for FMRPayload
* @param [out] dec_buffer - Decrypted buffer
* @param [in] is_fopts - Specifies whether to use FOpts key or not
*
* @return 0 if successful, or a cipher specific error code
*/
int decrypt_payload(const uint8_t *buffer, uint16_t size,
uint32_t address, uint8_t dir, uint32_t seq_counter,
seq_counter_type_t seq_cnt_type,
payload_type_t pld_type,
uint8_t *dec_buffer,
server_type_t serv_type, bool is_fopts = false);
/**
* Computes the LoRaMAC Join Request frame MIC field
*
* @param [in] buffer - Data buffer
* @param [in] size - Data buffer size
* @param [in] type - Type of message to handle
* @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,
join_frame_type_t type, uint32_t *mic);
/**
* Computes the LoRaMAC join frame decryption
*
* @param [in] buffer - Data buffer
* @param [in] size - Data buffer size
* @param [out] dec_buffer - Decrypted buffer
* @param [in] is_join_req - True for join request, false for rejoin requests
*
* @return 0 if successful, or a cipher specific error code
*/
int decrypt_join_frame(const uint8_t *buffer, uint16_t size,
uint8_t *dec_buffer, bool is_join_req);
/**
* @brief unset_js_keys In case we support LoRaWAN 1.1 but server does not, we need to
* unset Join server keys to work with LoRaWAN 1.0.2
*/
void unset_js_keys();
/**
* Computes the LoRaMAC join frame decryption
*
* @param [in] args - Combined string of args needed for key derivation
* @param [in] args_size - Args size
* @param [in] stype - Server type (LW1_0_2 or LW1_1)
*
* @return 0 if successful, or a cipher specific error code
*/
int compute_skeys_for_join_frame(const uint8_t *args, uint8_t args_size,
server_type_t stype);
/**
* Computes the LoRaMAC join server keys
* In case of LoRaWAN 1.0.x key will be copied to outputs,
* so we can continue using same code for all versions
*
* @param [in] eui - DevEUI
*
* @return 0 if successful, or a cipher specific error code
*/
int compute_join_server_keys(const uint8_t *eui);
/**
* Computes random value used to compute Ping slot offset (1.1 ch 13.2)
*
* @param [in] beacon_time - Time carried in beacon payload
* @param [in] dev_addr - Device Address
* @param [out] rand
*
* @return 0 if successful, or a cipher specific error code
*/
int compute_ping_slot_random_offset(uint32_t beacon_time, uint32_t dev_addr, uint16_t *rand);
private:
/**
* AES computation context variable
*/
mbedtls_aes_context aes_ctx;
/**
* CMAC computation context variable
*/
mbedtls_cipher_context_t aes_cmac_ctx[1];
loramac_keys _keys;
/*!
* Mote Address
*/
uint32_t _dev_addr;
};
#endif // MBED_LORAWAN_MAC_LORAMAC_CRYPTO_H__