diff --git a/.github/workflows/cmake-build.yml b/.github/workflows/cmake-build.yml index 28c3c8e..c343a3f 100644 --- a/.github/workflows/cmake-build.yml +++ b/.github/workflows/cmake-build.yml @@ -11,6 +11,11 @@ concurrency: jobs: cmake-build-and-test: + strategy: + matrix: + flags: ["", "-DCONFIG_EXTERNAL_KEY_LOAD=y"] + compiler: [gcc, clang] + runs-on: ubuntu-20.04 timeout-minutes: 15 @@ -26,11 +31,28 @@ jobs: - name: Install Embedded Toolchain uses: carlosperate/arm-none-eabi-gcc-action@v1.8.1 + if: matrix.compiler == 'gcc' + + - name: Install CLANG + run: | + sudo apt-get update + sudo apt-get install -y clang + if: matrix.compiler == 'clang' + + - name: Add key loaders to tests + run: | + echo "void ss_load_key_external(const uint8_t *key_id, size_t in_len, uint8_t *key, size_t *key_len){memcpy(key, key_id, in_len);*key_len = in_len;}" >> src/softsim/main.c + echo "void ss_load_key_external(const uint8_t *key_id, size_t in_len, uint8_t *key, size_t *key_len){memcpy(key, key_id, in_len);*key_len = in_len;}" >> tests/ota/ota_test.c + echo "void ss_load_key_external(const uint8_t *key_id, size_t in_len, uint8_t *key, size_t *key_len){memcpy(key, key_id, in_len);*key_len = in_len;}" >> tests/aes/aes_test.c + if: matrix.flags == '-DCONFIG_EXTERNAL_KEY_LOAD=y' - name: Configure and Build Project run: | - cmake -S . -B build -DBUILD_TESTING=y -DCONFIG_USE_SYSTEM_HEAP=y -DCONFIG_ENABLE_SANITIZE=y + cmake -S . -B build -DBUILD_TESTING=y -DCONFIG_USE_SYSTEM_HEAP=y -DCONFIG_ENABLE_SANITIZE=y ${{ matrix.flags }} cmake --build build + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.compiler }}++ - name: Test Project run: cd build && ctest --output-on-failure diff --git a/CMakeLists.txt b/CMakeLists.txt index 8976ee9..ae3322b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,9 @@ option(CONFIG_ENABLE_SANITIZE "Build with -fsanitize=address -fsanitize=undefine option(CONFIG_USE_SYSTEM_HEAP "Use free/malloc instead of port_free/port_malloc") option(CONFIG_USE_LOGS "Set SS_LOGP macro to link against ss_logp") option(CONFIG_USE_EXPERIMENTAL_SUSPEND_COMMAND "Building with experimental support for suspend") -option(CONFIG_USE_UTILS "Use the extra functionality found in the collective utils folder" ON) +option(CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION "Use external crypto implementations") +option(CONFIG_EXTERNAL_KEY_LOAD "Use crypto exstension for loading keys") +option(CONFIG_USE_UTILS "Use the extra functionality found in the collective utils folder") if(CONFIG_USE_SYSTEM_HEAP) add_compile_definitions(CONFIG_USE_SYSTEM_HEAP) @@ -26,6 +28,19 @@ if(CONFIG_USE_EXPERIMENTAL_SUSPEND_COMMAND) add_compile_definitions(CONFIG_USE_EXPERIMENTAL_SUSPEND_COMMAND) endif() +if(CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION AND CONFIG_EXTERNAL_KEY_LOAD) + message(FATAL_ERROR "CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION and CONFIG_EXTERNAL_KEY_LOAD should not be used together") +endif() + +if(CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION) + message(STATUS "Using external crypto implementation") + add_compile_definitions(-DCONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION) +endif() + +if(CONFIG_EXTERNAL_KEY_LOAD) + add_compile_definitions(-DCONFIG_EXTERNAL_KEY_LOAD) +endif() + if(CONFIG_ENABLE_SANITIZE) add_compile_options(-fsanitize=address -fsanitize=undefined) add_link_options(-fsanitize=address -fsanitize=undefined) diff --git a/include/onomondo/softsim/config.h b/include/onomondo/softsim/config.h index bd94c79..a641994 100644 --- a/include/onomondo/softsim/config.h +++ b/include/onomondo/softsim/config.h @@ -1,14 +1,33 @@ -#ifndef INCLUDE_ONOMONDO_SOFTSIM_CONFIG_H_ -#define INCLUDE_ONOMONDO_SOFTSIM_CONFIG_H_ +/* + * Copyright (c) 2024 Onomondo ApS. All rights reserved. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +/* + * This file solely exist to print config opitons at compile time + */ +#pragma once #ifdef CONFIG_USE_SYSTEM_HEAP - #pragma message "Using CONFIG_USE_SYSTEM_HEAP" -#else // DEFAULT - #pragma message "Using port_malloc and port_free instead of system default" -#endif // CONFIG_USE_SYSTEM_HEAP +#pragma message "Using CONFIG_USE_SYSTEM_HEAP" +#else +#pragma message "Using port_malloc and port_free instead of system default" +#endif // CONFIG_USE_SYSTEM_HEAP #ifdef CONFIG_USE_EXPERIMENTAL_SUSPEND_COMMAND - #pragma message "Building with experimental support for suspend" +#pragma message "Building with experimental support for suspend" #endif // CONFIG_USE_EXPERIMENTAL_SUSPEND_COMMAND -#endif // INCLUDE_ONOMONDO_SOFTSIM_CONFIG_H_ + +#if defined(CONFIG_EXTERNAL_KEY_LOAD) && defined(CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION) +#error "External CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION implementation and CONFIG_EXTERNAL_KEY_LOAD should not be enabled at the same time." +#endif // CONFIG_EXTERNAL_KEY_LOAD && EXTERNAL_CRYPTO_IMPLEMENTATION + +#ifdef CONFIG_EXTERNAL_KEY_LOAD +#pragma message "Enabling CONFIG_EXTERNAL_KEY_LOAD" +#endif // CONFIG_EXTERNAL_KEY_LOAD + +#ifdef CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION +#pragma message "Enabling CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION" +#endif // CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION diff --git a/include/onomondo/softsim/crypto.h b/include/onomondo/softsim/crypto.h new file mode 100644 index 0000000..4521b87 --- /dev/null +++ b/include/onomondo/softsim/crypto.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024 Onomondo ApS. All rights reserved. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include +#include +#include + +#define AES_BLOCKSIZE 16 + +/* See also ETSI TS 102 225, section 5.1.1 and 5.1.2 */ +enum enc_algorithm { + NONE, + TRIPLE_DES_CBC2, + AES_CBC, + AES_CMAC, +}; + +/*! Perform an in-place AES decryption with the common settings of OTA + * (CBC mode, zero IV). + * \param[inout] buffer user provided memory with plaintext to decrypt. + * \param[in] buffer_len length of the plaintext data to decrypt (multiple of 16). + * \param[in] key AES key. + * \param[in] key_len length of the AES key. */ +void ss_utils_aes_decrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key, size_t key_len); + +/*! Perform an in-place AES encryption with the common settings of OTA + * (CBC mode, zero IV). + * \param[inout] buffer user provided memory with plaintext to encrypt. + * \param[in] buffer_len length of the plaintext data to encrypt (multiple of 16). + * \param[in] key 16 byte AES key. + * \param[in] key_len length of the AES key. */ +void ss_utils_aes_encrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key, size_t key_len); + +/*! Perform an in-place 3DES decryption with the common settings of OTA + * (CBC mode, 16-byte key, zero IV). + * \param[inout] buffer user provided memory with plaintext to decrypt. + * \param[in] buffer_len length of the plaintext data to decrypt (multiple of 8). + * \param[in] key 16 byte DES key. */ +void ss_utils_3des_decrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key); + +/*! Perform an in-place 3DES encryption with the common settings of OTA + * (CBC mode, 16-byte key, zero IV). + * \param[inout] buffer user provided memory with plaintext to encrypt. + * \param[in] buffer_len length of the plaintext data to encrypt (multiple of 8). + * \param[in] key 16 byte DES key. */ +void ss_utils_3des_encrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key); + +/*! Calculate cryptographic checksum (CC) using a specified algorithm. + * \param[out] cc user provided memory for resulting cryptographic checksum. + * \param[out] cc_len length of user provided memory for resulting cryptographic checksum. + * \param[in] key cryptographic key. + * \param[in] key_len cryptographic key length. + * \param[in] data1 user buffer containing part 1 of the data. + * \param[in] data1_len length of data part 1 (must be multiple of blocksize) + * \param[in] data2 user buffer containing part 2 of the data. + * \param[in] data2_len length of data part 2 (unpadded). + * \returns 0 on success, -EINVAL on error. */ +int ss_utils_ota_calc_cc(uint8_t *cc, size_t cc_len, uint8_t *key, size_t key_len, enum enc_algorithm alg, + uint8_t *data1, size_t data1_len, uint8_t *data2, size_t data2_len); diff --git a/include/onomondo/utils/ss_crypto_extension.h b/include/onomondo/utils/ss_crypto_extension.h new file mode 100644 index 0000000..76623e3 --- /dev/null +++ b/include/onomondo/utils/ss_crypto_extension.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Onomondo ApS. All rights reserved. + * + * SPDX-License-Identifier: GPL-3.0-only + */ +#pragma once + +/* + * Motivation here is to provide a simple mechanism for importing keys from + * different locations than the file-system. Some platforms are very limited + * w.r.t. security and crypto engines. + * + * By doing this we can with relative ease enable the use of + * dedicated secure zones. Those zones however aren't suitable for storing all + * SoftSIM internal data. This is _a_ compromise that allows some sense of secure key storage. + * + * This mechanism is completely optional. By storing the key identifiers instead of keys in the + * A00X files we can use the key ID to fetch the correct key from secure storage. The keys will still + * live in potential non-secure RAM while in use. Immediately after use the keys are zeroed out. + * + * At all times where a dedicated crypto engine or other secure implementations exist (i.e. ARM TrustZone) + * the CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION should be used. + * + * This function is called immediately before the block encryption/decryption is carried out. + */ + +#ifdef CONFIG_EXTERNAL_KEY_LOAD + +#include +#include +#include +/*! + * \brief Load a key from an external source + * + * This function is called when the SoftSIM needs to load a key from an external + * source. The key is loaded into the buffer provided. + * + * \param key_id buffer with the key ID. + * \param key buffer with the resolved key. The key is loaded into this buffer. + * \param in_len Length of the key_id buffer + * \param key_len Length of the key_buffer. After loading the key this should hold the length of the key. + */ +void ss_load_key_external(const uint8_t *key_id, size_t in_len, uint8_t *key, size_t *key_len) __attribute__((weak)); +#endif /* ifdef CONFIG_EXTERNAL_KEY_LOAD */ diff --git a/src/softsim/CMakeLists.txt b/src/softsim/CMakeLists.txt index dd336f1..0a1f9ec 100644 --- a/src/softsim/CMakeLists.txt +++ b/src/softsim/CMakeLists.txt @@ -9,4 +9,5 @@ add_library(storage STATIC storage.c fs.c) target_include_directories(storage PUBLIC ${CMAKE_SOURCE_DIR}/include) add_executable(softsim main.c) -target_link_libraries(softsim uicc milenage crypto storage) +target_link_libraries(softsim uicc milenage crypto storage $<$:utils>) + diff --git a/src/softsim/crypto/aes-encblock.c b/src/softsim/crypto/aes-encblock.c index a521621..d1b9a2c 100644 --- a/src/softsim/crypto/aes-encblock.c +++ b/src/softsim/crypto/aes-encblock.c @@ -7,8 +7,8 @@ * See README for more details. */ +#include #include "includes.h" - #include "common.h" #include "aes.h" #include "aes_wrap.h" @@ -18,15 +18,18 @@ * @key: Key for AES * @in: Input data (16 bytes) * @out: Output of the AES block operation (16 bytes) - * Returns: 0 on success, -1 on failure + * Returns: 0 */ + +/* adjusted from Jouni Malinen impl */ int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out) { - void *ctx; - ctx = aes_encrypt_init(key, 16); - if (ctx == NULL) - return -1; - aes_encrypt(ctx, in, out); - aes_encrypt_deinit(ctx); + // ss_utils_aes_encrypt will overwrite input buffer + uint8_t buf[AES_BLOCK_SIZE]; + memcpy(buf, in, AES_BLOCK_SIZE); + + ss_utils_aes_encrypt(buf, AES_BLOCK_SIZE, key, AES_BLOCK_SIZE); + memcpy(out, buf, AES_BLOCK_SIZE); + return 0; } diff --git a/src/softsim/uicc/uicc_remote_cmd.c b/src/softsim/uicc/uicc_remote_cmd.c index 2947cb7..5978b00 100644 --- a/src/softsim/uicc/uicc_remote_cmd.c +++ b/src/softsim/uicc/uicc_remote_cmd.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2024 Onomondo ApS. All rights reserved. - * - * SPDX-License-Identifier: GPL-3.0-only + * + * SPDX-License-Identifier: GPL-3.0-only */ #include "uicc_remote_cmd.h" @@ -14,6 +14,7 @@ #include #include #include +#include #include "context.h" #include "fcp.h" @@ -22,7 +23,6 @@ #include "uicc_pin.h" #include "utils.h" #include "utils_3des.h" -#include "utils_aes.h" #include "utils_ota.h" /* Information element identifier for command packets, as used in TS 23.048 diff --git a/src/softsim/uicc/utils_3des.c b/src/softsim/uicc/utils_3des.c index 5bd6d87..f123149 100644 --- a/src/softsim/uicc/utils_3des.c +++ b/src/softsim/uicc/utils_3des.c @@ -8,7 +8,9 @@ #include "utils.h" #include "utils_3des.h" #include "crypto/des_i.h" +#include +#ifndef CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION void setup_key(const uint8_t *src, struct des3_key_s *dest) { /* The library wants keys in 24byte form, but we have the 16byte form */ @@ -137,3 +139,4 @@ void ss_utils_3des_cc_cleanup(struct utils_3des_cc_ctx *cc) ss_memzero(cc->key, sizeof(cc->key)); SS_FREE(cc->key); } +#endif // CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION diff --git a/src/softsim/uicc/utils_3des.h b/src/softsim/uicc/utils_3des.h index 586e3dd..007b343 100644 --- a/src/softsim/uicc/utils_3des.h +++ b/src/softsim/uicc/utils_3des.h @@ -1,19 +1,17 @@ /* * Copyright (c) 2024 Onomondo ApS. All rights reserved. - * - * SPDX-License-Identifier: GPL-3.0-only + * + * SPDX-License-Identifier: GPL-3.0-only */ #pragma once +#include +#include + #define DES_BLOCKSIZE 8 #define TRIPLE_DES_KEYLEN 16 -void ss_utils_3des_decrypt(uint8_t *buffer, size_t buffer_len, - const uint8_t *key); -void ss_utils_3des_encrypt(uint8_t *buffer, size_t buffer_len, - const uint8_t *key); - struct des3_key_s; struct utils_3des_cc_ctx { struct des3_key_s *key; @@ -23,6 +21,5 @@ struct utils_3des_cc_ctx { }; void ss_utils_3des_cc_setup(struct utils_3des_cc_ctx *cc, const uint8_t *key); -void ss_utils_3des_cc_feed(struct utils_3des_cc_ctx *cc, const uint8_t *data, - size_t data_len); +void ss_utils_3des_cc_feed(struct utils_3des_cc_ctx *cc, const uint8_t *data, size_t data_len); void ss_utils_3des_cc_cleanup(struct utils_3des_cc_ctx *cc); diff --git a/src/softsim/uicc/utils_aes.c b/src/softsim/uicc/utils_aes.c index 58ab0dd..d566f99 100644 --- a/src/softsim/uicc/utils_aes.c +++ b/src/softsim/uicc/utils_aes.c @@ -1,18 +1,35 @@ /* * Copyright (c) 2024 Onomondo ApS. All rights reserved. - * - * SPDX-License-Identifier: GPL-3.0-only + * + * SPDX-License-Identifier: GPL-3.0-only */ #include #include #include +#include +#include #include "utils.h" #include "utils_aes.h" #include "crypto/common.h" - #include "crypto/aes.h" +/* This allows users to fetch keys from more custom locations. + * Very useful for devices where the filesystem isn't trusted. + * I.e. The key is preferably loaded from a secure zone or from encrypted + * representation etc. */ + +#define COPY_EXTERNAL_KEY_TO_LOCAL_VAR() \ + uint8_t modified_key[AES_BLOCKSIZE]; \ + size_t modified_key_len = AES_BLOCKSIZE; \ + ss_load_key_external(key, key_len, modified_key, &modified_key_len); \ + key = modified_key; \ + key_len = modified_key_len; + +#define MEMZERO_EXTERNAL_KEY() ss_memzero(modified_key, sizeof(modified_key)); + +#ifndef CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION + /*! Perform an in-place AES decryption with the common settings of OTA * (CBC mode, zero IV). * \param[inout] buffer user provided memory with plaintext to decrypt. @@ -27,6 +44,10 @@ void ss_utils_aes_decrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key int i; int j; +#ifdef CONFIG_EXTERNAL_KEY_LOAD + COPY_EXTERNAL_KEY_TO_LOCAL_VAR() +#endif // CONFIG_EXTERNAL_KEY_LOAD + aes_ctx = aes_decrypt_init(key, key_len); /* Adjusted from hostap's crypto_internal-cipher.c */ @@ -41,6 +62,10 @@ void ss_utils_aes_decrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key } aes_decrypt_deinit(aes_ctx); + +#ifdef CONFIG_EXTERNAL_KEY_LOAD + MEMZERO_EXTERNAL_KEY() +#endif // CONFIG_EXTERNAL_KEY_LOAD } /*! Perform an in-place AES encryption with the common settings of OTA @@ -56,6 +81,10 @@ void ss_utils_aes_encrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key int i; int j; +#ifdef CONFIG_EXTERNAL_KEY_LOAD + COPY_EXTERNAL_KEY_TO_LOCAL_VAR() +#endif // CONFIG_EXTERNAL_KEY_LOAD + aes_ctx = aes_encrypt_init(key, key_len); /* Adjusted from hostap's crypto_internal-cipher.c */ @@ -68,7 +97,12 @@ void ss_utils_aes_encrypt(uint8_t *buffer, size_t buffer_len, const uint8_t *key } aes_encrypt_deinit(aes_ctx); + +#ifdef CONFIG_EXTERNAL_KEY_LOAD + MEMZERO_EXTERNAL_KEY() +#endif // CONFIG_EXTERNAL_KEY_LOAD } +#endif // CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION /* Shift a whole block to the left by one bit position. * (See also RFC 4493, appendix A) */ diff --git a/src/softsim/uicc/utils_aes.h b/src/softsim/uicc/utils_aes.h index 3a3dab7..2f79232 100644 --- a/src/softsim/uicc/utils_aes.h +++ b/src/softsim/uicc/utils_aes.h @@ -1,18 +1,13 @@ /* * Copyright (c) 2024 Onomondo ApS. All rights reserved. - * - * SPDX-License-Identifier: GPL-3.0-only + * + * SPDX-License-Identifier: GPL-3.0-only */ #pragma once #define AES_BLOCKSIZE 16 -void ss_utils_aes_decrypt(uint8_t *buffer, size_t buffer_len, - const uint8_t *key, size_t key_len); -void ss_utils_aes_encrypt(uint8_t *buffer, size_t buffer_len, - const uint8_t *key, size_t key_len); - struct utils_aes_cc_ctx { void *aes_ctx; @@ -30,8 +25,6 @@ struct utils_aes_cc_ctx { bool inert_padding; }; -void ss_utils_aes_cc_setup(struct utils_aes_cc_ctx *cc, const uint8_t *key, - size_t key_len, bool inert_padding); -void ss_utils_aes_cc_feed(struct utils_aes_cc_ctx *cc, const uint8_t *data, - size_t data_len, bool last); +void ss_utils_aes_cc_setup(struct utils_aes_cc_ctx *cc, const uint8_t *key, size_t key_len, bool inert_padding); +void ss_utils_aes_cc_feed(struct utils_aes_cc_ctx *cc, const uint8_t *data, size_t data_len, bool last); void ss_utils_aes_cc_cleanup(struct utils_aes_cc_ctx *cc); diff --git a/src/softsim/uicc/utils_ota.c b/src/softsim/uicc/utils_ota.c index a8e07b6..31cd2da 100644 --- a/src/softsim/uicc/utils_ota.c +++ b/src/softsim/uicc/utils_ota.c @@ -1,18 +1,20 @@ /* * Copyright (c) 2024 Onomondo ApS. All rights reserved. - * - * SPDX-License-Identifier: GPL-3.0-only + * + * SPDX-License-Identifier: GPL-3.0-only */ #include #include #include #include +#include +#include +#include +#include "utils_ota.h" #include "utils.h" #include "utils_3des.h" #include "utils_aes.h" -#include "utils_ota.h" -#include /*! Calculate the number of padding bytes (pcnt) for a given length. * \param[in] algorithm algorithm to use. @@ -36,11 +38,13 @@ uint8_t ss_utils_ota_calc_pcnt(enum enc_algorithm algorithm, size_t data_len) return (-(blocksize + data_len)) % blocksize; } +#ifndef CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION + /*! Calculate cryptographic checksum (CC) using a specified algorithm. - * \param[out] cc user provided memory for resulting cryptpgraphic checksum. - * \param[out] cc_len length of user provided memory for resulting cryptpgraphic checksum. - * \param[in] key cryptpgraphic key. - * \param[in] key_len cryptpgraphic key length. + * \param[out] cc user provided memory for resulting cryptographic checksum. + * \param[out] cc_len length of user provided memory for resulting cryptographic checksum. + * \param[in] key cryptographic key. + * \param[in] key_len cryptographic key length. * \param[in] data1 user buffer containing part 1 of the data. * \param[in] data1_len length of data part 1 (must be multiple of blocksize) * \param[in] data2 user buffer containing part 2 of the data. @@ -52,6 +56,18 @@ int ss_utils_ota_calc_cc(uint8_t *cc, size_t cc_len, uint8_t *key, size_t key_le struct utils_3des_cc_ctx cc_des; struct utils_aes_cc_ctx cc_aes; + /* This allows users to fetch keys from more custom locations. + * Very useful for devices where the filesystem isn't trusted. + * I.e. The key is preferably loaded from a secure zone or from encrypted + * representation etc.*/ +#ifdef CONFIG_EXTERNAL_KEY_LOAD + uint8_t modified_key[AES_BLOCKSIZE]; + size_t modified_key_len = AES_BLOCKSIZE; + ss_load_key_external(key, key_len, modified_key, &modified_key_len); + key = modified_key; + key_len = modified_key_len; +#endif // CONFIG_EXTERNAL_KEY_LOAD + /* NOTE: This function accepts two separate buffers (data1 and data2). * The reason for this is that the data we are going to sign is in two * separate buffers and to avoid copying the two buffers into a single @@ -88,4 +104,10 @@ int ss_utils_ota_calc_cc(uint8_t *cc, size_t cc_len, uint8_t *key, size_t key_le SS_LOGP(SREMOTECMD, LERROR, "unable to calculate cc, improper crypto algorithm selected\n"); return -EINVAL; } + +#ifdef CONFIG_EXTERNAL_KEY_LOAD + ss_memzero(modified_key, sizeof(modified_key)); +#endif // CONFIG_EXTERNAL_KEY_LOAD } + +#endif // CONFIG_EXTERNAL_CRYPTO_IMPLEMENTATION diff --git a/src/softsim/uicc/utils_ota.h b/src/softsim/uicc/utils_ota.h index e1615bc..441b5b8 100644 --- a/src/softsim/uicc/utils_ota.h +++ b/src/softsim/uicc/utils_ota.h @@ -1,24 +1,14 @@ /* * Copyright (c) 2024 Onomondo ApS. All rights reserved. - * - * SPDX-License-Identifier: GPL-3.0-only + * + * SPDX-License-Identifier: GPL-3.0-only */ #pragma once -/* See also ETSI TS 102 225, section 5.1.1 and 5.1.2 */ -enum enc_algorithm { - NONE, - TRIPLE_DES_CBC2, - AES_CBC, - AES_CMAC, -}; +#include #define OTA_KEY_LEN 16 #define OTA_INTEGRITY_LEN 8 uint8_t ss_utils_ota_calc_pcnt(enum enc_algorithm algorithm, size_t data_len); -int ss_utils_ota_calc_cc(uint8_t *cc, size_t cc_len, - uint8_t *key, size_t key_len, enum enc_algorithm alg, - uint8_t *data1, size_t data1_len, - uint8_t *data2, size_t data2_len); diff --git a/tests/aes/CMakeLists.txt b/tests/aes/CMakeLists.txt index 3bb7adf..5f9d044 100644 --- a/tests/aes/CMakeLists.txt +++ b/tests/aes/CMakeLists.txt @@ -5,8 +5,7 @@ add_executable(aes_test aes_test.c) include_directories(${PROJECT_SOURCE_DIR}) include_directories(${PROJECT_SOURCE_DIR}/include) - -target_link_libraries(aes_test uicc crypto) +target_link_libraries(aes_test uicc crypto $<$:utils>) add_test(NAME aes_test COMMAND sh -c "$ > aes_test.out") diff --git a/tests/app_transact/CMakeLists.txt b/tests/app_transact/CMakeLists.txt index f2ac40f..3a84561 100644 --- a/tests/app_transact/CMakeLists.txt +++ b/tests/app_transact/CMakeLists.txt @@ -5,6 +5,5 @@ add_executable(app_apdu_test app_transact_test.c) include_directories(${PROJECT_SOURCE_DIR}/include) -target_link_libraries(app_apdu_test uicc milenage crypto storage) - +target_link_libraries(app_apdu_test uicc milenage crypto storage $<$:utils>) diff --git a/tests/ota/CMakeLists.txt b/tests/ota/CMakeLists.txt index 9c61b83..5d15c1d 100644 --- a/tests/ota/CMakeLists.txt +++ b/tests/ota/CMakeLists.txt @@ -6,7 +6,7 @@ add_executable(ota_test ota_test.c) include_directories(${PROJECT_SOURCE_DIR}) include_directories(${PROJECT_SOURCE_DIR}/include) -target_link_libraries(ota_test uicc crypto) +target_link_libraries(ota_test uicc crypto $<$:utils>) add_test(NAME ota_test COMMAND sh -c "$ > ota_test.out") diff --git a/tests/ota/ota_test.c b/tests/ota/ota_test.c index 4bb6344..d044f85 100644 --- a/tests/ota/ota_test.c +++ b/tests/ota/ota_test.c @@ -16,7 +16,7 @@ static void calc_and_print_pcnt(enum enc_algorithm algorithm, size_t data_len, u { char *algorithm_str; uint8_t pcnt; - + switch (algorithm) { case TRIPLE_DES_CBC2: algorithm_str = "DES_CBC2"; @@ -32,7 +32,7 @@ static void calc_and_print_pcnt(enum enc_algorithm algorithm, size_t data_len, u } pcnt = ss_utils_ota_calc_pcnt(algorithm, data_len); - + printf("algorithm=%s data_len=%zu, pcnt=%u, pcnt_expected=%u\n", algorithm_str, data_len, ss_utils_ota_calc_pcnt(algorithm, data_len), pcnt_expected); @@ -53,7 +53,7 @@ static void ss_utils_ota_calc_pcnt_test(void) calc_and_print_pcnt(TRIPLE_DES_CBC2, 9, 7); calc_and_print_pcnt(TRIPLE_DES_CBC2, 17, 7); calc_and_print_pcnt(TRIPLE_DES_CBC2, 25, 7); - + /* DES Off by -1 */ calc_and_print_pcnt(TRIPLE_DES_CBC2, 7, 1); calc_and_print_pcnt(TRIPLE_DES_CBC2, 15, 1); @@ -70,7 +70,7 @@ static void ss_utils_ota_calc_pcnt_test(void) calc_and_print_pcnt(AES_CBC, 17, 15); calc_and_print_pcnt(AES_CBC, 33, 15); calc_and_print_pcnt(AES_CBC, 49, 15); - + /* AES Off by -1 */ calc_and_print_pcnt(AES_CBC, 15, 1); calc_and_print_pcnt(AES_CBC, 31, 1); diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 519dc0d..cab00b9 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -1,7 +1,15 @@ # Copyright (c) 2024 Onomondo ApS. All rights reserved. # SPDX-License-Identifier: GPL-3.0-only -add_library(utils STATIC ss_profile.c) +set(utils_collection + ss_profile.c +) + +if(CONFIG_EXTERNAL_KEY_LOAD) + set(utils_collection ${utils_collection} ss_crypto_extension.c) +endif() + +add_library(utils STATIC ${utils_collection}) target_include_directories(utils PUBLIC diff --git a/utils/ss_crypto_extension.c b/utils/ss_crypto_extension.c new file mode 100644 index 0000000..647d558 --- /dev/null +++ b/utils/ss_crypto_extension.c @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Onomondo ApS. All rights reserved. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include +#include +#include + +/* IMPL some sensible default */ + +void ss_load_key_external(const uint8_t *key_id, size_t in_len, uint8_t *key, size_t *key_len) +{ + memcpy(key, key_id, in_len); + *key_len = in_len; +}