Crypto: Modularise the interaction with crypto primitives
This patch creates an engine layer inside the service to
modularise all the operations that involve cryptography
primitives.
It also updates the service documentation, fixes some minor
issues in the NS crypto interface test suite, and updates the
manifest file for the crypto service removing outdated functions.
Change-Id: Id2d0e2140741debd22c145f816a4df2ab0351b58
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
diff --git a/docs/user_guides/services/tfm_crypto_integration_guide.md b/docs/user_guides/services/tfm_crypto_integration_guide.md
index 9b96527..c58ea9b 100644
--- a/docs/user_guides/services/tfm_crypto_integration_guide.md
+++ b/docs/user_guides/services/tfm_crypto_integration_guide.md
@@ -32,15 +32,25 @@
- `crypto_init.c` : This file provides basic functions to initialise the
secure service during TF-M boot;
- `crypto_key.c` : This file implements functionalities related to the key
- management module;
+ management module. The `TFM_CRYPTO_KEY_STORAGE_NUM`, defined in this file,
+ determines how many key stores are available (4 key stores for the current
+ implementation);
- `crypto_alloc.c` : This file implements extensions to the PSA interface
which are specifically required by the TF-M Crypto service, in particular
related to the allocation and deallocation of crypto operation contexts in
- the secure world;
+ the secure world. The `TFM_CRYPTO_CONC_OPER_NUM`, defined in this file,
+ determines how many concurrent contexts are supported (8 for the current
+ implementation). For multipart cipher/hash/MAC operations, a context is
+ associated to the handle provided during the setup phase, and is explicitly
+ cleared only following a successful termination or an abort;
- `crypto_wrappers.c` : This file implements TF-M compatible wrappers in
case they are needed by the functions exported by other modules;
- `crypto_utils.c` : This file implements utility functions that can be
- used by other modules of the TF-M Crypto service.
+ used by other modules of the TF-M Crypto service;
+ - `crypto_engine.c` : This file implements the layer which the other modules
+ use to interact with the cryptography primitives available (in SW or HW).
+ The current implementation provides only SW primitives based on Mbed TLS
+ functions.
## Crypto service integration guide
@@ -67,4 +77,4 @@
--------------
-*Copyright (c) 2018, Arm Limited. All rights reserved.*
+*Copyright (c) 2018-2019, Arm Limited. All rights reserved.*
diff --git a/interface/include/tfm_crypto_defs.h b/interface/include/tfm_crypto_defs.h
index e9bb955..391df84 100644
--- a/interface/include/tfm_crypto_defs.h
+++ b/interface/include/tfm_crypto_defs.h
@@ -67,16 +67,26 @@
/**
* \brief A macro to translate TFM Crypto service return values to the
- * corresponding PSA return value. The user of this macro needs
+ * corresponding psa_status_t value. The user of this macro needs
* to cast the produced value to psa_status_t explicitly if needed
*
* \return Values specified by \ref psa_status_t
*/
-#define TFM_CRYPTO_PSA_RETURN(val) \
+#define TFM_CRYPTO_ERR_TO_PSA_STATUS(val) \
( (val == TFM_CRYPTO_ERR_PSA_SUCCESS) ? val : \
((val >= (enum tfm_crypto_err_t)TFM_CRYPTO_ERR_PSA_ERROR_OFFSET) ? \
(val - ((enum tfm_crypto_err_t)TFM_CRYPTO_ERR_PSA_ERROR_OFFSET-1)) : \
TFM_CRYPTO_ERR_INVALID) )
+/**
+ * \brief A macro to translate psa_status_t values to the corresponding return
+ * values for the TFM Crypto service
+ *
+ * \return Values specified by \ref enum tfm_crypto_err_t
+ *
+ */
+#define PSA_STATUS_TO_TFM_CRYPTO_ERR(val) \
+ ( (val == PSA_SUCCESS) ? (enum tfm_crypto_err_t)val : \
+ (enum tfm_crypto_err_t)(val + TFM_CRYPTO_ERR_PSA_ERROR_OFFSET) )
#ifdef __cplusplus
}
diff --git a/interface/include/tfm_crypto_veneers.h b/interface/include/tfm_crypto_veneers.h
index bb2c6d4..5079901 100644
--- a/interface/include/tfm_crypto_veneers.h
+++ b/interface/include/tfm_crypto_veneers.h
@@ -19,7 +19,7 @@
#include "crypto_psa_wrappers.h"
/**
- * \brief Import the key data on the provided key slot (veneer function)
+ * \brief Import the key data in the provided key slot (veneer function)
*
* \param[in] key Key slot
* \param[in] type Key type
@@ -57,9 +57,9 @@
/**
* \brief Export the key contained in the provided key slot (veneer function)
*
- * \param[in] key Key slot
+ * \param[in] key Key slot
* \param[out] data Buffer to hold the exported key
- * \param[in] data_size Length of the buffer pointed to by data
+ * \param[in] data_size Length of the buffer pointed to by data
* \param[out] data_length Length of the exported key
*
* \return Return values as described in \ref tfm_crypto_err_t
@@ -86,9 +86,12 @@
* \brief Set the cipher operation using the provided algorithm and key slot,
* for encryption context (veneer function)
*
- * \param[in] operation Cipher operation context
- * \param[in] key Key slot to bind to the cipher context
- * \param[in] alg Algorithm to use for the cipher operation
+ * \note A successful call to this function initialises a cipher operation
+ * context which will be referred using the operation parameter
+ *
+ * \param[out] operation Cipher operation context
+ * \param[in] key Key slot to bind to the cipher context
+ * \param[in] alg Algorithm to use for the cipher operation
*
* \return Return values as described in \ref tfm_crypto_err_t
*/
@@ -100,9 +103,12 @@
* \brief Set the cipher operation using the provided algorithm and key slot,
* for decryption context (veneer function)
*
- * \param[in] operation Cipher operation context
- * \param[in] key Key slot to bind to the cipher context
- * \param[in] alg Algorithm to use for the cipher operation
+ * \note A successful call to this function initialises a cipher operation
+ * context which will be referred using the operation parameter
+ *
+ * \param[out] operation Cipher operation context
+ * \param[in] key Key slot to bind to the cipher context
+ * \param[in] alg Algorithm to use for the cipher operation
*
* \return Return values as described in \ref tfm_crypto_err_t
*/
@@ -127,24 +133,16 @@
struct psa_cipher_update_input *input_s,
struct psa_cipher_update_output *output_s);
/**
- * \brief Abort a cipher operation, clears the operation context provided
- * (veneer function)
- *
- * \param[in] operation Cipher operation context
- *
- * \return Return values as described in \ref tfm_crypto_err_t
- */
-enum tfm_crypto_err_t tfm_crypto_veneer_cipher_abort(
- psa_cipher_operation_t *operation);
-
-/**
* \brief Finalise a cipher context flushing out any remaining block of
* output data (veneer function)
*
- * \param[in] operation Cipher operation context
- * \param[out] output Buffer containing output data
- * \param[in] output_size Size of the output buffer
- * \param[out] output_length Size of the produced output
+ * \note A successful call to this function releases the cipher operation
+ * context provided as parameter
+ *
+ * \param[in/out] operation Cipher operation context
+ * \param[out] output Buffer containing output data
+ * \param[in] output_size Size of the output buffer
+ * \param[out] output_length Size of the produced output
*
* \return Return values as described in \ref tfm_crypto_err_t
*/
@@ -154,40 +152,59 @@
size_t output_size,
size_t *output_length);
/**
+ * \brief Abort a cipher operation, clear the operation context provided
+ * (veneer function)
+ *
+ * \note A successful call to this function releases the cipher operation
+ * context provided as parameter
+ *
+ * \param[in/out] operation Cipher operation context
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_veneer_cipher_abort(
+ psa_cipher_operation_t *operation);
+/**
* \brief Setup a hash operation with the provided algorithm (veneer function)
*
- * \param[in] operation Hash operation context
- * \param[in] alg Algorithm chosen as hash
+ * \note A successful call to this function initialises a hash operation
+ * context which will be referred using the operation parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[out] operation Hash operation context
+ * \param[in] alg Algorithm chosen as hash
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_veneer_hash_setup(
psa_hash_operation_t *operation,
psa_algorithm_t alg);
/**
- * \brief Adds a new input chunk to the data for which the final hash value
+ * \brief Add a new input chunk to the data for which the final hash value
* will be computed (veneer function)
*
- * \param[in] operation Hash operation context
- * \param[in] input Buffer containing the input data
- * \param[in] input_length Size of the provided input data
+ * \param[in/out] operation Hash operation context
+ * \param[in] input Buffer containing the input data
+ * \param[in] input_length Size of the provided input data
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_veneer_hash_update(
psa_hash_operation_t *operation,
const uint8_t *input,
size_t input_length);
/**
- * \brief Finalises a hash context operation producing the final hash value
+ * \brief Finalise a hash context operation producing the final hash value
* (veneer function)
*
- * \param[in] operation Hash operation context
- * \param[out] hash Buffer containing hash data
- * \param[in] hash_size Size of the hash buffer
- * \param[out] hash_length Size of the produced hash
+ * \note A successful call to this function releases the hash operation
+ * context provided as parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Hash operation context
+ * \param[out] hash Buffer containing hash data
+ * \param[in] hash_size Size of the hash buffer
+ * \param[out] hash_length Size of the produced hash
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_veneer_hash_finish(
psa_hash_operation_t *operation,
@@ -195,26 +212,33 @@
size_t hash_size,
size_t *hash_length);
/**
- * \brief Finalises a hash context operation, verifying that the final hash
+ * \brief Finalise a hash context operation, verifying that the final hash
* value matches the one provided as input (veneer function)
*
- * \param[in] operation Hash operation context
- * \param[in] hash Buffer containing the provided hash value
- * \param[in] hash_length Size of the provided hash value
+ * \note A successful call to this function releases the hash operation
+ * context provided as parameter. The hash operation is released
+ * also in case TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE is returned
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Hash operation context
+ * \param[in] hash Buffer containing the provided hash value
+ * \param[in] hash_length Size of the provided hash value
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_veneer_hash_verify(
psa_hash_operation_t *operation,
const uint8_t *hash,
size_t hash_length);
/**
- * \brief Aborts a hash operation, clears the operation context provided
+ * \brief Abort a hash operation, clears the operation context provided
* (veneer function)
*
- * \param[in] operation Hash operation context
+ * \note A successful call to this function releases the hash operation
+ * context provided as parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Hash operation context
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_veneer_hash_abort(
psa_hash_operation_t *operation);
diff --git a/interface/src/tfm_crypto_api.c b/interface/src/tfm_crypto_api.c
index a51ac1f..7eb0669 100644
--- a/interface/src/tfm_crypto_api.c
+++ b/interface/src/tfm_crypto_api.c
@@ -31,7 +31,7 @@
(uint32_t)data,
(uint32_t)data_length);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_destroy_key(psa_key_slot_t key)
@@ -44,7 +44,7 @@
0,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_get_key_information(psa_key_slot_t key,
@@ -59,7 +59,7 @@
(uint32_t)bits,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_export_key(psa_key_slot_t key,
@@ -75,7 +75,7 @@
(uint32_t)data_size,
(uint32_t)data_length);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_export_public_key(psa_key_slot_t key,
@@ -99,7 +99,7 @@
(uint32_t)iv_length,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
@@ -115,7 +115,7 @@
(uint32_t)alg,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
@@ -131,7 +131,7 @@
(uint32_t)alg,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
@@ -159,7 +159,7 @@
(uint32_t)&output_s,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation)
@@ -172,7 +172,7 @@
0,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
@@ -188,7 +188,7 @@
(uint32_t)output_size,
(uint32_t)output_length);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
@@ -202,7 +202,7 @@
0,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_hash_update(psa_hash_operation_t *operation,
@@ -217,7 +217,7 @@
(uint32_t)input_length,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
@@ -233,7 +233,7 @@
(uint32_t)hash_size,
(uint32_t)hash_length);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
@@ -248,7 +248,7 @@
(uint32_t)hash_length,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
psa_status_t psa_hash_abort(psa_hash_operation_t *operation)
@@ -261,5 +261,5 @@
0,
0);
- return TFM_CRYPTO_PSA_RETURN(err);
+ return TFM_CRYPTO_ERR_TO_PSA_STATUS(err);
}
diff --git a/secure_fw/services/crypto/CMakeLists.inc b/secure_fw/services/crypto/CMakeLists.inc
index 041e971..5ee5dd9 100644
--- a/secure_fw/services/crypto/CMakeLists.inc
+++ b/secure_fw/services/crypto/CMakeLists.inc
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -9,7 +9,7 @@
#This file assumes it will be included from a project specific cmakefile, and
#will not create a library or executable.
#Inputs:
-# MBEDTLS_INSTALL_DIR - directory where mbed TLS headers and libraries can be found.
+# MBEDTLS_INSTALL_DIR - directory where mbed TLS headers and libraries can be found. Needed only when using CRYPTO_ENGINE_MBEDTLS ON.
# TFM_ROOT_DIR - root directory of the TF-M repository.
#Outputs:
# Will modify include directories to make the source compile.
@@ -26,9 +26,15 @@
message(FATAL_ERROR "Incomplete build configuration: ENABLE_CRYPTO is undefined. ")
endif()
+if (NOT DEFINED CRYPTO_ENGINE_MBEDTLS)
+ message(FATAL_ERROR "Incomplete build configuration: CRYPTO_ENGINE_MBEDTLS is undefined. ")
+endif()
+
if (ENABLE_CRYPTO)
- if (NOT DEFINED MBEDTLS_INSTALL_DIR)
- message(FATAL_ERROR "Please set MBEDTLS_INSTALL_DIR before including this file.")
+ if (CRYPTO_ENGINE_MBEDTLS)
+ if (NOT DEFINED MBEDTLS_INSTALL_DIR)
+ message(FATAL_ERROR "Please set MBEDTLS_INSTALL_DIR before including this file.")
+ endif()
endif()
if (NOT DEFINED TFM_ROOT_DIR)
@@ -42,6 +48,7 @@
"${CRYPTO_DIR}/crypto_key.c"
"${CRYPTO_DIR}/crypto_wrappers.c"
"${CRYPTO_DIR}/crypto_utils.c"
+ "${CRYPTO_DIR}/crypto_engine.c"
)
#Append all our source files to global lists.
@@ -51,7 +58,13 @@
#Setting include directories
embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
embedded_include_directories(PATH ${TFM_ROOT_DIR}/interface/include ABSOLUTE)
- embedded_include_directories(PATH ${MBEDTLS_INSTALL_DIR}/include ABSOLUTE)
+ if (CRYPTO_ENGINE_MBEDTLS)
+ embedded_include_directories(PATH ${MBEDTLS_INSTALL_DIR}/include ABSOLUTE)
+ endif()
+
+ #Inform the user about Crypto service features selected based on the Crypto service cmake flags
+ message("The Crypto service compile configuration is as follows:")
+ message("- CRYPTO_ENGINE_MBEDTLS: " ${CRYPTO_ENGINE_MBEDTLS})
else()
message(FATAL_ERROR "Build system currently doesn't support selectively disabling of a service.")
diff --git a/secure_fw/services/crypto/CMakeLists.txt b/secure_fw/services/crypto/CMakeLists.txt
index e004836..f7074c7 100644
--- a/secure_fw/services/crypto/CMakeLists.txt
+++ b/secure_fw/services/crypto/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -21,17 +21,21 @@
###Some project global settings
set (CRYPTO_DIR "${CMAKE_CURRENT_LIST_DIR}")
get_filename_component(TFM_ROOT_DIR "${CRYPTO_DIR}/../../.." ABSOLUTE)
-#Define location of mbed TLS source, build, and installation directory.
-get_filename_component(MBEDTLS_SOURCE_DIR "${TFM_ROOT_DIR}/../mbedtls" ABSOLUTE)
-set (MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
-set (MBEDTLS_INSTALL_DIR ${MBEDTLS_BINARY_DIR}/mbedtls_install)
-set (MBEDTLS_TARGET_NAME "mbedtls_crypto_lib")
-
-#Set mbed TLS compiler flags
-set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_SERVICES})
###Get the definition of what files we need to build
set (ENABLE_CRYPTO ON)
+if (NOT DEFINED CRYPTO_ENGINE_MBEDTLS)
+ set (CRYPTO_ENGINE_MBEDTLS ON)
+endif()
+
+if (CRYPTO_ENGINE_MBEDTLS)
+ #Define location of mbed TLS source, build, and installation directory.
+ get_filename_component(MBEDTLS_SOURCE_DIR "${TFM_ROOT_DIR}/../mbedtls" ABSOLUTE)
+ set (MBEDTLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/mbedtls")
+ set (MBEDTLS_INSTALL_DIR ${MBEDTLS_BINARY_DIR}/mbedtls_install)
+ set (MBEDTLS_TARGET_NAME "mbedtls_crypto_lib")
+endif()
+
include(CMakeLists.inc)
###Configure how we build our target
@@ -41,23 +45,31 @@
set (TFM_LVL 1)
endif()
-#Set preinclude header options for mbed TLS
-set(MBEDTLS_PREINCLUDE_PREFIX __tfm_crypto__)
-set(MBEDTLS_PREINCLUDE_HEADER ${CRYPTO_DIR}/mbedtls_global_symbols.h)
+if (CRYPTO_ENGINE_MBEDTLS)
+ #Set mbed TLS compiler flags
+ set(MBEDTLS_C_FLAGS ${MBEDTLS_C_FLAGS_SERVICES})
-#Build mbed TLS as external project.
-#This ensures mbed TLS is built with exactly defined settings.
-#mbed TLS will be used from its install location
-include(${TFM_ROOT_DIR}/BuildMbedtls.cmake)
+ #Set preinclude header options for mbed TLS
+ set(MBEDTLS_PREINCLUDE_PREFIX __tfm_crypto__)
+ set(MBEDTLS_PREINCLUDE_HEADER ${CRYPTO_DIR}/mbedtls_global_symbols.h)
+
+ #Build mbed TLS as external project.
+ #This ensures mbed TLS is built with exactly defined settings.
+ #mbed TLS will be used from its install location
+ include(${TFM_ROOT_DIR}/BuildMbedtls.cmake)
+endif()
#Specify what we build (for the crypto service, build as a static library)
add_library(tfm_crypto STATIC ${ALL_SRC_ASM} ${ALL_SRC_C})
-embedded_set_target_compile_defines(TARGET tfm_crypto LANGUAGE C DEFINES __ARM_FEATURE_CMSE=3 __thumb2__ TFM_LVL=${TFM_LVL} MBEDTLS_CONFIG_FILE="platform/ext/common/tfm_mbedtls_config.h")
-#Add a dependency on the mbed_tls_lib_install target.
-add_dependencies(tfm_crypto ${MBEDTLS_TARGET_NAME}_install)
-#Ask the compiler to merge the mbed TLS and the secure storage libraries.
-compiler_merge_library(DEST tfm_crypto LIBS "${MBEDTLS_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX_C}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX_C}")
-
+if (CRYPTO_ENGINE_MBEDTLS)
+ embedded_set_target_compile_defines(TARGET tfm_crypto LANGUAGE C DEFINES __ARM_FEATURE_CMSE=3 __thumb2__ TFM_LVL=${TFM_LVL} MBEDTLS_CONFIG_FILE="platform/ext/common/tfm_mbedtls_config.h" TFM_CRYPTO_ENGINE_MBEDTLS)
+ #Add a dependency on the mbed_tls_lib_install target.
+ add_dependencies(tfm_crypto ${MBEDTLS_TARGET_NAME}_install)
+ #Ask the compiler to merge the mbed TLS and the crypto libraries.
+ compiler_merge_library(DEST tfm_crypto LIBS "${MBEDTLS_INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX_C}mbedcrypto${CMAKE_STATIC_LIBRARY_SUFFIX_C}")
+else()
+ embedded_set_target_compile_defines(TARGET tfm_crypto LANGUAGE C DEFINES __ARM_FEATURE_CMSE=3 __thumb2__ TFM_LVL=${TFM_LVL})
+endif()
#Set common compiler and linker flags
config_setting_shared_compiler_flags(tfm_crypto)
config_setting_shared_linker_flags(tfm_crypto)
diff --git a/secure_fw/services/crypto/crypto_alloc.c b/secure_fw/services/crypto/crypto_alloc.c
index 5ccd33c..119e664 100644
--- a/secure_fw/services/crypto/crypto_alloc.c
+++ b/secure_fw/services/crypto/crypto_alloc.c
@@ -9,23 +9,11 @@
#include "tfm_crypto_defs.h"
-/* Pre include Mbed TLS headers */
-#define LIB_PREFIX_NAME __tfm_crypto__
-#include "mbedtls_global_symbols.h"
-
-/* Include the Mbed TLS configuration file, the way Mbed TLS does it
- * in each of its header files.
- */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "platform/ext/common/tfm_mbedtls_config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
#include "psa_crypto.h"
#include "tfm_crypto_api.h"
#include "tfm_crypto_struct.h"
+#include "secure_fw/core/secure_utilities.h"
/**
* \brief This value defines the maximum number of simultaneous operations
@@ -84,6 +72,13 @@
*/
/*!@{*/
+enum tfm_crypto_err_t tfm_crypto_init_alloc(void)
+{
+ /* Clear the contents of the local contexts */
+ tfm_memset(operation, 0, sizeof(operation));
+ return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
enum tfm_crypto_err_t tfm_crypto_operation_alloc(
enum tfm_crypto_operation_type type,
uint32_t *handle)
diff --git a/secure_fw/services/crypto/crypto_cipher.c b/secure_fw/services/crypto/crypto_cipher.c
index be2ac5d..ca78e8a 100644
--- a/secure_fw/services/crypto/crypto_cipher.c
+++ b/secure_fw/services/crypto/crypto_cipher.c
@@ -9,18 +9,7 @@
#include "tfm_crypto_defs.h"
-/* Pre include Mbed TLS headers */
-#define LIB_PREFIX_NAME __tfm_crypto__
-#include "mbedtls_global_symbols.h"
-
-/* Include the Mbed TLS configuration file, the way Mbed TLS does it
- * in each of its header files.
- */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "platform/ext/common/tfm_mbedtls_config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+#include "crypto_engine.h"
#include "psa_crypto.h"
@@ -29,33 +18,19 @@
#include "tfm_crypto_api.h"
#include "crypto_utils.h"
-/**
- * \brief For a TFM_CRYPTO_CIPHER_OPERATION, define the possible
- * modes of configuration.
- *
- */
-enum tfm_crypto_cipher_mode_t {
- TFM_CRYPTO_CIPHER_MODE_DECRYPT = 0,
- TFM_CRYPTO_CIPHER_MODE_ENCRYPT = 1,
-};
-
static enum tfm_crypto_err_t tfm_crypto_cipher_setup(
psa_cipher_operation_t *operation,
psa_key_slot_t key,
psa_algorithm_t alg,
- enum tfm_crypto_cipher_mode_t c_mode)
+ enum engine_cipher_mode_t c_mode)
{
- const mbedtls_cipher_info_t *info = NULL;
- psa_algorithm_t padding_mode = PSA_ALG_BLOCK_CIPHER_PAD_NONE;
- psa_key_type_t key_type;
- size_t key_size;
- enum tfm_crypto_err_t err;
uint8_t key_data[TFM_CRYPTO_MAX_KEY_LENGTH];
- uint32_t ret;
- mbedtls_cipher_type_t type = MBEDTLS_CIPHER_NONE;
- mbedtls_cipher_padding_t mbedtls_padding_mode = MBEDTLS_PADDING_NONE;
-
+ size_t key_size;
+ psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
+ psa_status_t status = PSA_SUCCESS;
+ enum tfm_crypto_err_t err;
struct tfm_cipher_operation_s *ctx = NULL;
+ struct cipher_engine_info engine_info;
/* Validate pointers */
err = tfm_crypto_memory_check(operation,
@@ -66,38 +41,26 @@
}
if (!PSA_ALG_IS_CIPHER(alg)) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+ return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
}
- /* FIXME: Check that key is compatible with alg */
+ /* Access the key module to retrieve key related information */
err = tfm_crypto_get_key_information(key, &key_type, &key_size);
if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
}
- err = tfm_crypto_export_key(key, &key_data[0], TFM_CRYPTO_MAX_KEY_LENGTH,
- &key_size);
- if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
- return err;
+ /* Setup the algorithm on the crypto engine */
+ status = tfm_crypto_engine_cipher_setup(alg,
+ (const psa_key_type_t)key_type,
+ (const uint32_t)key_size,
+ c_mode,
+ &engine_info);
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
- /* Mbed TLS cipher setup */
- if (PSA_BYTES_TO_BITS(key_size) == 128) {
- if (alg == PSA_ALG_CBC_BASE) {
- type = MBEDTLS_CIPHER_AES_128_CBC;
- } else if (alg == PSA_ALG_CFB_BASE) {
- if (c_mode == TFM_CRYPTO_CIPHER_MODE_ENCRYPT) {
- type = MBEDTLS_CIPHER_AES_128_CFB128;
- }
- }
- }
-
- /* The requested alg/key/mode is not supported */
- if (type == MBEDTLS_CIPHER_NONE) {
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
- }
-
- /* Allocate the operation context in the TFM space */
+ /* Allocate the operation context in the secure world */
err = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
&(operation->handle));
if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
@@ -109,81 +72,67 @@
operation->handle,
(void **)&ctx);
if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+ /* Release the operation context */
+ tfm_crypto_operation_release(&(operation->handle));
return err;
}
+ /* Set the proper cipher mode (encrypt/decrypt) in the operation context */
+ ctx->cipher_mode = (uint8_t) c_mode;
+
/* Bind the algorithm to the cipher operation */
ctx->alg = alg;
- /* Mbed TLS cipher init */
- mbedtls_cipher_init(&(ctx->cipher));
- info = mbedtls_cipher_info_from_type(type);
- ret = mbedtls_cipher_setup(&(ctx->cipher), info);
- if (ret != 0) {
+ /* Start the crypto engine */
+ status = tfm_crypto_engine_cipher_start(&(ctx->engine_ctx), &engine_info);
+ if (status != PSA_SUCCESS) {
/* Release the operation context */
tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
- /* FIXME: Check based on the algorithm, if we need to have an IV */
- ctx->iv_required = 1;
+ /* Access the crypto service key module to retrieve key data */
+ err = tfm_crypto_export_key(key,
+ &key_data[0],
+ TFM_CRYPTO_MAX_KEY_LENGTH,
+ &key_size);
+ if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+ /* Release the operation context */
+ tfm_crypto_operation_release(&(operation->handle));
+ return err;
+ }
+
+ /* Set the key on the engine */
+ status = tfm_crypto_engine_cipher_set_key(&(ctx->engine_ctx),
+ key_data,
+ key_size,
+ &engine_info);
+ if (status != PSA_SUCCESS) {
+ /* Release the operation context */
+ tfm_crypto_operation_release(&(operation->handle));
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ }
/* Bind the key to the cipher operation */
ctx->key = key;
ctx->key_set = 1;
- /* Mbed TLS cipher set key */
- if (c_mode == TFM_CRYPTO_CIPHER_MODE_ENCRYPT) {
-
- ret = mbedtls_cipher_setkey(&(ctx->cipher),
- &key_data[0],
- PSA_BYTES_TO_BITS(key_size),
- MBEDTLS_ENCRYPT);
-
- } else if (c_mode == TFM_CRYPTO_CIPHER_MODE_DECRYPT) {
-
- ret = mbedtls_cipher_setkey(&(ctx->cipher),
- &key_data[0],
- PSA_BYTES_TO_BITS(key_size),
- MBEDTLS_DECRYPT);
- } else {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
-
- if (ret != 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
- }
-
- /* Mbed TLS cipher set padding mode in case of CBC */
+ /* Set padding mode on engine in case of CBC */
if ((alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK) == PSA_ALG_CBC_BASE) {
- /* Check the value of padding field */
- padding_mode = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
-
- switch (padding_mode) {
- case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
- mbedtls_padding_mode = MBEDTLS_PADDING_PKCS7;
- break;
- case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
- mbedtls_padding_mode = MBEDTLS_PADDING_NONE;
- break;
- default:
- return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
- }
-
- ret = mbedtls_cipher_set_padding_mode(&(ctx->cipher),
- mbedtls_padding_mode);
- if (ret != 0) {
+ status = tfm_crypto_engine_cipher_set_padding_mode(&(ctx->engine_ctx),
+ &engine_info);
+ if (status != PSA_SUCCESS) {
/* Release the operation context */
tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
}
+ /* FIXME: Check based on the algorithm, if we need to have an IV */
+ ctx->iv_required = 1;
+ ctx->block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type);
+
return TFM_CRYPTO_ERR_PSA_SUCCESS;
}
@@ -198,7 +147,7 @@
const unsigned char *iv,
size_t iv_length)
{
- int ret;
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
struct tfm_cipher_operation_s *ctx = NULL;
@@ -222,36 +171,25 @@
return err;
}
- if (ctx->iv_required == 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED;
+ if ((iv_length != ctx->block_size) || (iv_length > TFM_CIPHER_IV_MAX_SIZE)){
+ return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
}
- if (iv_length > PSA_CIPHER_IV_MAX_SIZE) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
+ if ((ctx->iv_set == 1) || (ctx->iv_required == 0)) {
+ return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
}
- /* Bind the IV to the cipher operation */
- ret = mbedtls_cipher_set_iv(&(ctx->cipher), iv, iv_length);
- if (ret != 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ /* Set the IV on the crypto engine */
+ status = tfm_crypto_engine_cipher_set_iv(&(ctx->engine_ctx),
+ iv,
+ iv_length);
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
+
ctx->iv_set = 1;
ctx->iv_size = iv_length;
- /* Reset the context after IV is set */
- ret = mbedtls_cipher_reset(&(ctx->cipher));
- if (ret != 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
- }
-
return TFM_CRYPTO_ERR_PSA_SUCCESS;
}
@@ -263,7 +201,7 @@
return tfm_crypto_cipher_setup(operation,
key,
alg,
- TFM_CRYPTO_CIPHER_MODE_ENCRYPT);
+ ENGINE_CIPHER_MODE_ENCRYPT);
}
enum tfm_crypto_err_t tfm_crypto_cipher_decrypt_setup(
@@ -274,7 +212,7 @@
return tfm_crypto_cipher_setup(operation,
key,
alg,
- TFM_CRYPTO_CIPHER_MODE_DECRYPT);
+ ENGINE_CIPHER_MODE_DECRYPT);
}
enum tfm_crypto_err_t tfm_crypto_cipher_update(
@@ -285,9 +223,8 @@
size_t output_size,
size_t *output_length)
{
- int ret;
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
- size_t olen;
struct tfm_cipher_operation_s *ctx = NULL;
/* Validate pointers */
@@ -327,9 +264,7 @@
/* If the IV is required and it's not been set yet */
if ((ctx->iv_required == 1) && (ctx->iv_set == 0)) {
- if (ctx->cipher.operation != MBEDTLS_DECRYPT) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
+ if (ctx->cipher_mode != ENGINE_CIPHER_MODE_DECRYPT) {
return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
}
@@ -343,24 +278,19 @@
/* If the key is not set, setup phase has not been completed */
if (ctx->key_set == 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
}
- *output_length = 0;
-
- ret = mbedtls_cipher_update(&(ctx->cipher), input, input_length,
- output, &olen);
- if ((ret != 0) || (olen == 0)) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ /* Update the cipher output with the input chunk on the engine */
+ status = tfm_crypto_engine_cipher_update(&(ctx->engine_ctx),
+ input,
+ input_length,
+ output,
+ (uint32_t *)output_length);
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
- /* Assign the output buffer length */
- *output_length = olen;
-
return TFM_CRYPTO_ERR_PSA_SUCCESS;
}
@@ -370,9 +300,8 @@
size_t output_size,
size_t *output_length)
{
- int ret;
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
- size_t olen;
struct tfm_cipher_operation_s *ctx = NULL;
/* Validate pointers */
@@ -395,8 +324,6 @@
return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
}
- *output_length = 0;
-
/* Look up the corresponding operation context */
err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
operation->handle,
@@ -405,17 +332,20 @@
return err;
}
- ret = mbedtls_cipher_finish(&(ctx->cipher), output, &olen);
- if (ret != 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ /* Finalise the operation on the crypto engine */
+ status = tfm_crypto_engine_cipher_finish(&(ctx->engine_ctx),
+ output,
+ (uint32_t *)output_length);
+ if (status != PSA_SUCCESS) {
+ *output_length = 0;
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
- *output_length = olen;
-
- /* Clear the Mbed TLS context */
- mbedtls_cipher_free(&(ctx->cipher));
+ /* Release resources on the crypto engine */
+ status = tfm_crypto_engine_cipher_release(&(ctx->engine_ctx));
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ }
/* Release the operation context */
err = tfm_crypto_operation_release(&(operation->handle));
@@ -428,6 +358,7 @@
enum tfm_crypto_err_t tfm_crypto_cipher_abort(psa_cipher_operation_t *operation)
{
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
struct tfm_cipher_operation_s *ctx = NULL;
@@ -447,8 +378,11 @@
return err;
}
- /* Clear the Mbed TLS context */
- mbedtls_cipher_free(&(ctx->cipher));
+ /* Release resources on the engine */
+ status = tfm_crypto_engine_cipher_release(&(ctx->engine_ctx));
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ }
/* Release the operation context */
err = tfm_crypto_operation_release(&(operation->handle));
diff --git a/secure_fw/services/crypto/crypto_engine.c b/secure_fw/services/crypto/crypto_engine.c
new file mode 100644
index 0000000..4f9290f
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_engine.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/**
+ * \brief Include the Crypto engine header. This source module implements the
+ * interface which is being used by the other components of the service
+ * to interact with the cryptography primitives available, in SW or HW.
+ * The current implementation provides only a SW implementation based on
+ * Mbed TLS functions.
+ */
+#include "crypto_engine.h"
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+/**
+ * \brief Buffer size used by Mbed TLS for its allocations
+ */
+#define TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN (1024)
+
+/**
+ * \brief Static buffer to be used by Mbed TLS for memory allocations
+ *
+ */
+static uint8_t mbedtls_mem_buf[TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN] = {0};
+
+/**
+ * \brief This function maps Mbed TLS return codes to PSA return codes.
+ *
+ * \param[in] ret Mbed TLS return value
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+static psa_status_t mbedtls_to_psa_return(int ret)
+{
+ /* zero return value means success */
+ if (ret == 0) {
+ return PSA_SUCCESS;
+ }
+
+ /* FIXME: For the time being map all errors to PSA_ERROR_UNKNOW_ERROR */
+ switch (ret) {
+ default:
+ return PSA_ERROR_UNKNOWN_ERROR;
+ }
+}
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+psa_status_t tfm_crypto_engine_init(void)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ /* Initialise the Mbed TLS static memory allocator so that Mbed TLS
+ * allocates memory from the provided static buffer instead of from
+ * the heap.
+ */
+ mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf,
+ TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN);
+ /* The previous function doesn't return any error code */
+ return_value = PSA_SUCCESS;
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_hash_setup(const psa_algorithm_t alg,
+ struct hash_engine_info *engine_info)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ mbedtls_md_type_t type = MBEDTLS_MD_NONE;
+
+ /* Mbed TLS message digest setup */
+ switch(alg) {
+ case PSA_ALG_MD2:
+#if defined(MBEDTLS_MD2_C)
+ type = MBEDTLS_MD_MD2;
+#endif
+ break;
+ case PSA_ALG_MD4:
+#if defined(MBEDTLS_MD4_C)
+ type = MBEDTLS_MD_MD4;
+#endif
+ break;
+ case PSA_ALG_MD5:
+#if defined(MBEDTLS_MD5_C)
+ type = MBEDTLS_MD_MD5;
+#endif
+ break;
+ case PSA_ALG_RIPEMD160:
+#if defined(MBEDTLS_RIPEMD160_C)
+ type = MBEDTLS_MD_RIPEMD160;
+#endif
+ break;
+ case PSA_ALG_SHA_1:
+#if defined(MBEDTLS_SHA1_C)
+ type = MBEDTLS_MD_SHA1;
+#endif
+ break;
+ case PSA_ALG_SHA_224:
+#if defined(MBEDTLS_SHA256_C)
+ type = MBEDTLS_MD_SHA224;
+#endif
+ break;
+ case PSA_ALG_SHA_256:
+#if defined(MBEDTLS_SHA256_C)
+ type = MBEDTLS_MD_SHA256;
+#endif
+ break;
+ case PSA_ALG_SHA_384:
+#if defined(MBEDTLS_SHA512_C)
+ type = MBEDTLS_MD_SHA384;
+#endif
+ break;
+ case PSA_ALG_SHA_512:
+#if defined(MBEDTLS_SHA512_C)
+ type = MBEDTLS_MD_SHA512;
+#endif
+ break;
+ default:
+ break;
+ }
+
+ engine_info->type = (uint32_t) type;
+
+ /* Mbed TLS currently does not support SHA3: PSA_ALG_SHA3_224,
+ * PSA_ALG_SHA3_256, PSA_ALG_SHA3_384, PSA_ALG_SHA3_512;
+ * Mbed TLS currently does not support SHA-512 Truncated modes:
+ * PSA_ALG_SHA_512_224, PSA_ALG_SHA_512_256
+ */
+ if (type == MBEDTLS_MD_NONE) {
+ return_value = PSA_ERROR_NOT_SUPPORTED;
+ } else {
+ return_value = PSA_SUCCESS;
+ }
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_hash_start(
+ union engine_hash_context *hp,
+ const struct hash_engine_info *engine_info)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ const mbedtls_md_info_t *info = NULL;
+ int ret;
+
+ /* Mbed TLS message digest init */
+ mbedtls_md_init(&(hp->ctx));
+ info = mbedtls_md_info_from_type((mbedtls_md_type_t)engine_info->type);
+ ret = mbedtls_md_setup(&(hp->ctx), info, 0); /* 0: not HMAC */
+ if (ret != 0) {
+ return_value = mbedtls_to_psa_return(ret);
+ } else {
+ /* Start the message digest context */
+ ret = mbedtls_md_starts(&(hp->ctx));
+ return_value = mbedtls_to_psa_return(ret);
+ }
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_hash_update(union engine_hash_context *hp,
+ const uint8_t *input,
+ const uint32_t input_length)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+ /* Update the message digest with a new chunk of information */
+ ret = mbedtls_md_update(&(hp->ctx), input, input_length);
+ return_value = mbedtls_to_psa_return(ret);
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_hash_finish(union engine_hash_context *hp,
+ uint8_t *hash)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+ /* Finalise the hash value, producing the output */
+ ret = mbedtls_md_finish(&(hp->ctx), hash);
+ return_value = mbedtls_to_psa_return(ret);
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_hash_release(union engine_hash_context *hp)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ /* Clear the Mbed TLS message digest context */
+ mbedtls_md_free(&(hp->ctx));
+ /* The previous function doesn't return any error code */
+ return_value = PSA_SUCCESS;
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_setup(const psa_algorithm_t alg,
+ const psa_key_type_t key_type,
+ const uint32_t key_size,
+ const enum engine_cipher_mode_t engine_cipher_mode,
+ struct cipher_engine_info *engine_info)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ mbedtls_cipher_type_t type = MBEDTLS_CIPHER_NONE;
+ mbedtls_cipher_padding_t padding_mode = MBEDTLS_PADDING_NONE;
+ psa_algorithm_t padding_mode_field = PSA_ALG_BLOCK_CIPHER_PAD_NONE;
+
+ /* FIXME: Check that key is compatible with alg. It's assumed that key
+ * key_type will be AES, this needs to be extended as well. A
+ * proper function to determine cipher type based on inputs
+ * will need to be designed here.
+ */
+ if ((engine_cipher_mode != ENGINE_CIPHER_MODE_ENCRYPT) &&
+ (engine_cipher_mode != ENGINE_CIPHER_MODE_DECRYPT)) {
+ return_value = PSA_ERROR_NOT_SUPPORTED;
+ } else {
+ /* Mbed TLS cipher setup */
+ if (key_size == 128) {
+ if (alg == PSA_ALG_CBC_BASE) {
+ type = MBEDTLS_CIPHER_AES_128_CBC;
+ } else if (alg == PSA_ALG_CFB_BASE) {
+ if (engine_cipher_mode == ENGINE_CIPHER_MODE_ENCRYPT) {
+ type = MBEDTLS_CIPHER_AES_128_CFB128;
+ }
+ }
+ }
+
+ if (type == MBEDTLS_CIPHER_NONE) {
+ return_value = PSA_ERROR_NOT_SUPPORTED;
+ } else {
+ /* If CBC, need to set check the padding mode */
+ if ((alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK) == PSA_ALG_CBC_BASE) {
+
+ /* Check the value of padding field */
+ padding_mode_field = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
+
+ switch (padding_mode_field) {
+ case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
+ padding_mode = MBEDTLS_PADDING_PKCS7;
+ return_value = PSA_SUCCESS;
+ break;
+ case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
+ padding_mode = MBEDTLS_PADDING_NONE;
+ return_value = PSA_SUCCESS;
+ break;
+ default:
+ return_value = PSA_ERROR_NOT_SUPPORTED;
+ }
+ } else {
+ /* The engine is correctly configured */
+ return_value = PSA_SUCCESS;
+ }
+ }
+ }
+
+ if (return_value == PSA_SUCCESS) {
+ engine_info->type = (uint32_t) type;
+ engine_info->cipher_mode = engine_cipher_mode;
+ engine_info->padding_mode = (uint32_t) padding_mode;
+ }
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_set_padding_mode(
+ union engine_cipher_context *cp,
+ const struct cipher_engine_info *engine_info)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+ ret = mbedtls_cipher_set_padding_mode(&(cp->ctx),
+ (mbedtls_cipher_padding_t)engine_info->padding_mode);
+ return_value = mbedtls_to_psa_return(ret);
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_start(
+ union engine_cipher_context *cp,
+ const struct cipher_engine_info *engine_info)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+ const mbedtls_cipher_info_t *info = NULL;
+
+ /* Mbed TLS cipher init */
+ mbedtls_cipher_init(&(cp->ctx));
+ info = mbedtls_cipher_info_from_type(engine_info->type);
+
+ ret = mbedtls_cipher_setup(&(cp->ctx), info);
+ return_value = mbedtls_to_psa_return(ret);
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_set_key(
+ union engine_cipher_context *cp,
+ const uint8_t *key_data,
+ const uint32_t key_size,
+ const struct cipher_engine_info *engine_info)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+ /* Mbed TLS cipher set key */
+ if ((engine_info->cipher_mode != ENGINE_CIPHER_MODE_ENCRYPT) &&
+ (engine_info->cipher_mode != ENGINE_CIPHER_MODE_DECRYPT)) {
+ return_value = PSA_ERROR_NOT_SUPPORTED;
+ } else {
+ /* Set the key on the context */
+ ret = mbedtls_cipher_setkey(
+ &(cp->ctx),
+ key_data,
+ PSA_BYTES_TO_BITS(key_size),
+ (engine_info->cipher_mode == ENGINE_CIPHER_MODE_ENCRYPT) ?
+ MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT);
+ return_value = mbedtls_to_psa_return(ret);
+ }
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_set_iv(union engine_cipher_context *cp,
+ const uint8_t *iv,
+ const uint32_t iv_length)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+
+ /* Bind the IV to the cipher operation */
+ ret = mbedtls_cipher_set_iv(&(cp->ctx), iv, iv_length);
+ if (ret != 0) {
+ return_value = mbedtls_to_psa_return(ret);
+ } else {
+ /* Reset the context after IV is set */
+ ret = mbedtls_cipher_reset(&(cp->ctx));
+ return_value = mbedtls_to_psa_return(ret);
+ }
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_update(union engine_cipher_context *cp,
+ const uint8_t *input,
+ const uint32_t input_length,
+ uint8_t *output,
+ uint32_t *output_length)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+ /* Update with the chunk of input data, eventually producing output */
+ ret = mbedtls_cipher_update(&(cp->ctx), input, input_length,
+ output, (size_t *)output_length);
+ return_value = mbedtls_to_psa_return(ret);
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_finish(union engine_cipher_context *cp,
+ uint8_t *output,
+ uint32_t *output_length)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ int ret;
+ /* Finalise the cipher operation */
+ ret = mbedtls_cipher_finish(&(cp->ctx), output, (size_t *)output_length);
+ return_value = mbedtls_to_psa_return(ret);
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
+
+psa_status_t tfm_crypto_engine_cipher_release(union engine_cipher_context *cp)
+{
+ psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ /* Clear the Mbed TLS context */
+ mbedtls_cipher_free(&(cp->ctx));
+ /* The previous function doesn't return any error code */
+ return_value = PSA_SUCCESS;
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+ return return_value;
+}
diff --git a/secure_fw/services/crypto/crypto_engine.h b/secure_fw/services/crypto/crypto_engine.h
new file mode 100644
index 0000000..a4e388d
--- /dev/null
+++ b/secure_fw/services/crypto/crypto_engine.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __CRYPTO_ENGINE_H__
+#define __CRYPTO_ENGINE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <limits.h>
+#include "psa_crypto.h"
+
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+/* Pre include Mbed TLS headers */
+#define LIB_PREFIX_NAME __tfm_crypto__
+#include "mbedtls_global_symbols.h"
+
+/* Include the Mbed TLS configuration file, the way Mbed TLS does it
+ * in each of its header files. */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "platform/ext/common/tfm_mbedtls_config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/**
+ * \brief List of engine specific includes for Mbed TLS
+ *
+ */
+#include "mbedtls/memory_buffer_alloc.h"
+#include "mbedtls/md.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/cmac.h"
+
+#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
+
+/**
+ * \brief Generic engine cipher context type
+ *
+ */
+union engine_cipher_context {
+ uint32_t dummy; /* Needed to keep the union always not empty */
+#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
+ mbedtls_cipher_context_t ctx;
+#endif
+};
+
+/**
+ * \brief Generic engine hash context type
+ *
+ */
+union engine_hash_context {
+ uint32_t dummy; /* Needed to keep the union always not empty */
+#if defined (TFM_CRYPTO_ENGINE_MBEDTLS)
+ mbedtls_md_context_t ctx;
+#endif
+};
+
+/**
+ * \brief Generic engine cmac context type
+ *
+ */
+union engine_cmac_context {
+ uint32_t dummy; /* Needed to keep the union always not empty */
+#if defined (TFM_CRYPTO_ENGINE_MBEDTLS)
+ mbedtls_cmac_context_t ctx;
+#endif
+};
+
+
+
+/**
+ * \brief For a cipher operation, define the possible modes of configuration.
+ */
+enum engine_cipher_mode_t {
+ ENGINE_CIPHER_MODE_NONE = 0, /*!< Cipher mode not selected */
+ ENGINE_CIPHER_MODE_DECRYPT, /*!< Cipher mode set to decryption */
+ ENGINE_CIPHER_MODE_ENCRYPT, /*!< Cipher mode set to encryption */
+ /* Used to force enum size */
+ ENGINE_CIPHER_MODE_FORCE_INT_SIZE = INT_MAX
+};
+
+/**
+ * \brief Structure used to keep engine information during the engine setup
+ * step for a hash operation.
+ */
+struct hash_engine_info {
+ uint32_t type; /*!< Engine specific identifier which describes
+ * the operation which has to be configured on
+ * the crypto engine
+ */
+};
+
+/**
+ * \brief Structure used to keep engine information during the engine setup
+ * step for a cipher operation
+ */
+struct cipher_engine_info {
+ uint32_t type; /*!< Engine specific identifier which describes
+ * the operation which has to be configured on
+ * the crypto engine
+ */
+ enum engine_cipher_mode_t cipher_mode; /*!< Describes if the cipher on
+ * the engine is configured for
+ * encryption or decryption
+ */
+ uint32_t padding_mode; /*!< Engine specific identifier which describes
+ * the padding mode which has been configured
+ * on the cipher, if any
+ */
+};
+
+/**
+ * \brief This function performs all the generic operations required to
+ * initialise the crypto engine
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_init(void);
+
+/**
+ * \brief This function performs the setup of a multipart hash operation on the
+ * crypto engine
+ *
+ * \param[in] alg Algorithm to be setup
+ * \param[out] engine_info Pointer to the engine_info structure containing
+ * engine parameters determined during the setup
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_hash_setup(const psa_algorithm_t alg,
+ struct hash_engine_info *engine_info);
+/**
+ * \brief This function starts a multipart hash operation on the crypto engine
+ *
+ * \param[in/out] hp Pointer to the hash engine context to be used
+ * \param[in] engine_info Pointer to the engine_info structure as determined
+ * during the setup step
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_hash_start(union engine_hash_context *hp,
+ const struct hash_engine_info *engine_info);
+/**
+ * \brief This function updates a multipart hash operation with one chunk of
+ * input data
+ *
+ * \param[in/out] hp Pointer to the hash engine context to be used
+ * \param[in] input Pointer to the buffer containing the input data
+ * \param[in] input_length Size in bytes of the input data
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_hash_update(union engine_hash_context *hp,
+ const uint8_t *input,
+ const uint32_t input_length);
+/**
+ * \brief This function finalises a multipart hash operation producing one hash
+ * value in output as described by the operation context
+ *
+ * \param[in/out] hp Pointer to the hash engine context to be used
+ * \param[out] hash Pointer to the buffer containing the output hash value
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_hash_finish(union engine_hash_context *hp,
+ uint8_t *hash);
+/**
+ * \brief This function releases the crypto engine resources associated to a
+ * multipart hash operation context
+ *
+ * \param[in/out] hp Pointer to the hash engine context to be used
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_hash_release(union engine_hash_context *hp);
+
+/**
+ * \brief This function performs the setup of a multipart cipher operation on
+ * the crypto engine
+ *
+ * \param[in] alg Algorithm to be configured
+ * \param[in] key_type Key type of the key that will be used
+ * \param[in] key_size Size in bits of the key that will be used
+ * \param[in] engine_cipher_mode Parameter specifying if the cipher must be set
+ * in encrypt or decrypt mode
+ * \param[out] engine_info Pointer to the engine configuration structure
+ * containing engine parameters determined during
+ * setup
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_setup(const psa_algorithm_t alg,
+ const psa_key_type_t key_type,
+ const uint32_t key_size,
+ const enum engine_cipher_mode_t engine_cipher_mode,
+ struct cipher_engine_info *engine_info);
+/**
+ * \brief This function sets the padding mode on the crypto engine based on the
+ * information gathered during the setup phase
+ *
+ * \param[in/out] cp Pointer to the cipher engine context to be used
+ * \param[in] engine_info Pointer to the engine configuration structure
+ * containing engine parameters determined during
+ * setup
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_set_padding_mode(
+ union engine_cipher_context *cp,
+ const struct cipher_engine_info *engine_info);
+/**
+ * \brief This function starts a multipart cipher operation
+ *
+ * \param[in/out] cp Pointer to the cipher engine context to be used
+ * \param[in] engine_info Pointer to the engine configuration structure
+ * containing engine parameters determined during
+ * setup
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_start(
+ union engine_cipher_context *cp,
+ const struct cipher_engine_info *engine_info);
+/**
+ * \brief This function sets the key data on the crypto engine for a multipart
+ * cipher operation. It reads also from the engine_info configuration
+ * item to determine if the key needs to be set in encryption or
+ * decryption mode on the engine.
+ *
+ * \param[in/out] cp Pointer to the cipher engine context to be used
+ * \param[in] key_data Pointer to the buffer containing key material
+ * \param[in] key_size Size in bytes of the key pointed by key_data
+ * \param[in] engine_info Pointer to the engine configuration structure
+ * containing engine parameters determined during
+ * setup
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_set_key(
+ union engine_cipher_context *cp,
+ const uint8_t *key_data,
+ const uint32_t key_size,
+ const struct cipher_engine_info *engine_info);
+/**
+ * \brief This function sets the initialisation vector on the crypto engine for
+ * a multipart cipher operation
+ *
+ * \param[in/out] cp Pointer to the cipher engine context to be used
+ * \param[in] iv Pointer to the buffer containing the IV
+ * \param[in] iv_length Size in bytes of the initialisation vector
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_set_iv(union engine_cipher_context *cp,
+ const uint8_t *iv,
+ const uint32_t iv_length);
+/**
+ * \brief This function updates a multipart cipher operation on the crypto
+ * engine with a new chunk of input data. It may produce output data.
+ *
+ * \param[in/out] cp Pointer to the cipher engine context to be used
+ * \param[in] input Pointer to the buffer containing the input data
+ * chunk
+ * \param[in] input_length Size in bytes of the input data chunk
+ * \param[out] output Pointer to the buffer containing the output data
+ * \param[out] output_length Pointer to the size in bytes of the data produced
+ * as output
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_update(union engine_cipher_context *cp,
+ const uint8_t *input,
+ const uint32_t input_length,
+ uint8_t *output,
+ uint32_t *output_length);
+/**
+ * \brief This function finalises a multipart cipher operation on the crypto
+ * engine. It may produce output data.
+ *
+ * \param[in/out] cp Pointer to the cipher engine context to be used
+ * \param[out] output Pointer to the buffer containing the output data
+ * \param[out] output_length Pointer to the size in bytes of the data produced
+ * as output
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_finish(union engine_cipher_context *cp,
+ uint8_t *output,
+ uint32_t *output_length);
+/**
+ * \brief This function releases the crypto engine resources associated to a
+ * multipart cipher operation context
+ *
+ * \param[in/out] cp Pointer to the cipher engine context to be used
+ *
+ * \return Return values as specified by \ref psa_status_t
+ */
+psa_status_t tfm_crypto_engine_cipher_release(union engine_cipher_context *cp);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CRYPTO_ENGINE_H__ */
diff --git a/secure_fw/services/crypto/crypto_hash.c b/secure_fw/services/crypto/crypto_hash.c
index 8356d55..265385b 100644
--- a/secure_fw/services/crypto/crypto_hash.c
+++ b/secure_fw/services/crypto/crypto_hash.c
@@ -8,19 +8,7 @@
#include <limits.h>
#include "tfm_crypto_defs.h"
-
-/* Pre include Mbed TLS headers */
-#define LIB_PREFIX_NAME __tfm_crypto__
-#include "mbedtls_global_symbols.h"
-
-/* Include the Mbed TLS configuration file, the way Mbed TLS does it
- * in each of its header files. */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "platform/ext/common/tfm_mbedtls_config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
+#include "crypto_engine.h"
#include "psa_crypto.h"
#include "tfm_crypto_struct.h"
@@ -37,12 +25,10 @@
enum tfm_crypto_err_t tfm_crypto_hash_setup(psa_hash_operation_t *operation,
psa_algorithm_t alg)
{
- int ret;
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
- const mbedtls_md_info_t *info = NULL;
- mbedtls_md_type_t type = MBEDTLS_MD_NONE;
-
struct tfm_hash_operation_s *ctx = NULL;
+ struct hash_engine_info engine_info;
/* Validate pointers */
err = tfm_crypto_memory_check(operation,
@@ -56,67 +42,13 @@
return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
}
- /* Mbed TLS message digest setup */
- switch(alg) {
- case PSA_ALG_MD2:
-#if defined(MBEDTLS_MD2_C)
- type = MBEDTLS_MD_MD2;
-#endif
- break;
- case PSA_ALG_MD4:
-#if defined(MBEDTLS_MD4_C)
- type = MBEDTLS_MD_MD4;
-#endif
- break;
- case PSA_ALG_MD5:
-#if defined(MBEDTLS_MD5_C)
- type = MBEDTLS_MD_MD5;
-#endif
- break;
- case PSA_ALG_RIPEMD160:
-#if defined(MBEDTLS_RIPEMD160_C)
- type = MBEDTLS_MD_RIPEMD160;
-#endif
- break;
- case PSA_ALG_SHA_1:
-#if defined(MBEDTLS_SHA1_C)
- type = MBEDTLS_MD_SHA1;
-#endif
- break;
- case PSA_ALG_SHA_224:
-#if defined(MBEDTLS_SHA256_C)
- type = MBEDTLS_MD_SHA224;
-#endif
- break;
- case PSA_ALG_SHA_256:
-#if defined(MBEDTLS_SHA256_C)
- type = MBEDTLS_MD_SHA256;
-#endif
- break;
- case PSA_ALG_SHA_384:
-#if defined(MBEDTLS_SHA512_C)
- type = MBEDTLS_MD_SHA384;
-#endif
- break;
- case PSA_ALG_SHA_512:
-#if defined(MBEDTLS_SHA512_C)
- type = MBEDTLS_MD_SHA512;
-#endif
- break;
- default:
- break;
- }
-
- /* Mbed TLS currently does not support SHA3: PSA_ALG_SHA3_224,
- * PSA_ALG_SHA3_256, PSA_ALG_SHA3_384, PSA_ALG_SHA3_512;
- * Mbed TLS currently does not support SHA-512 Truncated modes:
- * PSA_ALG_SHA_512_224, PSA_ALG_SHA_512_256
- */
- if (type == MBEDTLS_MD_NONE) {
+ /* Setup the engine for the requested algorithm */
+ status = tfm_crypto_engine_hash_setup(alg, &engine_info);
+ if (status != PSA_SUCCESS) {
return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
}
- /* Allocate the operation context in the Secure world */
+ /* Allocate the operation context in the secure world */
err = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
&(operation->handle));
if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
@@ -136,22 +68,12 @@
/* Bind the algorithm to the hash context */
ctx->alg = alg;
- /* Mbed TLS message digest init */
- mbedtls_md_init(&ctx->md);
- info = mbedtls_md_info_from_type(type);
- ret = mbedtls_md_setup(&(ctx->md), info, 0); /* 0: not HMAC */
- if (ret != 0) {
+ /* Start the engine */
+ status = tfm_crypto_engine_hash_start(&(ctx->engine_ctx), &engine_info);
+ if (status != PSA_SUCCESS) {
/* Release the operation context */
tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
- }
-
- /* Start the message digest context */
- ret = mbedtls_md_starts(&(ctx->md));
- if (ret != 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
return TFM_CRYPTO_ERR_PSA_SUCCESS;
@@ -161,7 +83,7 @@
const uint8_t *input,
size_t input_length)
{
- int ret;
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
struct tfm_hash_operation_s *ctx = NULL;
@@ -187,12 +109,12 @@
return err;
}
- /* Process the input chunk */
- ret = mbedtls_md_update(&(ctx->md), input, input_length);
- if (ret != 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ /* Process the input chunk with the engine */
+ status = tfm_crypto_engine_hash_update(&(ctx->engine_ctx),
+ input,
+ input_length);
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
return TFM_CRYPTO_ERR_PSA_SUCCESS;
@@ -203,7 +125,7 @@
size_t hash_size,
size_t *hash_length)
{
- int ret;
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
struct tfm_hash_operation_s *ctx = NULL;
@@ -236,25 +158,24 @@
}
if (hash_size < PSA_HASH_SIZE(ctx->alg)) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
}
- /* Finalise the hash value */
- ret = mbedtls_md_finish(&(ctx->md), hash);
- if (ret != 0) {
- /* Release the operation context */
- tfm_crypto_operation_release(&(operation->handle));
- return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
+ /* Finalise the hash value using the engine */
+ status = tfm_crypto_engine_hash_finish(&(ctx->engine_ctx), hash);
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ }
+
+ /* Release engine resources */
+ status = tfm_crypto_engine_hash_release(&(ctx->engine_ctx));
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
}
/* Set the length of the hash that has been produced */
*hash_length = PSA_HASH_SIZE(ctx->alg);
- /* Clear the Mbed TLS message digest context */
- mbedtls_md_free(&(ctx->md));
-
/* Release the operation context */
err = tfm_crypto_operation_release(&(operation->handle));
if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
@@ -307,6 +228,7 @@
enum tfm_crypto_err_t tfm_crypto_hash_abort(psa_hash_operation_t *operation)
{
+ psa_status_t status = PSA_SUCCESS;
enum tfm_crypto_err_t err;
struct tfm_hash_operation_s *ctx = NULL;
@@ -326,8 +248,11 @@
return err;
}
- /* Clear the Mbed TLS message digest context */
- mbedtls_md_free(&(ctx->md));
+ /* Release engine resources */
+ status = tfm_crypto_engine_hash_release(&(ctx->engine_ctx));
+ if (status != PSA_SUCCESS) {
+ return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
+ }
/* Release the operation context */
err = tfm_crypto_operation_release(&(operation->handle));
diff --git a/secure_fw/services/crypto/crypto_init.c b/secure_fw/services/crypto/crypto_init.c
index 4243466..083ce84 100644
--- a/secure_fw/services/crypto/crypto_init.c
+++ b/secure_fw/services/crypto/crypto_init.c
@@ -1,49 +1,51 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "tfm_crypto_defs.h"
+#include "crypto_engine.h"
#include "tfm_crypto_api.h"
-/* Pre include Mbed TLS headers */
-#define LIB_PREFIX_NAME __tfm_crypto__
-#include "mbedtls_global_symbols.h"
+static enum tfm_crypto_err_t tfm_crypto_module_init(void)
+{
+ enum tfm_crypto_err_t err;
-/* Include the Mbed TLS configuration file, the way Mbed TLS does it
- * in each of its header files.
- */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "platform/ext/common/tfm_mbedtls_config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+ /* Init the Key module */
+ err = tfm_crypto_init_key();
+ if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+ return err;
+ }
-#include "mbedtls/memory_buffer_alloc.h"
+ /* Init the Alloc module */
+ err = tfm_crypto_init_alloc();
-/**
- * \brief Buffer size used by Mbed TLS for its allocations
- */
-#define TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN (1024)
-
-/**
- * \brief Static buffer to be used by Mbed TLS for memory allocations
- *
- */
-static uint8_t mbedtls_mem_buf[TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN] = {0};
+ return err;
+}
enum tfm_crypto_err_t tfm_crypto_init(void)
{
- /* Initialise everything that is needed */
+ psa_status_t status;
+ enum tfm_crypto_err_t err;
- /* Initialise the Mbed TLS static memory allocator so that Mbed TLS
- * allocates memory from the provided static buffer instead of from
- * the heap.
- */
- mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf,
- TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN);
+ /* Initialise other modules of the service */
+ err = tfm_crypto_module_init();
+ if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
+ return err;
+ }
+
+ /* Initialise the engine interface module */
+ status = tfm_crypto_engine_init();
+ if (status != PSA_SUCCESS) {
+ /* FIXME: For the time being, keep returning success even if the engine
+ * is not initialised correctly. This can be used to test corner cases
+ * without triggering any TF-M recovery mechanism during boot-up if it
+ * recognises that a service has not completed booting correctly.
+ */
+ return TFM_CRYPTO_ERR_PSA_SUCCESS;
+ }
return TFM_CRYPTO_ERR_PSA_SUCCESS;
}
diff --git a/secure_fw/services/crypto/crypto_key.c b/secure_fw/services/crypto/crypto_key.c
index a6769d4..d6b99c7 100644
--- a/secure_fw/services/crypto/crypto_key.c
+++ b/secure_fw/services/crypto/crypto_key.c
@@ -8,23 +8,10 @@
#include <limits.h>
#include "tfm_crypto_defs.h"
-
-/* Pre include Mbed TLS headers */
-#define LIB_PREFIX_NAME __tfm_crypto__
-#include "mbedtls_global_symbols.h"
-
-/* Include the Mbed TLS configuration file, the way Mbed TLS does it
- * in each of its header files.
- */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "platform/ext/common/tfm_mbedtls_config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
-
#include "psa_crypto.h"
#include "tfm_crypto_struct.h"
+#include "secure_fw/core/secure_utilities.h"
/**
* \brief This value defines the maximum number of simultaneous key stores
@@ -47,6 +34,13 @@
*/
/*!@{*/
+enum tfm_crypto_err_t tfm_crypto_init_key(void)
+{
+ /* Clear the contents of the local key_storage */
+ tfm_memset(key_storage, 0, sizeof(key_storage));
+ return TFM_CRYPTO_ERR_PSA_SUCCESS;
+}
+
enum tfm_crypto_err_t tfm_crypto_import_key(psa_key_slot_t key,
psa_key_type_t type,
const uint8_t *data,
diff --git a/secure_fw/services/crypto/manifest.yaml b/secure_fw/services/crypto/manifest.yaml
index 10b53f3..f8fa5d3 100644
--- a/secure_fw/services/crypto/manifest.yaml
+++ b/secure_fw/services/crypto/manifest.yaml
@@ -146,6 +146,7 @@
"crypto_wrappers.c",
"crypto_utils.c",
"crypto_hash.c",
+ "crypto_engine.c",
],
"tfm_linker_pattern": [
"library_list": [
diff --git a/secure_fw/services/crypto/tfm_crypto_api.h b/secure_fw/services/crypto/tfm_crypto_api.h
index d596ed9..488b432 100644
--- a/secure_fw/services/crypto/tfm_crypto_api.h
+++ b/secure_fw/services/crypto/tfm_crypto_api.h
@@ -34,41 +34,55 @@
};
/**
- * \brief Initialises the service
+ * \brief Initialise the service
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_init(void);
/**
- * \brief Allocates an operation object
+ * \brief Initialise the Key module
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_init_key(void);
+
+/**
+ * \brief Initialise the Alloc module
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
+ */
+enum tfm_crypto_err_t tfm_crypto_init_alloc(void);
+
+/**
+ * \brief Allocate an operation object
*
* \param[in] type Type of the operation object to allocate
* \param[out] handle Pointer to the corresponding handle assigned
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_operation_alloc(
enum tfm_crypto_operation_type type,
uint32_t *handle);
/**
- * \brief Releases an operation object
+ * \brief Release an operation object
*
* \param[in] handle Pointer to the handle for the release of the
* corresponding object
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_operation_release(uint32_t *handle);
/**
- * \brief Looks up an operation object pointer from the corresponding handle
+ * \brief Look up an operation object pointer from the corresponding handle
*
* \param[in] type Type of the operation object to look up
* \param[in] handle Handle to the operation object to look up
* \param[out] oper Double pointer to the corresponding object
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_operation_lookup(
enum tfm_crypto_operation_type type,
@@ -82,18 +96,18 @@
* \param[in] data Key data to import
* \param[in] data_length Length in bytes of the data field
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_import_key(psa_key_slot_t key,
psa_key_type_t type,
const uint8_t *data,
size_t data_length);
/**
- * \brief Destroy the key on the provided key slot
+ * \brief Destroy the key in the provided key slot
*
* \param[in] key Key slot
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_destroy_key(psa_key_slot_t key);
@@ -104,7 +118,7 @@
* \param[out] type Key type associated to the key slot requested
* \param[out] bits Length in bits of the key in the requested slot
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_get_key_information(psa_key_slot_t key,
psa_key_type_t *type,
@@ -117,7 +131,7 @@
* \param[in] data_size Length of the buffer pointed to by data
* \param[out] data_length Length of the exported key
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_export_key(psa_key_slot_t key,
uint8_t *data,
@@ -125,20 +139,19 @@
size_t *data_length);
/**
* \brief Export the public key contained in the provided key slot
- * for an asymmetric key pair.
+ * for an asymmetric key pair
*
* \param[in] key Key slot
* \param[out] data Buffer to hold the exported key
* \param[in] data_size Length of the buffer pointed to by data
* \param[out] data_length Length of the exported key
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_export_public_key(psa_key_slot_t key,
uint8_t *data,
size_t data_size,
size_t *data_length);
-
/**
* \brief Set the initialisation vector on the provided cipher operation
*
@@ -146,7 +159,7 @@
* \param[in] iv Buffer that contains the IV
* \param[in] iv_length Length of the provided IV
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_cipher_set_iv(
psa_cipher_operation_t *operation,
@@ -154,13 +167,16 @@
size_t iv_length);
/**
* \brief Set the cipher operation using the provided algorithm and key slot,
- * for encryption context.
+ * for encryption context
*
- * \param[in] operation Cipher operation context
- * \param[in] key Key slot to bind to the cipher context
- * \param[in] alg Algorithm to use for the cipher operation
+ * \note A successful call to this function initialises a cipher operation
+ * context which will be referred using the operation parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[out] operation Cipher operation context
+ * \param[in] key Key slot to bind to the cipher context
+ * \param[in] alg Algorithm to use for the cipher operation
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_cipher_encrypt_setup(
psa_cipher_operation_t *operation,
@@ -168,13 +184,16 @@
psa_algorithm_t alg);
/**
* \brief Set the cipher operation using the provided algorithm and key slot,
- * for decryption context.
+ * for decryption context
*
- * \param[in] operation Cipher operation context
- * \param[in] key Key slot to bind to the cipher context
- * \param[in] alg Algorithm to use for the cipher operation
+ * \note A successful call to this function initialises a cipher operation
+ * context which will be referred using the operation parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[out] operation Cipher operation context
+ * \param[in] key Key slot to bind to the cipher context
+ * \param[in] alg Algorithm to use for the cipher operation
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_cipher_decrypt_setup(
psa_cipher_operation_t *operation,
@@ -184,16 +203,16 @@
* \brief Update the cipher context with a chunk of input data to create a
* chunk of encrypted output data (for encryption contexts), or to
* decrypt a chunk of encrypted input data to obtain decrypted data
- * (for decryption contexts).
+ * (for decryption contexts)
*
- * \param[in] operation Cipher operation context
- * \param[in] input Buffer containing input data
- * \param[in] input_length Input length
- * \param[out] output Buffer containing output data
- * \param[in] output_size Size of the output buffer
- * \param[out] output_length Size of the produced output
+ * \param[in/out] operation Cipher operation context
+ * \param[in] input Buffer containing input data
+ * \param[in] input_length Input length
+ * \param[out] output Buffer containing output data
+ * \param[in] output_size Size of the output buffer
+ * \param[out] output_length Size of the produced output
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_cipher_update(
psa_cipher_operation_t *operation,
@@ -203,15 +222,18 @@
size_t output_size,
size_t *output_length);
/**
- * \brief Finalises a cipher context flushing out any remaining block of
+ * \brief Finalise a cipher context flushing out any remaining block of
* output data
*
- * \param[in] operation Cipher operation context
- * \param[out] output Buffer containing output data
- * \param[in] output_size Size of the output buffer
- * \param[out] output_length Size of the produced output
+ * \note A successful call to this function de-initialises the cipher operation
+ * context provided as parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Cipher operation context
+ * \param[out] output Buffer containing output data
+ * \param[in] output_size Size of the output buffer
+ * \param[out] output_length Size of the produced output
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_cipher_finish(
psa_cipher_operation_t *operation,
@@ -219,70 +241,86 @@
size_t output_size,
size_t *output_length);
/**
- * \brief Aborts a cipher operation, clears the operation context provided
+ * \brief Abort a cipher operation, clears the operation context provided
*
- * \param[in] operation Cipher operation context
+ * \note A successful call to this function de-initialises the cipher operation
+ * context provided as parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Cipher operation context
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_cipher_abort(
psa_cipher_operation_t *operation);
/**
- * \brief Starts a hash operation with the provided algorithm
+ * \brief Start a hash operation with the provided algorithm
*
- * \param[in] operation Hash operation context
- * \param[in] alg Algorithm chosen as hash
+ * \note A successful call to this function initialises a hash operation
+ * context which will be referred using the operation parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[out] operation Hash operation context
+ * \param[in] alg Algorithm chosen as hash
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_hash_setup(psa_hash_operation_t *operation,
psa_algorithm_t alg);
/**
- * \brief Adds a new input chunk to the data for which the final hash value
+ * \brief Add a new input chunk to the data for which the final hash value
* will be computed
*
* \param[in] operation Hash operation context
* \param[in] input Buffer containing the input data
* \param[in] input_length Size of the provided input data
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_hash_update(psa_hash_operation_t *operation,
const uint8_t *input,
size_t input_length);
/**
- * \brief Finalises a hash context operation producing the final hash value
+ * \brief Finalise a hash context operation producing the final hash value
*
- * \param[in] operation Hash operation context
- * \param[out] hash Buffer containing hash data
- * \param[in] hash_size Size of the hash buffer
- * \param[out] hash_length Size of the produced hash
+ * \note A successful call to this function de-initialises the hash operation
+ * context provided as parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Hash operation context
+ * \param[out] hash Buffer containing hash data
+ * \param[in] hash_size Size of the hash buffer
+ * \param[out] hash_length Size of the produced hash
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_hash_finish(psa_hash_operation_t *operation,
uint8_t *hash,
size_t hash_size,
size_t *hash_length);
/**
- * \brief Finalises a hash context operation, verifying that the final hash
+ * \brief Finalise a hash context operation, verifying that the final hash
* value matches the one provided as input
*
- * \param[in] operation Hash operation context
- * \param[in] hash Buffer containing the provided hash value
- * \param[in] hash_length Size of the provided hash value
+ * \note A successful call to this function de-initialises the hash operation
+ * context provided as parameter. The hash operation is de-initialised
+ * also in case TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE is returned
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Hash operation context
+ * \param[in] hash Buffer containing the provided hash value
+ * \param[in] hash_length Size of the provided hash value
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_hash_verify(psa_hash_operation_t *operation,
const uint8_t *hash,
size_t hash_length);
/**
- * \brief Aborts a hash operation, clears the operation context provided
+ * \brief Abort a hash operation, clears the operation context provided
*
- * \param[in] operation Hash operation context
+ * \note A successful call to this function de-initialises the hash operation
+ * context provided as parameter
*
- * \return Returns values as described in \ref tfm_crypto_err_t
+ * \param[in/out] operation Hash operation context
+ *
+ * \return Return values as described in \ref tfm_crypto_err_t
*/
enum tfm_crypto_err_t tfm_crypto_hash_abort(psa_hash_operation_t *operation);
diff --git a/secure_fw/services/crypto/tfm_crypto_struct.h b/secure_fw/services/crypto/tfm_crypto_struct.h
index dbd5bc3..9909cf9 100644
--- a/secure_fw/services/crypto/tfm_crypto_struct.h
+++ b/secure_fw/services/crypto/tfm_crypto_struct.h
@@ -11,41 +11,30 @@
* \brief Similarly to what psa_crypto_struct.h defines for
* the frontend, this header provides Crypto service
* specific definitions for operation contexts.
- * Current implementation is directly based on Mbed TLS.
*/
+#include "psa_crypto.h"
+#include "crypto_engine.h"
+
#ifndef __TFM_CRYPTO_STRUCT_H__
#define __TFM_CRYPTO_STRUCT_H__
-/* Include the Mbed TLS configuration file, the way Mbed TLS does it
- * in each of its header files.
- */
-#if !defined(MBEDTLS_CONFIG_FILE)
-#include "platform/ext/common/tfm_mbedtls_config.h"
-#else
-#include MBEDTLS_CONFIG_FILE
-#endif
+struct tfm_hash_operation_s {
-#include "mbedtls/cipher.h"
-#include "mbedtls/cmac.h"
-#include "mbedtls/md.h"
-
-struct tfm_hash_operation_s
-{
psa_algorithm_t alg;
- mbedtls_md_context_t md;
+ union engine_hash_context engine_ctx;
};
-struct tfm_hmac_internal_data_s
-{
- /* The hash context. */
- struct psa_hash_operation_s hash_ctx;
+struct tfm_hmac_internal_data_s {
+
+ /* The hash operation. */
+ psa_hash_operation_t hash_operation;
/* The HMAC part of the context. */
uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
};
-struct tfm_mac_operation_s
-{
+struct tfm_mac_operation_s {
+
psa_algorithm_t alg;
uint8_t key_set;
uint8_t iv_required;
@@ -54,17 +43,16 @@
uint8_t key_usage_sign;
uint8_t key_usage_verify;
uint8_t mac_size;
- union
- {
+ union {
struct tfm_hmac_internal_data_s hmac;
- mbedtls_cipher_context_t cmac;
+ union engine_cmac_context cmac;
} ctx;
};
-#define PSA_CIPHER_IV_MAX_SIZE 16
+#define TFM_CIPHER_IV_MAX_SIZE 16
-struct tfm_cipher_operation_s
-{
+struct tfm_cipher_operation_s {
+
psa_algorithm_t alg;
uint8_t key_set;
uint8_t iv_required;
@@ -72,6 +60,7 @@
uint8_t iv_size;
uint8_t block_size;
psa_key_slot_t key;
- mbedtls_cipher_context_t cipher;
+ uint8_t cipher_mode;
+ union engine_cipher_context engine_ctx;
};
#endif /* __TFM_CRYPTO_STRUCT_H__ */
diff --git a/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c b/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
index 5a67d7c..06a5a47 100644
--- a/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
+++ b/test/suites/crypto/non_secure/crypto_ns_interface_testsuite.c
@@ -175,6 +175,8 @@
uint8_t encrypted_data[ENC_DEC_BUFFER_SIZE] = {0};
uint32_t comp_result;
+ ret->val = TEST_PASSED;
+
/* Import a key on slot 0 */
status = psa_import_key(slot, PSA_KEY_TYPE_AES, data, sizeof(data));
if (status != PSA_SUCCESS) {
@@ -185,31 +187,35 @@
status = psa_get_key_information(slot, &type, &bits);
if (status != PSA_SUCCESS) {
TEST_FAIL("Error getting key metadata");
- return;
+ goto destroy_key;
}
if (bits != BIT_SIZE_TEST_KEY) {
TEST_FAIL("The number of key bits is different from expected");
- return;
+ goto destroy_key;
}
if (type != PSA_KEY_TYPE_AES) {
TEST_FAIL("The type of the key is different from expected");
- return;
+ goto destroy_key;
}
/* Setup the encryption object */
status = psa_cipher_encrypt_setup(&handle, slot, alg);
if (status != PSA_SUCCESS) {
- TEST_FAIL("Error setting up cipher operation object");
- return;
+ if (status == PSA_ERROR_NOT_SUPPORTED) {
+ TEST_FAIL("Algorithm NOT SUPPORTED by the implementation");
+ } else {
+ TEST_FAIL("Error setting up cipher operation object");
+ }
+ goto destroy_key;
}
/* Set the IV */
status = psa_cipher_set_iv(&handle, iv, iv_length);
if (status != PSA_SUCCESS) {
TEST_FAIL("Error setting the IV on the cypher operation object");
- return;
+ goto destroy_key;
}
/* Encrypt one chunk of information */
@@ -219,12 +225,12 @@
if (status != PSA_SUCCESS) {
TEST_FAIL("Error encrypting one chunk of information");
- return;
+ goto destroy_key;
}
if (output_length != BYTE_SIZE_CHUNK) {
TEST_FAIL("Expected encrypted data length is different from expected");
- return;
+ goto destroy_key;
}
/* Finalise the cipher operation */
@@ -234,12 +240,12 @@
if (status != PSA_SUCCESS) {
TEST_FAIL("Error finalising the cipher operation");
- return;
+ goto destroy_key;
}
if (output_length != 0) {
TEST_FAIL("Unexpected output length after finalisation");
- return;
+ goto destroy_key;
}
/* Setup the decryption object */
@@ -252,7 +258,7 @@
if (status != PSA_SUCCESS) {
TEST_FAIL("Error setting up cipher operation object");
- return;
+ goto destroy_key;
}
/* Set the IV for decryption */
@@ -269,13 +275,13 @@
if (status != PSA_SUCCESS) {
TEST_FAIL("Error setting the IV for decryption");
- return;
+ goto destroy_key;
}
if (alg != PSA_ALG_CFB_BASE) {
if (output_length != 0) {
TEST_FAIL("Expected output length is different from expected");
- return;
+ goto destroy_key;
}
}
@@ -296,7 +302,7 @@
if (output_length != expected_output_length) {
TEST_FAIL("Decrypted length is different from expected one");
- return;
+ goto destroy_key;
}
/* Check that the plain text matches the decrypted data */
@@ -304,7 +310,7 @@
sizeof(plain_text), sizeof(decrypted_data));
if (comp_result != 0) {
TEST_FAIL("Decrypted data doesn't match with plain text");
- return;
+ goto destroy_key;
}
/* Finalise the cipher operation for decryption (destroys decrypted data) */
@@ -313,7 +319,7 @@
if (status != PSA_SUCCESS) {
TEST_FAIL("Error finalising the cipher operation");
- return;
+ goto destroy_key;
}
if (alg == PSA_ALG_CFB_BASE) {
@@ -324,17 +330,16 @@
if (output_length != expected_output_length) {
TEST_FAIL("After finalising, unexpected decrypted length");
- return;
+ goto destroy_key;
}
+destroy_key:
/* Destroy the key on slot 0 */
status = psa_destroy_key(slot);
if (status != PSA_SUCCESS) {
TEST_FAIL("Error destroying a key");
return;
}
-
- ret->val = TEST_PASSED;
}
static void tfm_crypto_test_6002(struct test_result_t *ret)