Espotel / Mbed 2 deprecated LoRaWAN_ELMO_TxRx_Template

Dependencies:   SX1272lib mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMacCrypto.cpp Source File

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 }