Skip to content

Commit 83aaf7c

Browse files
committed
Added new SecureElementProcessJoinAccept API to the secure-element.h
1 parent c94d7e3 commit 83aaf7c

File tree

3 files changed

+186
-99
lines changed

3 files changed

+186
-99
lines changed

src/mac/LoRaMacCrypto.c

Lines changed: 71 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
#define CRYPTO_BUFFER_SIZE CRYPTO_MAXMESSAGE_SIZE + MIC_BLOCK_BX_SIZE
103103

104104
/*
105-
* MIC computaion offset
105+
* MIC computation offset
106106
*/
107107
#define CRYPTO_MIC_COMPUTATION_OFFSET JOIN_REQ_TYPE_SIZE + LORAMAC_JOIN_EUI_FIELD_SIZE + DEV_NONCE_SIZE + LORAMAC_MHDR_FIELD_SIZE
108108

@@ -948,7 +948,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoInit( LoRaMacCryptoNvmEvent cryptoNvmCtxChang
948948
}
949949

950950
// Initialize with default
951-
memset1( (uint8_t*) CryptoCtx.NvmCtx, 0, sizeof( LoRaMacCryptoNvmCtx_t ) );
951+
memset1( ( uint8_t* )CryptoCtx.NvmCtx, 0, sizeof( LoRaMacCryptoNvmCtx_t ) );
952952

953953
// Set default LoRaWAN version
954954
CryptoCtx.NvmCtx->LrWanVersion.Fields.Major = 1;
@@ -973,7 +973,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoRestoreNvmCtx( void* cryptoNvmCtx )
973973
// Restore module context
974974
if( cryptoNvmCtx != 0 )
975975
{
976-
memcpy1( ( uint8_t* ) &NvmCryptoCtx, ( uint8_t* ) cryptoNvmCtx, CRYPTO_NVM_CTX_SIZE );
976+
memcpy1( ( uint8_t* )&NvmCryptoCtx, ( uint8_t* )cryptoNvmCtx, CRYPTO_NVM_CTX_SIZE );
977977
return LORAMAC_CRYPTO_SUCCESS;
978978
}
979979
else
@@ -1020,7 +1020,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint16_
10201020
// For LoRaWAN 1.0.X only, allow downlink frames of 0
10211021
if( lastDown == FCNT_DOWN_INITAL_VALUE )
10221022
{
1023-
*currentDown = frameFcnt;
1023+
*currentDown = frameFcnt;
10241024
}
10251025
else
10261026
{
@@ -1042,7 +1042,6 @@ LoRaMacCryptoStatus_t LoRaMacCryptoGetFCntDown( FCntIdentifier_t fCntID, uint16_
10421042
}
10431043
}
10441044

1045-
10461045
// For LoRaWAN 1.0.X only, check maxFCntGap
10471046
if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 0 )
10481047
{
@@ -1208,7 +1207,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoPrepareReJoinType0or2( LoRaMacMessageReJoinTy
12081207
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
12091208
}
12101209

1211-
// Reserialize message to add the MIC
1210+
// Re-serialize message to add the MIC
12121211
if( LoRaMacSerializerReJoinType0or2( macMsg ) != LORAMAC_SERIALIZER_SUCCESS )
12131212
{
12141213
return LORAMAC_CRYPTO_ERROR_SERIALIZER;
@@ -1228,101 +1227,60 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq
12281227
}
12291228

12301229
LoRaMacCryptoStatus_t retval = LORAMAC_CRYPTO_ERROR;
1231-
KeyIdentifier_t micComputationKeyID;
1232-
KeyIdentifier_t encryptionKeyID;
1233-
uint8_t micComputationOffset = 0;
1234-
#if( USE_LRWAN_1_1_X_CRYPTO == 1 )
1235-
uint8_t* devNonceForKeyDerivation = ( uint8_t* ) &CryptoCtx.NvmCtx->DevNonce;
1236-
#endif
12371230

1238-
// Determine decryption key and DevNonce for key derivation
1239-
if( joinReqType == JOIN_REQ )
1231+
// 1st trial for LoRaWAN 1.0.x
1232+
uint8_t micHeader10[1] = { 0x20 };
1233+
uint8_t macMsgBufferDec[33] = { 0 };
1234+
// mic = aes128_cmac(NwkKey, MHDR | JoinNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | CFListType)
1235+
if( SecureElementProcessJoinAccept( NWK_KEY, NWK_KEY, 0, micHeader10, macMsg->Buffer, macMsg->BufSize, macMsgBufferDec ) != SECURE_ELEMENT_SUCCESS )
12401236
{
1241-
encryptionKeyID = NWK_KEY;
1242-
micComputationOffset = CRYPTO_MIC_COMPUTATION_OFFSET;
1243-
}
12441237
#if( USE_LRWAN_1_1_X_CRYPTO == 1 )
1245-
else
1246-
{
1247-
encryptionKeyID = J_S_ENC_KEY;
1238+
// mic = aes128_cmac(JSIntKey, JoinReqType | JoinEUI | DevNonce | MHDR | JoinNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | CFListType)
1239+
// Prepare the msg for integrity check (adding JoinReqType, JoinEUI and DevNonce)
1240+
uint8_t micHeader11[CRYPTO_MIC_COMPUTATION_OFFSET];
1241+
uint16_t bufItr = 0;
1242+
micHeader11[bufItr++] = ( uint8_t )joinReqType;
12481243

1249-
// If Join-accept is a reply to a rejoin, the RJcount(0 or 1) replaces DevNonce in the key derivation process.
1250-
if( ( joinReqType == REJOIN_REQ_0 ) || ( joinReqType == REJOIN_REQ_2 ) )
1251-
{
1252-
devNonceForKeyDerivation = ( uint8_t* ) &CryptoCtx.RJcount0;
1253-
}
1254-
else
1255-
{
1256-
devNonceForKeyDerivation = ( uint8_t* ) &CryptoCtx.NvmCtx->RJcount1;
1257-
}
1258-
}
1259-
#endif
1260-
// Decrypt header, skip MHDR
1261-
uint8_t procBuffer[CRYPTO_MAXMESSAGE_SIZE + CRYPTO_MIC_COMPUTATION_OFFSET];
1262-
memset1( procBuffer, 0, ( macMsg->BufSize + micComputationOffset ) );
1244+
memcpyr( micHeader11 + bufItr, joinEUI, LORAMAC_JOIN_EUI_FIELD_SIZE );
1245+
bufItr += LORAMAC_JOIN_EUI_FIELD_SIZE;
12631246

1264-
if( SecureElementAesEncrypt( macMsg->Buffer + LORAMAC_MHDR_FIELD_SIZE, ( macMsg->BufSize - LORAMAC_MHDR_FIELD_SIZE ), encryptionKeyID, ( procBuffer + micComputationOffset ) ) != SECURE_ELEMENT_SUCCESS )
1265-
{
1266-
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
1267-
}
1268-
// Copy the result to an offset location to keep space for additional information which have to be added in case of 1.1 and later
1269-
memcpy1( macMsg->Buffer + LORAMAC_MHDR_FIELD_SIZE, ( procBuffer + micComputationOffset ), ( macMsg->BufSize - LORAMAC_MHDR_FIELD_SIZE ) );
1247+
micHeader11[bufItr++] = CryptoCtx.NvmCtx->DevNonce & 0xFF;
1248+
micHeader11[bufItr++] = ( CryptoCtx.NvmCtx->DevNonce >> 8 ) & 0xFF;
12701249

1271-
// Parse the message
1272-
if( LoRaMacParserJoinAccept( macMsg ) != LORAMAC_PARSER_SUCCESS )
1273-
{
1274-
return LORAMAC_CRYPTO_ERROR_PARSER;
1275-
}
1250+
micHeader11[bufItr++] = 0x20;
12761251

1277-
// Is it a LoRaWAN 1.1.0 or later ?
1278-
if( macMsg->DLSettings.Bits.OptNeg == 1 )
1279-
{
1252+
// 2nd trial for LoRaWAN 1.1.x
1253+
if( SecureElementProcessJoinAccept( J_S_ENC_KEY, J_S_INT_KEY, 1, micHeader11, macMsg->Buffer, macMsg->BufSize, macMsgBufferDec ) != SECURE_ELEMENT_SUCCESS )
1254+
{
1255+
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
1256+
}
12801257
CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor = 1;
1281-
micComputationKeyID = J_S_INT_KEY;
1258+
#else
1259+
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
1260+
#endif
12821261
}
12831262
else
12841263
{
12851264
CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor = 0;
1286-
micComputationKeyID = NWK_KEY;
12871265
}
12881266

1289-
// Verify mic
1290-
if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 0 )
1267+
memcpy1( macMsg->Buffer, macMsgBufferDec, macMsg->BufSize );
1268+
1269+
// Parse the message
1270+
if( LoRaMacParserJoinAccept( macMsg ) != LORAMAC_PARSER_SUCCESS )
12911271
{
1292-
// For legacy mode :
1293-
// cmac = aes128_cmac(NwkKey, MHDR | JoinNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | CFListType)
1294-
if( SecureElementVerifyAesCmac( macMsg->Buffer, ( macMsg->BufSize - LORAMAC_MIC_FIELD_SIZE ), macMsg->MIC, micComputationKeyID ) != SECURE_ELEMENT_SUCCESS )
1295-
{
1296-
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
1297-
}
1272+
return LORAMAC_CRYPTO_ERROR_PARSER;
12981273
}
1299-
else
1300-
{
1301-
// For 1.1 and later:
1302-
// cmac = aes128_cmac(JSIntKey, JoinReqType | JoinEUI | DevNonce | MHDR | JoinNonce | NetID | DevAddr | DLSettings | RxDelay | CFList | CFListType)
1303-
1304-
// Prepare the msg for integrity check (adding JoinReqType, JoinEUI and DevNonce)
1305-
uint16_t bufItr = 0;
1306-
procBuffer[bufItr++] = ( uint8_t ) joinReqType;
1307-
1308-
memcpyr( &procBuffer[bufItr], joinEUI, LORAMAC_JOIN_EUI_FIELD_SIZE );
1309-
bufItr += LORAMAC_JOIN_EUI_FIELD_SIZE;
1310-
1311-
procBuffer[bufItr++] = CryptoCtx.NvmCtx->DevNonce & 0xFF;
1312-
procBuffer[bufItr++] = ( CryptoCtx.NvmCtx->DevNonce >> 8 ) & 0xFF;
1313-
1314-
procBuffer[bufItr++] = macMsg->MHDR.Value;
1315-
1316-
if( SecureElementVerifyAesCmac( procBuffer, ( macMsg->BufSize + micComputationOffset - LORAMAC_MHDR_FIELD_SIZE - LORAMAC_MIC_FIELD_SIZE ), macMsg->MIC, micComputationKeyID ) != SECURE_ELEMENT_SUCCESS )
1317-
{
1318-
return LORAMAC_CRYPTO_ERROR_SECURE_ELEMENT_FUNC;
1319-
}
13201274

1275+
#if( USE_LRWAN_1_1_X_CRYPTO == 1 )
1276+
if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 )
1277+
{
13211278
// Check if the JoinNonce is greater as the previous one
13221279
uint32_t currentJoinNonce = 0;
1323-
currentJoinNonce = ( uint32_t ) macMsg->JoinNonce[0];
1324-
currentJoinNonce |= ( ( uint32_t ) macMsg->JoinNonce[1] << 8 );
1325-
currentJoinNonce |= ( ( uint32_t ) macMsg->JoinNonce[2] << 16 );
1280+
1281+
currentJoinNonce = ( uint32_t )macMsg->JoinNonce[0];
1282+
currentJoinNonce |= ( ( uint32_t )macMsg->JoinNonce[1] << 8 );
1283+
currentJoinNonce |= ( ( uint32_t )macMsg->JoinNonce[2] << 16 );
13261284

13271285
if( currentJoinNonce > CryptoCtx.NvmCtx->JoinNonce )
13281286
{
@@ -1334,11 +1292,35 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq
13341292
return LORAMAC_CRYPTO_FAIL_JOIN_NONCE;
13351293
}
13361294
}
1295+
#endif
13371296

13381297
// Derive session keys
13391298
#if( USE_LRWAN_1_1_X_CRYPTO == 1 )
1299+
uint8_t* devNonceForKeyDerivation = ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce;
1300+
#endif
1301+
1302+
// Determine decryption key and DevNonce for key derivation
1303+
if( joinReqType == JOIN_REQ )
1304+
{
1305+
// Nothing to be done
1306+
}
1307+
#if( USE_LRWAN_1_1_X_CRYPTO == 1 )
1308+
else
1309+
{
1310+
// If Join-accept is a reply to a rejoin, the RJcount(0 or 1) replaces DevNonce in the key derivation process.
1311+
if( ( joinReqType == REJOIN_REQ_0 ) || ( joinReqType == REJOIN_REQ_2 ) )
1312+
{
1313+
devNonceForKeyDerivation = ( uint8_t* )&CryptoCtx.RJcount0;
1314+
}
1315+
else
1316+
{
1317+
devNonceForKeyDerivation = ( uint8_t* )&CryptoCtx.NvmCtx->RJcount1;
1318+
}
1319+
}
1320+
13401321
if( CryptoCtx.NvmCtx->LrWanVersion.Fields.Minor == 1 )
13411322
{
1323+
// Operating in LoRaWAN 1.1.x mode
13421324
// Derive lifetime keys
13431325
retval = LoRaMacCryptoDeriveMcRootKey( APP_KEY );
13441326
if( retval != LORAMAC_CRYPTO_SUCCESS )
@@ -1379,7 +1361,7 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq
13791361
else
13801362
#endif
13811363
{
1382-
// prior LoRaWAN 1.1.0
1364+
// Operating in LoRaWAN 1.0.x mode
13831365
retval = LoRaMacCryptoDeriveMcRootKey( GEN_APP_KEY );
13841366
if( retval != LORAMAC_CRYPTO_SUCCESS )
13851367
{
@@ -1392,25 +1374,25 @@ LoRaMacCryptoStatus_t LoRaMacCryptoHandleJoinAccept( JoinReqIdentifier_t joinReq
13921374
return retval;
13931375
}
13941376

1395-
retval = DeriveSessionKey10x( APP_S_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* ) &CryptoCtx.NvmCtx->DevNonce );
1377+
retval = DeriveSessionKey10x( APP_S_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce );
13961378
if( retval != LORAMAC_CRYPTO_SUCCESS )
13971379
{
13981380
return retval;
13991381
}
14001382

1401-
retval = DeriveSessionKey10x( NWK_S_ENC_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* ) &CryptoCtx.NvmCtx->DevNonce );
1383+
retval = DeriveSessionKey10x( NWK_S_ENC_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce );
14021384
if( retval != LORAMAC_CRYPTO_SUCCESS )
14031385
{
14041386
return retval;
14051387
}
14061388

1407-
retval = DeriveSessionKey10x( F_NWK_S_INT_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* ) &CryptoCtx.NvmCtx->DevNonce );
1389+
retval = DeriveSessionKey10x( F_NWK_S_INT_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce );
14081390
if( retval != LORAMAC_CRYPTO_SUCCESS )
14091391
{
14101392
return retval;
14111393
}
14121394

1413-
retval = DeriveSessionKey10x( S_NWK_S_INT_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* ) &CryptoCtx.NvmCtx->DevNonce );
1395+
retval = DeriveSessionKey10x( S_NWK_S_INT_KEY, macMsg->JoinNonce, macMsg->NetID, ( uint8_t* )&CryptoCtx.NvmCtx->DevNonce );
14141396
if( retval != LORAMAC_CRYPTO_SUCCESS )
14151397
{
14161398
return retval;
@@ -1661,8 +1643,8 @@ LoRaMacCryptoStatus_t LoRaMacCryptoDeriveMcSessionKeyPair( AddressIdentifier_t a
16611643
return retval;
16621644
}
16631645

1664-
//McAppSKey = aes128_encrypt(McKey, 0x01 | McAddr | pad16)
1665-
//McNwkSKey = aes128_encrypt(McKey, 0x02 | McAddr | pad16)
1646+
// McAppSKey = aes128_encrypt(McKey, 0x01 | McAddr | pad16)
1647+
// McNwkSKey = aes128_encrypt(McKey, 0x02 | McAddr | pad16)
16661648

16671649
uint8_t compBaseAppS[16] = { 0 };
16681650
uint8_t compBaseNwkS[16] = { 0 };

src/mac/secure-element.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ extern "C"
4646
#include <stdint.h>
4747
#include "LoRaMacCrypto.h"
4848

49-
#define SE_EUI_SIZE 16
49+
#define SE_EUI_SIZE 8
5050

5151
/*!
5252
* Return values.
@@ -57,6 +57,10 @@ typedef enum eSecureElementStatus
5757
* No error occurred
5858
*/
5959
SECURE_ELEMENT_SUCCESS = 0,
60+
/*!
61+
* Failed to encrypt
62+
*/
63+
SECURE_ELEMENT_FAIL_ENCRYPT,
6064
/*!
6165
* CMAC does not match
6266
*/
@@ -169,6 +173,26 @@ SecureElementStatus_t SecureElementAesEncrypt( uint8_t* buffer, uint16_t size, K
169173
*/
170174
SecureElementStatus_t SecureElementDeriveAndStoreKey( Version_t version, uint8_t* input, KeyIdentifier_t rootKeyID, KeyIdentifier_t targetKeyID );
171175

176+
/*!
177+
* Process JoinAccept message.
178+
*
179+
* \param[IN] encKeyID - Key identifier of the key which will be used to decrypt the JoinAccept message
180+
* \param[IN] micKeyID - Key identifier of the key which will be used to compute the JoinAccept message MIC
181+
* \param[IN] versionMinor - LoRaWAN specification version minor field which will be used to perform the processing.
182+
* - 0 -> LoRaWAN 1.0.x
183+
* - 1 -> LoRaWAN 1.1.x
184+
* \param[IN] micHeader - Header buffer to be used for MIC computation
185+
* - LoRaWAN 1.0.x : micHeader = [MHDR(1)]
186+
* - LoRaWAN 1.1.x : micHeader = [JoinReqType(1), JoinEUI(8), DevNonce(2), MHDR(1)]
187+
* \param[IN] encJoinAccept - Received encrypted JoinAccept message
188+
* \param[IN] encJoinAcceptSize - Received encrypted JoinAccept message Size
189+
* \param[IN] decJoinAccept - Decrypted and validated JoinAccept message
190+
* \retval - Status of the operation
191+
*/
192+
SecureElementStatus_t SecureElementProcessJoinAccept( KeyIdentifier_t encKeyID, KeyIdentifier_t micKeyID, uint8_t versionMinor,
193+
uint8_t *micHeader, uint8_t *encJoinAccept, uint8_t encJoinAcceptSize,
194+
uint8_t *decJoinAccept );
195+
172196
/*!
173197
* Generates a random number
174198
*

0 commit comments

Comments
 (0)