LoRaMacCrypto.c 6.4 KB

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