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 };
0 commit comments