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