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 "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 Aug 9 2022 00:37:09 by
1.7.2