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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 "LoRaMacCrypto.h" 00030 #include "system/lorawan_data_structures.h" 00031 #include "mbedtls/platform.h" 00032 00033 00034 #if defined(MBEDTLS_CMAC_C) && defined(MBEDTLS_AES_C) && defined(MBEDTLS_CIPHER_C) 00035 00036 LoRaMacCrypto::LoRaMacCrypto() 00037 { 00038 #if defined(MBEDTLS_PLATFORM_C) 00039 int ret = mbedtls_platform_setup(NULL); 00040 if (ret != 0) { 00041 MBED_ASSERT(0 && "LoRaMacCrypto: Fail in mbedtls_platform_setup."); 00042 } 00043 #endif /* MBEDTLS_PLATFORM_C */ 00044 } 00045 00046 LoRaMacCrypto::~LoRaMacCrypto() 00047 { 00048 #if defined(MBEDTLS_PLATFORM_C) 00049 mbedtls_platform_teardown(NULL); 00050 #endif /* MBEDTLS_PLATFORM_C */ 00051 } 00052 00053 int LoRaMacCrypto::compute_mic(const uint8_t *buffer, uint16_t size, 00054 const uint8_t *key, const uint32_t key_length, 00055 uint32_t address, uint8_t dir, uint32_t seq_counter, 00056 uint32_t *mic) 00057 { 00058 uint8_t computed_mic[16] = {}; 00059 uint8_t mic_block_b0[16] = {}; 00060 int ret = 0; 00061 00062 mic_block_b0[0] = 0x49; 00063 00064 mic_block_b0[5] = dir; 00065 00066 mic_block_b0[6] = (address) & 0xFF; 00067 mic_block_b0[7] = (address >> 8) & 0xFF; 00068 mic_block_b0[8] = (address >> 16) & 0xFF; 00069 mic_block_b0[9] = (address >> 24) & 0xFF; 00070 00071 mic_block_b0[10] = (seq_counter) & 0xFF; 00072 mic_block_b0[11] = (seq_counter >> 8) & 0xFF; 00073 mic_block_b0[12] = (seq_counter >> 16) & 0xFF; 00074 mic_block_b0[13] = (seq_counter >> 24) & 0xFF; 00075 00076 mic_block_b0[15] = size & 0xFF; 00077 00078 mbedtls_cipher_init(aes_cmac_ctx); 00079 00080 const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); 00081 00082 if (NULL != cipher_info) { 00083 ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info); 00084 if (0 != ret) { 00085 goto exit; 00086 } 00087 00088 ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, key_length); 00089 if (0 != ret) { 00090 goto exit; 00091 } 00092 00093 ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, mic_block_b0, sizeof(mic_block_b0)); 00094 if (0 != ret) { 00095 goto exit; 00096 } 00097 00098 ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF); 00099 if (0 != ret) { 00100 goto exit; 00101 } 00102 00103 ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic); 00104 if (0 != ret) { 00105 goto exit; 00106 } 00107 00108 *mic = (uint32_t)((uint32_t) computed_mic[3] << 24 00109 | (uint32_t) computed_mic[2] << 16 00110 | (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]); 00111 } else { 00112 ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED; 00113 } 00114 00115 exit: 00116 mbedtls_cipher_free(aes_cmac_ctx); 00117 return ret; 00118 } 00119 00120 int LoRaMacCrypto::encrypt_payload(const uint8_t *buffer, uint16_t size, 00121 const uint8_t *key, const uint32_t key_length, 00122 uint32_t address, uint8_t dir, uint32_t seq_counter, 00123 uint8_t *enc_buffer) 00124 { 00125 uint16_t i; 00126 uint8_t bufferIndex = 0; 00127 uint16_t ctr = 1; 00128 int ret = 0; 00129 uint8_t a_block[16] = {}; 00130 uint8_t s_block[16] = {}; 00131 00132 mbedtls_aes_init(&aes_ctx); 00133 ret = mbedtls_aes_setkey_enc(&aes_ctx, key, key_length); 00134 if (0 != ret) { 00135 goto exit; 00136 } 00137 00138 a_block[0] = 0x01; 00139 a_block[5] = dir; 00140 00141 a_block[6] = (address) & 0xFF; 00142 a_block[7] = (address >> 8) & 0xFF; 00143 a_block[8] = (address >> 16) & 0xFF; 00144 a_block[9] = (address >> 24) & 0xFF; 00145 00146 a_block[10] = (seq_counter) & 0xFF; 00147 a_block[11] = (seq_counter >> 8) & 0xFF; 00148 a_block[12] = (seq_counter >> 16) & 0xFF; 00149 a_block[13] = (seq_counter >> 24) & 0xFF; 00150 00151 while (size >= 16) { 00152 a_block[15] = ((ctr) & 0xFF); 00153 ctr++; 00154 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block, 00155 s_block); 00156 if (0 != ret) { 00157 goto exit; 00158 } 00159 00160 for (i = 0; i < 16; i++) { 00161 enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i]; 00162 } 00163 size -= 16; 00164 bufferIndex += 16; 00165 } 00166 00167 if (size > 0) { 00168 a_block[15] = ((ctr) & 0xFF); 00169 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, a_block, 00170 s_block); 00171 if (0 != ret) { 00172 goto exit; 00173 } 00174 00175 for (i = 0; i < size; i++) { 00176 enc_buffer[bufferIndex + i] = buffer[bufferIndex + i] ^ s_block[i]; 00177 } 00178 } 00179 00180 exit: 00181 mbedtls_aes_free(&aes_ctx); 00182 return ret; 00183 } 00184 00185 int LoRaMacCrypto::decrypt_payload(const uint8_t *buffer, uint16_t size, 00186 const uint8_t *key, uint32_t key_length, 00187 uint32_t address, uint8_t dir, uint32_t seq_counter, 00188 uint8_t *dec_buffer) 00189 { 00190 return encrypt_payload(buffer, size, key, key_length, address, dir, seq_counter, 00191 dec_buffer); 00192 } 00193 00194 int LoRaMacCrypto::compute_join_frame_mic(const uint8_t *buffer, uint16_t size, 00195 const uint8_t *key, uint32_t key_length, 00196 uint32_t *mic) 00197 { 00198 uint8_t computed_mic[16] = {}; 00199 int ret = 0; 00200 00201 mbedtls_cipher_init(aes_cmac_ctx); 00202 const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); 00203 00204 if (NULL != cipher_info) { 00205 ret = mbedtls_cipher_setup(aes_cmac_ctx, cipher_info); 00206 if (0 != ret) { 00207 goto exit; 00208 } 00209 00210 ret = mbedtls_cipher_cmac_starts(aes_cmac_ctx, key, key_length); 00211 if (0 != ret) { 00212 goto exit; 00213 } 00214 00215 ret = mbedtls_cipher_cmac_update(aes_cmac_ctx, buffer, size & 0xFF); 00216 if (0 != ret) { 00217 goto exit; 00218 } 00219 00220 ret = mbedtls_cipher_cmac_finish(aes_cmac_ctx, computed_mic); 00221 if (0 != ret) { 00222 goto exit; 00223 } 00224 00225 *mic = (uint32_t)((uint32_t) computed_mic[3] << 24 00226 | (uint32_t) computed_mic[2] << 16 00227 | (uint32_t) computed_mic[1] << 8 | (uint32_t) computed_mic[0]); 00228 } else { 00229 ret = MBEDTLS_ERR_CIPHER_ALLOC_FAILED; 00230 } 00231 00232 exit: 00233 mbedtls_cipher_free(aes_cmac_ctx); 00234 return ret; 00235 } 00236 00237 int LoRaMacCrypto::decrypt_join_frame(const uint8_t *buffer, uint16_t size, 00238 const uint8_t *key, uint32_t key_length, 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, key_length); 00246 if (0 != ret) { 00247 goto exit; 00248 } 00249 00250 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer, 00251 dec_buffer); 00252 if (0 != ret) { 00253 goto exit; 00254 } 00255 00256 // Check if optional CFList is included 00257 if (size >= 16) { 00258 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, buffer + 16, 00259 dec_buffer + 16); 00260 } 00261 00262 exit: 00263 mbedtls_aes_free(&aes_ctx); 00264 return ret; 00265 } 00266 00267 int LoRaMacCrypto::compute_skeys_for_join_frame(const uint8_t *key, uint32_t key_length, 00268 const uint8_t *app_nonce, uint16_t dev_nonce, 00269 uint8_t *nwk_skey, uint8_t *app_skey) 00270 { 00271 uint8_t nonce[16]; 00272 uint8_t *p_dev_nonce = (uint8_t *) &dev_nonce; 00273 int ret = 0; 00274 00275 mbedtls_aes_init(&aes_ctx); 00276 00277 ret = mbedtls_aes_setkey_enc(&aes_ctx, key, key_length); 00278 if (0 != ret) { 00279 goto exit; 00280 } 00281 00282 memset(nonce, 0, sizeof(nonce)); 00283 nonce[0] = 0x01; 00284 memcpy(nonce + 1, app_nonce, 6); 00285 memcpy(nonce + 7, p_dev_nonce, 2); 00286 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, nwk_skey); 00287 if (0 != ret) { 00288 goto exit; 00289 } 00290 00291 memset(nonce, 0, sizeof(nonce)); 00292 nonce[0] = 0x02; 00293 memcpy(nonce + 1, app_nonce, 6); 00294 memcpy(nonce + 7, p_dev_nonce, 2); 00295 ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, nonce, app_skey); 00296 00297 exit: 00298 mbedtls_aes_free(&aes_ctx); 00299 return ret; 00300 } 00301 #else 00302 00303 LoRaMacCrypto::LoRaMacCrypto() 00304 { 00305 MBED_ASSERT(0 && "[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00306 } 00307 00308 LoRaMacCrypto::~LoRaMacCrypto() 00309 { 00310 } 00311 00312 // If mbedTLS is not configured properly, these dummies will ensure that 00313 // user knows what is wrong and in addition to that these ensure that 00314 // Mbed-OS compiles properly under normal conditions where LoRaWAN in conjunction 00315 // with mbedTLS is not being used. 00316 int LoRaMacCrypto::compute_mic(const uint8_t *, uint16_t, const uint8_t *, uint32_t, uint32_t, 00317 uint8_t dir, uint32_t, uint32_t *) 00318 { 00319 MBED_ASSERT(0 && "[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00320 00321 // Never actually reaches here 00322 return LORAWAN_STATUS_CRYPTO_FAIL; 00323 } 00324 00325 int LoRaMacCrypto::encrypt_payload(const uint8_t *, uint16_t, const uint8_t *, uint32_t, uint32_t, 00326 uint8_t, uint32_t, uint8_t *) 00327 { 00328 MBED_ASSERT(0 && "[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00329 00330 // Never actually reaches here 00331 return LORAWAN_STATUS_CRYPTO_FAIL; 00332 } 00333 00334 int LoRaMacCrypto::decrypt_payload(const uint8_t *, uint16_t, const uint8_t *, uint32_t, uint32_t, 00335 uint8_t, uint32_t, uint8_t *) 00336 { 00337 MBED_ASSERT(0 && "[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00338 00339 // Never actually reaches here 00340 return LORAWAN_STATUS_CRYPTO_FAIL; 00341 } 00342 00343 int LoRaMacCrypto::compute_join_frame_mic(const uint8_t *, uint16_t, const uint8_t *, uint32_t, uint32_t *) 00344 { 00345 MBED_ASSERT(0 && "[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00346 00347 // Never actually reaches here 00348 return LORAWAN_STATUS_CRYPTO_FAIL; 00349 } 00350 00351 int LoRaMacCrypto::decrypt_join_frame(const uint8_t *, uint16_t, const uint8_t *, uint32_t, uint8_t *) 00352 { 00353 MBED_ASSERT(0 && "[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00354 00355 // Never actually reaches here 00356 return LORAWAN_STATUS_CRYPTO_FAIL; 00357 } 00358 00359 int LoRaMacCrypto::compute_skeys_for_join_frame(const uint8_t *, uint32_t, const uint8_t *, uint16_t, 00360 uint8_t *, uint8_t *) 00361 { 00362 MBED_ASSERT(0 && "[LoRaCrypto] Must enable AES, CMAC & CIPHER from mbedTLS"); 00363 00364 // Never actually reaches here 00365 return LORAWAN_STATUS_CRYPTO_FAIL; 00366 } 00367 00368 #endif
Generated on Tue Jul 12 2022 13:54:26 by
