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 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 19:00:53 by
