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