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