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