Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaMacCrypto.cpp Source File

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