init
Embed:
(wiki syntax)
Show/hide line numbers
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 13:24:47 by
1.7.2