LoRaWAN MAC layer implementation
Dependents: LoRaWAN-demo-72_tjm LoRaWAN-demo-72_jlc LoRaWAN-demo-elmo frdm_LoRa_Connect_Woodstream_Demo_tjm ... more
LoRaMacCrypto.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2013 Semtech 00008 ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 embedded.connectivity.solutions=============== 00013 00014 Description: LoRa MAC layer implementation 00015 00016 License: Revised BSD License, see LICENSE.TXT file include in the project 00017 00018 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jäckle ( STACKFORCE ) 00019 */ 00020 #include <stdlib.h> 00021 #include <stdint.h> 00022 #include "utilities.h" 00023 00024 #include "aes.h" 00025 #include "cmac.h" 00026 00027 #include "LoRaMacCrypto.h" 00028 00029 /*! 00030 * CMAC/AES Message Integrity Code (MIC) Block B0 size 00031 */ 00032 #define LORAMAC_MIC_BLOCK_B0_SIZE 16 00033 00034 /*! 00035 * MIC field computation initial data 00036 */ 00037 static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00038 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00039 }; 00040 00041 /*! 00042 * Contains the computed MIC field. 00043 * 00044 * \remark Only the 4 first bytes are used 00045 */ 00046 static uint8_t Mic[16]; 00047 00048 /*! 00049 * Encryption aBlock and sBlock 00050 */ 00051 static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00052 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00053 }; 00054 static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00055 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00056 }; 00057 00058 /*! 00059 * AES computation context variable 00060 */ 00061 static aes_context AesContext; 00062 00063 /*! 00064 * CMAC computation context variable 00065 */ 00066 static AES_CMAC_CTX AesCmacCtx[1]; 00067 00068 /*! 00069 * \brief Computes the LoRaMAC frame MIC field 00070 * 00071 * \param [IN] buffer Data buffer 00072 * \param [IN] size Data buffer size 00073 * \param [IN] key AES key to be used 00074 * \param [IN] address Frame address 00075 * \param [IN] dir Frame direction [0: uplink, 1: downlink] 00076 * \param [IN] sequenceCounter Frame sequence counter 00077 * \param [OUT] mic Computed MIC field 00078 */ 00079 void LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic ) 00080 { 00081 MicBlockB0[5] = dir; 00082 00083 MicBlockB0[6] = ( address ) & 0xFF; 00084 MicBlockB0[7] = ( address >> 8 ) & 0xFF; 00085 MicBlockB0[8] = ( address >> 16 ) & 0xFF; 00086 MicBlockB0[9] = ( address >> 24 ) & 0xFF; 00087 00088 MicBlockB0[10] = ( sequenceCounter ) & 0xFF; 00089 MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF; 00090 MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF; 00091 MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF; 00092 00093 MicBlockB0[15] = size & 0xFF; 00094 00095 AES_CMAC_Init( AesCmacCtx ); 00096 00097 AES_CMAC_SetKey( AesCmacCtx, key ); 00098 00099 AES_CMAC_Update( AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE ); 00100 00101 AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF ); 00102 00103 AES_CMAC_Final( Mic, AesCmacCtx ); 00104 00105 *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); 00106 } 00107 00108 void LoRaMacPayloadEncrypt ( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *encBuffer ) 00109 { 00110 uint16_t i; 00111 uint8_t bufferIndex = 0; 00112 uint16_t ctr = 1; 00113 00114 memset1( AesContext.ksch, '\0', 240 ); 00115 aes_set_key( key, 16, &AesContext ); 00116 00117 aBlock[5] = dir; 00118 00119 aBlock[6] = ( address ) & 0xFF; 00120 aBlock[7] = ( address >> 8 ) & 0xFF; 00121 aBlock[8] = ( address >> 16 ) & 0xFF; 00122 aBlock[9] = ( address >> 24 ) & 0xFF; 00123 00124 aBlock[10] = ( sequenceCounter ) & 0xFF; 00125 aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF; 00126 aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF; 00127 aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF; 00128 00129 while( size >= 16 ) 00130 { 00131 aBlock[15] = ( ( ctr ) & 0xFF ); 00132 ctr++; 00133 aes_encrypt( aBlock, sBlock, &AesContext ); 00134 for( i = 0; i < 16; i++ ) 00135 { 00136 encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; 00137 } 00138 size -= 16; 00139 bufferIndex += 16; 00140 } 00141 00142 if( size > 0 ) 00143 { 00144 aBlock[15] = ( ( ctr ) & 0xFF ); 00145 aes_encrypt( aBlock, sBlock, &AesContext ); 00146 for( i = 0; i < size; i++ ) 00147 { 00148 encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i]; 00149 } 00150 } 00151 } 00152 00153 void LoRaMacPayloadDecrypt ( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint8_t *decBuffer ) 00154 { 00155 LoRaMacPayloadEncrypt ( buffer, size, key, address, dir, sequenceCounter, decBuffer ); 00156 } 00157 00158 void LoRaMacJoinComputeMic ( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic ) 00159 { 00160 AES_CMAC_Init( AesCmacCtx ); 00161 00162 AES_CMAC_SetKey( AesCmacCtx, key ); 00163 00164 AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF ); 00165 00166 AES_CMAC_Final( Mic, AesCmacCtx ); 00167 00168 *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] ); 00169 } 00170 00171 void LoRaMacJoinDecrypt ( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer ) 00172 { 00173 memset1( AesContext.ksch, '\0', 240 ); 00174 aes_set_key( key, 16, &AesContext ); 00175 aes_encrypt( buffer, decBuffer, &AesContext ); 00176 // Check if optional CFList is included 00177 if( size >= 16 ) 00178 { 00179 aes_encrypt( buffer + 16, decBuffer + 16, &AesContext ); 00180 } 00181 } 00182 00183 void LoRaMacJoinComputeSKeys ( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey ) 00184 { 00185 uint8_t nonce[16]; 00186 uint8_t *pDevNonce = ( uint8_t * )&devNonce; 00187 00188 memset1( AesContext.ksch, '\0', 240 ); 00189 aes_set_key( key, 16, &AesContext ); 00190 00191 memset1( nonce, 0, sizeof( nonce ) ); 00192 nonce[0] = 0x01; 00193 memcpy1( nonce + 1, appNonce, 6 ); 00194 memcpy1( nonce + 7, pDevNonce, 2 ); 00195 aes_encrypt( nonce, nwkSKey, &AesContext ); 00196 00197 memset1( nonce, 0, sizeof( nonce ) ); 00198 nonce[0] = 0x02; 00199 memcpy1( nonce + 1, appNonce, 6 ); 00200 memcpy1( nonce + 7, pDevNonce, 2 ); 00201 aes_encrypt( nonce, appSKey, &AesContext ); 00202 }
Generated on Tue Jul 12 2022 14:27:11 by 1.7.2