Forked LoRaWAN-lib for Legacy Gateway testing

Fork of LoRaWAN-lib by Miguel Luis

Committer:
mluis
Date:
Mon Nov 23 10:09:43 2015 +0000
Revision:
1:91e4e6c60d1e
Parent:
0:91d1a7783bb9
Child:
2:14a5d6ad92d5
Keep LoRaMac only related files in the library.; Updated files according to latest GitHub version

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