end node on synchronous star LoRa network.

Dependencies:   SX127x sx12xx_hal TSL2561

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMacCrypto.cpp Source File

LoRaMacCrypto.cpp

00001 /* */
00002 
00003 #include <stdlib.h>
00004 #include <stdint.h>
00005 #include "utilities.h"
00006 
00007 #include "cmac.h"
00008 #include "aes.h"
00009 
00010 #include "LoRaMacCrypto.h"
00011 
00012 /*!
00013  * CMAC/AES Message Integrity Code (MIC) Block B0 size
00014  */
00015 #define LORAMAC_MIC_BLOCK_B0_SIZE                   16
00016 
00017 /*!
00018  * MIC field computation initial data
00019  */
00020 static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00021                                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00022                               };
00023 
00024 /*!
00025  * Contains the computed MIC field.
00026  *
00027  * \remark Only the 4 first bytes are used
00028  */
00029 static uint8_t Mic[16];
00030 
00031 /*!
00032  * Encryption aBlock and sBlock
00033  */
00034 static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00035                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00036                           };
00037 static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00038                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00039                           };
00040 
00041 static mbedtls_cipher_context_t ctx;
00042 
00043 /*!
00044  * \brief Computes the LoRaMAC frame MIC field  
00045  *
00046  * \param [IN]  buffer          Data buffer
00047  * \param [IN]  size            Data buffer size
00048  * \param [IN]  key             AES key to be used
00049  * \param [IN]  address         Frame address
00050  * \param [IN]  dir             Frame direction [0: uplink, 1: downlink]
00051  * \param [IN]  sequenceCounter Frame sequence counter
00052  * \param [OUT] mic Computed MIC field
00053  */
00054 int LoRaMacComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t address, uint8_t dir, uint32_t sequenceCounter, uint32_t *mic )
00055 {
00056     //tls_printf("LoRaMacComputeMic:\r\n");
00057     MicBlockB0[5] = dir;
00058     
00059     MicBlockB0[6] = ( address ) & 0xFF;
00060     MicBlockB0[7] = ( address >> 8 ) & 0xFF;
00061     MicBlockB0[8] = ( address >> 16 ) & 0xFF;
00062     MicBlockB0[9] = ( address >> 24 ) & 0xFF;
00063 
00064     MicBlockB0[10] = ( sequenceCounter ) & 0xFF;
00065     MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF;
00066     MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF;
00067     MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF;
00068 
00069     MicBlockB0[15] = size & 0xFF;
00070 
00071     if (mbedtls_cipher_cmac_starts(&ctx, key, 128))
00072         return -1;
00073  
00074     mbedtls_cipher_cmac_update(&ctx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE);
00075  
00076     mbedtls_cipher_cmac_update(&ctx, buffer, size & 0xff);
00077  
00078     mbedtls_cipher_cmac_finish(&ctx, Mic);
00079     *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
00080     return 0;
00081 }
00082 
00083 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 )
00084 {
00085     mbedtls_aes_context actx;
00086     uint16_t i;
00087     uint8_t bufferIndex = 0;
00088     uint16_t ctr = 1;
00089 
00090     mbedtls_aes_init(&actx);
00091     mbedtls_aes_setkey_enc(&actx, key, 128);
00092 
00093     aBlock[5] = dir;
00094 
00095     aBlock[6] = ( address ) & 0xFF;
00096     aBlock[7] = ( address >> 8 ) & 0xFF;
00097     aBlock[8] = ( address >> 16 ) & 0xFF;
00098     aBlock[9] = ( address >> 24 ) & 0xFF;
00099 
00100     aBlock[10] = ( sequenceCounter ) & 0xFF;
00101     aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF;
00102     aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF;
00103     aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF;
00104 
00105     while( size >= 16 )
00106     {
00107         aBlock[15] = ( ( ctr ) & 0xFF );
00108         ctr++;
00109         mbedtls_aes_encrypt(&actx, aBlock, sBlock);
00110         for( i = 0; i < 16; i++ )
00111         {
00112             encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
00113         }
00114         size -= 16;
00115         bufferIndex += 16;
00116     }
00117 
00118     if (size > 0)
00119     {
00120         aBlock[15] = ( ( ctr ) & 0xFF );
00121         mbedtls_aes_encrypt(&actx, aBlock, sBlock);
00122         for( i = 0; i < size; i++ )
00123         {
00124             encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
00125         }
00126     }
00127 
00128     mbedtls_aes_free(&actx);
00129 }
00130 
00131 void LoRaMacPayloadDecrypt (
00132         const uint8_t *buffer,
00133         uint16_t size,
00134         const uint8_t *key,
00135         uint32_t address,
00136         uint8_t dir,
00137         uint32_t sequenceCounter,
00138         uint8_t *decBuffer )
00139 {
00140     LoRaMacPayloadEncrypt ( buffer, size, key, address, dir, sequenceCounter, decBuffer );
00141 }
00142 
00143 int LoRaMacJoinComputeMic ( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic )
00144 {
00145     int ret;
00146     uint8_t Mic[16];
00147     ret = mbedtls_cipher_cmac_starts(&ctx, key, 128);
00148     if (ret < 0)
00149         return ret;
00150     ret = mbedtls_cipher_cmac_update(&ctx, buffer, size & 0xff);
00151     if (ret < 0)
00152         return ret;
00153     ret = mbedtls_cipher_cmac_finish(&ctx, Mic);
00154     if (ret < 0)
00155         return ret;
00156     *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
00157     return 0; 
00158 }
00159 
00160 int LoRaMacJoinDecrypt ( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer )
00161 {
00162     int ret;
00163     mbedtls_aes_context actx;
00164 
00165     mbedtls_aes_init(&actx);
00166     ret = mbedtls_aes_setkey_enc(&actx, key, 128);
00167     if (ret < 0)
00168         return -1;
00169 
00170     mbedtls_aes_encrypt(&actx, buffer, decBuffer);
00171 
00172     if (size >= 16) {
00173         mbedtls_aes_encrypt(&actx, buffer + 16, decBuffer + 16);
00174     }
00175 
00176     mbedtls_aes_free(&actx);
00177 
00178     return 0;
00179 }
00180 
00181 int LoRaMacJoinComputeSKeys ( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey )
00182 {
00183     mbedtls_aes_context actx;
00184     uint8_t nonce[16];
00185     uint8_t *pDevNonce = ( uint8_t * )&devNonce;
00186 
00187     mbedtls_aes_init(&actx);
00188     if (mbedtls_aes_setkey_enc(&actx, key, 128) < 0)
00189         return -1;
00190 
00191     memset1( nonce, 0, sizeof( nonce ) );
00192     nonce[0] = 0x01;
00193     memcpy1( nonce + 1, appNonce, 6 );
00194     memcpy1( nonce + 7, pDevNonce, 2 );
00195     mbedtls_aes_encrypt(&actx, nonce, nwkSKey);
00196 
00197     memset1( nonce, 0, sizeof( nonce ) );
00198     nonce[0] = 0x02;
00199     memcpy1( nonce + 1, appNonce, 6 );
00200     memcpy1( nonce + 7, pDevNonce, 2 );
00201     mbedtls_aes_encrypt(&actx, nonce, appSKey);
00202 
00203     mbedtls_aes_free(&actx);
00204 
00205     return 0;
00206 }
00207 
00208 int LoRaMacCryptoInit()
00209 {
00210     int ret;
00211     const mbedtls_cipher_info_t *cipher_info;
00212     mbedtls_cipher_init(&ctx);
00213     cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB );
00214     if (cipher_info == NULL) {
00215         return -1;
00216     }
00217     ret = mbedtls_cipher_setup(&ctx, cipher_info);
00218     return ret;
00219 }
00220