From c02fffba3cb901546e07cd04f129789eac947376 Mon Sep 17 00:00:00 2001 From: Julian Hall Date: Mon, 23 Nov 2020 18:22:06 +0100 Subject: Add crypto service Change-Id: Ifd55a4caaf0b95e3d1b6504863fba112a7e18f15 Signed-off-by: Julian Hall --- .../service/crypto/client/cpp/component.cmake | 22 + .../service/crypto/client/cpp/config_mbed_crypto.h | 1955 ++++++++++++++++++++ .../service/crypto/client/cpp/crypto_client.cpp | 806 ++++++++ .../service/crypto/client/cpp/crypto_client.h | 76 + .../service/crypto/client/test/component.cmake | 14 + .../crypto/client/test/mock/component.cmake | 14 + .../crypto/client/test/mock/mock_crypto_client.cpp | 114 ++ .../crypto/client/test/mock/mock_crypto_client.h | 49 + .../crypto/client/test/standalone/component.cmake | 14 + .../test/standalone/standalone_crypto_client.cpp | 138 ++ .../test/standalone/standalone_crypto_client.h | 52 + .../crypto/client/test/test_crypto_client.cpp | 105 ++ .../crypto/client/test/test_crypto_client.h | 88 + .../crypto/provider/mbedcrypto/component.cmake | 31 + .../provider/mbedcrypto/config_mbed_crypto.h | 1954 +++++++++++++++++++ .../crypto/provider/mbedcrypto/crypto_provider.c | 605 ++++++ .../crypto/provider/mbedcrypto/crypto_provider.h | 46 + .../mbedcrypto/entropy_source/mock/component.cmake | 13 + .../entropy_source/mock/mock_entropy_source.c | 25 + .../serializer/crypto_provider_serializer.h | 113 ++ .../provider/serializer/protobuf/component.cmake | 20 + .../protobuf/pb_crypto_provider_serializer.c | 591 ++++++ .../protobuf/pb_crypto_provider_serializer.h | 25 + .../protobuf/pb_key_attributes_translator.c | 25 + .../protobuf/pb_key_attributes_translator.h | 17 + .../service/crypto/test/service/component.cmake | 15 + .../test/service/crypto_service_limit_tests.cpp | 170 ++ .../test/service/crypto_service_op_tests.cpp | 383 ++++ .../service/crypto/test/unit/component.cmake | 16 + .../crypto/test/unit/crypto_fault_tests.cpp | 91 + .../crypto/test/unit/crypto_msg_encode_decode.cpp | 270 +++ .../service/crypto/test/unit/poc_crypto_ops.cpp | 110 ++ external/mbed-crypto/mbedcrypto.cmake | 93 + protocols/service/crypto/packed-c/component.cmake | 14 + protocols/service/crypto/packed-c/opcodes.h | 26 + .../crypto/protobuf/asymmetric_decrypt.proto | 18 + .../crypto/protobuf/asymmetric_encrypt.proto | 18 + protocols/service/crypto/protobuf/close_key.proto | 11 + protocols/service/crypto/protobuf/component.cmake | 26 + .../service/crypto/protobuf/destroy_key.proto | 13 + protocols/service/crypto/protobuf/export_key.proto | 15 + .../crypto/protobuf/export_public_key.proto | 15 + .../service/crypto/protobuf/generate_key.proto | 17 + .../service/crypto/protobuf/generate_random.proto | 15 + protocols/service/crypto/protobuf/import_key.proto | 18 + .../service/crypto/protobuf/key_attributes.proto | 130 ++ protocols/service/crypto/protobuf/opcodes.proto | 23 + protocols/service/crypto/protobuf/open_key.proto | 15 + protocols/service/crypto/protobuf/sign_hash.proto | 17 + .../service/crypto/protobuf/verify_hash.proto | 16 + 50 files changed, 8467 insertions(+) create mode 100644 components/service/crypto/client/cpp/component.cmake create mode 100644 components/service/crypto/client/cpp/config_mbed_crypto.h create mode 100644 components/service/crypto/client/cpp/crypto_client.cpp create mode 100644 components/service/crypto/client/cpp/crypto_client.h create mode 100644 components/service/crypto/client/test/component.cmake create mode 100644 components/service/crypto/client/test/mock/component.cmake create mode 100644 components/service/crypto/client/test/mock/mock_crypto_client.cpp create mode 100644 components/service/crypto/client/test/mock/mock_crypto_client.h create mode 100644 components/service/crypto/client/test/standalone/component.cmake create mode 100644 components/service/crypto/client/test/standalone/standalone_crypto_client.cpp create mode 100644 components/service/crypto/client/test/standalone/standalone_crypto_client.h create mode 100644 components/service/crypto/client/test/test_crypto_client.cpp create mode 100644 components/service/crypto/client/test/test_crypto_client.h create mode 100644 components/service/crypto/provider/mbedcrypto/component.cmake create mode 100644 components/service/crypto/provider/mbedcrypto/config_mbed_crypto.h create mode 100644 components/service/crypto/provider/mbedcrypto/crypto_provider.c create mode 100644 components/service/crypto/provider/mbedcrypto/crypto_provider.h create mode 100644 components/service/crypto/provider/mbedcrypto/entropy_source/mock/component.cmake create mode 100644 components/service/crypto/provider/mbedcrypto/entropy_source/mock/mock_entropy_source.c create mode 100644 components/service/crypto/provider/serializer/crypto_provider_serializer.h create mode 100644 components/service/crypto/provider/serializer/protobuf/component.cmake create mode 100644 components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c create mode 100644 components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h create mode 100644 components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c create mode 100644 components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h create mode 100644 components/service/crypto/test/service/component.cmake create mode 100644 components/service/crypto/test/service/crypto_service_limit_tests.cpp create mode 100644 components/service/crypto/test/service/crypto_service_op_tests.cpp create mode 100644 components/service/crypto/test/unit/component.cmake create mode 100644 components/service/crypto/test/unit/crypto_fault_tests.cpp create mode 100644 components/service/crypto/test/unit/crypto_msg_encode_decode.cpp create mode 100644 components/service/crypto/test/unit/poc_crypto_ops.cpp create mode 100644 external/mbed-crypto/mbedcrypto.cmake create mode 100644 protocols/service/crypto/packed-c/component.cmake create mode 100644 protocols/service/crypto/packed-c/opcodes.h create mode 100644 protocols/service/crypto/protobuf/asymmetric_decrypt.proto create mode 100644 protocols/service/crypto/protobuf/asymmetric_encrypt.proto create mode 100644 protocols/service/crypto/protobuf/close_key.proto create mode 100644 protocols/service/crypto/protobuf/component.cmake create mode 100644 protocols/service/crypto/protobuf/destroy_key.proto create mode 100644 protocols/service/crypto/protobuf/export_key.proto create mode 100644 protocols/service/crypto/protobuf/export_public_key.proto create mode 100644 protocols/service/crypto/protobuf/generate_key.proto create mode 100644 protocols/service/crypto/protobuf/generate_random.proto create mode 100644 protocols/service/crypto/protobuf/import_key.proto create mode 100644 protocols/service/crypto/protobuf/key_attributes.proto create mode 100644 protocols/service/crypto/protobuf/opcodes.proto create mode 100644 protocols/service/crypto/protobuf/open_key.proto create mode 100644 protocols/service/crypto/protobuf/sign_hash.proto create mode 100644 protocols/service/crypto/protobuf/verify_hash.proto diff --git a/components/service/crypto/client/cpp/component.cmake b/components/service/crypto/client/cpp/component.cmake new file mode 100644 index 000000000..18b83e9bd --- /dev/null +++ b/components/service/crypto/client/cpp/component.cmake @@ -0,0 +1,22 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/crypto_client.cpp" + ) + +# The crypto client presents the PSA Crypto API and hence has a dependency on mbedcrypto for functions +# related to setting key attributes. A minimal configuration is provided to allow a minimal library +# to be built. This configuration may be overridden by other components that have their own +# dependency on mbedctupto. +set(MBEDCRYPTO_CONFIG_FILE + "${CMAKE_CURRENT_LIST_DIR}/config_mbed_crypto.h" + CACHE STRING "Configuration file for mbedcrypto") + diff --git a/components/service/crypto/client/cpp/config_mbed_crypto.h b/components/service/crypto/client/cpp/config_mbed_crypto.h new file mode 100644 index 000000000..d3c2a7333 --- /dev/null +++ b/components/service/crypto/client/cpp/config_mbed_crypto.h @@ -0,0 +1,1955 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_MBED_CRYPTO_H +#define CONFIG_MBED_CRYPTO_H + +/** + * Defines the configuration to use when the crypto_client + * component is used in a deployment. + */ + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/aria.c + * library/timing.c + * include/mbedtls/bn_mul.h + * + * Required by: + * MBEDTLS_AESNI_C + * MBEDTLS_PADLOCK_C + * + * Comment to disable the use of assembly code. + */ +#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +#define MBEDTLS_NO_UDBL_DIVISION + +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +//#define MBEDTLS_NO_64BIT_MULTIPLICATION + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions + */ +//#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). + * The time needs to be correct (not necessarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. + */ +//#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT +//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions so that they generate a warning if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions so that they generate an error if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * Uncomment to get errors on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/** + * \def MBEDTLS_CHECK_PARAMS + * + * This configuration option controls whether the library validates more of + * the parameters passed to it. + * + * When this flag is not defined, the library only attempts to validate an + * input parameter if: (1) they may come from the outside world (such as the + * network, the filesystem, etc.) or (2) not validating them could result in + * internal memory errors such as overflowing a buffer controlled by the + * library. On the other hand, it doesn't attempt to validate parameters whose + * values are fully controlled by the application (such as pointers). + * + * When this flag is defined, the library additionally attempts to validate + * parameters that are fully controlled by the application, and should always + * be valid if the application code is fully correct and trusted. + * + * For example, when a function accepts as input a pointer to a buffer that may + * contain untrusted data, and its documentation mentions that this pointer + * must not be NULL: + * - the pointer is checked to be non-NULL only if this option is enabled + * - the content of the buffer is always validated + * + * When this flag is defined, if a library function receives a parameter that + * is invalid, it will: + * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a + * call to the function mbedtls_param_failed() + * - immediately return (with a specific error code unless the function + * returns void and can't communicate an error). + * + * When defining this flag, you also need to: + * - either provide a definition of the function mbedtls_param_failed() in + * your application (see platform_util.h for its prototype) as the library + * calls that function, but does not provide a default definition for it, + * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED() + * below if the above mechanism is not flexible enough to suit your needs. + * See the documentation of this macro later in this file. + * + * Uncomment to enable validation of application-controlled parameters. + */ +//#define MBEDTLS_CHECK_PARAMS + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + * + * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_ARIA_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT +//#define MBEDTLS_CMAC_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT +//#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT +//#define MBEDTLS_XTEA_ALT + +/* + * When replacing the elliptic curve module, pleace consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT + +/** + * \def MBEDTLS_MD2_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * \note Because of a signature change, the core AES encryption and decryption routines are + * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, + * respectively. When setting up alternative implementations, these functions should + * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * must stay untouched. + * + * \note If you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + * + * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use + * constitutes a security risk. If possible, we recommend avoiding + * dependencies on them, and considering stronger message digests + * and ciphers instead. + * + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT +//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT +//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT +//#define MBEDTLS_ECDSA_VERIFY_ALT +//#define MBEDTLS_ECDSA_SIGN_ALT +//#define MBEDTLS_ECDSA_GENKEY_ALT + +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac + * function, but will use your mbedtls_internal_ecp_double_jac if the group is + * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when + * receives it as an argument). If the group is not supported then the original + * implementation is used. The other functions and the definition of + * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your + * implementation of mbedtls_internal_ecp_double_jac and + * mbedtls_internal_ecp_grp_capable must be compatible with this definition. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +#define MBEDTLS_TEST_NULL_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Use precomputed AES tables stored in ROM. + * + * Uncomment this macro to use precomputed AES tables stored in ROM. + * Comment this macro to generate AES tables in RAM at runtime. + * + * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb + * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the + * initialization time before the first AES operation can be performed. + * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c + * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded + * performance if ROM access is slower than RAM access. + * + * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + * + */ +//#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_AES_FEWER_TABLES + * + * Use less ROM/RAM for AES tables. + * + * Uncommenting this macro omits 75% of the AES tables from + * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) + * by computing their values on the fly during operations + * (the tables are entry-wise rotations of one another). + * + * Tradeoff: Uncommenting this reduces the RAM / ROM footprint + * by ~6kb but at the cost of more arithmetic operations during + * runtime. Specifically, one has to compare 4 accesses within + * different tables to 4 accesses with additional arithmetic + * operations within the same table. The performance gain/loss + * depends on the system and memory details. + * + * This option is independent of \c MBEDTLS_AES_ROM_TABLES. + * + */ +//#define MBEDTLS_AES_FEWER_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +#define MBEDTLS_CIPHER_MODE_XTS + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * This module is required to support the TLS ciphersuites that use the NULL + * cipher. + * + * Uncomment this macro to enable the NULL cipher + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECP_RESTARTABLE + * + * Enable "non-blocking" ECC operations that can return early and be resumed. + * + * This allows various functions to pause by returning + * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in Mbed TLS's SSL module, + * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in order + * to further progress and eventually complete their operation. This is + * controlled through mbedtls_ecp_set_max_ops() which limits the maximum number + * of ECC operations a function may perform before pausing; see + * mbedtls_ecp_set_max_ops() for more information. + * + * This is useful in non-threaded environments if you want to avoid blocking + * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. + * + * Uncomment this macro to enable restartable ECC computations. + * + * \note This option only works with the default software implementation of + * elliptic curve functionality. It is incompatible with + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. + */ +//#define MBEDTLS_ECP_RESTARTABLE + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +#define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + * + * In PSA key storage, encode the owner of the key. + * + * This is only meaningful when building the library as part of a + * multi-client service. When you activate this option, you must provide + * an implementation of the type psa_key_owner_id_t and a translation + * from psa_key_file_id_t to file name in all the storage backends that + * you wish to support. + * + * Note that this option is meant for internal use only and may be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +#define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +#define MBEDTLS_PKCS1_V21 + +/** + * \def MBEDTLS_PSA_CRYPTO_SPM + * + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure + * Partition Manager) integration which separates the code into two parts: a + * NSPE (Non-Secure Process Environment) and an SPE (Secure Process + * Environment). + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SPM + +/** + * \def MBEDTLS_PSA_INJECT_ENTROPY + * + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. + * + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED + * + */ +//#define MBEDTLS_PSA_INJECT_ENTROPY + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonnable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_USE_PSA_CRYPTO + * + * Make the X.509 and TLS library use PSA for cryptographic operations, see + * #MBEDTLS_PSA_CRYPTO_C. + * + * Note: this option is still in progress, the full X.509 and TLS modules are + * not covered yet, but parts that are not ported to PSA yet will still work + * as usual, so enabling this option should not break backwards compatibility. + * + * \warning Support for PSA is still an experimental feature. + * Any public API that depends on this option may change + * at any time until this warning is removed. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + */ +//#define MBEDTLS_USE_PSA_CRYPTO + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +#define MBEDTLS_VERSION_FEATURES + +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/cipher.c + * library/pem.c + * library/ctr_drbg.c + * + * This module is required to support the TLS ciphersuites that use the AES + * cipher. + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the ARC4 + * cipher. + * + * \warning ARC4 is considered a weak cipher and its use constitutes a + * security risk. If possible, we recommend avoidng dependencies on + * it, and considering stronger ciphers instead. + * + */ +#define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + */ +#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/rsa_internal.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +#define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * Camellia cipher. + */ +#define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_ARIA_C + * + * Enable the ARIA block cipher. + * + * Module: library/aria.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * ARIA cipher. + */ +//#define MBEDTLS_ARIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support AES-CCM ciphersuites in TLS. + */ +#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +#define MBEDTLS_CHACHA20_C + +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +#define MBEDTLS_CHACHAPOLY_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-based random generator. + * The CTR_DRBG generator uses AES-256 by default. + * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES random number generator. + */ +#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the DES + * cipher. + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + * + * \warning DES is considered a weak cipher and its use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +#define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +#define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + */ +#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support the TLS ciphersuites that use GCM. + */ +#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +#define MBEDTLS_HKDF_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_NIST_KW_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + * + * \warning MD2 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + * + * \warning MD4 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * + * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 + * depending on the handshake parameters. Further, it is used for checking + * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded + * encrypted keys. + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * + * This modules translates between OIDs and internal values. + */ +#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +//#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +#define MBEDTLS_POLY1305_C + +/** + * \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * Module: library/psa_crypto.c + * + * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C + * + */ +#define MBEDTLS_PSA_CRYPTO_C + +/** + * \def MBEDTLS_PSA_CRYPTO_STORAGE_C + * + * Enable the Platform Security Architecture persistent key storage. + * + * Module: library/psa_crypto_storage.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface + */ +//#define MBEDTLS_PSA_CRYPTO_STORAGE_C + +/** + * \def MBEDTLS_PSA_ITS_FILE_C + * + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. + * + * Module: library/psa_its_file.c + * + * Requires: MBEDTLS_FS_IO + */ +//#define MBEDTLS_PSA_ITS_FILE_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * library/rsa_internal.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +#define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * + * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 + * depending on the handshake parameters, and for SHA1-signed certificates. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by Mbed + * TLS's \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and + * provide your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +#define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ + +/** + * Uncomment the macro to let mbed TLS use your alternate implementation of + * mbedtls_platform_zeroize(). This replaces the default implementation in + * platform_util.c. + * + * mbedtls_platform_zeroize() is a widely used function across the library to + * zero a block of memory. The implementation is expected to be secure in the + * sense that it has been written to prevent the compiler from removing calls + * to mbedtls_platform_zeroize() as part of redundant code elimination + * optimizations. However, it is difficult to guarantee that calls to + * mbedtls_platform_zeroize() will not be optimized by the compiler as older + * versions of the C language standards do not provide a secure implementation + * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to + * configure their own implementation of mbedtls_platform_zeroize(), for + * example by using directives specific to their compiler, features from newer + * C standards (e.g using memset_s() in C11) or calling a secure memset() from + * their system (e.g explicit_bzero() in BSD). + */ +//#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + +/* \} name SECTION: Customisation configuration options */ + +/* Target and application specific configurations + * + * Allow user to override any previous default. + * + */ +#if defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +#include "mbedtls/check_config.h" + +#endif /* CONFIG_MBED_CRYPTO_H */ diff --git a/components/service/crypto/client/cpp/crypto_client.cpp b/components/service/crypto/client/cpp/crypto_client.cpp new file mode 100644 index 000000000..a374954ec --- /dev/null +++ b/components/service/crypto/client/cpp/crypto_client.cpp @@ -0,0 +1,806 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include "crypto_client.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +crypto_client::crypto_client() : + m_caller(NULL), + m_err_rpc_status(TS_RPC_CALL_ACCEPTED) +{ + +} + +crypto_client::crypto_client(struct rpc_caller *caller) : + m_caller(caller), + m_err_rpc_status(TS_RPC_CALL_ACCEPTED) +{ + +} + +crypto_client::~crypto_client() +{ + +} + +int crypto_client::err_rpc_status() const +{ + return m_err_rpc_status; +} + +psa_status_t crypto_client::generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_GenerateKeyIn req_msg = ts_crypto_GenerateKeyIn_init_default; + + translate_key_attributes(req_msg.attributes, *attributes); + req_msg.has_attributes = true; + + if (pb_get_encoded_size(&req_len, ts_crypto_GenerateKeyIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_GenerateKeyIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_GENERATE_KEY, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + ts_crypto_GenerateKeyOut resp_msg = ts_crypto_GenerateKeyOut_init_default; + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) { + + *handle = resp_msg.handle; + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + return psa_status; +} + +psa_status_t crypto_client::destroy_key(psa_key_handle_t handle) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_DestroyKeyIn req_msg = ts_crypto_DestroyKeyIn_init_default; + + req_msg.handle = handle; + + if (pb_get_encoded_size(&req_len, ts_crypto_DestroyKeyIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_DestroyKeyIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_DESTROY_KEY, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus; + + rpc_caller_end(m_caller, call_handle); + } + } + + return psa_status; +} + +psa_status_t crypto_client::open_key(psa_key_id_t id, psa_key_handle_t *handle) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_OpenKeyIn req_msg = ts_crypto_OpenKeyIn_init_default; + req_msg.id = id; + + if (pb_get_encoded_size(&req_len, ts_crypto_OpenKeyIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_OpenKeyIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_OPEN_KEY, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + ts_crypto_OpenKeyOut resp_msg = ts_crypto_OpenKeyOut_init_default; + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_OpenKeyOut_fields, &resp_msg)) { + + *handle = resp_msg.handle; + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + return psa_status; +} + +psa_status_t crypto_client::close_key(psa_key_handle_t handle) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_CloseKeyIn req_msg = ts_crypto_CloseKeyIn_init_default; + + req_msg.handle = handle; + + if (pb_get_encoded_size(&req_len, ts_crypto_CloseKeyIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_CloseKeyIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_CLOSE_KEY, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus; + + rpc_caller_end(m_caller, call_handle); + } + } + + return psa_status; +} + +psa_status_t crypto_client::import_key(const psa_key_attributes_t *attributes, + const uint8_t *data, size_t data_length, psa_key_handle_t *handle) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_ImportKeyIn req_msg = ts_crypto_ImportKeyIn_init_default; + pb_bytes_array_t *key_byte_array = pb_malloc_byte_array_containing_bytes(data, data_length); + + translate_key_attributes(req_msg.attributes, *attributes); + req_msg.has_attributes = true; + req_msg.data = pb_out_byte_array(key_byte_array); + + if (pb_get_encoded_size(&req_len, ts_crypto_ImportKeyIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_ImportKeyIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_IMPORT_KEY, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + ts_crypto_ImportKeyOut resp_msg = ts_crypto_ImportKeyOut_init_default; + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_ImportKeyOut_fields, &resp_msg)) { + + *handle = resp_msg.handle; + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + ::free(key_byte_array); + + return psa_status; +} + +psa_status_t crypto_client::export_key(psa_key_handle_t handle, + uint8_t *data, size_t data_size, + size_t *data_length) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_ExportKeyIn req_msg = ts_crypto_ExportKeyIn_init_default; + req_msg.handle = handle; + + *data_length = 0; /* For failure case */ + + if (pb_get_encoded_size(&req_len, ts_crypto_ExportKeyIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_ExportKeyIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_EXPORT_KEY, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + ts_crypto_ExportKeyOut resp_msg = ts_crypto_ExportKeyOut_init_default; + pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len); + + if (exported_key) { + + resp_msg.data = pb_in_byte_array(exported_key); + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_ExportKeyOut_fields, &resp_msg)) { + + if (exported_key->size <= data_size) { + + memcpy(data, exported_key->bytes, exported_key->size); + *data_length = exported_key->size; + } + else { + /* Provided buffer is too small */ + psa_status = PSA_ERROR_BUFFER_TOO_SMALL; + } + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + + ::free(exported_key); + } + else { + /* Failed to allocate buffer for exported key */ + psa_status = PSA_ERROR_INSUFFICIENT_MEMORY; + } + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + return psa_status; +} + +psa_status_t crypto_client::export_public_key(psa_key_handle_t handle, + uint8_t *data, size_t data_size, size_t *data_length) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_ExportPublicKeyIn req_msg = ts_crypto_ExportPublicKeyIn_init_default; + req_msg.handle = handle; + + *data_length = 0; /* For failure case */ + + if (pb_get_encoded_size(&req_len, ts_crypto_ExportPublicKeyIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_ExportPublicKeyIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_EXPORT_PUBLIC_KEY, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + ts_crypto_ExportPublicKeyOut resp_msg = ts_crypto_ExportPublicKeyOut_init_default; + pb_bytes_array_t *exported_key = pb_malloc_byte_array(resp_len); + + if (exported_key) { + + resp_msg.data = pb_in_byte_array(exported_key); + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_ExportPublicKeyOut_fields, &resp_msg)) { + + if (exported_key->size <= data_size) { + + memcpy(data, exported_key->bytes, exported_key->size); + *data_length = exported_key->size; + } + else { + /* Provided buffer is too small */ + psa_status = PSA_ERROR_BUFFER_TOO_SMALL; + } + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + + ::free(exported_key); + } + else { + /* Failed to alloocate buffer for exported key */ + psa_status = PSA_ERROR_INSUFFICIENT_MEMORY; + } + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + return psa_status; +} + +psa_status_t crypto_client::sign_hash(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + uint8_t *signature, size_t signature_size, size_t *signature_length) +{ + size_t req_len; + pb_bytes_array_t *hash_byte_array = pb_malloc_byte_array_containing_bytes(hash, hash_length); + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_SignHashIn req_msg = ts_crypto_SignHashIn_init_default; + + *signature_length = 0; /* For failure case */ + + req_msg.handle = handle; + req_msg.alg = alg; + req_msg.hash = pb_out_byte_array(hash_byte_array); + + if (pb_get_encoded_size(&req_len, ts_crypto_SignHashIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_SignHashIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_SIGN_HASH, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + pb_bytes_array_t *sig_byte_array = pb_malloc_byte_array(PSA_SIGNATURE_MAX_SIZE); + ts_crypto_SignHashOut resp_msg = ts_crypto_SignHashOut_init_default; + resp_msg.signature = pb_in_byte_array(sig_byte_array); + + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_SignHashOut_fields, &resp_msg)) { + + if (sig_byte_array->size <= signature_size) { + + memcpy(signature, sig_byte_array->bytes, sig_byte_array->size); + *signature_length = sig_byte_array->size; + } + else { + /* Provided buffer is too small */ + psa_status = PSA_ERROR_BUFFER_TOO_SMALL; + } + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + + ::free(sig_byte_array); + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + ::free(hash_byte_array); + + return psa_status; +} + + +psa_status_t crypto_client::verify_hash(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length) +{ + size_t req_len; + pb_bytes_array_t *hash_byte_array = pb_malloc_byte_array_containing_bytes(hash, hash_length); + pb_bytes_array_t *sig_byte_array = pb_malloc_byte_array_containing_bytes(signature, signature_length); + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_VerifyHashIn req_msg = ts_crypto_VerifyHashIn_init_default; + + req_msg.handle = handle; + req_msg.alg = alg; + req_msg.hash = pb_out_byte_array(hash_byte_array); + req_msg.signature = pb_out_byte_array(sig_byte_array); + + if (pb_get_encoded_size(&req_len, ts_crypto_VerifyHashIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_VerifyHashIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_VERIFY_HASH, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) psa_status = opstatus; + + rpc_caller_end(m_caller, call_handle); + } + } + + ::free(hash_byte_array); + ::free(sig_byte_array); + + return psa_status; +} + +psa_status_t crypto_client::asymmetric_encrypt(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, size_t *output_length) +{ + size_t req_len; + pb_bytes_array_t *plaintext_byte_array = pb_malloc_byte_array_containing_bytes(input, input_length); + pb_bytes_array_t *salt_byte_array = pb_malloc_byte_array_containing_bytes(salt, salt_length); + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_AsymmetricEncryptIn req_msg = ts_crypto_AsymmetricEncryptIn_init_default; + + *output_length = 0; /* For failure case */ + + req_msg.handle = handle; + req_msg.alg = alg; + req_msg.plaintext = pb_out_byte_array(plaintext_byte_array); + req_msg.salt = pb_out_byte_array(salt_byte_array); + + if (pb_get_encoded_size(&req_len, ts_crypto_AsymmetricEncryptIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus = PSA_ERROR_GENERIC_ERROR; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_AsymmetricEncryptIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_ASYMMETRIC_ENCRYPT, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + pb_bytes_array_t *ciphertext_byte_array = pb_malloc_byte_array(output_size); + ts_crypto_AsymmetricEncryptOut resp_msg = ts_crypto_AsymmetricEncryptOut_init_default; + resp_msg.ciphertext = pb_in_byte_array(ciphertext_byte_array); + + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) { + + if (ciphertext_byte_array->size <= output_size) { + + memcpy(output, ciphertext_byte_array->bytes, ciphertext_byte_array->size); + *output_length = ciphertext_byte_array->size; + } + else { + /* Provided buffer is too small */ + psa_status = PSA_ERROR_BUFFER_TOO_SMALL; + } + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + + ::free(ciphertext_byte_array); + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + ::free(plaintext_byte_array); + ::free(salt_byte_array); + + return psa_status; +} + +psa_status_t crypto_client::asymmetric_decrypt(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, size_t *output_length) +{ + size_t req_len; + pb_bytes_array_t *ciphertext_byte_array = pb_malloc_byte_array_containing_bytes(input, input_length); + pb_bytes_array_t *salt_byte_array = pb_malloc_byte_array_containing_bytes(salt, salt_length); + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_AsymmetricDecryptIn req_msg = ts_crypto_AsymmetricDecryptIn_init_default; + + *output_length = 0; /* For failure case */ + + req_msg.handle = handle; + req_msg.alg = alg; + req_msg.ciphertext = pb_out_byte_array(ciphertext_byte_array); + req_msg.salt = pb_out_byte_array(salt_byte_array); + + if (pb_get_encoded_size(&req_len, ts_crypto_AsymmetricDecryptIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_AsymmetricDecryptIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_ASYMMETRIC_DECRYPT, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + pb_bytes_array_t *plaintext_byte_array = pb_malloc_byte_array(output_size); + ts_crypto_AsymmetricDecryptOut resp_msg = ts_crypto_AsymmetricDecryptOut_init_default; + resp_msg.plaintext = pb_in_byte_array(plaintext_byte_array); + + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) { + + if (plaintext_byte_array->size <= output_size) { + + memcpy(output, plaintext_byte_array->bytes, plaintext_byte_array->size); + *output_length = plaintext_byte_array->size; + } + else { + /* Provided buffer is too small */ + m_err_rpc_status = PSA_ERROR_BUFFER_TOO_SMALL; + } + } + else { + /* Failed to decode response message */ + m_err_rpc_status = PSA_ERROR_GENERIC_ERROR; + } + + ::free(plaintext_byte_array); + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + ::free(ciphertext_byte_array); + ::free(salt_byte_array); + + return psa_status; +} + +psa_status_t crypto_client::generate_random(uint8_t *output, size_t output_size) +{ + size_t req_len; + psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR; + ts_crypto_GenerateRandomIn req_msg = ts_crypto_GenerateRandomIn_init_default; + + req_msg.size = output_size; + + if (pb_get_encoded_size(&req_len, ts_crypto_GenerateRandomIn_fields, &req_msg)) { + + rpc_call_handle call_handle; + uint8_t *req_buf; + + call_handle = rpc_caller_begin(m_caller, &req_buf, req_len); + + if (call_handle) { + + uint8_t *resp_buf; + size_t resp_len; + int opstatus; + + pb_ostream_t ostream = pb_ostream_from_buffer(req_buf, req_len); + pb_encode(&ostream, ts_crypto_GenerateRandomIn_fields, &req_msg); + + m_err_rpc_status = rpc_caller_invoke(m_caller, call_handle, + ts_crypto_Opcode_GENERATE_RANDOM, &opstatus, &resp_buf, &resp_len); + + if (m_err_rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status = opstatus; + + if (psa_status == PSA_SUCCESS) { + + pb_bytes_array_t *output_byte_array = pb_malloc_byte_array(output_size); + ts_crypto_GenerateRandomOut resp_msg = ts_crypto_GenerateRandomOut_init_default; + resp_msg.random_bytes = pb_in_byte_array(output_byte_array); + + pb_istream_t istream = pb_istream_from_buffer(resp_buf, resp_len); + + if (pb_decode(&istream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) { + + if (output_byte_array->size == output_size) { + + memcpy(output, output_byte_array->bytes, output_byte_array->size); + } + else { + /* Mismatch between requested and generated length */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + } + else { + /* Failed to decode response message */ + psa_status = PSA_ERROR_GENERIC_ERROR; + } + + ::free(output_byte_array); + } + } + + rpc_caller_end(m_caller, call_handle); + } + } + + return psa_status; +} + +void crypto_client::translate_key_attributes(ts_crypto_KeyAttributes &proto_attributes, + const psa_key_attributes_t &psa_attributes) +{ + proto_attributes.type = psa_get_key_type(&psa_attributes); + proto_attributes.key_bits = psa_get_key_bits(&psa_attributes); + proto_attributes.lifetime = psa_get_key_lifetime(&psa_attributes); + proto_attributes.id = psa_get_key_id(&psa_attributes); + + proto_attributes.has_policy = true; + proto_attributes.policy.usage = psa_get_key_usage_flags(&psa_attributes); + proto_attributes.policy.alg = psa_get_key_algorithm(&psa_attributes); + } diff --git a/components/service/crypto/client/cpp/crypto_client.h b/components/service/crypto/client/cpp/crypto_client.h new file mode 100644 index 000000000..391f521a5 --- /dev/null +++ b/components/service/crypto/client/cpp/crypto_client.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CRYPTO_CLIENT_H +#define CRYPTO_CLIENT_H + +#include +#include +#include + + +struct rpc_caller; + +/** Provides a client interface for accessing an instance of the PSA Crypto service. + **/ +class crypto_client +{ +public: + crypto_client(struct rpc_caller *caller); + virtual ~crypto_client(); + + int err_rpc_status() const; + + /* Key lifecycle methods */ + psa_status_t generate_key(const psa_key_attributes_t *attributes, psa_key_handle_t *handle); + psa_status_t destroy_key(psa_key_handle_t handle); + psa_status_t open_key(psa_key_id_t id, psa_key_handle_t *handle); + psa_status_t close_key(psa_key_handle_t handle); + psa_status_t import_key(const psa_key_attributes_t *attributes, + const uint8_t *data, size_t data_length, psa_key_handle_t *handle); + + /* Key export methods */ + psa_status_t export_key(psa_key_handle_t handle, + uint8_t *data, size_t data_size, + size_t *data_length); + psa_status_t export_public_key(psa_key_handle_t handle, + uint8_t *data, size_t data_size, size_t *data_length); + + /* Sign/verify methods */ + psa_status_t sign_hash(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + uint8_t *signature, size_t signature_size, size_t *signature_length); + psa_status_t verify_hash(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *hash, size_t hash_length, + const uint8_t *signature, size_t signature_length); + + /* Asymmetric encrypt/decrypt */ + psa_status_t asymmetric_encrypt(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, size_t *output_length); + psa_status_t asymmetric_decrypt(psa_key_handle_t handle, psa_algorithm_t alg, + const uint8_t *input, size_t input_length, + const uint8_t *salt, size_t salt_length, + uint8_t *output, size_t output_size, size_t *output_length); + + /* Random number generation */ + psa_status_t generate_random(uint8_t *output, size_t output_size); + +protected: + crypto_client(); + void set_caller(struct rpc_caller *caller) {m_caller = caller;} + +private: + + void translate_key_attributes(ts_crypto_KeyAttributes &proto_attributes, + const psa_key_attributes_t &psa_attributes); + + struct rpc_caller *m_caller; + int m_err_rpc_status; +}; + +#endif /* CRYPTO_CLIENT_H */ diff --git a/components/service/crypto/client/test/component.cmake b/components/service/crypto/client/test/component.cmake new file mode 100644 index 000000000..0374e849e --- /dev/null +++ b/components/service/crypto/client/test/component.cmake @@ -0,0 +1,14 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/test_crypto_client.cpp" + ) + diff --git a/components/service/crypto/client/test/mock/component.cmake b/components/service/crypto/client/test/mock/component.cmake new file mode 100644 index 000000000..8202578c5 --- /dev/null +++ b/components/service/crypto/client/test/mock/component.cmake @@ -0,0 +1,14 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/mock_crypto_client.cpp" + ) + diff --git a/components/service/crypto/client/test/mock/mock_crypto_client.cpp b/components/service/crypto/client/test/mock/mock_crypto_client.cpp new file mode 100644 index 000000000..8e55d34b4 --- /dev/null +++ b/components/service/crypto/client/test/mock/mock_crypto_client.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "mock_crypto_client.h" + +mock_crypto_client::mock_crypto_client() : + test_crypto_client(), + m_crypto_provider(), + m_storage_provider(), + m_crypto_caller(), + m_storage_caller() +{ + +} + +mock_crypto_client::~mock_crypto_client() +{ + +} + +bool mock_crypto_client::init() +{ + bool should_do = test_crypto_client::init(); + + if (should_do) { + + struct call_ep *storage_ep = mock_store_provider_init(&m_storage_provider); + struct rpc_caller *storage_caller = direct_caller_init_default(&m_storage_caller, storage_ep); + + struct call_ep *crypto_ep = mbed_crypto_provider_init(&m_crypto_provider, storage_caller); + struct rpc_caller *crypto_caller = direct_caller_init_default(&m_crypto_caller, crypto_ep); + + crypto_client::set_caller(crypto_caller); + } + + return should_do; +} + +bool mock_crypto_client::deinit() +{ + bool should_do = test_crypto_client::deinit(); + + if (should_do) { + + mbed_crypto_provider_deinit(&m_crypto_provider); + mock_store_provider_deinit(&m_storage_provider); + + direct_caller_deinit(&m_storage_caller); + direct_caller_deinit(&m_crypto_caller); + } + + return should_do; +} + +/* Test Methods */ +bool mock_crypto_client::keystore_reset_is_supported() const +{ + return true; +} + +void mock_crypto_client::keystore_reset() +{ + mock_store_reset(&m_storage_provider); +} + +bool mock_crypto_client::keystore_key_exists_is_supported() const +{ + return true; +} + +bool mock_crypto_client::keystore_key_exists(uint32_t id) const +{ + return mock_store_exists(&m_storage_provider, id); +} + +bool mock_crypto_client::keystore_keys_held_is_supported() const +{ + return true; +} + +size_t mock_crypto_client::keystore_keys_held() const +{ + return mock_store_num_items(&m_storage_provider); +} + +/* Factory for creating mock_crypto_client objects */ +class mock_crypto_client_factory : public test_crypto_client::factory +{ +public: + mock_crypto_client_factory() : + test_crypto_client::factory() + { + test_crypto_client::register_factory(this); + } + + ~mock_crypto_client_factory() + { + test_crypto_client::deregister_factory(this); + } + + test_crypto_client *create() + { + return new mock_crypto_client; + }; +}; + +/* + * Static construction causes this to be registered + * as the default factory for constructing test_crypto_client objects. + */ +static mock_crypto_client_factory default_factory; diff --git a/components/service/crypto/client/test/mock/mock_crypto_client.h b/components/service/crypto/client/test/mock/mock_crypto_client.h new file mode 100644 index 000000000..92ee6a993 --- /dev/null +++ b/components/service/crypto/client/test/mock/mock_crypto_client.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOCK_CRYPTO_CLIENT_H +#define MOCK_CRYPTO_CLIENT_H + +#include +#include +#include +#include + +/* + * A specialization of the crypto_client class that extends it to add crypto + * and storage providers to offer a viable crypto service from a single object. + * The mock_store storage provider is used for persistent key storage. + * This is only used for test purposes and should not be used for production + * deployments. Provides methods used for inspecting service state that + * support test. + */ +class mock_crypto_client : public test_crypto_client +{ +public: + mock_crypto_client(); + virtual ~mock_crypto_client(); + + bool init(); + bool deinit(); + + /* Test support methods */ + bool keystore_reset_is_supported() const; + void keystore_reset(); + + bool keystore_key_exists_is_supported() const; + bool keystore_key_exists(uint32_t id) const; + + bool keystore_keys_held_is_supported() const; + size_t keystore_keys_held() const; + +private: + struct mbed_crypto_provider m_crypto_provider; + struct mock_store_provider m_storage_provider; + struct direct_caller m_crypto_caller; + struct direct_caller m_storage_caller; +}; + +#endif /* MOCK_CRYPTO_CLIENT_H */ diff --git a/components/service/crypto/client/test/standalone/component.cmake b/components/service/crypto/client/test/standalone/component.cmake new file mode 100644 index 000000000..13488e898 --- /dev/null +++ b/components/service/crypto/client/test/standalone/component.cmake @@ -0,0 +1,14 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/standalone_crypto_client.cpp" + ) + diff --git a/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp b/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp new file mode 100644 index 000000000..da3224d34 --- /dev/null +++ b/components/service/crypto/client/test/standalone/standalone_crypto_client.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "standalone_crypto_client.h" +#include +#include + +standalone_crypto_client::standalone_crypto_client() : + test_crypto_client(), + m_crypto_provider(), + m_storage_provider(), + m_crypto_caller(), + m_storage_caller(), + m_dummy_storage_caller() +{ + +} + +standalone_crypto_client::~standalone_crypto_client() +{ + +} + +bool standalone_crypto_client::init() +{ + bool should_do = test_crypto_client::init(); + + if (should_do) { + + struct rpc_caller *storage_caller; + + if (!is_fault_injected(FAILED_TO_DISCOVER_SECURE_STORAGE)) { + + /* Establish rpc session with storage provider */ + struct call_ep *storage_ep = sfs_provider_init(&m_storage_provider); + storage_caller = direct_caller_init_default(&m_storage_caller, storage_ep); + } + else { + + /* + * Missing storage service fault injected. To allow a somewhat viable + * crypto service to be started, use a dummy _caller that will safely + * terminate storage calls with an appropriate error. + */ + storage_caller = dummy_caller_init(&m_dummy_storage_caller, + TS_RPC_CALL_ACCEPTED, PSA_ERROR_STORAGE_FAILURE); + } + + struct call_ep *crypto_ep = mbed_crypto_provider_init(&m_crypto_provider, storage_caller); + struct rpc_caller *crypto_caller = direct_caller_init_default(&m_crypto_caller, crypto_ep); + + crypto_client::set_caller(crypto_caller); + } + + return should_do; +} + +bool standalone_crypto_client::deinit() +{ + bool should_do = test_crypto_client::deinit(); + + if (should_do) { + + mbed_crypto_provider_deinit(&m_crypto_provider); + + direct_caller_deinit(&m_storage_caller); + direct_caller_deinit(&m_crypto_caller); + } + + return should_do; +} + +/* Fault injection */ +bool standalone_crypto_client::is_fault_supported(enum fault_code code) const +{ + return (code == test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE); +} + +/* Test Methods */ +bool standalone_crypto_client::keystore_reset_is_supported() const +{ + return test_crypto_client::keystore_reset_is_supported(); +} + +void standalone_crypto_client::keystore_reset() +{ + test_crypto_client::keystore_reset(); +} + +bool standalone_crypto_client::keystore_key_exists_is_supported() const +{ + return test_crypto_client::keystore_key_exists_is_supported() ; +} + +bool standalone_crypto_client::keystore_key_exists(uint32_t id) const +{ + return test_crypto_client::keystore_key_exists(id); +} + +bool standalone_crypto_client::keystore_keys_held_is_supported() const +{ + return test_crypto_client::keystore_keys_held_is_supported(); +} + +size_t standalone_crypto_client::keystore_keys_held() const +{ + return test_crypto_client::keystore_keys_held(); +} + +/* Factory for creating standalone_crypto_client objects */ +class standalone_crypto_client_factory : public test_crypto_client::factory +{ +public: + standalone_crypto_client_factory() : + test_crypto_client::factory() + { + test_crypto_client::register_factory(this); + } + + ~standalone_crypto_client_factory() + { + test_crypto_client::deregister_factory(this); + } + + test_crypto_client *create() + { + return new standalone_crypto_client; + }; +}; + +/* + * Static construction causes this to be registered + * as the default factory for constructing test_crypto_client objects. + */ +static standalone_crypto_client_factory default_factory; diff --git a/components/service/crypto/client/test/standalone/standalone_crypto_client.h b/components/service/crypto/client/test/standalone/standalone_crypto_client.h new file mode 100644 index 000000000..9327fdcd6 --- /dev/null +++ b/components/service/crypto/client/test/standalone/standalone_crypto_client.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef STANDALONE_CRYPTO_CLIENT_H +#define STANDALONE_CRYPTO_CLIENT_H + +#include +#include +#include +#include +#include + +/* + * A specialization of the crypto_client class that extends it to add crypto + * and storage providers to offer a viable crypto service from a single object. + * This is only used for test purposes and should not be used for production + * deployments. Provides methods used for inspecting service state that + * support test. + */ +class standalone_crypto_client : public test_crypto_client +{ +public: + standalone_crypto_client(); + virtual ~standalone_crypto_client(); + + bool init(); + bool deinit(); + + /* Test support methods */ + bool keystore_reset_is_supported() const; + void keystore_reset(); + + bool keystore_key_exists_is_supported() const; + bool keystore_key_exists(uint32_t id) const; + + bool keystore_keys_held_is_supported() const; + size_t keystore_keys_held() const; + +private: + bool is_fault_supported(enum fault_code code) const; + + struct mbed_crypto_provider m_crypto_provider; + struct sfs_provider m_storage_provider; + struct direct_caller m_crypto_caller; + struct direct_caller m_storage_caller; + struct dummy_caller m_dummy_storage_caller; +}; + +#endif /* STANDALONE_CRYPTO_CLIENT_H */ diff --git a/components/service/crypto/client/test/test_crypto_client.cpp b/components/service/crypto/client/test/test_crypto_client.cpp new file mode 100644 index 000000000..72327904c --- /dev/null +++ b/components/service/crypto/client/test/test_crypto_client.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include "test_crypto_client.h" + +test_crypto_client::factory *test_crypto_client::m_default_factory = NULL; + +test_crypto_client::test_crypto_client() : + crypto_client(), + m_is_initialized(false), + m_injected_faults() +{ + +} + +test_crypto_client::~test_crypto_client() +{ + deinit(); +} + +bool test_crypto_client::init() +{ + bool success = !m_is_initialized; + m_is_initialized = true; + return success; +} + +bool test_crypto_client::deinit() +{ + bool success = m_is_initialized; + m_is_initialized = false; + return success; +} + +test_crypto_client *test_crypto_client::create_default() +{ + /* + * It's mandatory to include a concrete test_crypto_client + * that registers its own factory in a deployment if you + * want to use this factory method. + */ + assert(m_default_factory); + return m_default_factory->create(); +} + +void test_crypto_client::register_factory(factory *factory) +{ + /* + * Don't allow overriding of an existing default. This + * will happen if two test_crypto_client components have + * been included in a deployment. + */ + assert(!m_default_factory); + m_default_factory = factory; +} + +void test_crypto_client::deregister_factory(factory *factory) +{ + if (m_default_factory == factory) m_default_factory = NULL; +} + +bool test_crypto_client::inject_fault(enum fault_code code) +{ + assert(!m_is_initialized); + + bool is_supported = is_fault_supported(code); + if (is_supported) m_injected_faults.push_back(code); + return is_supported; +} + +bool test_crypto_client::is_fault_supported(enum fault_code code) const +{ + /* Derived classes may override this if fault simualtion is supported */ + (void)code; + return false; +} + +bool test_crypto_client::is_fault_injected(enum fault_code code) const +{ + bool is_injected = false; + + for (size_t i = 0; !is_injected && i < m_injected_faults.size(); ++i) { + is_injected = (m_injected_faults[i] == code); + } + + return is_injected; +} + +/* + * Test methods by default are not supported. Calling a non-supported + * method will trigger an assert. A class derived from this one may + * pick and choose which test methods it supports. + */ +bool test_crypto_client::keystore_reset_is_supported() const { return false; } +void test_crypto_client::keystore_reset() { assert(false); } + +bool test_crypto_client::keystore_key_exists_is_supported() const { return false; } +bool test_crypto_client::keystore_key_exists(uint32_t id) const { (void)id; assert(false); return false; } + +bool test_crypto_client::keystore_keys_held_is_supported() const { return false; } +size_t test_crypto_client::keystore_keys_held() const { assert(false); return 0; } \ No newline at end of file diff --git a/components/service/crypto/client/test/test_crypto_client.h b/components/service/crypto/client/test/test_crypto_client.h new file mode 100644 index 000000000..5b927dbe0 --- /dev/null +++ b/components/service/crypto/client/test/test_crypto_client.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEST_CRYPTO_CLIENT_H +#define TEST_CRYPTO_CLIENT_H + +#include +#include + +/* + * A specialization of the crypto_client class that extends it to add + * virtial methods to support test. Depending on the deployment, + * real implementations of test methods may or may not exist. For example, + * for a real distributed deployment where the key store is located in + * a secure processing environment, back door test methods that peak + * into the keystore are clearly not possible (or at least desirable!). + * Each virtual test method is paired with a is_supported() method to + * allow test cases to adapt to circumstances. + */ +class test_crypto_client : public crypto_client +{ +public: + virtual ~test_crypto_client(); + + virtual bool init(); + virtual bool deinit(); + + /* + * A factory method for contsructing the default class + * of test_crypto_client for the deployment. + */ + static test_crypto_client *create_default(); + + /* + * Fault conditions that may be injected to allow error + * handling to be tested. + */ + enum fault_code + { + FAILED_TO_DISCOVER_SECURE_STORAGE + }; + + /* + * Injects the specified fault. May be called multiple + * times to inject different fault conditions. Faults + * should be injected prior to calling the init() method + * to allow startup faults to be simulated. Returns true + * if the fault condition can be simulated. + */ + bool inject_fault(enum fault_code code); + + /* Wipe all keys held in the keystore */ + virtual bool keystore_reset_is_supported() const; + virtual void keystore_reset(); + + /* Check if a key is held in the keystore */ + virtual bool keystore_key_exists_is_supported() const; + virtual bool keystore_key_exists(uint32_t id) const; + + /* Return the number of keys in the keystore */ + virtual bool keystore_keys_held_is_supported() const; + virtual size_t keystore_keys_held() const; + + /* An abstract factory for constructing concrete test_crypto_client objects */ + class factory + { + public: + virtual test_crypto_client *create() = 0; + }; + + static void register_factory(factory *factory); + static void deregister_factory(factory *factory); + +protected: + test_crypto_client(); + virtual bool is_fault_supported(enum fault_code code) const; + bool is_fault_injected(enum fault_code code) const; + +private: + bool m_is_initialized; + std::vector m_injected_faults; + static factory *m_default_factory; +}; + +#endif /* STANDALONE_CRYPTO_CLIENT_H */ diff --git a/components/service/crypto/provider/mbedcrypto/component.cmake b/components/service/crypto/provider/mbedcrypto/component.cmake new file mode 100644 index 000000000..f508e53d3 --- /dev/null +++ b/components/service/crypto/provider/mbedcrypto/component.cmake @@ -0,0 +1,31 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/crypto_provider.c" + ) + +target_include_directories(${TGT} + PRIVATE + "${CMAKE_CURRENT_LIST_DIR}" + ) + +# Force use of the mbed crypto configuration required by the crypto service +# provider. This configuration includes enabling the use of the PSA ITS API +# for persistent key storage which is realised by the its client adapter +# for the secure storage service. +set(MBEDCRYPTO_CONFIG_FILE + "${CMAKE_CURRENT_LIST_DIR}/config_mbed_crypto.h" + CACHE STRING "Configuration file for mbedcrypto" FORCE) + +set(MBEDCRYPTO_EXTRA_INCLUDES + "${TS_ROOT}/components/service/common" + "${TS_ROOT}/components/service/secure_storage/client" + CACHE STRING "PSA ITS for mbedcrypto" FORCE) diff --git a/components/service/crypto/provider/mbedcrypto/config_mbed_crypto.h b/components/service/crypto/provider/mbedcrypto/config_mbed_crypto.h new file mode 100644 index 000000000..cb8d6bd2e --- /dev/null +++ b/components/service/crypto/provider/mbedcrypto/config_mbed_crypto.h @@ -0,0 +1,1954 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CONFIG_MBED_CRYPTO_H +#define CONFIG_MBED_CRYPTO_H + +/** + * Defines the configuration needed by the crypto service provider + */ + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/aria.c + * library/timing.c + * include/mbedtls/bn_mul.h + * + * Required by: + * MBEDTLS_AESNI_C + * MBEDTLS_PADLOCK_C + * + * Comment to disable the use of assembly code. + */ +#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +#define MBEDTLS_NO_UDBL_DIVISION + +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +//#define MBEDTLS_NO_64BIT_MULTIPLICATION + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions + */ +//#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). + * The time needs to be correct (not necessarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. + */ +//#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) + * + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Uncomment to prevent default assignment of standard functions in the + * platform layer. + */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT +//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions so that they generate a warning if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions so that they generate an error if used. + * Functions deprecated in one version will usually be removed in the next + * version. You can enable this to help you prepare the transition to a new + * major version by making sure your code is not using these functions. + * + * Uncomment to get errors on using deprecated functions. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/** + * \def MBEDTLS_CHECK_PARAMS + * + * This configuration option controls whether the library validates more of + * the parameters passed to it. + * + * When this flag is not defined, the library only attempts to validate an + * input parameter if: (1) they may come from the outside world (such as the + * network, the filesystem, etc.) or (2) not validating them could result in + * internal memory errors such as overflowing a buffer controlled by the + * library. On the other hand, it doesn't attempt to validate parameters whose + * values are fully controlled by the application (such as pointers). + * + * When this flag is defined, the library additionally attempts to validate + * parameters that are fully controlled by the application, and should always + * be valid if the application code is fully correct and trusted. + * + * For example, when a function accepts as input a pointer to a buffer that may + * contain untrusted data, and its documentation mentions that this pointer + * must not be NULL: + * - the pointer is checked to be non-NULL only if this option is enabled + * - the content of the buffer is always validated + * + * When this flag is defined, if a library function receives a parameter that + * is invalid, it will: + * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a + * call to the function mbedtls_param_failed() + * - immediately return (with a specific error code unless the function + * returns void and can't communicate an error). + * + * When defining this flag, you also need to: + * - either provide a definition of the function mbedtls_param_failed() in + * your application (see platform_util.h for its prototype) as the library + * calls that function, but does not provide a default definition for it, + * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED() + * below if the above mechanism is not flexible enough to suit your needs. + * See the documentation of this macro later in this file. + * + * Uncomment to enable validation of application-controlled parameters. + */ +//#define MBEDTLS_CHECK_PARAMS + +/* \} name SECTION: System support */ + +/** + * \name SECTION: mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(), + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + * + * \warning MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARC4_ALT +//#define MBEDTLS_ARIA_ALT +//#define MBEDTLS_BLOWFISH_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT +//#define MBEDTLS_CMAC_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT +//#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT +//#define MBEDTLS_MD2_ALT +//#define MBEDTLS_MD4_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT +//#define MBEDTLS_XTEA_ALT + +/* + * When replacing the elliptic curve module, pleace consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT + +/** + * \def MBEDTLS_MD2_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * \note Because of a signature change, the core AES encryption and decryption routines are + * currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt, + * respectively. When setting up alternative implementations, these functions should + * be overridden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt + * must stay untouched. + * + * \note If you use the AES_xxx_ALT macros, then is is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + * + * \warning MD2, MD4, MD5, DES and SHA-1 are considered weak and their use + * constitutes a security risk. If possible, we recommend avoiding + * dependencies on them, and considering stronger message digests + * and ciphers instead. + * + */ +//#define MBEDTLS_MD2_PROCESS_ALT +//#define MBEDTLS_MD4_PROCESS_ALT +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT +//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT +//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT +//#define MBEDTLS_ECDSA_VERIFY_ALT +//#define MBEDTLS_ECDSA_SIGN_ALT +//#define MBEDTLS_ECDSA_GENKEY_ALT + +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac + * function, but will use your mbedtls_internal_ecp_double_jac if the group is + * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when + * receives it as an argument). If the group is not supported then the original + * implementation is used. The other functions and the definition of + * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your + * implementation of mbedtls_internal_ecp_double_jac and + * mbedtls_internal_ecp_grp_capable must be compatible with this definition. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT + +/** + * \def MBEDTLS_TEST_NULL_ENTROPY + * + * Enables testing and use of mbed TLS without any configured entropy sources. + * This permits use of the library on platforms before an entropy source has + * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the + * MBEDTLS_ENTROPY_NV_SEED switches). + * + * WARNING! This switch MUST be disabled in production builds, and is suitable + * only for development. + * Enabling the switch negates any security provided by the library. + * + * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + */ +//#define MBEDTLS_TEST_NULL_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in entropy_poll.h, and accept NULL as first argument. + * + * Uncomment to use your own hardware entropy collector. + */ +#define MBEDTLS_ENTROPY_HARDWARE_ALT + +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Use precomputed AES tables stored in ROM. + * + * Uncomment this macro to use precomputed AES tables stored in ROM. + * Comment this macro to generate AES tables in RAM at runtime. + * + * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb + * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the + * initialization time before the first AES operation can be performed. + * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c + * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded + * performance if ROM access is slower than RAM access. + * + * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + * + */ +//#define MBEDTLS_AES_ROM_TABLES + +/** + * \def MBEDTLS_AES_FEWER_TABLES + * + * Use less ROM/RAM for AES tables. + * + * Uncommenting this macro omits 75% of the AES tables from + * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) + * by computing their values on the fly during operations + * (the tables are entry-wise rotations of one another). + * + * Tradeoff: Uncommenting this reduces the RAM / ROM footprint + * by ~6kb but at the cost of more arithmetic operations during + * runtime. Specifically, one has to compare 4 accesses within + * different tables to 4 accesses with additional arithmetic + * operations within the same table. The performance gain/loss + * depends on the system and memory details. + * + * This option is independent of \c MBEDTLS_AES_ROM_TABLES. + * + */ +//#define MBEDTLS_AES_FEWER_TABLES + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_CTR + +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +#define MBEDTLS_CIPHER_MODE_XTS + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * This module is required to support the TLS ciphersuites that use the NULL + * cipher. + * + * Uncomment this macro to enable the NULL cipher + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ +#define MBEDTLS_CIPHER_PADDING_PKCS7 +#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS +#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN +#define MBEDTLS_CIPHER_PADDING_ZEROS + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ +#define MBEDTLS_ECP_NIST_OPTIM + +/** + * \def MBEDTLS_ECP_RESTARTABLE + * + * Enable "non-blocking" ECC operations that can return early and be resumed. + * + * This allows various functions to pause by returning + * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in Mbed TLS's SSL module, + * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in order + * to further progress and eventually complete their operation. This is + * controlled through mbedtls_ecp_set_max_ops() which limits the maximum number + * of ECC operations a function may perform before pausing; see + * mbedtls_ecp_set_max_ops() for more information. + * + * This is useful in non-threaded environments if you want to avoid blocking + * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. + * + * Uncomment this macro to enable restartable ECC computations. + * + * \note This option only works with the default software implementation of + * elliptic curve functionality. It is incompatible with + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT. + */ +//#define MBEDTLS_ECP_RESTARTABLE + +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C + * + * Comment this macro to disable deterministic ECDSA. + */ +#define MBEDTLS_ECDSA_DETERMINISTIC + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +//#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources. These are the platform specific, + * mbedtls_timing_hardclock and HAVEGE based poll functions. + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/* MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + * + * In PSA key storage, encode the owner of the key. + * + * This is only meaningful when building the library as part of a + * multi-client service. When you activate this option, you must provide + * an implementation of the type psa_key_owner_id_t and a translation + * from psa_key_file_id_t to file name in all the storage backends that + * you wish to support. + * + * Note that this option is meant for internal use only and may be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() an backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +#define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +#define MBEDTLS_PKCS1_V21 + +/** + * \def MBEDTLS_PSA_CRYPTO_SPM + * + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure + * Partition Manager) integration which separates the code into two parts: a + * NSPE (Non-Secure Process Environment) and an SPE (Secure Process + * Environment). + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SPM + +/** + * \def MBEDTLS_PSA_INJECT_ENTROPY + * + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. + * + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED + * + */ +//#define MBEDTLS_PSA_INJECT_ENTROPY + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +//#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonnable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +//#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_USE_PSA_CRYPTO + * + * Make the X.509 and TLS library use PSA for cryptographic operations, see + * #MBEDTLS_PSA_CRYPTO_C. + * + * Note: this option is still in progress, the full X.509 and TLS modules are + * not covered yet, but parts that are not ported to PSA yet will still work + * as usual, so enabling this option should not break backwards compatibility. + * + * \warning Support for PSA is still an experimental feature. + * Any public API that depends on this option may change + * at any time until this warning is removed. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + */ +//#define MBEDTLS_USE_PSA_CRYPTO + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +#define MBEDTLS_VERSION_FEATURES + +/* \} name SECTION: mbed TLS feature support */ + +/** + * \name SECTION: mbed TLS modules + * + * This section enables or disables entire modules in mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the AES-NI instructions on x86-64 + */ +//#define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/cipher.c + * library/pem.c + * library/ctr_drbg.c + * + * This module is required to support the TLS ciphersuites that use the AES + * cipher. + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ARC4_C + * + * Enable the ARCFOUR stream cipher. + * + * Module: library/arc4.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the ARC4 + * cipher. + * + * \warning ARC4 is considered a weak cipher and its use constitutes a + * security risk. If possible, we recommend avoidng dependencies on + * it, and considering stronger ciphers instead. + * + */ +#define MBEDTLS_ARC4_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + */ +#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/rsa_internal.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_BLOWFISH_C + * + * Enable the Blowfish block cipher. + * + * Module: library/blowfish.c + */ +#define MBEDTLS_BLOWFISH_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * Camellia cipher. + */ +#define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_ARIA_C + * + * Enable the ARIA block cipher. + * + * Module: library/aria.c + * Caller: library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the + * ARIA cipher. + */ +//#define MBEDTLS_ARIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support AES-CCM ciphersuites in TLS. + */ +#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +#define MBEDTLS_CHACHA20_C + +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +#define MBEDTLS_CHACHAPOLY_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-based random generator. + * The CTR_DRBG generator uses AES-256 by default. + * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C + * + * This module provides the CTR_DRBG AES random number generator. + */ +#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/cipher.c + * + * This module is required to support the TLS ciphersuites that use the DES + * cipher. + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + * + * \warning DES is considered a weak cipher and its use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +#define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +#define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C + */ +#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C + */ +//#define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM) for AES. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C + * + * This module is required to support the TLS ciphersuites that use GCM. + */ +#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_HAVEGE_C + * + * Enable the HAVEGE random generator. + * + * Warning: the HAVEGE random generator is not suitable for virtualized + * environments + * + * Warning: the HAVEGE random generator is dependent on timing and specific + * processor traits. It is therefore not advised to use HAVEGE as + * your applications primary random generator or primary entropy pool + * input. As a secondary input to your entropy pool, it IS able add + * the (limited) extra entropy it provides. + * + * Module: library/havege.c + * Caller: + * + * Requires: MBEDTLS_TIMING_C + * + * Uncomment to enable the HAVEGE random generator. + */ +//#define MBEDTLS_HAVEGE_C + +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +#define MBEDTLS_HKDF_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number geerator. + */ +#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +//#define MBEDTLS_NIST_KW_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic message digest layer. + * + * Module: library/md.c + * Caller: + * + * Uncomment to enable generic message digest wrappers. + */ +#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD2_C + * + * Enable the MD2 hash algorithm. + * + * Module: library/md2.c + * Caller: + * + * Uncomment to enable support for (rare) MD2-signed X.509 certs. + * + * \warning MD2 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD2_C + +/** + * \def MBEDTLS_MD4_C + * + * Enable the MD4 hash algorithm. + * + * Module: library/md4.c + * Caller: + * + * Uncomment to enable support for (rare) MD4-signed X.509 certs. + * + * \warning MD4 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +//#define MBEDTLS_MD4_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * + * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2 + * depending on the handshake parameters. Further, it is used for checking + * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded + * encrypted keys. + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * + * This modules translates between OIDs and internal values. + */ +#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +//#define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for decoding / parsing PEM files. + */ +#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymetric) key layer. + * + * Module: library/pk.c + * + * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymetric) key parser. + * + * Module: library/pkparse.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymetric) key writer. + * + * Module: library/pkwrite.c + * + * Requires: MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the PKCS#5 functions. + */ +#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * Can use: MBEDTLS_ARC4_C + * + * This module enables PKCS#12 functions. + */ +#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other module rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +//#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +#define MBEDTLS_POLY1305_C + +/** + * \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * Module: library/psa_crypto.c + * + * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C + * + */ +#define MBEDTLS_PSA_CRYPTO_C + +/** + * \def MBEDTLS_PSA_CRYPTO_STORAGE_C + * + * Enable the Platform Security Architecture persistent key storage. + * + * Module: library/psa_crypto_storage.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface + */ +#define MBEDTLS_PSA_CRYPTO_STORAGE_C + +/** + * \def MBEDTLS_PSA_ITS_FILE_C + * + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. + * + * Module: library/psa_its_file.c + * + * Requires: MBEDTLS_FS_IO + */ +//#define MBEDTLS_PSA_ITS_FILE_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * library/rsa_internal.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +#define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * + * This module is required for SSL/TLS up to version 1.1, for TLS 1.2 + * depending on the handshake parameters, and for SHA1-signed certificates. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-224 and SHA-256 cryptographic hash algorithms. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-224 and SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable the SHA-384 and SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * + * This module adds support for SHA-384 and SHA-512. + */ +#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within mbed TLS + */ +//#define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by Mbed + * TLS's \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and + * provide your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + * Caller: library/havege.c + * + * This module is used by the HAVEGE random number generator. + */ +//#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_XTEA_C + * + * Enable the XTEA block cipher. + * + * Module: library/xtea.c + * Caller: + */ +#define MBEDTLS_XTEA_C + +/* \} name SECTION: mbed TLS modules */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * + * Please check the respective header file for documentation on these + * parameters (to prevent duplicate documentation). + * \{ + */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_MAX_BITS 521 /**< Maximum bit size of groups */ +//#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default allocator to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ + +/** + * Uncomment the macro to let mbed TLS use your alternate implementation of + * mbedtls_platform_zeroize(). This replaces the default implementation in + * platform_util.c. + * + * mbedtls_platform_zeroize() is a widely used function across the library to + * zero a block of memory. The implementation is expected to be secure in the + * sense that it has been written to prevent the compiler from removing calls + * to mbedtls_platform_zeroize() as part of redundant code elimination + * optimizations. However, it is difficult to guarantee that calls to + * mbedtls_platform_zeroize() will not be optimized by the compiler as older + * versions of the C language standards do not provide a secure implementation + * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to + * configure their own implementation of mbedtls_platform_zeroize(), for + * example by using directives specific to their compiler, features from newer + * C standards (e.g using memset_s() in C11) or calling a secure memset() from + * their system (e.g explicit_bzero() in BSD). + */ +//#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + +/* \} name SECTION: Customisation configuration options */ + +/* Target and application specific configurations + * + * Allow user to override any previous default. + * + */ +#if defined(MBEDTLS_USER_CONFIG_FILE) +#include MBEDTLS_USER_CONFIG_FILE +#endif + +#include "mbedtls/check_config.h" + +#endif /* CONFIG_MBED_CRYPTO_H */ diff --git a/components/service/crypto/provider/mbedcrypto/crypto_provider.c b/components/service/crypto/provider/mbedcrypto/crypto_provider.c new file mode 100644 index 000000000..e8c77e90a --- /dev/null +++ b/components/service/crypto/provider/mbedcrypto/crypto_provider.c @@ -0,0 +1,605 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Service request handlers */ +static rpc_status_t nop_handler(void *context, struct call_req* req); +static rpc_status_t generate_key_handler(void *context, struct call_req* req); +static rpc_status_t destroy_key_handler(void *context, struct call_req* req); +static rpc_status_t open_key_handler(void *context, struct call_req* req); +static rpc_status_t close_key_handler(void *context, struct call_req* req); +static rpc_status_t export_key_handler(void *context, struct call_req* req); +static rpc_status_t export_public_key_handler(void *context, struct call_req* req); +static rpc_status_t import_key_handler(void *context, struct call_req* req); +static rpc_status_t sign_hash_handler(void *context, struct call_req* req); +static rpc_status_t verify_hash_handler(void *context, struct call_req* req); +static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req); +static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req); +static rpc_status_t generate_random_handler(void *context, struct call_req* req); + +/* Handler mapping table for service */ +static const struct service_handler handler_table[] = { + {TS_CRYPTO_OPCODE_NOP, nop_handler}, + {TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler}, + {TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler}, + {TS_CRYPTO_OPCODE_OPEN_KEY, open_key_handler}, + {TS_CRYPTO_OPCODE_CLOSE_KEY, close_key_handler}, + {TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler}, + {TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler}, + {TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler}, + {TS_CRYPTO_OPCODE_SIGN_HASH, sign_hash_handler}, + {TS_CRYPTO_OPCODE_VERIFY_HASH, verify_hash_handler}, + {TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler}, + {TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler}, + {TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler} +}; + +struct call_ep *mbed_crypto_provider_init(struct mbed_crypto_provider *context, + struct rpc_caller *storage_provider) +{ + struct call_ep *call_ep = NULL; + + /* + * A storage provider is required for persistent key storage. As this + * is a mandatory feature of the crypto service, insist on a storage + * provider being available. + */ + if (context && storage_provider) { + + service_provider_init(&context->base_provider, context, + handler_table, sizeof(handler_table)/sizeof(struct service_handler)); + + service_set_default_serializer(&context->base_provider, + pb_crypto_provider_serializer_instance()); + + if ((psa_its_client_init(storage_provider) == PSA_SUCCESS) && + (psa_crypto_init() == PSA_SUCCESS)) + call_ep = service_provider_get_call_ep(&context->base_provider); + } + + return call_ep; +} + +void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context) +{ + (void)context; +} + +static inline const struct crypto_provider_serializer* get_crypto_serializer(const struct call_req *req) +{ + return (const struct crypto_provider_serializer*)call_req_get_serializer(req); +} + +static rpc_status_t nop_handler(void *context, struct call_req* req) +{ + /* Responds to a request by returning success */ + rpc_status_t rpc_status = TS_RPC_CALL_ACCEPTED; + psa_status_t psa_status = PSA_SUCCESS; + + (void)context; + call_req_set_opstatus(req, psa_status); + + return rpc_status; +} + +static rpc_status_t generate_key_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + rpc_status = serializer->deserialize_generate_key_req(req_buf, &attributes); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + psa_key_handle_t handle; + + psa_status = psa_generate_key(&attributes, &handle); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_generate_key_resp(resp_buf, handle); + } + + call_req_set_opstatus(req, psa_status); + } + + psa_reset_key_attributes(&attributes); + + return rpc_status; +} + +static rpc_status_t destroy_key_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_handle_t handle; + + rpc_status = serializer->deserialize_destroy_key_req(req_buf, &handle); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + + psa_status = psa_destroy_key(handle); + call_req_set_opstatus(req, psa_status); + } + + return rpc_status; +} + +static rpc_status_t open_key_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_id_t id; + + rpc_status = serializer->deserialize_open_key_req(req_buf, &id); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + psa_key_handle_t handle; + + psa_status = psa_open_key(id, &handle); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_open_key_resp(resp_buf, handle); + } + + call_req_set_opstatus(req, psa_status); + } + + return rpc_status; +} + +static rpc_status_t close_key_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_handle_t handle; + + rpc_status = serializer->deserialize_close_key_req(req_buf, &handle); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + + psa_status = psa_close_key(handle); + call_req_set_opstatus(req, psa_status); + } + + return rpc_status; +} + +static rpc_status_t export_key_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_handle_t handle; + + rpc_status = serializer->deserialize_export_key_req(req_buf, &handle); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status = psa_get_key_attributes(handle, &attributes); + + if (psa_status == PSA_SUCCESS) { + + size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE( + psa_get_key_type(&attributes), + psa_get_key_bits(&attributes)); + + uint8_t *key_buffer = malloc(max_export_size); + + if (key_buffer) { + + size_t export_size; + psa_status = psa_export_key(handle, key_buffer, max_export_size, &export_size); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_export_key_resp(resp_buf, key_buffer, export_size); + } + + free(key_buffer); + } + else { + /* Failed to allocate key buffer */ + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + } + + call_req_set_opstatus(req, psa_status); + psa_reset_key_attributes(&attributes); + } + + return rpc_status; +} + +static rpc_status_t export_public_key_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_handle_t handle; + + rpc_status = serializer->deserialize_export_public_key_req(req_buf, &handle); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status = psa_get_key_attributes(handle, &attributes); + + if (psa_status == PSA_SUCCESS) { + + size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE( + PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)), + psa_get_key_bits(&attributes)); + + uint8_t *key_buffer = malloc(max_export_size); + + if (key_buffer) { + + size_t export_size; + psa_status = psa_export_public_key(handle, key_buffer, max_export_size, &export_size); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_export_public_key_resp(resp_buf, key_buffer, export_size); + } + + free(key_buffer); + } + else { + /* Failed to allocate key buffer */ + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + } + + call_req_set_opstatus(req, psa_status); + psa_reset_key_attributes(&attributes); + } + + return rpc_status; +} + +static rpc_status_t import_key_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + size_t key_data_len = serializer->max_deserialised_parameter_size(req_buf); + uint8_t *key_buffer = malloc(key_data_len); + + if (key_buffer) { + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + rpc_status = serializer->deserialize_import_key_req(req_buf, &attributes, key_buffer, &key_data_len); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + psa_key_handle_t handle; + + psa_status = psa_import_key(&attributes, key_buffer, key_data_len, &handle); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_import_key_resp(resp_buf, handle); + } + + call_req_set_opstatus(req, psa_status); + } + + psa_reset_key_attributes(&attributes); + free(key_buffer); + } + else { + + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + + return rpc_status; +} + +static rpc_status_t sign_hash_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_handle_t handle; + psa_algorithm_t alg; + size_t hash_len = PSA_HASH_MAX_SIZE; + uint8_t hash_buffer[PSA_HASH_MAX_SIZE]; + + rpc_status = serializer->deserialize_sign_hash_req(req_buf, &handle, &alg, hash_buffer, &hash_len); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + size_t sig_len; + uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE]; + + psa_status = psa_sign_hash(handle, alg, + hash_buffer, hash_len, + sig_buffer, sizeof(sig_buffer), &sig_len); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_sign_hash_resp(resp_buf, sig_buffer, sig_len); + } + + call_req_set_opstatus(req, psa_status); + } + + return rpc_status; +} + +static rpc_status_t verify_hash_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + psa_key_handle_t handle; + psa_algorithm_t alg; + size_t hash_len = PSA_HASH_MAX_SIZE; + uint8_t hash_buffer[PSA_HASH_MAX_SIZE]; + size_t sig_len = PSA_SIGNATURE_MAX_SIZE; + uint8_t sig_buffer[PSA_SIGNATURE_MAX_SIZE]; + + rpc_status = serializer->deserialize_verify_hash_req(req_buf, &handle, &alg, + hash_buffer, &hash_len, + sig_buffer, &sig_len); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + + psa_status = psa_verify_hash(handle, alg, + hash_buffer, hash_len, + sig_buffer, sig_len); + + call_req_set_opstatus(req, psa_status); + } + + return rpc_status; +} + +static rpc_status_t asymmetric_decrypt_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf); + (void)context; + + psa_key_handle_t handle; + psa_algorithm_t alg; + size_t ciphertext_len = max_param_size; + uint8_t *ciphertext_buffer = malloc(ciphertext_len); + size_t salt_len = max_param_size; + uint8_t *salt_buffer = malloc(salt_len); + + if (ciphertext_buffer && salt_buffer) { + + rpc_status = serializer->deserialize_asymmetric_decrypt_req(req_buf, + &handle, &alg, + ciphertext_buffer, &ciphertext_len, + salt_buffer, &salt_len); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status = psa_get_key_attributes(handle, &attributes); + + if (psa_status == PSA_SUCCESS) { + + size_t max_decrypt_size = PSA_ASYMMETRIC_DECRYPT_OUTPUT_SIZE( + psa_get_key_type(&attributes), + psa_get_key_bits(&attributes), + alg); + + size_t plaintext_len; + uint8_t *plaintext_buffer = malloc(max_decrypt_size); + + if (plaintext_buffer) { + + psa_status = psa_asymmetric_decrypt(handle, alg, + ciphertext_buffer, ciphertext_len, + salt_buffer, salt_len, + plaintext_buffer, max_decrypt_size, &plaintext_len); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_asymmetric_decrypt_resp(resp_buf, + plaintext_buffer, plaintext_len); + } + + free(plaintext_buffer); + } + else { + /* Failed to allocate ouptput buffer */ + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + } + + call_req_set_opstatus(req, psa_status); + psa_reset_key_attributes(&attributes); + } + } + else { + /* Failed to allocate buffers */ + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + + free(ciphertext_buffer); + free(salt_buffer); + + return rpc_status; +} + +static rpc_status_t asymmetric_encrypt_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + size_t max_param_size = serializer->max_deserialised_parameter_size(req_buf); + (void)context; + + psa_key_handle_t handle; + psa_algorithm_t alg; + size_t plaintext_len = max_param_size; + uint8_t *plaintext_buffer = malloc(plaintext_len); + size_t salt_len = max_param_size; + uint8_t *salt_buffer = malloc(salt_len); + + if (plaintext_buffer && salt_buffer) { + + rpc_status = serializer->deserialize_asymmetric_encrypt_req(req_buf, + &handle, &alg, + plaintext_buffer, &plaintext_len, + salt_buffer, &salt_len); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_status = psa_get_key_attributes(handle, &attributes); + + if (psa_status == PSA_SUCCESS) { + + size_t max_encrypt_size = PSA_ASYMMETRIC_ENCRYPT_OUTPUT_SIZE( + psa_get_key_type(&attributes), + psa_get_key_bits(&attributes), + alg); + + size_t ciphertext_len; + uint8_t *ciphertext_buffer = malloc(max_encrypt_size); + + if (ciphertext_buffer) { + + psa_status = psa_asymmetric_encrypt(handle, alg, + plaintext_buffer, plaintext_len, + salt_buffer, salt_len, + ciphertext_buffer, max_encrypt_size, &ciphertext_len); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_asymmetric_encrypt_resp(resp_buf, + ciphertext_buffer, ciphertext_len); + } + + free(ciphertext_buffer); + } + else { + /* Failed to allocate ouptput buffer */ + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + } + + call_req_set_opstatus(req, psa_status); + psa_reset_key_attributes(&attributes); + } + } + else { + /* Failed to allocate buffers */ + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + + free(plaintext_buffer); + free(salt_buffer); + + return rpc_status; +} + +static rpc_status_t generate_random_handler(void *context, struct call_req* req) +{ + rpc_status_t rpc_status; + struct call_param_buf *req_buf = call_req_get_req_buf(req); + const struct crypto_provider_serializer *serializer = get_crypto_serializer(req); + (void)context; + + size_t output_size; + + rpc_status = serializer->deserialize_generate_random_req(req_buf, &output_size); + + if (rpc_status == TS_RPC_CALL_ACCEPTED) { + + psa_status_t psa_status; + uint8_t *output_buffer = malloc(output_size); + + if (output_buffer) { + + psa_status = psa_generate_random(output_buffer, output_size); + + if (psa_status == PSA_SUCCESS) { + + struct call_param_buf *resp_buf = call_req_get_resp_buf(req); + rpc_status = serializer->serialize_generate_random_resp(resp_buf, + output_buffer, output_size); + } + + call_req_set_opstatus(req, psa_status); + free(output_buffer); + } + else { + /* Failed to allocate output buffer */ + rpc_status = TS_RPC_ERROR_RESOURCE_FAILURE; + } + } + + return rpc_status; +} \ No newline at end of file diff --git a/components/service/crypto/provider/mbedcrypto/crypto_provider.h b/components/service/crypto/provider/mbedcrypto/crypto_provider.h new file mode 100644 index 000000000..856867d07 --- /dev/null +++ b/components/service/crypto/provider/mbedcrypto/crypto_provider.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MBED_CRYPTO_PROVIDER_H +#define MBED_CRYPTO_PROVIDER_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct mbed_crypto_provider +{ + struct service_provider base_provider; +}; + +/* + * Initializes an instance of the crypto service provider that uses the + * Mbed Crypto library to implement crypto operations. Secure storage + * for persistent keys needs to be provided by a suitable storage + * provider, accessed using the secure storage service access protocol + * using the provided rpc_caller. Any rpc endpoint discovery and + * session establishment should have been performed prior to initializing + * the mbed_crypto_provider. On successfully initializing the provider, + * a pointer to the call_ep for the service is returned. + */ +struct call_ep *mbed_crypto_provider_init(struct mbed_crypto_provider *context, + struct rpc_caller *storage_provider); + +/* + * When operation of the provider is no longer required, this function + * frees any resource used by the previously initialized provider instance. + */ +void mbed_crypto_provider_deinit(struct mbed_crypto_provider *context); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* MBED_CRYPTO_PROVIDER_H */ diff --git a/components/service/crypto/provider/mbedcrypto/entropy_source/mock/component.cmake b/components/service/crypto/provider/mbedcrypto/entropy_source/mock/component.cmake new file mode 100644 index 000000000..cb48329b5 --- /dev/null +++ b/components/service/crypto/provider/mbedcrypto/entropy_source/mock/component.cmake @@ -0,0 +1,13 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/mock_entropy_source.c" + ) diff --git a/components/service/crypto/provider/mbedcrypto/entropy_source/mock/mock_entropy_source.c b/components/service/crypto/provider/mbedcrypto/entropy_source/mock/mock_entropy_source.c new file mode 100644 index 000000000..f76448170 --- /dev/null +++ b/components/service/crypto/provider/mbedcrypto/entropy_source/mock/mock_entropy_source.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +/* + * A mock entropy source without any hardware dependencies. Should not be + * used in production deployments. + */ +int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) +{ + ((void) data); + ((void) output); + *olen = 0; + + if (len < sizeof(unsigned char) ) + return (0); + + *olen = sizeof(unsigned char); + + return (0); +} diff --git a/components/service/crypto/provider/serializer/crypto_provider_serializer.h b/components/service/crypto/provider/serializer/crypto_provider_serializer.h new file mode 100644 index 000000000..de7a8731f --- /dev/null +++ b/components/service/crypto/provider/serializer/crypto_provider_serializer.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef CRYPTO_PROVIDER_SERIALIZER_H +#define CRYPTO_PROVIDER_SERIALIZER_H + +#include +#include +#include +#include + +/* Provides a common interface for parameter serialization operations + * for the crypto service provider. Allows alternative serialization + * protocols to be used without hard-wiring a particular protocol + * into the service provider code. A concrete serializer must + * implement this interface. + */ +struct crypto_provider_serializer { + + /* Returns the maximum deserialized parameter size that could + * be encoded in a request buffer. Used for determining worst-case + * buffer size without having to actually deserialize the message. + */ + size_t (*max_deserialised_parameter_size)(const struct call_param_buf *req_buf); + + /* Operation: generate_key */ + rpc_status_t (*deserialize_generate_key_req)(const struct call_param_buf *req_buf, + psa_key_attributes_t *attributes); + + rpc_status_t (*serialize_generate_key_resp)(struct call_param_buf *resp_buf, + psa_key_handle_t handle); + + /* Operation: destroy_key */ + rpc_status_t (*deserialize_destroy_key_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle); + + /* Operation: open_key */ + rpc_status_t (*deserialize_open_key_req)(const struct call_param_buf *req_buf, + psa_key_id_t *id); + + rpc_status_t (*serialize_open_key_resp)(struct call_param_buf *resp_buf, + psa_key_handle_t handle); + + /* Operation: close_key */ + rpc_status_t (*deserialize_close_key_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle); + + /* Operation: export_key */ + rpc_status_t (*deserialize_export_key_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle); + + rpc_status_t (*serialize_export_key_resp)(struct call_param_buf *resp_buf, + const uint8_t *data, size_t data_len); + + /* Operation: export_public_key */ + rpc_status_t (*deserialize_export_public_key_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle); + + rpc_status_t (*serialize_export_public_key_resp)(struct call_param_buf *resp_buf, + const uint8_t *data, size_t data_len); + + /* Operation: import_key */ + rpc_status_t (*deserialize_import_key_req)(const struct call_param_buf *req_buf, + psa_key_attributes_t *attributes, + uint8_t *data, size_t *data_len); + + rpc_status_t (*serialize_import_key_resp)(struct call_param_buf *resp_buf, + psa_key_handle_t handle); + + /* Operation: sign_hash */ + rpc_status_t (*deserialize_sign_hash_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *hash, size_t *hash_len); + + rpc_status_t (*serialize_sign_hash_resp)(struct call_param_buf *resp_buf, + const uint8_t *sig, size_t sig_len); + + /* Operation: verify_hash */ + rpc_status_t (*deserialize_verify_hash_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *hash, size_t *hash_len, + uint8_t *sig, size_t *sig_len); + + /* Operation: asymmetric_decrypt */ + rpc_status_t (*deserialize_asymmetric_decrypt_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *ciphertext, size_t *ciphertext_len, + uint8_t *salt, size_t *salt_len); + + rpc_status_t (*serialize_asymmetric_decrypt_resp)(struct call_param_buf *resp_buf, + const uint8_t *plaintext, size_t plaintext_len); + + /* Operation: asymmetric_encrypt */ + rpc_status_t (*deserialize_asymmetric_encrypt_req)(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *plaintext, size_t *plaintext_len, + uint8_t *salt, size_t *salt_len); + + rpc_status_t (*serialize_asymmetric_encrypt_resp)(struct call_param_buf *resp_buf, + const uint8_t *ciphertext, size_t ciphertext_len); + + /* Operation: generate_random */ + rpc_status_t (*deserialize_generate_random_req)(const struct call_param_buf *req_buf, + size_t *size); + + rpc_status_t (*serialize_generate_random_resp)(struct call_param_buf *resp_buf, + const uint8_t *output, size_t output_len); +}; + +#endif /* CRYPTO_PROVIDER_SERIALIZER_H */ diff --git a/components/service/crypto/provider/serializer/protobuf/component.cmake b/components/service/crypto/provider/serializer/protobuf/component.cmake new file mode 100644 index 000000000..2a075b74d --- /dev/null +++ b/components/service/crypto/provider/serializer/protobuf/component.cmake @@ -0,0 +1,20 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/pb_crypto_provider_serializer.c" + "${CMAKE_CURRENT_LIST_DIR}/pb_key_attributes_translator.c" + ) + + +target_include_directories(${TGT} + PRIVATE + "${CMAKE_CURRENT_LIST_DIR}" + ) diff --git a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c new file mode 100644 index 000000000..2cf38fee8 --- /dev/null +++ b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.c @@ -0,0 +1,591 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pb_key_attributes_translator.h" +#include "pb_crypto_provider_serializer.h" + +/* Returns the maximum possible deserialized parameter size for a protobuf encoded message. */ +static size_t max_deserialised_parameter_size(const struct call_param_buf *req_buf) +{ + /* + * Assume that a deserialized parameter must be the same size or smalled than the + * entire serialized message. + */ + return req_buf->data_len; +} + +/* Operation: generate_key */ +static rpc_status_t deserialize_generate_key_req(const struct call_param_buf *req_buf, + psa_key_attributes_t *attributes) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_GenerateKeyIn recv_msg = ts_crypto_GenerateKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_GenerateKeyIn_fields, &recv_msg) && recv_msg.has_attributes) { + + pb_crypto_provider_translate_key_attributes(attributes, &recv_msg.attributes); + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +static rpc_status_t serialize_generate_key_resp(struct call_param_buf *resp_buf, + psa_key_handle_t handle) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_GenerateKeyOut resp_msg = ts_crypto_GenerateKeyOut_init_default; + resp_msg.handle = handle; + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_GenerateKeyOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_GenerateKeyOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + return rpc_status; +} + +/* Operation: destroy_key */ +static rpc_status_t deserialize_destroy_key_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_DestroyKeyIn recv_msg = ts_crypto_DestroyKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_DestroyKeyIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +/* Operation: open_key */ +static rpc_status_t deserialize_open_key_req(const struct call_param_buf *req_buf, psa_key_id_t *id) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_OpenKeyIn recv_msg = ts_crypto_OpenKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_OpenKeyIn_fields, &recv_msg)) { + + *id = recv_msg.id; + + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +static rpc_status_t serialize_open_key_resp(struct call_param_buf *resp_buf, + psa_key_handle_t handle) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_OpenKeyOut resp_msg = ts_crypto_OpenKeyOut_init_default; + resp_msg.handle = handle; + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_OpenKeyOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_OpenKeyOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + return rpc_status; +} + +/* Operation: close_key */ +static rpc_status_t deserialize_close_key_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_CloseKeyIn recv_msg = ts_crypto_CloseKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_CloseKeyIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +/* Operation: export_key */ +static rpc_status_t deserialize_export_key_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_ExportKeyIn recv_msg = ts_crypto_ExportKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_ExportKeyIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +static rpc_status_t serialize_export_key_resp(struct call_param_buf *resp_buf, + const uint8_t *data, size_t data_len) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_ExportKeyOut resp_msg = ts_crypto_ExportKeyOut_init_default; + pb_bytes_array_t *key_buffer = pb_malloc_byte_array(data_len); + + memcpy(&key_buffer->bytes, data, data_len); + resp_msg.data = pb_out_byte_array(key_buffer); + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_ExportKeyOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_ExportKeyOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + free(key_buffer); + + return rpc_status; +} + +/* Operation: export_public_key */ +static rpc_status_t deserialize_export_public_key_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_ExportPublicKeyIn recv_msg = ts_crypto_ExportPublicKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_ExportPublicKeyIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +static rpc_status_t serialize_export_public_key_resp(struct call_param_buf *resp_buf, + const uint8_t *data, size_t data_len) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_ExportPublicKeyOut resp_msg = ts_crypto_ExportPublicKeyOut_init_default; + + pb_bytes_array_t *key_buffer = pb_malloc_byte_array(data_len); + resp_msg.data = pb_out_byte_array(key_buffer); + memcpy(&key_buffer->bytes, data, data_len); + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_ExportPublicKeyOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_ExportPublicKeyOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + free(key_buffer); + + return rpc_status; +} + +/* Operation: import_key */ +static rpc_status_t deserialize_import_key_req(const struct call_param_buf *req_buf, + psa_key_attributes_t *attributes, uint8_t *data, size_t *data_len) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_ImportKeyIn recv_msg = ts_crypto_ImportKeyIn_init_default; + + pb_bytes_array_t *key_buffer = pb_malloc_byte_array(*data_len); + recv_msg.data = pb_in_byte_array(key_buffer); + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_ImportKeyIn_fields, &recv_msg) && + recv_msg.has_attributes && + (key_buffer->size <= *data_len)) { + + pb_crypto_provider_translate_key_attributes(attributes, &recv_msg.attributes); + + memcpy(data, &key_buffer->bytes, key_buffer->size); + *data_len = key_buffer->size; + + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + free(key_buffer); + + return rpc_status; +} + +static rpc_status_t serialize_import_key_resp(struct call_param_buf *resp_buf, + psa_key_handle_t handle) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_ImportKeyOut resp_msg = ts_crypto_ImportKeyOut_init_default; + resp_msg.handle = handle; + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_ImportKeyOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_ImportKeyOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + return rpc_status; +} + +/* Operation: sign_hash */ +static rpc_status_t deserialize_sign_hash_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *hash, size_t *hash_len) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_SignHashIn recv_msg = ts_crypto_SignHashIn_init_default; + + pb_bytes_array_t *hash_buffer = pb_malloc_byte_array(*hash_len); + recv_msg.hash = pb_in_byte_array(hash_buffer); + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_SignHashIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + *alg = recv_msg.alg; + + memcpy(hash, &hash_buffer->bytes, hash_buffer->size); + *hash_len = hash_buffer->size; + + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + free(hash_buffer); + + return rpc_status; +} + +static rpc_status_t serialize_sign_hash_resp(struct call_param_buf *resp_buf, + const uint8_t *sig, size_t sig_len) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_SignHashOut resp_msg = ts_crypto_SignHashOut_init_default; + + pb_bytes_array_t *sig_buffer = pb_malloc_byte_array(sig_len); + resp_msg.signature = pb_out_byte_array(sig_buffer); + memcpy(&sig_buffer->bytes, sig, sig_len); + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_SignHashOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_SignHashOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + free(sig_buffer); + + return rpc_status; +} + +/* Operation: verify_hash */ +static rpc_status_t deserialize_verify_hash_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *hash, size_t *hash_len, + uint8_t *sig, size_t *sig_len) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_VerifyHashIn recv_msg = ts_crypto_VerifyHashIn_init_default; + + pb_bytes_array_t *hash_buffer = pb_malloc_byte_array(*hash_len); + recv_msg.hash = pb_in_byte_array(hash_buffer); + + pb_bytes_array_t *sig_buffer = pb_malloc_byte_array(*sig_len); + recv_msg.signature = pb_in_byte_array(sig_buffer); + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_VerifyHashIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + *alg = recv_msg.alg; + + memcpy(hash, &hash_buffer->bytes, hash_buffer->size); + *hash_len = hash_buffer->size; + + memcpy(sig, &sig_buffer->bytes, sig_buffer->size); + *sig_len = sig_buffer->size; + + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + free(hash_buffer); + free(sig_buffer); + + return rpc_status; +} + +/* Operation: asymmetric_decrypt */ +static rpc_status_t deserialize_asymmetric_decrypt_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *ciphertext, size_t *ciphertext_len, + uint8_t *salt, size_t *salt_len) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_AsymmetricDecryptIn recv_msg = ts_crypto_AsymmetricDecryptIn_init_default; + + pb_bytes_array_t *ciphertext_buffer = pb_malloc_byte_array(*ciphertext_len); + recv_msg.ciphertext = pb_in_byte_array(ciphertext_buffer); + + pb_bytes_array_t *salt_buffer = pb_malloc_byte_array(*salt_len); + recv_msg.salt = pb_in_byte_array(salt_buffer); + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_AsymmetricDecryptIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + *alg = recv_msg.alg; + + memcpy(ciphertext, &ciphertext_buffer->bytes, ciphertext_buffer->size); + *ciphertext_len = ciphertext_buffer->size; + + memcpy(salt, &salt_buffer->bytes, salt_buffer->size); + *salt_len = salt_buffer->size; + + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + free(ciphertext_buffer); + free(salt_buffer); + + return rpc_status; +} + +static rpc_status_t serialize_asymmetric_decrypt_resp(struct call_param_buf *resp_buf, + const uint8_t *plaintext, size_t plaintext_len) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_AsymmetricDecryptOut resp_msg = ts_crypto_AsymmetricDecryptOut_init_default; + + pb_bytes_array_t *plaintext_buffer = pb_malloc_byte_array(plaintext_len); + resp_msg.plaintext = pb_out_byte_array(plaintext_buffer); + memcpy(&plaintext_buffer->bytes, plaintext, plaintext_len); + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_AsymmetricDecryptOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + free(plaintext_buffer); + + return rpc_status; +} + +/* Operation: asymmetric_encrypt */ +static rpc_status_t deserialize_asymmetric_encrypt_req(const struct call_param_buf *req_buf, + psa_key_handle_t *handle, psa_algorithm_t *alg, + uint8_t *plaintext, size_t *plaintext_len, + uint8_t *salt, size_t *salt_len) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_AsymmetricEncryptIn recv_msg = ts_crypto_AsymmetricEncryptIn_init_default; + + pb_bytes_array_t *plaintext_buffer = pb_malloc_byte_array(*plaintext_len); + recv_msg.plaintext = pb_in_byte_array(plaintext_buffer); + + pb_bytes_array_t *salt_buffer = pb_malloc_byte_array(*salt_len); + recv_msg.salt = pb_in_byte_array(salt_buffer); + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_AsymmetricEncryptIn_fields, &recv_msg)) { + + *handle = recv_msg.handle; + *alg = recv_msg.alg; + + memcpy(plaintext, &plaintext_buffer->bytes, plaintext_buffer->size); + *plaintext_len = plaintext_buffer->size; + + memcpy(salt, &salt_buffer->bytes, salt_buffer->size); + *salt_len = salt_buffer->size; + + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + free(plaintext_buffer); + free(salt_buffer); + + return rpc_status; +} + +static rpc_status_t serialize_asymmetric_encrypt_resp(struct call_param_buf *resp_buf, + const uint8_t *ciphertext, size_t ciphertext_len) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_AsymmetricEncryptOut resp_msg = ts_crypto_AsymmetricEncryptOut_init_default; + + pb_bytes_array_t *ciphertext_buffer = pb_malloc_byte_array(ciphertext_len); + resp_msg.ciphertext = pb_out_byte_array(ciphertext_buffer); + memcpy(&ciphertext_buffer->bytes, ciphertext, ciphertext_len); + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_AsymmetricEncryptOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + free(ciphertext_buffer); + + return rpc_status; +} + +/* Operation: generate_random */ +static rpc_status_t deserialize_generate_random_req(const struct call_param_buf *req_buf, + size_t *size) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INVALID_REQ_BODY; + ts_crypto_GenerateRandomIn recv_msg = ts_crypto_GenerateRandomIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer((const uint8_t*)req_buf->data, req_buf->data_len); + + if (pb_decode(&istream, ts_crypto_GenerateRandomIn_fields, &recv_msg)) { + + *size = recv_msg.size; + + rpc_status = TS_RPC_CALL_ACCEPTED; + } + + return rpc_status; +} + +static rpc_status_t serialize_generate_random_resp(struct call_param_buf *resp_buf, + const uint8_t *output, size_t output_len) +{ + size_t packed_resp_size; + rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL; + ts_crypto_GenerateRandomOut resp_msg = ts_crypto_GenerateRandomOut_init_default; + + pb_bytes_array_t *output_buffer = pb_malloc_byte_array(output_len); + resp_msg.random_bytes = pb_out_byte_array(output_buffer); + memcpy(&output_buffer->bytes, output, output_len); + + if (pb_get_encoded_size(&packed_resp_size, ts_crypto_GenerateRandomOut_fields, &resp_msg) && + (packed_resp_size <= resp_buf->size)) { + + pb_ostream_t ostream = pb_ostream_from_buffer((uint8_t*)resp_buf->data, packed_resp_size); + if (pb_encode(&ostream, ts_crypto_GenerateRandomOut_fields, &resp_msg)) { + + resp_buf->data_len = packed_resp_size; + rpc_status = TS_RPC_CALL_ACCEPTED; + } + } + + free(output_buffer); + + return rpc_status; +} + +/* Singleton method to provide access to the serializer instance */ +const struct crypto_provider_serializer *pb_crypto_provider_serializer_instance(void) +{ + static const struct crypto_provider_serializer instance = { + max_deserialised_parameter_size, + deserialize_generate_key_req, + serialize_generate_key_resp, + deserialize_destroy_key_req, + deserialize_open_key_req, + serialize_open_key_resp, + deserialize_close_key_req, + deserialize_export_key_req, + serialize_export_key_resp, + deserialize_export_public_key_req, + serialize_export_public_key_resp, + deserialize_import_key_req, + serialize_import_key_resp, + deserialize_sign_hash_req, + serialize_sign_hash_resp, + deserialize_verify_hash_req, + deserialize_asymmetric_decrypt_req, + serialize_asymmetric_decrypt_resp, + deserialize_asymmetric_encrypt_req, + serialize_asymmetric_encrypt_resp, + deserialize_generate_random_req, + serialize_generate_random_resp + }; + + return &instance; +} diff --git a/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h new file mode 100644 index 000000000..64191c02d --- /dev/null +++ b/components/service/crypto/provider/serializer/protobuf/pb_crypto_provider_serializer.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PB_CRYPTO_PROVIDER_SERIALIZER_H +#define PB_CRYPTO_PROVIDER_SERIALIZER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Singleton method to provide access to the Protobuf serializer + * for the crypto service provider. + */ +extern const struct crypto_provider_serializer *pb_crypto_provider_serializer_instance(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PB_CRYPTO_PROVIDER_SERIALIZER_H */ diff --git a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c new file mode 100644 index 000000000..14286a37d --- /dev/null +++ b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "pb_key_attributes_translator.h" + +void pb_crypto_provider_translate_key_attributes(psa_key_attributes_t *psa_attributes, + const ts_crypto_KeyAttributes *proto_attributes) { + + psa_set_key_type(psa_attributes, proto_attributes->type); + psa_set_key_bits(psa_attributes, proto_attributes->key_bits); + psa_set_key_lifetime(psa_attributes, proto_attributes->lifetime); + + if (proto_attributes->lifetime == PSA_KEY_LIFETIME_PERSISTENT) { + + psa_set_key_id(psa_attributes, proto_attributes->id); + } + + if (proto_attributes->has_policy) { + + psa_set_key_usage_flags(psa_attributes, proto_attributes->policy.usage); + psa_set_key_algorithm(psa_attributes, proto_attributes->policy.alg); + } +} diff --git a/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h new file mode 100644 index 000000000..5de359bb3 --- /dev/null +++ b/components/service/crypto/provider/serializer/protobuf/pb_key_attributes_translator.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PB_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H +#define PB_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H + +#include +#include + +extern void pb_crypto_provider_translate_key_attributes( + psa_key_attributes_t *psa_attributes, + const ts_crypto_KeyAttributes *proto_attributes); + +#endif /* PB_CRYPTO_PROVIDER_KEY_ATTRIBUTES_TRANSLATOR_H */ \ No newline at end of file diff --git a/components/service/crypto/test/service/component.cmake b/components/service/crypto/test/service/component.cmake new file mode 100644 index 000000000..26366fd36 --- /dev/null +++ b/components/service/crypto/test/service/component.cmake @@ -0,0 +1,15 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/crypto_service_op_tests.cpp" + "${CMAKE_CURRENT_LIST_DIR}/crypto_service_limit_tests.cpp" + ) + diff --git a/components/service/crypto/test/service/crypto_service_limit_tests.cpp b/components/service/crypto/test/service/crypto_service_limit_tests.cpp new file mode 100644 index 000000000..53c856082 --- /dev/null +++ b/components/service/crypto/test/service/crypto_service_limit_tests.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Service-level tests that focus on verifying that expected limits are met. + * e.g. number of keys, key sizes etc. + */ +TEST_GROUP(CryptoServiceLimitTests) +{ + void setup() + { + struct rpc_caller *caller; + int status; + + m_rpc_session_handle = NULL; + m_crypto_service_context = NULL; + m_crypto_client = NULL; + + service_locator_init(); + + m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status); + assert(m_crypto_service_context); + + m_rpc_session_handle = service_context_open(m_crypto_service_context, &caller); + assert(m_rpc_session_handle); + + m_crypto_client = new crypto_client(caller); + } + + void teardown() + { + delete m_crypto_client; + m_crypto_client = NULL; + + service_context_close(m_crypto_service_context, m_rpc_session_handle); + m_rpc_session_handle = NULL; + + service_context_relinquish(m_crypto_service_context); + m_crypto_service_context = NULL; + } + + psa_status_t generateVolatileEccKeyPair(std::vector &key_handles) + { + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 521); + + psa_key_handle_t key_handle; + status = m_crypto_client->generate_key(&attributes, &key_handle); + + psa_reset_key_attributes(&attributes); + + if (status == PSA_SUCCESS) key_handles.push_back(key_handle); + + return status; + } + + psa_status_t generateVolatileRsaKeyPair(std::vector &key_handles) + { + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT); + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, 512); + + psa_key_handle_t key_handle; + status = m_crypto_client->generate_key(&attributes, &key_handle); + + psa_reset_key_attributes(&attributes); + + if (status == PSA_SUCCESS) key_handles.push_back(key_handle); + + return status; + } + + psa_status_t destroyKeys(const std::vector &key_handles) + { + psa_status_t status = PSA_SUCCESS; + size_t key_index = 0; + + while ((key_index < key_handles.size()) && (status == PSA_SUCCESS)) { + + status = m_crypto_client->destroy_key(key_handles[key_index]); + ++key_index; + } + + return status; + } + + /* + * Maximum number of key slots in mbedcrypto + * is 32. We would expect it to be possible to + * generate keys up to that limit. + */ + const size_t MAX_KEY_SLOTS = 32; + + rpc_session_handle m_rpc_session_handle; + struct service_context *m_crypto_service_context; + crypto_client *m_crypto_client; +}; + +TEST(CryptoServiceLimitTests, volatileEccKeyPairLimit) +{ + size_t expected_limit = MAX_KEY_SLOTS; + size_t actual_limit = 0; + std::vector key_handles; + psa_status_t generate_status = PSA_SUCCESS; + psa_status_t destroy_status; + + while (actual_limit < expected_limit) { + + generate_status = generateVolatileEccKeyPair(key_handles); + + if (generate_status == PSA_SUCCESS) + ++actual_limit; + else + break; + } + + destroy_status = destroyKeys(key_handles); + + CHECK_EQUAL(PSA_SUCCESS, generate_status); + CHECK_EQUAL(PSA_SUCCESS, destroy_status); + CHECK_EQUAL(expected_limit, actual_limit); +} + +TEST(CryptoServiceLimitTests, volatileRsaKeyPairLimit) +{ + size_t expected_limit = MAX_KEY_SLOTS; + size_t actual_limit = 0; + std::vector key_handles; + psa_status_t generate_status = PSA_SUCCESS; + psa_status_t destroy_status; + + while (actual_limit < expected_limit) { + + generate_status = generateVolatileRsaKeyPair(key_handles); + + if (generate_status == PSA_SUCCESS) + ++actual_limit; + else + break; + } + + destroy_status = destroyKeys(key_handles); + + CHECK_EQUAL(PSA_SUCCESS, generate_status); + CHECK_EQUAL(PSA_SUCCESS, destroy_status); + CHECK_EQUAL(expected_limit, actual_limit); +} \ No newline at end of file diff --git a/components/service/crypto/test/service/crypto_service_op_tests.cpp b/components/service/crypto/test/service/crypto_service_op_tests.cpp new file mode 100644 index 000000000..cd4bd0406 --- /dev/null +++ b/components/service/crypto/test/service/crypto_service_op_tests.cpp @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +/* + * Service-level tests that focus on exercising each supported operation. + * These are mainly valid behaviour tests with the goal of checking + * that the number of operations supported is as expected. + */ +TEST_GROUP(CryptoServiceOpTests) +{ + void setup() + { + struct rpc_caller *caller; + int status; + + m_rpc_session_handle = NULL; + m_crypto_service_context = NULL; + m_crypto_client = NULL; + + service_locator_init(); + + m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0", &status); + assert(m_crypto_service_context); + + m_rpc_session_handle = service_context_open(m_crypto_service_context, &caller); + assert(m_rpc_session_handle); + + m_crypto_client = new crypto_client(caller); + } + + void teardown() + { + delete m_crypto_client; + m_crypto_client = NULL; + + service_context_close(m_crypto_service_context, m_rpc_session_handle); + m_rpc_session_handle = NULL; + + service_context_relinquish(m_crypto_service_context); + m_crypto_service_context = NULL; + } + + rpc_session_handle m_rpc_session_handle; + struct service_context *m_crypto_service_context; + crypto_client *m_crypto_client; +}; + +TEST(CryptoServiceOpTests, generateVolatileKeys) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + /* Generate first key */ + psa_key_handle_t key_handle_1; + status = m_crypto_client->generate_key(&attributes, &key_handle_1); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* And another */ + psa_key_handle_t key_handle_2; + status = m_crypto_client->generate_key(&attributes, &key_handle_2); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Expect the key handles to be different */ + CHECK(key_handle_1 != key_handle_2); + + /* Remove the keys */ + status = m_crypto_client->destroy_key(key_handle_1); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->destroy_key(key_handle_2); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); +} + +TEST(CryptoServiceOpTests, generatePersistentKeys) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + /* First try and generate a key with an invalid keu id */ + psa_key_id_t key_id_invalid = 0; + psa_set_key_id(&attributes, key_id_invalid); + psa_key_handle_t key_handle_invalid; + status = m_crypto_client->generate_key(&attributes, &key_handle_invalid); + CHECK_EQUAL(PSA_ERROR_INVALID_ARGUMENT, status); + + /* Generate first key */ + psa_key_id_t key_id_1 = 100000; + psa_set_key_id(&attributes, key_id_1); + psa_key_handle_t key_handle_1; + status = m_crypto_client->generate_key(&attributes, &key_handle_1); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* And another */ + psa_key_id_t key_id_2 = 2; + psa_set_key_id(&attributes, key_id_2); + psa_key_handle_t key_handle_2; + status = m_crypto_client->generate_key(&attributes, &key_handle_2); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Expect the key handles to be different */ + CHECK(key_handle_1 != key_handle_2); + + /* Obtain more handles using key_open */ + psa_key_handle_t key_handle_3; + status = m_crypto_client->open_key(key_id_1, &key_handle_3); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_key_handle_t key_handle_4; + status = m_crypto_client->open_key(key_id_1, &key_handle_4); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Relinquish handles */ + status = m_crypto_client->close_key(key_handle_3); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->close_key(key_handle_4); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Expect close handle to now be invalid */ + status = m_crypto_client->close_key(key_handle_4); + CHECK_EQUAL(PSA_ERROR_INVALID_HANDLE, status); + + /* Remove the keys */ + status = m_crypto_client->destroy_key(key_handle_1); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->destroy_key(key_handle_2); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); +} + +TEST(CryptoServiceOpTests, exportPublicKey) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_handle_t key_handle; + + psa_set_key_id(&attributes, 10); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + /* Generate a key */ + status = m_crypto_client->generate_key(&attributes, &key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + + /* Export the public key */ + uint8_t key_buf[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256)]; + size_t key_len = 0; + + status = m_crypto_client->export_public_key(key_handle, key_buf, sizeof(key_buf), &key_len); + CHECK_EQUAL(PSA_SUCCESS, status); + CHECK(key_len > 0); + + /* Remove the key */ + status = m_crypto_client->destroy_key(key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); +} + +TEST(CryptoServiceOpTests, exportAndImportKeyPair) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_handle_t key_handle_1; + psa_key_handle_t key_handle_2; + + psa_set_key_id(&attributes, 11); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + /* Generate a key */ + status = m_crypto_client->generate_key(&attributes, &key_handle_1); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Export the key pair */ + uint8_t key_buf[PSA_KEY_EXPORT_ECC_KEY_PAIR_MAX_SIZE(256)]; + size_t key_len = 0; + + status = m_crypto_client->export_key(key_handle_1, key_buf, sizeof(key_buf), &key_len); + CHECK_EQUAL(PSA_SUCCESS, status); + CHECK(key_len > 0); + + /* Import the key pair value with a different key id */ + psa_set_key_id(&attributes, 12); + status = m_crypto_client->import_key(&attributes, key_buf, key_len, &key_handle_2); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + + /* Remove the keys */ + status = m_crypto_client->destroy_key(key_handle_1); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->destroy_key(key_handle_2); + CHECK_EQUAL(PSA_SUCCESS, status); +} + +TEST(CryptoServiceOpTests, signAndVerifyHash) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_handle_t key_handle; + + psa_set_key_id(&attributes, 13); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + /* Generate a key */ + status = m_crypto_client->generate_key(&attributes, &key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + + /* Sign a hash */ + uint8_t hash[20]; + uint8_t signature[PSA_SIGNATURE_MAX_SIZE]; + size_t signature_length; + + memset(hash, 0x71, sizeof(hash)); + + status = m_crypto_client->sign_hash(key_handle, + PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash), + signature, sizeof(signature), &signature_length); + + CHECK_EQUAL(PSA_SUCCESS, status); + CHECK(signature_length > 0); + + /* Verify the signature */ + status = m_crypto_client->verify_hash(key_handle, + PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash), + signature, signature_length); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Change the hash and expect verify to fail */ + hash[0] = 0x72; + status = m_crypto_client->verify_hash(key_handle, + PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, sizeof(hash), + signature, signature_length); + CHECK_EQUAL(PSA_ERROR_INVALID_SIGNATURE, status); + + /* Remove the key */ + status = m_crypto_client->destroy_key(key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); +} + +TEST(CryptoServiceOpTests, asymEncryptDecrypt) +{ + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_handle_t key_handle; + + psa_set_key_id(&attributes, 14); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT); + psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT); + psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR); + psa_set_key_bits(&attributes, 256); + + /* Generate a key */ + status = m_crypto_client->generate_key(&attributes, &key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + + /* Encrypt a message */ + uint8_t message[] = {'q','u','i','c','k','b','r','o','w','n','f','o','x'}; + uint8_t ciphertext[256]; + size_t ciphertext_len = 0; + + status = m_crypto_client->asymmetric_encrypt(key_handle, PSA_ALG_RSA_PKCS1V15_CRYPT, + message, sizeof(message), NULL, 0, + ciphertext, sizeof(ciphertext), &ciphertext_len); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Decrypt it */ + uint8_t plaintext[256]; + size_t plaintext_len = 0; + + status = m_crypto_client->asymmetric_decrypt(key_handle, PSA_ALG_RSA_PKCS1V15_CRYPT, + ciphertext, ciphertext_len, NULL, 0, + plaintext, sizeof(plaintext), &plaintext_len); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Expect the encrypted/decrypted message to match theh original */ + CHECK_EQUAL(sizeof(message), plaintext_len); + CHECK(memcmp(message, plaintext, plaintext_len) == 0); + + /* Remove the key */ + status = m_crypto_client->destroy_key(key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); +} + +TEST(CryptoServiceOpTests, generateRandomNumbers) +{ + psa_status_t status; + uint8_t num1_8bit[1]; + uint8_t num2_8bit[1]; + uint8_t num3_16bit[2]; + uint8_t num4_16bit[2]; + uint8_t num5_24bit[3]; + uint8_t num6_24bit[3]; + uint8_t num7_32bit[4]; + uint8_t num8_32bit[4]; + uint8_t num9_64bit[8]; + uint8_t num10_64bit[8]; + uint8_t num11_128bit[16]; + uint8_t num12_128bit[16]; + + /* Clear all buffers */ + memset(num1_8bit, 0, sizeof(num1_8bit)); + memset(num2_8bit, 0, sizeof(num2_8bit)); + memset(num3_16bit, 0, sizeof(num3_16bit)); + memset(num4_16bit, 0, sizeof(num4_16bit)); + memset(num5_24bit, 0, sizeof(num5_24bit)); + memset(num6_24bit, 0, sizeof(num6_24bit)); + memset(num7_32bit, 0, sizeof(num7_32bit)); + memset(num8_32bit, 0, sizeof(num8_32bit)); + memset(num9_64bit, 0, sizeof(num9_64bit)); + memset(num10_64bit, 0, sizeof(num10_64bit)); + memset(num11_128bit, 0, sizeof(num11_128bit)); + memset(num12_128bit, 0, sizeof(num12_128bit)); + + /* Generate some different size random numbers */ + status = m_crypto_client->generate_random(num1_8bit, sizeof(num1_8bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num2_8bit, sizeof(num2_8bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num3_16bit, sizeof(num3_16bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num4_16bit, sizeof(num4_16bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num5_24bit, sizeof(num5_24bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num6_24bit, sizeof(num6_24bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num7_32bit, sizeof(num7_32bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num8_32bit, sizeof(num8_32bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num9_64bit, sizeof(num9_64bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num10_64bit, sizeof(num10_64bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num11_128bit, sizeof(num11_128bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + status = m_crypto_client->generate_random(num12_128bit, sizeof(num12_128bit)); + CHECK_EQUAL(PSA_SUCCESS, status); + + /* Expect different numbers to be generated */ + CHECK(memcmp(num1_8bit, num2_8bit, sizeof(num1_8bit)) != 0); + CHECK(memcmp(num3_16bit, num4_16bit, sizeof(num3_16bit)) != 0); + CHECK(memcmp(num5_24bit, num6_24bit, sizeof(num5_24bit)) != 0); + CHECK(memcmp(num7_32bit, num8_32bit, sizeof(num7_32bit)) != 0); + CHECK(memcmp(num9_64bit, num10_64bit, sizeof(num9_64bit)) != 0); + CHECK(memcmp(num11_128bit, num12_128bit, sizeof(num11_128bit)) != 0); +} diff --git a/components/service/crypto/test/unit/component.cmake b/components/service/crypto/test/unit/component.cmake new file mode 100644 index 000000000..bdb38bcba --- /dev/null +++ b/components/service/crypto/test/unit/component.cmake @@ -0,0 +1,16 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/crypto_msg_encode_decode.cpp" + "${CMAKE_CURRENT_LIST_DIR}/poc_crypto_ops.cpp" + "${CMAKE_CURRENT_LIST_DIR}/crypto_fault_tests.cpp" + ) + diff --git a/components/service/crypto/test/unit/crypto_fault_tests.cpp b/components/service/crypto/test/unit/crypto_fault_tests.cpp new file mode 100644 index 000000000..63a4b3910 --- /dev/null +++ b/components/service/crypto/test/unit/crypto_fault_tests.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +TEST_GROUP(CryptoFaultTests) +{ + void setup() + { + m_crypto_client = new standalone_crypto_client; + } + + void teardown() + { + m_crypto_client->deinit(); + delete m_crypto_client; + m_crypto_client = NULL; + } + + test_crypto_client *m_crypto_client; +}; + +TEST(CryptoFaultTests, volatileKeyWithBrokenStorage) +{ + /* Inject broken secure storage fault */ + m_crypto_client->inject_fault(test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE); + m_crypto_client->init(); + + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + /* Expect generation of volatile key to still work with fault */ + psa_key_handle_t key_handle; + status = m_crypto_client->generate_key(&attributes, &key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); +} + +TEST(CryptoFaultTests, persistentKeysWithBrokenStorage) +{ + /* Inject broken secure storage fault */ + m_crypto_client->inject_fault(test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE); + m_crypto_client->init(); + + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + /* Expect persist key generation to fail */ + psa_key_id_t key_id_1 = 1; + psa_set_key_id(&attributes, key_id_1); + psa_key_handle_t key_handle_1; + status = m_crypto_client->generate_key(&attributes, &key_handle_1); + CHECK(PSA_SUCCESS != status); + + psa_reset_key_attributes(&attributes); +} + +TEST(CryptoFaultTests, randomNumbersWithBrokenStorage) +{ + /* Inject broken secure storage fault */ + m_crypto_client->inject_fault(test_crypto_client::FAILED_TO_DISCOVER_SECURE_STORAGE); + m_crypto_client->init(); + + psa_status_t status; + uint8_t num12_128bit[16]; + + memset(num12_128bit, 0, sizeof(num12_128bit)); + + /* Expect random number generation to work, despite the broken storage */ + status = m_crypto_client->generate_random(num12_128bit, sizeof(num12_128bit)); + CHECK_EQUAL(PSA_SUCCESS, status); +} diff --git a/components/service/crypto/test/unit/crypto_msg_encode_decode.cpp b/components/service/crypto/test/unit/crypto_msg_encode_decode.cpp new file mode 100644 index 000000000..ea8e38826 --- /dev/null +++ b/components/service/crypto/test/unit/crypto_msg_encode_decode.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +TEST_GROUP(CryptoMsgTests) { + + void setup() { + print_info = false; + } + + /* Nanopb encode/decode methods */ + static bool encode_byte_array(pb_ostream_t *stream, const pb_field_t *field, void * const *arg) { + + const pb_bytes_array_t *byte_array = (const pb_bytes_array_t *)*arg; + if (!pb_encode_tag_for_field(stream, field)) return false; + + return pb_encode_string(stream, byte_array->bytes, byte_array->size); + } + + static bool decode_byte_array(pb_istream_t *stream, const pb_field_t *field, void **arg) { + + (void)field; + pb_bytes_array_t *byte_array = (pb_bytes_array_t *)*arg; + if (stream->bytes_left > byte_array->size) return false; + + return pb_read(stream, byte_array->bytes, stream->bytes_left); + } + + static pb_callback_t out_byte_array(const pb_bytes_array_t *byte_array) { + + pb_callback_t callback; + callback.funcs.encode = encode_byte_array; + callback.arg = (void*)byte_array; + + return callback; + } + + static pb_callback_t in_byte_array(pb_bytes_array_t *byte_array) { + + pb_callback_t callback; + callback.funcs.decode = decode_byte_array; + callback.arg = (void*)byte_array; + return callback; + } + + bool print_info; +}; + +TEST(CryptoMsgTests, GenerateKeyInMsgTest) { + /* Sender - set values and serialize */ + ts_crypto_GenerateKeyIn sent_msg = ts_crypto_GenerateKeyIn_init_default; + ts_crypto_KeyAttributes sent_key_attributes = ts_crypto_KeyAttributes_init_default; + + sent_key_attributes.type = + ts_crypto_KeyType_KEY_TYPE_ECC_PUBLIC_KEY_BASE | + ts_crypto_EccCurve_ECC_CURVE_SECP_R1; + + sent_key_attributes.key_bits = 256; + sent_key_attributes.lifetime = ts_crypto_KeyLifetime_KEY_LIFETIME_PERSISTENT; + sent_key_attributes.id = 3; + + sent_key_attributes.has_policy = true; + sent_key_attributes.policy.usage = ts_crypto_KeyUsage_KEY_USAGE_SIGN_HASH; + sent_key_attributes.policy.alg = + ts_crypto_Alg_ALG_DETERMINISTIC_ECDSA_BASE | + ts_crypto_Alg_ALG_SHA_256; + + sent_msg.attributes = sent_key_attributes; + sent_msg.has_attributes = true; + + size_t sent_msg_len; + CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_GenerateKeyIn_fields, &sent_msg)); + uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len); + CHECK(sent_msg_len > 0); + CHECK(sent_msg_buf); + + pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK(pb_encode(&ostream, ts_crypto_GenerateKeyIn_fields, &sent_msg)); + CHECK_EQUAL(sent_msg_len, ostream.bytes_written); + + /* Receiver - deserialize and use values */ + ts_crypto_GenerateKeyIn recv_msg = ts_crypto_GenerateKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK_EQUAL(sent_msg_len, istream.bytes_left); + CHECK(pb_decode(&istream, ts_crypto_GenerateKeyIn_fields, &recv_msg)); + CHECK_EQUAL(0, istream.bytes_left); + + free(sent_msg_buf); + + CHECK(recv_msg.has_attributes); + CHECK_EQUAL(sent_key_attributes.type, recv_msg.attributes.type); + CHECK_EQUAL(sent_key_attributes.key_bits, recv_msg.attributes.key_bits); + CHECK_EQUAL(sent_key_attributes.lifetime, recv_msg.attributes.lifetime); + CHECK_EQUAL(sent_key_attributes.id, recv_msg.attributes.id); + + CHECK(recv_msg.attributes.has_policy); + CHECK_EQUAL(sent_key_attributes.policy.usage, recv_msg.attributes.policy.usage); + CHECK_EQUAL(sent_key_attributes.policy.alg, recv_msg.attributes.policy.alg); + + if (print_info) { + printf("Serialized op_export_public_key len: %ld\n", sent_msg_len); + } +} + +TEST(CryptoMsgTests, ExportPublicKeyInMsgTest) { + /* Sender - set values and serialize */ + ts_crypto_ExportPublicKeyIn sent_msg = ts_crypto_ExportPublicKeyIn_init_default; + + sent_msg.handle = 55; + + size_t sent_msg_len; + CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_ExportPublicKeyIn_fields, &sent_msg)); + uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len); + CHECK(sent_msg_len > 0); + CHECK(sent_msg_buf); + + pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK(pb_encode(&ostream, ts_crypto_ExportPublicKeyIn_fields, &sent_msg)); + CHECK_EQUAL(sent_msg_len, ostream.bytes_written); + + /* Receiver - deserialize and use values */ + ts_crypto_ExportPublicKeyIn recv_msg = ts_crypto_ExportPublicKeyIn_init_default; + + pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK_EQUAL(sent_msg_len, istream.bytes_left); + CHECK(pb_decode(&istream, ts_crypto_ExportPublicKeyIn_fields, &recv_msg)); + CHECK_EQUAL(0, istream.bytes_left); + + CHECK_EQUAL(sent_msg.handle, recv_msg.handle); + + free(sent_msg_buf); + + if (print_info) { + printf("Serialized op_export_public_key len: %ld\n", sent_msg_len); + } +} + +TEST(CryptoMsgTests, ExportPublicKeyOutMsgTest) { + /* Sender - set values and serialize */ + ts_crypto_ExportPublicKeyOut sent_msg = ts_crypto_ExportPublicKeyOut_init_default; + + PB_BYTES_ARRAY_T(5) example_key = {5, {0x31, 0x32, 0x33, 0x34, 0x35}}; + sent_msg.data = out_byte_array((const pb_bytes_array_t *)&example_key); + + size_t sent_msg_len; + CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_ExportPublicKeyOut_fields, &sent_msg)); + uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len); + CHECK(sent_msg_len > 0); + CHECK(sent_msg_buf); + + pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK(pb_encode(&ostream, ts_crypto_ExportPublicKeyOut_fields, &sent_msg)); + CHECK_EQUAL(sent_msg_len, ostream.bytes_written); + + /* Receiver - deserialize and use values */ + PB_BYTES_ARRAY_T(5) recv_key = {5, {0}}; + ts_crypto_ExportPublicKeyOut recv_msg = ts_crypto_ExportPublicKeyOut_init_default; + recv_msg.data = in_byte_array((pb_bytes_array_t *)&recv_key); + + pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK_EQUAL(sent_msg_len, istream.bytes_left); + CHECK(pb_decode(&istream, ts_crypto_ExportPublicKeyOut_fields, &recv_msg)); + CHECK_EQUAL(0, istream.bytes_left); + + free(sent_msg_buf); + + CHECK_EQUAL(example_key.size, recv_key.size); + CHECK(memcmp(example_key.bytes, recv_key.bytes, example_key.size) == 0); + + if (print_info) { + printf("Serialized result_export_public_key len: %ld\n", sent_msg_len); + } +} + +TEST(CryptoMsgTests, SignHashInMsgTest) { + /* Sender - set values and serialize */ + ts_crypto_SignHashIn sent_msg = ts_crypto_SignHashIn_init_default; + + PB_BYTES_ARRAY_T(6) msg_to_sign = {6, {0x34, 0x32, 0x33, 0x34, 0x35, 0x36}}; + sent_msg.hash = out_byte_array((const pb_bytes_array_t *)&msg_to_sign); + + sent_msg.handle = 71; + sent_msg.alg = + ts_crypto_Alg_ALG_DETERMINISTIC_ECDSA_BASE | + ts_crypto_Alg_ALG_SHA_256; + + size_t sent_msg_len; + CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_SignHashIn_fields, &sent_msg)); + uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len); + CHECK(sent_msg_len > 0); + CHECK(sent_msg_buf); + + pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK(pb_encode(&ostream, ts_crypto_SignHashIn_fields, &sent_msg)); + CHECK_EQUAL(sent_msg_len, ostream.bytes_written); + + /* Receiver - deserialize and use values */ + PB_BYTES_ARRAY_T(6) recv_msg_to_sign = {6, {0}}; + ts_crypto_SignHashIn recv_msg = ts_crypto_SignHashIn_init_default; + recv_msg.hash = in_byte_array((pb_bytes_array_t *)&recv_msg_to_sign); + + pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK_EQUAL(sent_msg_len, istream.bytes_left); + CHECK(pb_decode(&istream, ts_crypto_SignHashIn_fields, &recv_msg)); + CHECK_EQUAL(0, istream.bytes_left); + + free(sent_msg_buf); + + CHECK_EQUAL(sent_msg.handle, recv_msg.handle); + CHECK_EQUAL(sent_msg.alg, recv_msg.alg); + + CHECK_EQUAL(msg_to_sign.size, recv_msg_to_sign.size); + CHECK(memcmp(msg_to_sign.bytes, recv_msg_to_sign.bytes, msg_to_sign.size) == 0); + + if (print_info) { + printf("Serialized op_asym_sign len: %ld\n", sent_msg_len); + } +} + +TEST(CryptoMsgTests, SignHashOutMsgTest) { + /* Sender - set values and serialize */ + ts_crypto_SignHashOut sent_msg = ts_crypto_SignHashOut_init_default; + + PB_BYTES_ARRAY_T(10) example_signature = {10, {0x01, 0x02, 0x5a, 0x7c, 0x35, 0x01, 0x02, 0x5a, 0x7c, 0x35}}; + sent_msg.signature = out_byte_array((const pb_bytes_array_t *)&example_signature); + + size_t sent_msg_len; + CHECK(pb_get_encoded_size(&sent_msg_len, ts_crypto_SignHashOut_fields, &sent_msg)); + uint8_t *sent_msg_buf = (uint8_t*)malloc(sent_msg_len); + CHECK(sent_msg_len > 0); + CHECK(sent_msg_buf); + + pb_ostream_t ostream = pb_ostream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK(pb_encode(&ostream, ts_crypto_SignHashOut_fields, &sent_msg)); + CHECK_EQUAL(sent_msg_len, ostream.bytes_written); + + /* Receiver - deserialize and use values */ + PB_BYTES_ARRAY_T(10) recv_signature = {10, {0}}; + ts_crypto_SignHashOut recv_msg = ts_crypto_SignHashOut_init_default; + recv_msg.signature = in_byte_array((pb_bytes_array_t *)&recv_signature); + + pb_istream_t istream = pb_istream_from_buffer(sent_msg_buf, sent_msg_len); + CHECK_EQUAL(sent_msg_len, istream.bytes_left); + CHECK(pb_decode(&istream, ts_crypto_SignHashOut_fields, &recv_msg)); + CHECK_EQUAL(0, istream.bytes_left); + + free(sent_msg_buf); + + CHECK_EQUAL(example_signature.size, recv_signature.size); + CHECK(memcmp(example_signature.bytes, recv_signature.bytes, example_signature.size) == 0); + + if (print_info) { + printf("Serialized result_asym_sign len: %ld\n", sent_msg_len); + } +} diff --git a/components/service/crypto/test/unit/poc_crypto_ops.cpp b/components/service/crypto/test/unit/poc_crypto_ops.cpp new file mode 100644 index 000000000..30be0eb24 --- /dev/null +++ b/components/service/crypto/test/unit/poc_crypto_ops.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include +#include +#include + +/* Tests to prototype each of the Crypto operations used for the PoC Crypto SP + * demonstrator. + */ +TEST_GROUP(PocCryptoOpTests) { + + void setup() { + print_info = false; + (void)psa_crypto_init(); + } + + void generateEcdsaKeyPair() { + psa_status_t status; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP_R1)); + psa_set_key_bits(&attributes, 256); + + status = psa_generate_key(&attributes, &ecdsa_key_handle); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + + if (print_info) { + printf("Generated ECDSA key pair\n"); + printf(" Inputs: attributes: %ld\n", sizeof(attributes)); + printf(" Outputs: handle: %ld status: %ld\n", sizeof(ecdsa_key_handle), sizeof(status)); + } + } + + void exportPublicKey() { + psa_status_t status; + exported_key_len = 0; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + status = psa_get_key_attributes(ecdsa_key_handle, &attributes); + + CHECK_EQUAL(PSA_SUCCESS, status); + + size_t max_export_size = PSA_KEY_EXPORT_MAX_SIZE(PSA_KEY_TYPE_PUBLIC_KEY_OF_KEY_PAIR(psa_get_key_type(&attributes)), + psa_get_key_bits(&attributes)); + + status = psa_export_public_key(ecdsa_key_handle, exported_key, sizeof(exported_key), + &exported_key_len); + + CHECK_EQUAL(PSA_SUCCESS, status); + CHECK_EQUAL(max_export_size, exported_key_len); + + psa_reset_key_attributes(&attributes); + + if (print_info) { + printf("Exported a public key\n"); + printf(" Inputs: handle: %ld\n", sizeof(ecdsa_key_handle)); + printf(" Outputs: exported_length: %ld status: %ld\n", sizeof(exported_key_len), sizeof(status)); + printf(" Outputs: space of key value: %ld bytes\n", exported_key_len); + } + } + + void signMessage() { + psa_status_t status; + uint8_t hash[20]; + uint8_t signature[PSA_SIGNATURE_MAX_SIZE]; + size_t signature_length; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + memset(hash, 0x55, sizeof(hash)); + + status = psa_get_key_attributes(ecdsa_key_handle, &attributes); + + CHECK_EQUAL(PSA_SUCCESS, status); + + status = psa_sign_hash(ecdsa_key_handle, psa_get_key_algorithm(&attributes), + hash, sizeof(hash), + signature, sizeof(signature), + &signature_length); + CHECK_EQUAL(PSA_SUCCESS, status); + + psa_reset_key_attributes(&attributes); + + if (print_info) { + printf("Signed a message\n"); + printf(" Inputs: handle: %ld algo 1 message %ld\n", sizeof(ecdsa_key_handle), sizeof(hash)); + printf(" Outputs: signature: %ld\n", signature_length); + } + } + + bool print_info; + psa_key_handle_t ecdsa_key_handle; + uint8_t exported_key[PSA_KEY_EXPORT_ECC_PUBLIC_KEY_MAX_SIZE(256)]; + size_t exported_key_len; +}; + +TEST(PocCryptoOpTests, checkOpSequence) { + + generateEcdsaKeyPair(); + exportPublicKey(); + signMessage(); +} \ No newline at end of file diff --git a/external/mbed-crypto/mbedcrypto.cmake b/external/mbed-crypto/mbedcrypto.cmake new file mode 100644 index 000000000..bf0058875 --- /dev/null +++ b/external/mbed-crypto/mbedcrypto.cmake @@ -0,0 +1,93 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- + +set(MBEDCRYPTO_URL "https://github.com/ARMmbed/mbed-crypto.git" CACHE STRING "mbedcrypto repository URL") +set(MBEDCRYPTO_REFSPEC "mbedcrypto-3.1.0" CACHE STRING "mbedcrypto git refspec") +set(MBEDCRYPTO_INSTALL_PATH "${CMAKE_CURRENT_BINARY_DIR}/mbedcrypto_install" CACHE PATH "mbedcrypto installation directory") +set(MBEDCRYPTO_PACKAGE_PATH "${MBEDCRYPTO_INSTALL_PATH}/lib/mbedcrypto/cmake" CACHE PATH "mbedcrypto CMake package directory") + +include(FetchContent) + +# Checking git +find_program(GIT_COMMAND "git") +if (NOT GIT_COMMAND) + message(FATAL_ERROR "Please install git") +endif() + +# Fetching mbedcrypto +FetchContent_Declare( + mbedcrypto + GIT_REPOSITORY ${MBEDCRYPTO_URL} + GIT_TAG ${MBEDCRYPTO_REFSPEC} + GIT_SHALLOW TRUE +) + +# FetchContent_GetProperties exports mbedcrypto_SOURCE_DIR and mbedcrypto_BINARY_DIR variables +FetchContent_GetProperties(mbedcrypto) +if(NOT mbedcrypto_POPULATED) + message(STATUS "Fetching mbedcrypto") + FetchContent_Populate(mbedcrypto) +endif() + +# Convert the include path list to a string. Needed to make parameter passing to +# mbedcrypto build work fine. +string(REPLACE ";" "\\;" MBEDCRYPTO_EXTRA_INCLUDES "${MBEDCRYPTO_EXTRA_INCLUDES}") + +#Configure the library +if(NOT CMAKE_CROSSCOMPILING) + execute_process(COMMAND + ${CMAKE_COMMAND} + -DENABLE_PROGRAMS=OFF + -DENABLE_TESTING=OFF + -DCMAKE_INSTALL_PREFIX=${MBEDCRYPTO_INSTALL_PATH} + -DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE} + -Dthirdparty_def=-DMBEDTLS_CONFIG_FILE="${MBEDCRYPTO_CONFIG_FILE}" + -Dthirdparty_inc=${MBEDCRYPTO_EXTRA_INCLUDES} + -GUnix\ Makefiles + ${mbedcrypto_SOURCE_DIR} + WORKING_DIRECTORY + ${mbedcrypto_BINARY_DIR} + ) +else() + execute_process(COMMAND + ${CMAKE_COMMAND} + -DENABLE_PROGRAMS=OFF + -DENABLE_TESTING=OFF + -DCMAKE_INSTALL_PREFIX=${MBEDCRYPTO_INSTALL_PATH} + -DCMAKE_TOOLCHAIN_FILE=${TS_EXTERNAL_LIB_TOOLCHAIN_FILE} + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY + -Dthirdparty_def=-DMBEDTLS_CONFIG_FILE="${MBEDCRYPTO_CONFIG_FILE}" + -Dthirdparty_inc=${MBEDCRYPTO_EXTRA_INCLUDES} + -GUnix\ Makefiles + ${mbedcrypto_SOURCE_DIR} + WORKING_DIRECTORY + ${mbedcrypto_BINARY_DIR} + RESULT_VARIABLE _exec_error + ) + + if (_exec_error) + message(FATAL_ERROR "Configuration step of mbedcrypto failed with ${_exec_error}.") + endif() +endif() + +#TODO: add dependnecy to generated project on this file! +#TODO: add custom target to rebuild mbedcrypto + +#Build the library +execute_process(COMMAND + ${CMAKE_COMMAND} --build ${mbedcrypto_BINARY_DIR} -- install -j8 + RESULT_VARIABLE _exec_error + ) +if (_exec_error) + message(FATAL_ERROR "Build step of mbedcrypto failed with ${_exec_error}.") +endif() + +#Create an imported target to have clean abstraction in the build-system. +add_library(mbedcrypto STATIC IMPORTED) +set_property(TARGET mbedcrypto PROPERTY IMPORTED_LOCATION "${MBEDCRYPTO_INSTALL_PATH}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX}") +set_property(TARGET mbedcrypto PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${MBEDCRYPTO_INSTALL_PATH}/include") + diff --git a/protocols/service/crypto/packed-c/component.cmake b/protocols/service/crypto/packed-c/component.cmake new file mode 100644 index 000000000..041f7d549 --- /dev/null +++ b/protocols/service/crypto/packed-c/component.cmake @@ -0,0 +1,14 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_include_directories(${TGT} + PRIVATE + "${CMAKE_CURRENT_LIST_DIR}" + ) diff --git a/protocols/service/crypto/packed-c/opcodes.h b/protocols/service/crypto/packed-c/opcodes.h new file mode 100644 index 000000000..40f8ab3ee --- /dev/null +++ b/protocols/service/crypto/packed-c/opcodes.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TS_CRYPTO_OPCODES_H +#define TS_CRYPTO_OPCODES_H + +/* C/C++ definition of crypto service opcodes + */ +#define TS_CRYPTO_OPCODE_NOP (0x0000) +#define TS_CRYPTO_OPCODE_GENERATE_KEY (0x0101) +#define TS_CRYPTO_OPCODE_DESTROY_KEY (0x0102) +#define TS_CRYPTO_OPCODE_OPEN_KEY (0x0103) +#define TS_CRYPTO_OPCODE_CLOSE_KEY (0x0104) +#define TS_CRYPTO_OPCODE_EXPORT_KEY (0x0105) +#define TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY (0x0106) +#define TS_CRYPTO_OPCODE_IMPORT_KEY (0x0107) +#define TS_CRYPTO_OPCODE_SIGN_HASH (0x0108) +#define TS_CRYPTO_OPCODE_VERIFY_HASH (0x0109) +#define TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT (0x010a) +#define TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT (0x010b) +#define TS_CRYPTO_OPCODE_GENERATE_RANDOM (0x010c) + +#endif /* TS_CRYPTO_OPCODES_H */ diff --git a/protocols/service/crypto/protobuf/asymmetric_decrypt.proto b/protocols/service/crypto/protobuf/asymmetric_decrypt.proto new file mode 100644 index 000000000..0155c3043 --- /dev/null +++ b/protocols/service/crypto/protobuf/asymmetric_decrypt.proto @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message AsymmetricDecryptIn { + uint32 handle = 1; + uint32 alg = 2; + bytes ciphertext = 3; + bytes salt = 4; +} + +message AsymmetricDecryptOut { + bytes plaintext = 1; +} diff --git a/protocols/service/crypto/protobuf/asymmetric_encrypt.proto b/protocols/service/crypto/protobuf/asymmetric_encrypt.proto new file mode 100644 index 000000000..c85b9da18 --- /dev/null +++ b/protocols/service/crypto/protobuf/asymmetric_encrypt.proto @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message AsymmetricEncryptIn { + uint32 handle = 1; + uint32 alg = 2; + bytes plaintext = 3; + bytes salt = 4; +} + +message AsymmetricEncryptOut { + bytes ciphertext = 1; +} diff --git a/protocols/service/crypto/protobuf/close_key.proto b/protocols/service/crypto/protobuf/close_key.proto new file mode 100644 index 000000000..b9f5ea3fd --- /dev/null +++ b/protocols/service/crypto/protobuf/close_key.proto @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message CloseKeyIn { + uint32 handle = 1; +} diff --git a/protocols/service/crypto/protobuf/component.cmake b/protocols/service/crypto/protobuf/component.cmake new file mode 100644 index 000000000..7583f18ea --- /dev/null +++ b/protocols/service/crypto/protobuf/component.cmake @@ -0,0 +1,26 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +set_property(TARGET ${TGT} APPEND PROPERTY PROTOBUF_FILES + "${CMAKE_CURRENT_LIST_DIR}/asymmetric_decrypt.proto" + "${CMAKE_CURRENT_LIST_DIR}/asymmetric_encrypt.proto" + "${CMAKE_CURRENT_LIST_DIR}/destroy_key.proto" + "${CMAKE_CURRENT_LIST_DIR}/open_key.proto" + "${CMAKE_CURRENT_LIST_DIR}/close_key.proto" + "${CMAKE_CURRENT_LIST_DIR}/export_key.proto" + "${CMAKE_CURRENT_LIST_DIR}/export_public_key.proto" + "${CMAKE_CURRENT_LIST_DIR}/generate_key.proto" + "${CMAKE_CURRENT_LIST_DIR}/generate_random.proto" + "${CMAKE_CURRENT_LIST_DIR}/import_key.proto" + "${CMAKE_CURRENT_LIST_DIR}/key_attributes.proto" + "${CMAKE_CURRENT_LIST_DIR}/opcodes.proto" + "${CMAKE_CURRENT_LIST_DIR}/sign_hash.proto" + "${CMAKE_CURRENT_LIST_DIR}/verify_hash.proto" + ) diff --git a/protocols/service/crypto/protobuf/destroy_key.proto b/protocols/service/crypto/protobuf/destroy_key.proto new file mode 100644 index 000000000..8b718af4d --- /dev/null +++ b/protocols/service/crypto/protobuf/destroy_key.proto @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message DestroyKeyIn { + uint32 handle = 1; +} + +message DestroyKeyOut {} diff --git a/protocols/service/crypto/protobuf/export_key.proto b/protocols/service/crypto/protobuf/export_key.proto new file mode 100644 index 000000000..14cc6a985 --- /dev/null +++ b/protocols/service/crypto/protobuf/export_key.proto @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message ExportKeyIn { + uint32 handle = 1; +} + +message ExportKeyOut { + bytes data = 1; +} diff --git a/protocols/service/crypto/protobuf/export_public_key.proto b/protocols/service/crypto/protobuf/export_public_key.proto new file mode 100644 index 000000000..e8443257b --- /dev/null +++ b/protocols/service/crypto/protobuf/export_public_key.proto @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message ExportPublicKeyIn { + uint32 handle = 1; +} + +message ExportPublicKeyOut { + bytes data = 1; +} diff --git a/protocols/service/crypto/protobuf/generate_key.proto b/protocols/service/crypto/protobuf/generate_key.proto new file mode 100644 index 000000000..48025a659 --- /dev/null +++ b/protocols/service/crypto/protobuf/generate_key.proto @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +import "service/crypto/protobuf/key_attributes.proto"; + +message GenerateKeyIn { + KeyAttributes attributes = 1; +} + +message GenerateKeyOut { + uint32 handle = 1; +} diff --git a/protocols/service/crypto/protobuf/generate_random.proto b/protocols/service/crypto/protobuf/generate_random.proto new file mode 100644 index 000000000..3fbb5bea5 --- /dev/null +++ b/protocols/service/crypto/protobuf/generate_random.proto @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message GenerateRandomIn { + uint64 size = 1; +} + +message GenerateRandomOut { + bytes random_bytes = 1; +} diff --git a/protocols/service/crypto/protobuf/import_key.proto b/protocols/service/crypto/protobuf/import_key.proto new file mode 100644 index 000000000..727b2bcf0 --- /dev/null +++ b/protocols/service/crypto/protobuf/import_key.proto @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +import "service/crypto/protobuf/key_attributes.proto"; + +message ImportKeyIn { + KeyAttributes attributes = 1; + bytes data = 3; +} + +message ImportKeyOut { + uint32 handle = 1; +} diff --git a/protocols/service/crypto/protobuf/key_attributes.proto b/protocols/service/crypto/protobuf/key_attributes.proto new file mode 100644 index 000000000..7e504f643 --- /dev/null +++ b/protocols/service/crypto/protobuf/key_attributes.proto @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +/* Key types */ +enum KeyType { + option allow_alias = true; + + KEY_TYPE_NONE = 0x0000; + KEY_TYPE_RAW_DATA = 0x1001; + KEY_TYPE_HMAC = 0x1100; + KEY_TYPE_DERIVE = 0x1200; + KEY_TYPE_AES = 0x2400; + KEY_TYPE_DES = 0x2301; + KEY_TYPE_CAMELLIA = 0x2403; + KEY_TYPE_ARC4 = 0x2002; + KEY_TYPE_CHACHA20 = 0x2004; + KEY_TYPE_PUBLIC_KEY = 0x4001; + KEY_TYPE_RSA_KEY_PAIR = 0x7001; + KEY_TYPE_ECC_PUBLIC_KEY_BASE = 0x4100; + KEY_TYPE_ECC_KEY_PAIR_BASE = 0x7100; + KEY_TYPE_ECC_CURVE_MASK = 0x00ff; + KEY_TYPE_DH_PUBLIC_KEY_BASE = 0x4200; + KEY_TYPE_DH_KEY_PAIR_BASE = 0x7200; + KEY_TYPE_DH_GROUP_MASK = 0x00ff; +} + +/* ECC curves for use with ECC Key types */ +enum EccCurve { + ECC_CURVE_NONE = 0x00; + ECC_CURVE_SECP_K1 = 0x17; + ECC_CURVE_SECP_R1 = 0x12; + ECC_CURVE_SECP_R2 = 0x1b; + ECC_CURVE_SECT_K1 = 0x27; + ECC_CURVE_SECT_R1 = 0x22; + ECC_CURVE_SECT_R2 = 0x2b; + ECC_CURVE_BRAINPOOL_P_R1 = 0x30; + ECC_CURVE_MONTGOMERY = 0x41; +} + +/* Diffie-Hellman groups for use with DH key types */ +enum DhGroup { + DH_GROUP_NONE = 0x00; + DH_GROUP_RFC7919 = 0x03; +} + +/* Crypto algorithms */ +enum Alg { + ALG_NONE = 0x00000000; + ALG_HASH_MASK = 0x000000ff; + ALG_MD2 = 0x01000001; + ALG_MD4 = 0x01000002; + ALG_MD5 = 0x01000003; + ALG_RIPEMD160 = 0x01000004; + ALG_SHA_1 = 0x01000005; + ALG_SHA_224 = 0x01000008; + ALG_SHA_256 = 0x01000009; + ALG_SHA_384 = 0x0100000a; + ALG_SHA_512 = 0x0100000b; + ALG_SHA_512_224 = 0x0100000c; + ALG_SHA_512_256 = 0x0100000d; + ALG_SHA3_224 = 0x01000010; + ALG_SHA3_256 = 0x01000011; + ALG_SHA3_384 = 0x01000012; + ALG_SHA3_512 = 0x01000013; + ALG_CBC_MAC = 0x02c00001; + ALG_CMAC = 0x02c00002; + ALG_ARC4 = 0x04800001; + ALG_CHACHA20 = 0x04800005; + ALG_CTR = 0x04c00001; + ALG_CFB = 0x04c00002; + ALG_OFB = 0x04c00003; + ALG_XTS = 0x044000ff; + ALG_CBC_NO_PADDING = 0x04600100; + ALG_CBC_PKCS7 = 0x04600101; + ALG_AEAD_FROM_BLOCK_FLAG = 0x00400000; + ALG_CCM = 0x06401001; + ALG_GCM = 0x06401002; + ALG_CHACHA20_POLY1305 = 0x06001005; + ALG_RSA_PKCS1V15_SIGN_BASE = 0x10020000; + ALG_RSA_PSS_BASE = 0x10030000; + ALG_ECDSA_BASE = 0x10060000; + ALG_DETERMINISTIC_ECDSA_BASE = 0x10070000; + ALG_RSA_PKCS1V15_CRYPT = 0x12020000; + ALG_RSA_OAEP_BASE = 0x12030000; + ALG_HKDF_BASE = 0x20000100; + ALG_TLS12_PRF_BASE = 0x20000200; + ALG_TLS12_PSK_TO_MS_BASE = 0x20000300; + ALG_KEY_DERIVATION_MASK = 0x0803ffff; + ALG_KEY_AGREEMENT_MASK = 0x10fc0000; + ALG_FFDH = 0x30100000; + ALG_ECDH = 0x30200000; +} + +/* Key lifetime */ +enum KeyLifetime { + KEY_LIFETIME_VOLATILE = 0x00000000; + KEY_LIFETIME_PERSISTENT = 0x00000001; +} + +/* Key usage constraints */ +enum KeyUsage { + KEY_USAGE_NONE = 0x00000000; + KEY_USAGE_EXPORT = 0x00000001; + KEY_USAGE_COPY = 0x00000002; + KEY_USAGE_ENCRYPT = 0x00000100; + KEY_USAGE_DECRYPT = 0x00000200; + KEY_USAGE_SIGN_HASH = 0x00000400; + KEY_USAGE_VERIFY_HASH = 0x00000800; + KEY_USAGE_DERIVE = 0x00001000; +} + +/* Key policy to define what key can be used for */ +message KeyPolicy { + uint32 usage = 1; + uint32 alg = 2; +} + +/* Key attributes object */ +message KeyAttributes { + uint32 type = 1; + uint32 key_bits = 2; + uint32 lifetime = 3; + uint32 id = 4; + KeyPolicy policy = 5; +} \ No newline at end of file diff --git a/protocols/service/crypto/protobuf/opcodes.proto b/protocols/service/crypto/protobuf/opcodes.proto new file mode 100644 index 000000000..b16127ec2 --- /dev/null +++ b/protocols/service/crypto/protobuf/opcodes.proto @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +enum Opcode { + NOP = 0x0000; + GENERATE_KEY = 0x0101; + DESTROY_KEY = 0x0102; + OPEN_KEY = 0x0103; + CLOSE_KEY = 0x0104; + EXPORT_KEY = 0x0105; + EXPORT_PUBLIC_KEY = 0x0106; + IMPORT_KEY = 0x0107; + SIGN_HASH = 0x0108; + VERIFY_HASH = 0x0109; + ASYMMETRIC_DECRYPT = 0x010a; + ASYMMETRIC_ENCRYPT = 0x010b; + GENERATE_RANDOM = 0x010c; +} diff --git a/protocols/service/crypto/protobuf/open_key.proto b/protocols/service/crypto/protobuf/open_key.proto new file mode 100644 index 000000000..90fb2ad6c --- /dev/null +++ b/protocols/service/crypto/protobuf/open_key.proto @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message OpenKeyIn { + uint32 id = 1; +} + +message OpenKeyOut { + uint32 handle = 1; +} diff --git a/protocols/service/crypto/protobuf/sign_hash.proto b/protocols/service/crypto/protobuf/sign_hash.proto new file mode 100644 index 000000000..a40900862 --- /dev/null +++ b/protocols/service/crypto/protobuf/sign_hash.proto @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message SignHashIn { + uint32 handle = 1; + uint32 alg = 2; + bytes hash = 3; +} + +message SignHashOut { + bytes signature = 1; +} diff --git a/protocols/service/crypto/protobuf/verify_hash.proto b/protocols/service/crypto/protobuf/verify_hash.proto new file mode 100644 index 000000000..9253d9408 --- /dev/null +++ b/protocols/service/crypto/protobuf/verify_hash.proto @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +syntax = "proto3"; + +package ts_crypto; + +message VerifyHashIn { + uint32 handle = 1; + uint32 alg = 2; + bytes hash = 3; + bytes signature = 4; +} + +message VerifyHashOut {} -- cgit v1.2.3