Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

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 
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