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