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