Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
LoRaMacCrypto.cpp
00001 /** 00002 * / _____) _ | | 00003 * ( (____ _____ ____ _| |_ _____ ____| |__ 00004 * \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 * _____) ) ____| | | || |_| ____( (___| | | | 00006 * (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 * (C)2013 Semtech 00008 * ___ _____ _ ___ _ _____ ___ ___ ___ ___ 00009 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __| 00010 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _| 00011 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___| 00012 * embedded.connectivity.solutions=============== 00013 * 00014 * Description: LoRa MAC crypto implementation 00015 * 00016 * License: Revised BSD License, see LICENSE.TXT file include in the project 00017 * 00018 * Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jäckle ( STACKFORCE ) 00019 * 00020 * 00021 * Copyright (c) 2017, Arm Limited and affiliates. 00022 * 00023 * SPDX-License-Identifier: BSD-3-Clause 00024 */ 00025 00026 #include <stdlib.h> 00027 #include <stdint.h> 00028 00029 #include "mbedtls/aes.h" 00030 #include "mbedtls/cmac.h" 00031 00032 #include "LoRaMacCrypto.h" 00033 #include "system/lorawan_data_structures.h" 00034 00035 00036 #if defined(MBEDTLS_CMAC_C) && defined(MBEDTLS_AES_C) && defined(MBEDTLS_CIPHER_C) 00037 00038 /** 00039 * CMAC/AES Message Integrity Code (MIC) Block B0 size 00040 */ 00041 #define LORAMAC_MIC_BLOCK_B0_SIZE 16 00042 00043 /** 00044 * MIC field computation initial data 00045 */ 00046 static uint8_t mic_block_b0[] = {0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00047 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00048 00049 /** 00050 * Contains the computed MIC field. 00051 * 00052 * \remark Only the 4 first bytes are used 00053 */ 00054 static uint8_t computed_mic[16]; 00055 00056 /** 00057 * Encryption aBlock and sBlock 00058 */ 00059 static uint8_t a_block[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00060 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00061 00062 static uint8_t s_block[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00064 00065 /** 00066 * AES computation context variable 00067 */ 00068 static mbedtls_aes_context aes_ctx; 00069 00070 /** 00071 * CMAC computation context variable 00072 */ 00073 static mbedtls_cipher_context_t aes_cmac_ctx[1]; 00074 00075 #define AES_CMAC_KEY_LENGTH 16 00076 00077 int compute_mic(const uint8_t *buffer, uint16_t size, const uint8_t *key, 00078 uint32_t address, uint8_t dir, uint32_t seq_counter, 00079 uint32_t *mic) 00080 { 00081 00082 int ret = 0; 00083 00084 mic_block_b0[5] = dir; 00085 00086 mic_block_b0[6] = (address) & 0xFF; 00087 mic_block_b0[7] = (address >> 8) & 0xFF; 00088 mic_block_b0[8] = (address >> 16) & 0xFF; 00089 mic_block_b0[9] = (address >> 24) & 0xFF; 00090 00091 mic_block_b0[10] = (seq_counter) & 0xFF; 00092 mic_block_b0[11] = (seq_counter >> 8) & 0xFF; 00093 mic_block_b0[12] = (seq_counter >> 16) & 0xFF; 00094 mic_block_b0[13] = (seq_counter >> 24) & 0xFF; 00095 00096 mic_block_b0[15] = size & 0xFF; 00097 00098 mbedtls_cipher_init(aes_cmac_ctx); 00099 00100 const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); 00101 00102 if (NULL != cipher_info) { 00103 ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info); 00104 if (0 != ret) 00105 goto exit; 00106 00107 ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, 00108 AES_CMAC_KEY_LENGTH * 8); 00109 if (0 != ret) 00110 goto exit; 00111 00112 ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0, 00113 LORAMAC_MIC_BLOCK_B0_SIZE); 00114 if (0 != ret) 00115 goto exit; 00116 00117 ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF); 00118 if (0 != ret) 00119 goto exit; 00120 00121 ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic); 00122 if (0 != ret) 00123 goto exit; 00124 00125 *mic = (uint32_t) ((uint32_t) computed_mic[3] << 24 00126 | (uint32_t) computed_mic[2] << 16 00127 | (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]); 00128 } else { 00129 ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED; 00130 } 00131 00132 exit: mbedtls_cipher_free(aes_cmac_ctx); 00133 return ret; 00134 } 00135 00136 int encrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key, 00137 uint32_t address, uint8_t dir, uint32_t seq_counter, 00138 uint8_t *enc_buffer) 00139 { 00140 uint16_t i; 00141 uint8_t bufferIndex = 0; 00142 uint16_t ctr = 1; 00143 int ret = 0; 00144 00145 mbedtls_aes_init(&aes_ctx); 00146 ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8); 00147 if (0 != ret) 00148 goto exit; 00149 00150 a_block[5] = dir; 00151 00152 a_block[6] = (address) & 0xFF; 00153 a_block[7] = (address >> 8) & 0xFF; 00154 a_block[8] = (address >> 16) & 0xFF; 00155 a_block[9] = (address >> 24) & 0xFF; 00156 00157 a_block[10] = (seq_counter) & 0xFF; 00158 a_block[11] = (seq_counter >> 8) & 0xFF; 00159 a_block[12] = (seq_counter >> 16) & 0xFF; 00160 a_block[13] = (seq_counter >> 24) & 0xFF; 00161 00162 while (size >= 16) { 00163 a_block[15] = ((ctr) & 0xFF); 00164 ctr++; 00165 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block, 00166 s_block); 00167 if (0 != ret) 00168 goto exit; 00169 00170 for (i = 0; i < 16; i++) { 00171 enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i]; 00172 } 00173 size -= 16; 00174 bufferIndex += 16; 00175 } 00176 00177 if (size > 0) { 00178 a_block[15] = ((ctr) & 0xFF); 00179 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block, 00180 s_block); 00181 if (0 != ret) 00182 goto exit; 00183 00184 for (i = 0; i < size; i++) { 00185 enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i]; 00186 } 00187 } 00188 00189 exit: mbedtls_aes_free(&aes_ctx); 00190 return ret; 00191 } 00192 00193 int decrypt_payload(const uint8_t *buffer, uint16_t size, const uint8_t *key, 00194 uint32_t address, uint8_t dir, uint32_t seq_counter, 00195 uint8_t *dec_buffer) 00196 { 00197 return encrypt_payload(buffer, size, key, address, dir, seq_counter, 00198 dec_buffer); 00199 } 00200 00201 int compute_join_frame_mic(const uint8_t *buffer, uint16_t size, 00202 const uint8_t *key, uint32_t *mic) 00203 { 00204 int ret = 0; 00205 00206 mbedtls_cipher_init(aes_cmac_ctx); 00207 const mbedtls_cipher_info_t* cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); 00208 00209 if (NULL != cipher_info) { 00210 ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info); 00211 if (0 != ret) 00212 goto exit; 00213 00214 ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, 00215 AES_CMAC_KEY_LENGTH * 8); 00216 if (0 != ret) 00217 goto exit; 00218 00219 ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF); 00220 if (0 != ret) 00221 goto exit; 00222 00223 ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic); 00224 if (0 != ret) 00225 goto exit; 00226 00227 *mic = (uint32_t) ((uint32_t) computed_mic[3] << 24 00228 | (uint32_t) computed_mic[2] << 16 00229 | (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]); 00230 } else { 00231 ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED; 00232 } 00233 00234 exit: mbedtls_cipher_free(aes_cmac_ctx); 00235 return ret; 00236 } 00237 00238 int decrypt_join_frame(const uint8_t *buffer, uint16_t size, const uint8_t *key, 00239 uint8_t *dec_buffer) 00240 { 00241 int ret = 0; 00242 00243 mbedtls_aes_init(&aes_ctx); 00244 00245 ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8); 00246 if (0 != ret) 00247 goto exit; 00248 00249 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer, 00250 dec_buffer); 00251 if (0 != ret) 00252 goto exit; 00253 00254 // Check if optional CFList is included 00255 if (size >= 16) { 00256 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer + 16, 00257 dec_buffer + 16); 00258 } 00259 00260 exit: mbedtls_aes_free(&aes_ctx); 00261 return ret; 00262 } 00263 00264 int compute_skeys_for_join_frame(const uint8_t *key, const uint8_t *app_nonce, 00265 uint16_t dev_nonce, uint8_t *nwk_skey, 00266 uint8_t *app_skey) 00267 { 00268 uint8_t nonce[16]; 00269 uint8_t *p_dev_nonce = (uint8_t *) &dev_nonce; 00270 int ret = 0; 00271 00272 mbedtls_aes_init(&aes_ctx); 00273 00274 ret = mbedtls_aes_setkey_enc(&aes_ctx, key, 16 * 8); 00275 if (0 != ret) 00276 goto exit; 00277 00278 memset(nonce, 0, sizeof(nonce)); 00279 nonce[0] = 0x01; 00280 memcpy(nonce + 1, app_nonce, 6); 00281 memcpy(nonce + 7, p_dev_nonce, 2); 00282 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, nwk_skey); 00283 if (0 != ret) 00284 goto exit; 00285 00286 memset(nonce, 0, sizeof(nonce)); 00287 nonce[0] = 0x02; 00288 memcpy(nonce + 1, app_nonce, 6); 00289 memcpy(nonce + 7, p_dev_nonce, 2); 00290 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, app_skey); 00291 00292 exit: mbedtls_aes_free(&aes_ctx); 00293 return ret; 00294 } 00295 #else 00296 00297 // If mbedTLS is not configured properly, these dummies will ensure that 00298 // user knows what is wrong and in addition to that these ensure that 00299 // Mbed-OS compiles properly under normal conditions where LoRaWAN in conjunction 00300 // with mbedTLS is not being used. 00301 int compute_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t, 00302 uint8_t dir, uint32_t, uint32_t *) 00303 { 00304 MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00305 00306 // Never actually reaches here 00307 return LORAWAN_STATUS_CRYPTO_FAIL; 00308 } 00309 00310 int encrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t, 00311 uint8_t , uint32_t , uint8_t *) 00312 { 00313 MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00314 00315 // Never actually reaches here 00316 return LORAWAN_STATUS_CRYPTO_FAIL; 00317 } 00318 00319 int decrypt_payload(const uint8_t *, uint16_t , const uint8_t *, uint32_t, 00320 uint8_t , uint32_t , uint8_t *) 00321 { 00322 MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00323 00324 // Never actually reaches here 00325 return LORAWAN_STATUS_CRYPTO_FAIL; 00326 } 00327 00328 int compute_join_frame_mic(const uint8_t *, uint16_t , const uint8_t *, uint32_t *) 00329 { 00330 MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00331 00332 // Never actually reaches here 00333 return LORAWAN_STATUS_CRYPTO_FAIL; 00334 } 00335 00336 int decrypt_join_frame(const uint8_t *, uint16_t , const uint8_t *, uint8_t *) 00337 { 00338 MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00339 00340 // Never actually reaches here 00341 return LORAWAN_STATUS_CRYPTO_FAIL; 00342 } 00343 00344 int compute_skeys_for_join_frame(const uint8_t *, const uint8_t *, uint16_t , 00345 uint8_t *, uint8_t *) 00346 { 00347 MBED_ASSERT("[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00348 00349 // Never actually reaches here 00350 return LORAWAN_STATUS_CRYPTO_FAIL; 00351 } 00352 00353 #endif
Generated on Tue Jul 12 2022 15:17:25 by
1.7.2