Forked LoRaWAN-lib for Legacy Gateway testing

Fork of LoRaWAN-lib by Miguel Luis

Committer:
mluis
Date:
Tue Jan 05 16:41:54 2016 +0000
Revision:
2:14a5d6ad92d5
Parent:
1:91e4e6c60d1e
Synchronized with https://github.com/Lora-net/LoRaMac-node git revision a2226468d470eceb251338e1acfb24cfd121effa

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:91d1a7783bb9 1 /*
mluis 0:91d1a7783bb9 2 / _____) _ | |
mluis 0:91d1a7783bb9 3 ( (____ _____ ____ _| |_ _____ ____| |__
mluis 0:91d1a7783bb9 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
mluis 0:91d1a7783bb9 5 _____) ) ____| | | || |_| ____( (___| | | |
mluis 0:91d1a7783bb9 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mluis 0:91d1a7783bb9 7 (C)2013 Semtech
mluis 2:14a5d6ad92d5 8 ___ _____ _ ___ _ _____ ___ ___ ___ ___
mluis 2:14a5d6ad92d5 9 / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
mluis 2:14a5d6ad92d5 10 \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
mluis 2:14a5d6ad92d5 11 |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
mluis 2:14a5d6ad92d5 12 embedded.connectivity.solutions===============
mluis 0:91d1a7783bb9 13
mluis 0:91d1a7783bb9 14 Description: LoRa MAC layer implementation
mluis 0:91d1a7783bb9 15
mluis 0:91d1a7783bb9 16 License: Revised BSD License, see LICENSE.TXT file include in the project
mluis 0:91d1a7783bb9 17
mluis 2:14a5d6ad92d5 18 Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jäckle ( STACKFORCE )
mluis 0:91d1a7783bb9 19 */
mluis 1:91e4e6c60d1e 20 #include <stdlib.h>
mluis 1:91e4e6c60d1e 21 #include <stdint.h>
mluis 0:91d1a7783bb9 22 #include "utilities.h"
mluis 0:91d1a7783bb9 23
mluis 0:91d1a7783bb9 24 #include "aes.h"
mluis 0:91d1a7783bb9 25 #include "cmac.h"
mluis 0:91d1a7783bb9 26
mluis 0:91d1a7783bb9 27 #include "LoRaMacCrypto.h"
mluis 0:91d1a7783bb9 28
mluis 0:91d1a7783bb9 29 /*!
mluis 0:91d1a7783bb9 30 * CMAC/AES Message Integrity Code (MIC) Block B0 size
mluis 0:91d1a7783bb9 31 */
mluis 0:91d1a7783bb9 32 #define LORAMAC_MIC_BLOCK_B0_SIZE 16
mluis 0:91d1a7783bb9 33
mluis 0:91d1a7783bb9 34 /*!
mluis 0:91d1a7783bb9 35 * MIC field computation initial data
mluis 0:91d1a7783bb9 36 */
mluis 0:91d1a7783bb9 37 static uint8_t MicBlockB0[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mluis 0:91d1a7783bb9 38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:91d1a7783bb9 39 };
mluis 0:91d1a7783bb9 40
mluis 0:91d1a7783bb9 41 /*!
mluis 0:91d1a7783bb9 42 * Contains the computed MIC field.
mluis 0:91d1a7783bb9 43 *
mluis 0:91d1a7783bb9 44 * \remark Only the 4 first bytes are used
mluis 0:91d1a7783bb9 45 */
mluis 0:91d1a7783bb9 46 static uint8_t Mic[16];
mluis 0:91d1a7783bb9 47
mluis 0:91d1a7783bb9 48 /*!
mluis 0:91d1a7783bb9 49 * Encryption aBlock and sBlock
mluis 0:91d1a7783bb9 50 */
mluis 0:91d1a7783bb9 51 static uint8_t aBlock[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mluis 0:91d1a7783bb9 52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:91d1a7783bb9 53 };
mluis 0:91d1a7783bb9 54 static uint8_t sBlock[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mluis 0:91d1a7783bb9 55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
mluis 0:91d1a7783bb9 56 };
mluis 0:91d1a7783bb9 57
mluis 0:91d1a7783bb9 58 /*!
mluis 0:91d1a7783bb9 59 * AES computation context variable
mluis 0:91d1a7783bb9 60 */
mluis 0:91d1a7783bb9 61 static aes_context AesContext;
mluis 1:91e4e6c60d1e 62
mluis 0:91d1a7783bb9 63 /*!
mluis 0:91d1a7783bb9 64 * CMAC computation context variable
mluis 0:91d1a7783bb9 65 */
mluis 0:91d1a7783bb9 66 static AES_CMAC_CTX AesCmacCtx[1];
mluis 0:91d1a7783bb9 67
mluis 0:91d1a7783bb9 68 /*!
mluis 0:91d1a7783bb9 69 * \brief Computes the LoRaMAC frame MIC field
mluis 0:91d1a7783bb9 70 *
mluis 0:91d1a7783bb9 71 * \param [IN] buffer Data buffer
mluis 0:91d1a7783bb9 72 * \param [IN] size Data buffer size
mluis 0:91d1a7783bb9 73 * \param [IN] key AES key to be used
mluis 0:91d1a7783bb9 74 * \param [IN] address Frame address
mluis 0:91d1a7783bb9 75 * \param [IN] dir Frame direction [0: uplink, 1: downlink]
mluis 0:91d1a7783bb9 76 * \param [IN] sequenceCounter Frame sequence counter
mluis 0:91d1a7783bb9 77 * \param [OUT] mic Computed MIC field
mluis 0:91d1a7783bb9 78 */
mluis 0:91d1a7783bb9 79 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 )
mluis 0:91d1a7783bb9 80 {
mluis 0:91d1a7783bb9 81 MicBlockB0[5] = dir;
mluis 0:91d1a7783bb9 82
mluis 0:91d1a7783bb9 83 MicBlockB0[6] = ( address ) & 0xFF;
mluis 0:91d1a7783bb9 84 MicBlockB0[7] = ( address >> 8 ) & 0xFF;
mluis 0:91d1a7783bb9 85 MicBlockB0[8] = ( address >> 16 ) & 0xFF;
mluis 0:91d1a7783bb9 86 MicBlockB0[9] = ( address >> 24 ) & 0xFF;
mluis 0:91d1a7783bb9 87
mluis 0:91d1a7783bb9 88 MicBlockB0[10] = ( sequenceCounter ) & 0xFF;
mluis 0:91d1a7783bb9 89 MicBlockB0[11] = ( sequenceCounter >> 8 ) & 0xFF;
mluis 0:91d1a7783bb9 90 MicBlockB0[12] = ( sequenceCounter >> 16 ) & 0xFF;
mluis 0:91d1a7783bb9 91 MicBlockB0[13] = ( sequenceCounter >> 24 ) & 0xFF;
mluis 0:91d1a7783bb9 92
mluis 0:91d1a7783bb9 93 MicBlockB0[15] = size & 0xFF;
mluis 0:91d1a7783bb9 94
mluis 0:91d1a7783bb9 95 AES_CMAC_Init( AesCmacCtx );
mluis 0:91d1a7783bb9 96
mluis 0:91d1a7783bb9 97 AES_CMAC_SetKey( AesCmacCtx, key );
mluis 0:91d1a7783bb9 98
mluis 0:91d1a7783bb9 99 AES_CMAC_Update( AesCmacCtx, MicBlockB0, LORAMAC_MIC_BLOCK_B0_SIZE );
mluis 0:91d1a7783bb9 100
mluis 0:91d1a7783bb9 101 AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF );
mluis 0:91d1a7783bb9 102
mluis 0:91d1a7783bb9 103 AES_CMAC_Final( Mic, AesCmacCtx );
mluis 0:91d1a7783bb9 104
mluis 0:91d1a7783bb9 105 *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
mluis 0:91d1a7783bb9 106 }
mluis 0:91d1a7783bb9 107
mluis 0:91d1a7783bb9 108 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 )
mluis 0:91d1a7783bb9 109 {
mluis 0:91d1a7783bb9 110 uint16_t i;
mluis 0:91d1a7783bb9 111 uint8_t bufferIndex = 0;
mluis 0:91d1a7783bb9 112 uint16_t ctr = 1;
mluis 0:91d1a7783bb9 113
mluis 0:91d1a7783bb9 114 memset1( AesContext.ksch, '\0', 240 );
mluis 0:91d1a7783bb9 115 aes_set_key( key, 16, &AesContext );
mluis 0:91d1a7783bb9 116
mluis 0:91d1a7783bb9 117 aBlock[5] = dir;
mluis 0:91d1a7783bb9 118
mluis 0:91d1a7783bb9 119 aBlock[6] = ( address ) & 0xFF;
mluis 0:91d1a7783bb9 120 aBlock[7] = ( address >> 8 ) & 0xFF;
mluis 0:91d1a7783bb9 121 aBlock[8] = ( address >> 16 ) & 0xFF;
mluis 0:91d1a7783bb9 122 aBlock[9] = ( address >> 24 ) & 0xFF;
mluis 0:91d1a7783bb9 123
mluis 0:91d1a7783bb9 124 aBlock[10] = ( sequenceCounter ) & 0xFF;
mluis 0:91d1a7783bb9 125 aBlock[11] = ( sequenceCounter >> 8 ) & 0xFF;
mluis 0:91d1a7783bb9 126 aBlock[12] = ( sequenceCounter >> 16 ) & 0xFF;
mluis 0:91d1a7783bb9 127 aBlock[13] = ( sequenceCounter >> 24 ) & 0xFF;
mluis 0:91d1a7783bb9 128
mluis 0:91d1a7783bb9 129 while( size >= 16 )
mluis 0:91d1a7783bb9 130 {
mluis 0:91d1a7783bb9 131 aBlock[15] = ( ( ctr ) & 0xFF );
mluis 0:91d1a7783bb9 132 ctr++;
mluis 0:91d1a7783bb9 133 aes_encrypt( aBlock, sBlock, &AesContext );
mluis 0:91d1a7783bb9 134 for( i = 0; i < 16; i++ )
mluis 0:91d1a7783bb9 135 {
mluis 0:91d1a7783bb9 136 encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
mluis 0:91d1a7783bb9 137 }
mluis 0:91d1a7783bb9 138 size -= 16;
mluis 0:91d1a7783bb9 139 bufferIndex += 16;
mluis 0:91d1a7783bb9 140 }
mluis 0:91d1a7783bb9 141
mluis 0:91d1a7783bb9 142 if( size > 0 )
mluis 0:91d1a7783bb9 143 {
mluis 0:91d1a7783bb9 144 aBlock[15] = ( ( ctr ) & 0xFF );
mluis 0:91d1a7783bb9 145 aes_encrypt( aBlock, sBlock, &AesContext );
mluis 0:91d1a7783bb9 146 for( i = 0; i < size; i++ )
mluis 0:91d1a7783bb9 147 {
mluis 0:91d1a7783bb9 148 encBuffer[bufferIndex + i] = buffer[bufferIndex + i] ^ sBlock[i];
mluis 0:91d1a7783bb9 149 }
mluis 0:91d1a7783bb9 150 }
mluis 0:91d1a7783bb9 151 }
mluis 0:91d1a7783bb9 152
mluis 0:91d1a7783bb9 153 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 )
mluis 0:91d1a7783bb9 154 {
mluis 0:91d1a7783bb9 155 LoRaMacPayloadEncrypt( buffer, size, key, address, dir, sequenceCounter, decBuffer );
mluis 0:91d1a7783bb9 156 }
mluis 0:91d1a7783bb9 157
mluis 0:91d1a7783bb9 158 void LoRaMacJoinComputeMic( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint32_t *mic )
mluis 0:91d1a7783bb9 159 {
mluis 0:91d1a7783bb9 160 AES_CMAC_Init( AesCmacCtx );
mluis 0:91d1a7783bb9 161
mluis 0:91d1a7783bb9 162 AES_CMAC_SetKey( AesCmacCtx, key );
mluis 0:91d1a7783bb9 163
mluis 0:91d1a7783bb9 164 AES_CMAC_Update( AesCmacCtx, buffer, size & 0xFF );
mluis 0:91d1a7783bb9 165
mluis 0:91d1a7783bb9 166 AES_CMAC_Final( Mic, AesCmacCtx );
mluis 0:91d1a7783bb9 167
mluis 0:91d1a7783bb9 168 *mic = ( uint32_t )( ( uint32_t )Mic[3] << 24 | ( uint32_t )Mic[2] << 16 | ( uint32_t )Mic[1] << 8 | ( uint32_t )Mic[0] );
mluis 0:91d1a7783bb9 169 }
mluis 0:91d1a7783bb9 170
mluis 0:91d1a7783bb9 171 void LoRaMacJoinDecrypt( const uint8_t *buffer, uint16_t size, const uint8_t *key, uint8_t *decBuffer )
mluis 0:91d1a7783bb9 172 {
mluis 0:91d1a7783bb9 173 memset1( AesContext.ksch, '\0', 240 );
mluis 0:91d1a7783bb9 174 aes_set_key( key, 16, &AesContext );
mluis 0:91d1a7783bb9 175 aes_encrypt( buffer, decBuffer, &AesContext );
mluis 0:91d1a7783bb9 176 // Check if optional CFList is included
mluis 0:91d1a7783bb9 177 if( size >= 16 )
mluis 0:91d1a7783bb9 178 {
mluis 0:91d1a7783bb9 179 aes_encrypt( buffer + 16, decBuffer + 16, &AesContext );
mluis 0:91d1a7783bb9 180 }
mluis 0:91d1a7783bb9 181 }
mluis 0:91d1a7783bb9 182
mluis 0:91d1a7783bb9 183 void LoRaMacJoinComputeSKeys( const uint8_t *key, const uint8_t *appNonce, uint16_t devNonce, uint8_t *nwkSKey, uint8_t *appSKey )
mluis 0:91d1a7783bb9 184 {
mluis 0:91d1a7783bb9 185 uint8_t nonce[16];
mluis 0:91d1a7783bb9 186 uint8_t *pDevNonce = ( uint8_t * )&devNonce;
mluis 0:91d1a7783bb9 187
mluis 0:91d1a7783bb9 188 memset1( AesContext.ksch, '\0', 240 );
mluis 0:91d1a7783bb9 189 aes_set_key( key, 16, &AesContext );
mluis 0:91d1a7783bb9 190
mluis 0:91d1a7783bb9 191 memset1( nonce, 0, sizeof( nonce ) );
mluis 0:91d1a7783bb9 192 nonce[0] = 0x01;
mluis 2:14a5d6ad92d5 193 memcpy1( nonce + 1, appNonce, 6 );
mluis 2:14a5d6ad92d5 194 memcpy1( nonce + 7, pDevNonce, 2 );
mluis 0:91d1a7783bb9 195 aes_encrypt( nonce, nwkSKey, &AesContext );
mluis 0:91d1a7783bb9 196
mluis 0:91d1a7783bb9 197 memset1( nonce, 0, sizeof( nonce ) );
mluis 0:91d1a7783bb9 198 nonce[0] = 0x02;
mluis 2:14a5d6ad92d5 199 memcpy1( nonce + 1, appNonce, 6 );
mluis 2:14a5d6ad92d5 200 memcpy1( nonce + 7, pDevNonce, 2 );
mluis 0:91d1a7783bb9 201 aes_encrypt( nonce, appSKey, &AesContext );
mluis 0:91d1a7783bb9 202 }