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