1 /*! 2 * \file LoRaMacCrypto.h 3 * 4 * \brief LoRa MAC layer cryptographic functionality implementation 5 * 6 * \copyright Revised BSD License, see section \ref LICENSE. 7 * 8 * \code 9 * ______ _ 10 * / _____) _ | | 11 * ( (____ _____ ____ _| |_ _____ ____| |__ 12 * \____ \| ___ | (_ _) ___ |/ ___) _ \ 13 * _____) ) ____| | | || |_| ____( (___| | | | 14 * (______/|_____)_|_|_| \__)_____)\____)_| |_| 15 * (C)2013-2017 Semtech 16 * 17 * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 18 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 19 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 20 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 21 * embedded.connectivity.solutions=============== 22 * 23 * \endcode 24 * 25 * \author Miguel Luis ( Semtech ) 26 * 27 * \author Gregory Cristian ( Semtech ) 28 * 29 * \author Daniel Jaeckle ( STACKFORCE ) 30 * 31 * \author Johannes Bruder ( STACKFORCE ) 32 * 33 * addtogroup LORAMAC 34 * \{ 35 * 36 */ 37 #ifndef __LORAMAC_CRYPTO_H__ 38 #define __LORAMAC_CRYPTO_H__ 39 40 #ifdef __cplusplus 41 extern "C" 42 { 43 #endif 44 45 #include <stdlib.h> 46 #include <stdint.h> 47 #include <stdbool.h> 48 #include "utilities.h" 49 #include "LoRaMacTypes.h" 50 #include "LoRaMacMessageTypes.h" 51 #include "LoRaMacCryptoNvm.h" 52 53 /*! 54 * Indicates if LoRaWAN 1.1.x crypto scheme is enabled 55 */ 56 #define USE_LRWAN_1_1_X_CRYPTO 0 57 58 /*! 59 * Indicates if a random devnonce must be used or not 60 */ 61 #define USE_RANDOM_DEV_NONCE 0 62 63 /*! 64 * Indicates if JoinNonce is counter based and requires to be checked 65 */ 66 #define USE_JOIN_NONCE_COUNTER_CHECK 0 67 68 /*! 69 * Initial value of the frame counters 70 */ 71 #define FCNT_DOWN_INITAL_VALUE 0xFFFFFFFF 72 73 /*! 74 * LoRaMac Cryto Status 75 */ 76 typedef enum eLoRaMacCryptoStatus 77 { 78 /*! 79 * No error occurred 80 */ 81 LORAMAC_CRYPTO_SUCCESS = 0, 82 /*! 83 * MIC does not match 84 */ 85 LORAMAC_CRYPTO_FAIL_MIC, 86 /*! 87 * Address does not match 88 */ 89 LORAMAC_CRYPTO_FAIL_ADDRESS, 90 /*! 91 * JoinNonce was not greater than previous one. 92 */ 93 LORAMAC_CRYPTO_FAIL_JOIN_NONCE, 94 /*! 95 * RJcount0 reached 2^16-1 96 */ 97 LORAMAC_CRYPTO_FAIL_RJCOUNT0_OVERFLOW, 98 /*! 99 * FCNT_ID is not supported 100 */ 101 LORAMAC_CRYPTO_FAIL_FCNT_ID, 102 /*! 103 * FCntUp/Down check failed (new FCnt is smaller than previous one) 104 */ 105 LORAMAC_CRYPTO_FAIL_FCNT_SMALLER, 106 /*! 107 * FCntUp/Down check failed (duplicated) 108 */ 109 LORAMAC_CRYPTO_FAIL_FCNT_DUPLICATED, 110 /*! 111 * Not allowed parameter value 112 */ 113 LORAMAC_CRYPTO_FAIL_PARAM, 114 /*! 115 * Null pointer exception 116 */ 117 LORAMAC_CRYPTO_ERROR_NPE, 118 /*! 119 * Invalid key identifier exception 120 */ 121 LORAMAC_CRYPTO_ERROR_INVALID_KEY_ID, 122 /*! 123 * Invalid address identifier exception 124 */ 125 LORAMAC_CRYPTO_ERROR_INVALID_ADDR_ID, 126 /*! 127 * Invalid LoRaWAN specification version 128 */ 129 LORAMAC_CRYPTO_ERROR_INVALID_VERSION, 130 /*! 131 * Incompatible buffer size 132 */ 133 LORAMAC_CRYPTO_ERROR_BUF_SIZE, 134 /*! 135 * The secure element reports an error 136 */ 137 LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC, 138 /*! 139 * Error from parser reported 140 */ 141 LORAMAC_CRYPTO_ERROR_PARSER, 142 /*! 143 * Error from serializer reported 144 */ 145 LORAMAC_CRYPTO_ERROR_SERIALIZER, 146 /*! 147 * RJcount1 reached 2^16-1 which should never happen 148 */ 149 LORAMAC_CRYPTO_ERROR_RJCOUNT1_OVERFLOW, 150 /*! 151 * Undefined Error occurred 152 */ 153 LORAMAC_CRYPTO_ERROR, 154 }LoRaMacCryptoStatus_t; 155 156 /*! 157 * Signature of callback function to be called by the LoRaMac Crypto module when the 158 * non-volatile context have to be stored. It is also possible to save the entire 159 * crypto module context. 160 * 161 */ 162 typedef void ( *LoRaMacCryptoNvmEvent )( void ); 163 164 /*! 165 * Initialization of LoRaMac Crypto module 166 * It sets initial values of volatile variables and assigns the non-volatile context. 167 * 168 * \param[IN] nvm - Pointer to the non-volatile memory data 169 * structure. 170 * \retval - Status of the operation 171 */ 172 LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmData_t* nvm ); 173 174 /*! 175 * Sets the LoRaWAN specification version to be used. 176 * 177 * \warning This function should be used for ABP only. In case of OTA the version will be set automatically. 178 * 179 * \param[IN] version - LoRaWAN specification version to be used. 180 * 181 * \retval - Status of the operation 182 */ 183 LoRaMacCryptoStatus_t LoRaMacCryptoSetLrWanVersion( Version_t version ); 184 185 /*! 186 * Returns updated fCntID downlink counter value. 187 * 188 * \param[IN] fCntID - Frame counter identifier 189 * \param[IN] frameFcnt - Received frame counter (used to update current counter value) 190 * \param[OUT] currentDown - Current downlink counter value 191 * \retval - Status of the operation 192 */ 193 LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint32_t frameFcnt, uint32_t* currentDown ); 194 195 /*! 196 * Returns updated fCntUp uplink counter value. 197 * 198 * \param[IN] currentUp - Uplink counter value 199 * \retval - Status of the operation 200 */ 201 LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp ); 202 203 /*! 204 * Provides multicast context. 205 * 206 * \param[IN] multicastList - Pointer to the multicast context list 207 * 208 * \retval - Status of the operation 209 */ 210 LoRaMacCryptoStatus_t LoRaMacCryptoSetMulticastReference( MulticastCtx_t* multicastList ); 211 212 /*! 213 * Sets a key 214 * 215 * \param[IN] keyID - Key identifier 216 * \param[IN] key - Key value (16 byte), if its a multicast key it must be encrypted with McKEKey 217 * \retval - Status of the operation 218 */ 219 LoRaMacCryptoStatus_t LoRaMacCryptoSetKey( KeyIdentifier_t keyID, uint8_t* key ); 220 221 /*! 222 * Prepares the join-request message. 223 * It computes the mic and add it to the message. 224 * 225 * \param[IN/OUT] macMsg - Join-request message object 226 * \retval - Status of the operation 227 */ 228 LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest_t* macMsg ); 229 230 /*! 231 * Prepares a rejoin-request type 1 message. 232 * It computes the mic and add it to the message. 233 * 234 * \param[IN/OUT] macMsg - Rejoin message object 235 * \retval - Status of the operation 236 */ 237 LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1_t* macMsg ); 238 239 /*! 240 * Prepares a rejoin-request type 0 or 2 message. 241 * It computes the mic and add it to the message. 242 * 243 * \param[IN/OUT] macMsg - Rejoin message object 244 * \retval - Status of the operation 245 */ 246 LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinType0or2_t* macMsg ); 247 248 /*! 249 * Handles the join-accept message. 250 * It decrypts the message, verifies the MIC and if successful derives the session keys. 251 * 252 * \param[IN] joinReqType - Type of last join-request or rejoin which triggered the join-accept response 253 * \param[IN] joinEUI - Join server EUI (8 byte) 254 * \param[IN/OUT] macMsg - Join-accept message object 255 * \retval - Status of the operation 256 */ 257 LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReqType, uint8_t* joinEUI, LoRaMacMessageJoinAccept_t* macMsg ); 258 259 /*! 260 * Secures a message (encryption + integrity). 261 * 262 * \param[IN] fCntUp - Uplink sequence counter 263 * \param[IN] txDr - Data rate used for the transmission 264 * \param[IN] txCh - Index of the channel used for the transmission 265 * \param[IN/OUT] macMsg - Data message object 266 * \retval - Status of the operation 267 */ 268 LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, uint8_t txCh, LoRaMacMessageData_t* macMsg ); 269 270 /*! 271 * Unsecures a message (decryption + integrity verification). 272 * 273 * \param[IN] addrID - Address identifier 274 * \param[IN] address - Address 275 * \param[IN] fCntID - Frame counter identifier 276 * \param[IN] fCntDown - Downlink sequence counter 277 * \param[IN/OUT] macMsg - Data message object 278 * \retval - Status of the operation 279 */ 280 LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, uint32_t address, FCntIdentifier_t fCntID, uint32_t fCntDown, LoRaMacMessageData_t* macMsg ); 281 282 /*! 283 * Derives the McRootKey from the AppKey. 284 * 285 * 1.0.x 286 * McRootKey = aes128_encrypt(AppKey, 0x00 | pad16) 287 * 288 * 1.1.x 289 * McRootKey = aes128_encrypt(AppKey, 0x20 | pad16) 290 * 291 * \param[IN] versionMinor - LoRaWAN specification minor version to be used. 292 * \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( AppKey ) 293 * \retval - Status of the operation 294 */ 295 LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( uint8_t versionMinor, KeyIdentifier_t keyID ); 296 297 /*! 298 * Derives the McKEKey from the McRootKey. 299 * 300 * McKEKey = aes128_encrypt(McRootKey , 0x00 | pad16) 301 * 302 * \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( McRootKey ) 303 * \retval - Status of the operation 304 */ 305 LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcKEKey( KeyIdentifier_t keyID ); 306 307 /*! 308 * Derives a Multicast group key pair ( McAppSKey, McNwkSKey ) from McKey 309 * 310 * McAppSKey = aes128_encrypt(McKey, 0x01 | McAddr | pad16) 311 * McNwkSKey = aes128_encrypt(McKey, 0x02 | McAddr | pad16) 312 * 313 * \param[IN] addrID - Address identifier to select the multicast group 314 * \param[IN] mcAddr - Multicast group address (4 bytes) 315 * \retval - Status of the operation 316 */ 317 LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcSessionKeyPair( AddressIdentifier_t addrID, uint32_t mcAddr ); 318 319 /*! \} addtogroup LORAMAC */ 320 321 #ifdef __cplusplus 322 } 323 #endif 324 325 #endif // __LORAMAC_CRYPTO_H__ 326