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 1 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 on 1.0.x devices 65 * \remark Only applies to LoRaWAN 1.0.x when following recomendations provided 66 * by "Technical Recommendations for Preventing State Synchronization 67 * Issues around LoRaWAN� 1.0.x Join Procedure" 68 * https://lora-alliance.org/wp-content/uploads/2020/11/lorawan-1.0.x-join-synch-issues-remedies-v1.0.0.pdf 69 */ 70 #define USE_10X_JOIN_NONCE_COUNTER_CHECK 0 71 72 /*! 73 * Initial value of the frame counters 74 */ 75 #define FCNT_DOWN_INITAL_VALUE 0xFFFFFFFF 76 77 /*! 78 * LoRaMac Crypto Status 79 */ 80 typedef enum eLoRaMacCryptoStatus 81 { 82 /*! 83 * No error occurred 84 */ 85 LORAMAC_CRYPTO_SUCCESS = 0, 86 /*! 87 * MIC does not match 88 */ 89 LORAMAC_CRYPTO_FAIL_MIC, 90 /*! 91 * Address does not match 92 */ 93 LORAMAC_CRYPTO_FAIL_ADDRESS, 94 /*! 95 * JoinNonce was not greater than previous one. 96 */ 97 LORAMAC_CRYPTO_FAIL_JOIN_NONCE, 98 /*! 99 * RJcount0 reached 2^16-1 100 */ 101 LORAMAC_CRYPTO_FAIL_RJCOUNT0_OVERFLOW, 102 /*! 103 * FCNT_ID is not supported 104 */ 105 LORAMAC_CRYPTO_FAIL_FCNT_ID, 106 /*! 107 * FCntUp/Down check failed (new FCnt is smaller than previous one) 108 */ 109 LORAMAC_CRYPTO_FAIL_FCNT_SMALLER, 110 /*! 111 * FCntUp/Down check failed (duplicated) 112 */ 113 LORAMAC_CRYPTO_FAIL_FCNT_DUPLICATED, 114 /*! 115 * Not allowed parameter value 116 */ 117 LORAMAC_CRYPTO_FAIL_PARAM, 118 /*! 119 * Null pointer exception 120 */ 121 LORAMAC_CRYPTO_ERROR_NPE, 122 /*! 123 * Invalid key identifier exception 124 */ 125 LORAMAC_CRYPTO_ERROR_INVALID_KEY_ID, 126 /*! 127 * Invalid address identifier exception 128 */ 129 LORAMAC_CRYPTO_ERROR_INVALID_ADDR_ID, 130 /*! 131 * Invalid LoRaWAN specification version 132 */ 133 LORAMAC_CRYPTO_ERROR_INVALID_VERSION, 134 /*! 135 * Incompatible buffer size 136 */ 137 LORAMAC_CRYPTO_ERROR_BUF_SIZE, 138 /*! 139 * The secure element reports an error 140 */ 141 LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC, 142 /*! 143 * Error from parser reported 144 */ 145 LORAMAC_CRYPTO_ERROR_PARSER, 146 /*! 147 * Error from serializer reported 148 */ 149 LORAMAC_CRYPTO_ERROR_SERIALIZER, 150 /*! 151 * RJcount1 reached 2^16-1 which should never happen 152 */ 153 LORAMAC_CRYPTO_ERROR_RJCOUNT1_OVERFLOW, 154 /*! 155 * Undefined Error occurred 156 */ 157 LORAMAC_CRYPTO_ERROR, 158 }LoRaMacCryptoStatus_t; 159 160 /*! 161 * Signature of callback function to be called by the LoRaMac Crypto module when the 162 * non-volatile context have to be stored. It is also possible to save the entire 163 * crypto module context. 164 * 165 */ 166 typedef void ( *LoRaMacCryptoNvmEvent )( void ); 167 168 /*! 169 * Initialization of LoRaMac Crypto module 170 * It sets initial values of volatile variables and assigns the non-volatile context. 171 * 172 * \param[IN] nvm - Pointer to the non-volatile memory data 173 * structure. 174 * \retval - Status of the operation 175 */ 176 LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmData_t* nvm ); 177 178 /*! 179 * Sets the LoRaWAN specification version to be used. 180 * 181 * \warning This function should be used for ABP only. In case of OTA the version will be set automatically. 182 * 183 * \param[IN] version - LoRaWAN specification version to be used. 184 * 185 * \retval - Status of the operation 186 */ 187 LoRaMacCryptoStatus_t LoRaMacCryptoSetLrWanVersion( Version_t version ); 188 189 /*! 190 * Returns updated fCntID downlink counter value. 191 * 192 * \param[IN] fCntID - Frame counter identifier 193 * \param[IN] frameFcnt - Received frame counter (used to update current counter value) 194 * \param[OUT] currentDown - Current downlink counter value 195 * \retval - Status of the operation 196 */ 197 LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint32_t frameFcnt, uint32_t* currentDown ); 198 199 /*! 200 * Returns updated fCntUp uplink counter value. 201 * 202 * \param[IN] currentUp - Uplink counter value 203 * \retval - Status of the operation 204 */ 205 LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntUp( uint32_t* currentUp ); 206 207 /*! 208 * Computes next RJcount0 or RJcount1 counter value. 209 * 210 * \param[IN] fCntID - Frame counter identifier 211 * \param[OUT] rJcount - RJcount value 212 * 213 * \retval - Status of the operation 214 */ 215 LoRaMacCryptoStatus_t LoRaMacCryptoGetRJcount( FCntIdentifier_t fCntID, uint16_t* rJcount ); 216 217 /*! 218 * Provides multicast context. 219 * 220 * \param[IN] multicastList - Pointer to the multicast context list 221 * 222 * \retval - Status of the operation 223 */ 224 LoRaMacCryptoStatus_t LoRaMacCryptoSetMulticastReference( MulticastCtx_t* multicastList ); 225 226 /*! 227 * Sets a key 228 * 229 * \param[IN] keyID - Key identifier 230 * \param[IN] key - Key value (16 byte), if its a multicast key it must be encrypted with McKEKey 231 * \retval - Status of the operation 232 */ 233 LoRaMacCryptoStatus_t LoRaMacCryptoSetKey( KeyIdentifier_t keyID, uint8_t* key ); 234 235 /*! 236 * Prepares the join-request message. 237 * It computes the mic and add it to the message. 238 * 239 * \param[IN/OUT] macMsg - Join-request message object 240 * \retval - Status of the operation 241 */ 242 LoRaMacCryptoStatus_t LoRaMacCryptoPrepareJoinRequest( LoRaMacMessageJoinRequest_t* macMsg ); 243 244 /*! 245 * Prepares a rejoin-request type 1 message. 246 * It computes the mic and add it to the message. 247 * 248 * \param[IN/OUT] macMsg - Rejoin message object 249 * \retval - Status of the operation 250 */ 251 LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType1( LoRaMacMessageReJoinType1_t* macMsg ); 252 253 /*! 254 * Prepares a rejoin-request type 0 or 2 message. 255 * It computes the mic and add it to the message. 256 * 257 * \param[IN/OUT] macMsg - Rejoin message object 258 * \retval - Status of the operation 259 */ 260 LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinType0or2_t* macMsg ); 261 262 /*! 263 * Handles the join-accept message. 264 * It decrypts the message, verifies the MIC and if successful derives the session keys. 265 * 266 * \param[IN] joinReqType - Type of last join-request or rejoin which triggered the join-accept response 267 * \param[IN] joinEUI - Join server EUI (8 byte) 268 * \param[IN/OUT] macMsg - Join-accept message object 269 * \retval - Status of the operation 270 */ 271 LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReqType, uint8_t* joinEUI, LoRaMacMessageJoinAccept_t* macMsg ); 272 273 /*! 274 * Secures a message (encryption + integrity). 275 * 276 * \param[IN] fCntUp - Uplink sequence counter 277 * \param[IN] txDr - Data rate used for the transmission 278 * \param[IN] txCh - Index of the channel used for the transmission 279 * \param[IN/OUT] macMsg - Data message object 280 * \retval - Status of the operation 281 */ 282 LoRaMacCryptoStatus_t LoRaMacCryptoSecureMessage( uint32_t fCntUp, uint8_t txDr, uint8_t txCh, LoRaMacMessageData_t* macMsg ); 283 284 /*! 285 * Unsecures a message (decryption + integrity verification). 286 * 287 * \param[IN] addrID - Address identifier 288 * \param[IN] address - Address 289 * \param[IN] fCntID - Frame counter identifier 290 * \param[IN] fCntDown - Downlink sequence counter 291 * \param[IN/OUT] macMsg - Data message object 292 * \retval - Status of the operation 293 */ 294 LoRaMacCryptoStatus_t LoRaMacCryptoUnsecureMessage( AddressIdentifier_t addrID, uint32_t address, FCntIdentifier_t fCntID, uint32_t fCntDown, LoRaMacMessageData_t* macMsg ); 295 296 /*! 297 * Derives the McRootKey from the AppKey. 298 * 299 * 1.0.x 300 * McRootKey = aes128_encrypt(AppKey, 0x00 | pad16) 301 * 302 * 1.1.x 303 * McRootKey = aes128_encrypt(AppKey, 0x20 | pad16) 304 * 305 * \param[IN] versionMinor - LoRaWAN specification minor version to be used. 306 * \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( AppKey ) 307 * \retval - Status of the operation 308 */ 309 LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcRootKey( uint8_t versionMinor, KeyIdentifier_t keyID ); 310 311 /*! 312 * Derives the McKEKey from the McRootKey. 313 * 314 * McKEKey = aes128_encrypt(McRootKey , 0x00 | pad16) 315 * 316 * \param[IN] keyID - Key identifier of the root key to use to perform the derivation ( McRootKey ) 317 * \retval - Status of the operation 318 */ 319 LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcKEKey( KeyIdentifier_t keyID ); 320 321 /*! 322 * Derives a Multicast group key pair ( McAppSKey, McNwkSKey ) from McKey 323 * 324 * McAppSKey = aes128_encrypt(McKey, 0x01 | McAddr | pad16) 325 * McNwkSKey = aes128_encrypt(McKey, 0x02 | McAddr | pad16) 326 * 327 * \param[IN] addrID - Address identifier to select the multicast group 328 * \param[IN] mcAddr - Multicast group address (4 bytes) 329 * \retval - Status of the operation 330 */ 331 LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcSessionKeyPair( AddressIdentifier_t addrID, uint32_t mcAddr ); 332 333 /*! \} addtogroup LORAMAC */ 334 335 #ifdef __cplusplus 336 } 337 #endif 338 339 #endif // __LORAMAC_CRYPTO_H__ 340