Merge remote-tracking branch 'origin/master' into feature-cc-psa-crypto-drivers
Signed-off-by: Antonio de Angelis <antonio.deangelis@arm.com>
Change-Id: I60c51e7da4ed81437c5dec8ce1a4a4e3f6e74df6
diff --git a/interface/src/tfm_crypto_func_api.c b/interface/src/tfm_crypto_func_api.c
index 6e6c419..5d7826b 100644
--- a/interface/src/tfm_crypto_func_api.c
+++ b/interface/src/tfm_crypto_func_api.c
@@ -887,10 +887,7 @@
status = API_DISPATCH(tfm_crypto_sign_message,
TFM_CRYPTO_SIGN_MESSAGE);
- if (status == PSA_SUCCESS) {
- *signature_length = out_vec[0].len;
- }
-
+ *signature_length = out_vec[0].len;
return status;
}
@@ -1301,10 +1298,7 @@
status = API_DISPATCH(tfm_crypto_mac_compute,
TFM_CRYPTO_MAC_COMPUTE);
- if (status == PSA_SUCCESS) {
- *mac_length = out_vec[0].len;
- }
-
+ *mac_length = out_vec[0].len;
return status;
}
@@ -1342,6 +1336,9 @@
size_t output_size,
size_t *output_length)
{
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
psa_status_t status;
struct tfm_crypto_pack_iovec iov = {
.sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
@@ -1360,11 +1357,9 @@
status = API_DISPATCH(tfm_crypto_cipher_encrypt,
TFM_CRYPTO_CIPHER_ENCRYPT);
- if (status == PSA_SUCCESS) {
- *output_length = out_vec[0].len;
- }
-
+ *output_length = out_vec[0].len;
return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
}
psa_status_t psa_cipher_decrypt(psa_key_id_t key,
@@ -1375,6 +1370,9 @@
size_t output_size,
size_t *output_length)
{
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
psa_status_t status;
struct tfm_crypto_pack_iovec iov = {
.sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
@@ -1393,11 +1391,9 @@
status = API_DISPATCH(tfm_crypto_cipher_decrypt,
TFM_CRYPTO_CIPHER_DECRYPT);
- if (status == PSA_SUCCESS) {
- *output_length = out_vec[0].len;
- }
-
+ *output_length = out_vec[0].len;
return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
}
psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
diff --git a/interface/src/tfm_crypto_ipc_api.c b/interface/src/tfm_crypto_ipc_api.c
index 9dfa473..a396a27 100644
--- a/interface/src/tfm_crypto_ipc_api.c
+++ b/interface/src/tfm_crypto_ipc_api.c
@@ -905,10 +905,7 @@
status = API_DISPATCH(tfm_crypto_sign_message,
TFM_CRYPTO_SIGN_MESSAGE);
- if (status == PSA_SUCCESS) {
- *signature_length = out_vec[0].len;
- }
-
+ *signature_length = out_vec[0].len;
return status;
}
@@ -1328,10 +1325,7 @@
status = API_DISPATCH(tfm_crypto_mac_compute,
TFM_CRYPTO_MAC_COMPUTE);
- if (status == PSA_SUCCESS) {
- *mac_length = out_vec[0].len;
- }
-
+ *mac_length = out_vec[0].len;
return status;
}
@@ -1369,6 +1363,9 @@
size_t output_size,
size_t *output_length)
{
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
psa_status_t status;
struct tfm_crypto_pack_iovec iov = {
.sfn_id = TFM_CRYPTO_CIPHER_ENCRYPT_SID,
@@ -1387,11 +1384,9 @@
status = API_DISPATCH(tfm_crypto_cipher_encrypt,
TFM_CRYPTO_CIPHER_ENCRYPT);
- if (status == PSA_SUCCESS) {
- *output_length = out_vec[0].len;
- }
-
+ *output_length = out_vec[0].len;
return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
}
psa_status_t psa_cipher_decrypt(psa_key_id_t key,
@@ -1402,6 +1397,9 @@
size_t output_size,
size_t *output_length)
{
+#ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
+ return PSA_ERROR_NOT_SUPPORTED;
+#else
psa_status_t status;
struct tfm_crypto_pack_iovec iov = {
.sfn_id = TFM_CRYPTO_CIPHER_DECRYPT_SID,
@@ -1420,11 +1418,9 @@
status = API_DISPATCH(tfm_crypto_cipher_decrypt,
TFM_CRYPTO_CIPHER_DECRYPT);
- if (status == PSA_SUCCESS) {
- *output_length = out_vec[0].len;
- }
-
+ *output_length = out_vec[0].len;
return status;
+#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
}
psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/CMakeLists.txt b/lib/ext/cryptocell-312-runtime/codesafe/CMakeLists.txt
index 04f498e..acfcb47 100644
--- a/lib/ext/cryptocell-312-runtime/codesafe/CMakeLists.txt
+++ b/lib/ext/cryptocell-312-runtime/codesafe/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,4 +7,5 @@
add_subdirectory(src/crypto_api)
add_subdirectory(src/mbedtls_api)
+add_subdirectory(src/psa_driver_api)
# add_subdirectory(src/secure_boot_debug)
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/CMakeLists.txt b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/CMakeLists.txt
index fcb62d2..aadbc72 100644
--- a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/CMakeLists.txt
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/CMakeLists.txt
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,9 +8,10 @@
########################## LIB #################################################
target_include_directories(${CC312_LIB_TARGET}
+ PUBLIC
+ cc3x_sym/driver
PRIVATE
common
- cc3x_sym/driver
cc3x_sym/api
pki/poly
pki/ec_wrst
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/CMakeLists.txt b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/CMakeLists.txt
new file mode 100644
index 0000000..1fddbe5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/CMakeLists.txt
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+target_include_directories(${CC312_LIB_TARGET}
+ PUBLIC
+ include
+ .
+)
+
+target_sources(${CC312_LIB_TARGET}
+ PRIVATE
+ src/cc3xx_psa_hash.c
+ src/cc3xx_psa_cipher.c
+ src/cc3xx_psa_mac.c
+
+ src/cc3xx_internal_aes.c
+ src/cc3xx_internal_chacha20.c
+)
+
+target_compile_definitions(${CC312_LIB_TARGET}
+ PUBLIC
+ MBEDTLS_PSA_CRYPTO_DRIVERS
+ PSA_CRYPTO_DRIVER_CC3XX
+)
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/cc3xx.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/cc3xx.h
new file mode 100644
index 0000000..340d33c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/cc3xx.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_DRIVER_H
+#define CC3XX_DRIVER_H
+
+#include "cc3xx_psa_hash.h"
+#include "cc3xx_psa_cipher.h"
+#include "cc3xx_psa_mac.h"
+
+#endif /* CC3XX_DRIVER_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_crypto_primitives.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_crypto_primitives.h
new file mode 100644
index 0000000..9b93e18
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_crypto_primitives.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_CRYPTO_PRIMITIVES_H
+#define CC3XX_CRYPTO_PRIMITIVES_H
+
+#include "psa/crypto_driver_common.h"
+#include "psa/crypto_sizes.h"
+#include "psa/crypto_types.h"
+
+#include "hash_driver.h"
+
+#include "aes_driver.h"
+#include "chacha_driver.h"
+
+typedef HashContext_t cc3xx_hash_operation_t;
+
+typedef struct {
+ psa_algorithm_t alg;
+ psa_key_type_t key_type;
+ psa_encrypt_or_decrypt_t dir;
+ size_t block_size;
+
+ psa_status_t(*add_padding)(uint8_t *, size_t, size_t);
+
+ uint8_t unprocessed_data[AES_BLOCK_SIZE];
+ size_t unprocessed_size;
+ uint8_t iv[AES_IV_SIZE];
+ size_t iv_size;
+
+ AesContext_t aes_ctx;
+
+ ChachaContext_t chacha_ctx;
+} cc3xx_cipher_operation_t;
+
+typedef struct {
+ psa_algorithm_t alg;
+ union {
+ cc3xx_cipher_operation_t cmac;
+ cc3xx_hash_operation_t hmac;
+ };
+ /* Only for HMAC */
+ uint8_t opad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
+} cc3xx_mac_operation_t;
+
+#endif /* CC3XX_CRYPTO_PRIMITIVES_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_aes.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_aes.h
new file mode 100644
index 0000000..4dfcd10
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_aes.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_INTERNAL_AES_H
+#define CC3XX_INTERNAL_AES_H
+
+#include "cc3xx_crypto_primitives.h"
+
+/**
+ * \brief Initialize the specified AES context.
+ */
+void cc3xx_aes_init(AesContext_t *ctx);
+
+/**
+ * \brief Release and clear the specified AES context.
+ */
+void cc3xx_aes_free(AesContext_t *ctx);
+
+/**
+ * \brief Set the encryption key.
+ */
+psa_status_t cc3xx_aes_setkey_enc(
+ AesContext_t *ctx,
+ const uint8_t *key,
+ size_t key_bits);
+
+/**
+ * \brief Set the decryption key.
+ */
+psa_status_t cc3xx_aes_setkey_dec(
+ AesContext_t *ctx,
+ const uint8_t *key,
+ size_t key_bits);
+
+/**
+ * \brief AES block encryption/decryption.
+ */
+psa_status_t cc3xx_aes_crypt(
+ AesContext_t *ctx,
+ aesMode_t mode,
+ size_t length,
+ uint8_t iv[AES_IV_SIZE],
+ const uint8_t *input,
+ uint8_t *output);
+
+#endif /* CC3XX_INTERNAL_AES_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_chacha20.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_chacha20.h
new file mode 100644
index 0000000..72625a6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_chacha20.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_INTERNAL_CHACHA20_H
+#define CC3XX_INTERNAL_CHACHA20_H
+
+#include "cc3xx_crypto_primitives.h"
+
+/**
+ * \brief Initialize the specified ChaCha20 context.
+ */
+void cc3xx_chacha20_init(ChachaContext_t *ctx);
+
+/**
+ * \brief Release and clear the specified ChaCha20 context.
+ */
+void cc3xx_chacha20_free(ChachaContext_t *ctx);
+
+/**
+ * \brief Set the encryption/decryption key.
+ */
+psa_status_t cc3xx_chacha20_setkey(
+ ChachaContext_t *ctx,
+ const uint8_t key[CHACHA_256_BIT_KEY_SIZE]);
+
+/**
+ * \brief Set the nonce and initial counter value.
+ */
+psa_status_t cc3xx_chacha20_starts(
+ ChachaContext_t *ctx,
+ const uint8_t nonce[CHACHA_IV_96_SIZE_BYTES],
+ uint32_t counter);
+
+/**
+ * \brief Encrypt/decrypt data.
+ */
+psa_status_t cc3xx_chacha20_update(
+ ChachaContext_t *ctx,
+ size_t size,
+ const uint8_t *input,
+ unsigned char *output);
+
+#endif /* CC3XX_INTERNAL_CHACHA20_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_cipher.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_cipher.h
new file mode 100644
index 0000000..178184f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_cipher.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_PSA_CIPHER_H
+#define CC3XX_PSA_CIPHER_H
+
+#include "psa/crypto.h"
+
+#include "cc3xx_crypto_primitives.h"
+#include "cc3xx_internal_aes.h"
+#include "cc3xx_internal_chacha20.h"
+
+psa_status_t cc3xx_cipher_encrypt_setup(
+ cc3xx_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg);
+
+psa_status_t cc3xx_cipher_decrypt_setup(
+ cc3xx_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg);
+
+psa_status_t cc3xx_cipher_set_iv(
+ cc3xx_cipher_operation_t *operation,
+ const uint8_t *iv, size_t iv_length);
+
+psa_status_t cc3xx_cipher_update(
+ cc3xx_cipher_operation_t *operation,
+ const uint8_t *input, size_t input_length,
+ uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t cc3xx_cipher_finish(
+ cc3xx_cipher_operation_t *operation,
+ uint8_t *output, size_t output_size, size_t *output_length);
+
+psa_status_t cc3xx_cipher_abort(
+ cc3xx_cipher_operation_t *operation);
+
+psa_status_t cc3xx_psa_cipher_encrypt(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+psa_status_t cc3xx_psa_cipher_decrypt(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length);
+
+#endif /* CC3XX_PSA_CIPHER_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_hash.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_hash.h
new file mode 100644
index 0000000..a4554de
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_hash.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HASH_COMMON_H
+#define HASH_COMMON_H
+
+#include "cc3xx_crypto_primitives.h"
+#include "psa/crypto.h"
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+psa_status_t cc3xx_hash_setup(cc3xx_hash_operation_t *operation,
+ psa_algorithm_t alg);
+
+psa_status_t cc3xx_hash_clone(const cc3xx_hash_operation_t *source_operation,
+ cc3xx_hash_operation_t *target_operation);
+
+psa_status_t cc3xx_hash_update(cc3xx_hash_operation_t *operation,
+ const uint8_t *input, size_t input_length);
+
+psa_status_t cc3xx_hash_finish(cc3xx_hash_operation_t *operation, uint8_t *hash,
+ size_t hash_size, size_t *hash_length);
+
+psa_status_t cc3xx_hash_abort(cc3xx_hash_operation_t *operation);
+
+psa_status_t cc3xx_hash_compute(psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, uint8_t *hash,
+ size_t hash_size, size_t *hash_length);
+#endif /*HASH_COMMON_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_mac.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_mac.h
new file mode 100644
index 0000000..2a494b5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_mac.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_PSA_MAC_H
+#define CC3XX_PSA_MAC_H
+
+#include "cc3xx_crypto_primitives.h"
+#include "psa/crypto.h"
+
+psa_status_t cc3xx_mac_sign_setup(cc3xx_mac_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, psa_algorithm_t alg);
+
+psa_status_t cc3xx_mac_verify_setup(cc3xx_mac_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ psa_algorithm_t alg);
+
+psa_status_t cc3xx_mac_update(cc3xx_mac_operation_t *operation,
+ const uint8_t *input, size_t input_length);
+
+psa_status_t cc3xx_mac_sign_finish(cc3xx_mac_operation_t *operation,
+ uint8_t *mac, size_t mac_size,
+ size_t *mac_length);
+
+psa_status_t cc3xx_mac_verify_finish(cc3xx_mac_operation_t *operation,
+ const uint8_t *mac, size_t mac_length);
+
+psa_status_t cc3xx_mac_abort(cc3xx_mac_operation_t *operation);
+
+psa_status_t cc3xx_mac_compute(const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ uint8_t *mac, size_t mac_size,
+ size_t *mac_length);
+
+#endif /* CC3XX_PSA_MAC_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_aes.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_aes.c
new file mode 100644
index 0000000..69cdf45
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_aes.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_internal_aes.h"
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+
+void cc3xx_aes_init(AesContext_t *ctx)
+{
+ if (NULL == ctx) {
+ CC_PalAbort("ctx cannot be NULL");
+ return;
+ }
+
+ ctx->padType = CRYPTO_PADDING_NONE;
+ ctx->dataBlockType = FIRST_BLOCK;
+ ctx->inputDataAddrType = DLLI_ADDR;
+ ctx->outputDataAddrType = DLLI_ADDR;
+}
+
+void cc3xx_aes_free(AesContext_t *ctx)
+{
+ if (NULL == ctx) {
+ CC_PAL_LOG_ERR("ctx cannot be NULL\n");
+ return;
+ }
+
+ CC_PalMemSet(ctx, 0, sizeof(AesContext_t));
+}
+
+static psa_status_t aes_setkey(
+ AesContext_t *ctx,
+ const uint8_t *key,
+ size_t key_bits,
+ cryptoDirection_t direction)
+{
+ if (NULL == ctx) {
+ CC_PAL_LOG_ERR("ctx cannot be NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (NULL == key) {
+ CC_PAL_LOG_ERR("key cannot be NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ ctx->dir = direction;
+ ctx->cryptoKey = USER_KEY;
+
+ switch (key_bits) {
+ case 128:
+ ctx->keySizeId = KEY_SIZE_128_BIT;
+ break;
+ case 192:
+ ctx->keySizeId = KEY_SIZE_192_BIT;
+ break;
+ case 256:
+ ctx->keySizeId = KEY_SIZE_256_BIT;
+ break;
+ default:
+ CC_PAL_LOG_ERR("key_bits (%d) not supported\n", key_bits);
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ CC_PalMemCopy(ctx->keyBuf, key, key_bits/8);
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_aes_setkey_enc(
+ AesContext_t *ctx,
+ const uint8_t *key,
+ size_t key_bits)
+{
+ return aes_setkey(ctx, key, key_bits, CRYPTO_DIRECTION_ENCRYPT);
+}
+
+psa_status_t cc3xx_aes_setkey_dec(
+ AesContext_t *ctx,
+ const uint8_t *key,
+ size_t key_bits)
+{
+ return aes_setkey(ctx, key, key_bits, CRYPTO_DIRECTION_DECRYPT);
+}
+
+psa_status_t cc3xx_aes_crypt(
+ AesContext_t *ctx,
+ aesMode_t mode,
+ size_t length,
+ uint8_t iv[AES_IV_SIZE],
+ const uint8_t *input,
+ uint8_t *output)
+{
+ drvError_t drvRet;
+ CCBuffInfo_t inBuffInfo;
+ CCBuffInfo_t outBuffInfo;
+
+ if (0 == length) {
+ return PSA_SUCCESS;
+ }
+
+ if (NULL == ctx || NULL == input || NULL == output || NULL == iv) {
+ CC_PAL_LOG_ERR("Null pointer exception\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (length % AES_BLOCK_SIZE) {
+ CC_PAL_LOG_ERR("Length not a multiple of the block size %d\n",
+ AES_BLOCK_SIZE);
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ ctx->mode = mode;
+
+ if (mode != CIPHER_ECB) {
+ CC_PalMemCopy(ctx->ivBuf, iv, AES_IV_SIZE);
+ }
+
+ drvRet = SetDataBuffersInfo(input, length, &inBuffInfo,
+ output, length, &outBuffInfo);
+ if (drvRet != 0) {
+ CC_PAL_LOG_ERR("Bad i/o buffers\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ drvRet = ProcessAesDrv(ctx, &inBuffInfo, &outBuffInfo, length);
+ if (drvRet != AES_DRV_OK) {
+ CC_PAL_LOG_ERR("cc3xx_aes_crypt failed: %d\n", drvRet);
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (mode != CIPHER_ECB) {
+ CC_PalMemCopy(iv, ctx->ivBuf, AES_IV_SIZE);
+ }
+
+ return PSA_SUCCESS;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_chacha20.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_chacha20.c
new file mode 100644
index 0000000..954ea05
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_chacha20.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_internal_chacha20.h"
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+
+void cc3xx_chacha20_init(ChachaContext_t *ctx)
+{
+ if (NULL == ctx) {
+ CC_PalAbort("ctx cannot be NULL");
+ return;
+ }
+
+ ctx->inputDataAddrType = DLLI_ADDR;
+ ctx->outputDataAddrType = DLLI_ADDR;
+}
+
+void cc3xx_chacha20_free(ChachaContext_t *ctx)
+{
+ if (NULL == ctx) {
+ CC_PAL_LOG_ERR("ctx cannot be NULL\n");
+ return;
+ }
+
+ CC_PalMemSet(ctx, 0, sizeof(AesContext_t));
+}
+
+psa_status_t cc3xx_chacha20_setkey(
+ ChachaContext_t *ctx,
+ const uint8_t key[CHACHA_256_BIT_KEY_SIZE])
+{
+ if (NULL == ctx) {
+ CC_PAL_LOG_ERR("ctx cannot be NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (NULL == key) {
+ CC_PAL_LOG_ERR("key cannot be NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ CC_PalMemCopy(ctx->keyBuf, key, CHACHA_256_BIT_KEY_SIZE);
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_chacha20_starts(
+ ChachaContext_t *ctx,
+ const uint8_t nonce[CHACHA_IV_96_SIZE_BYTES],
+ uint32_t counter)
+{
+ if (NULL == ctx) {
+ CC_PAL_LOG_ERR("ctx cannot be NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (nonce == NULL) {
+ CC_PAL_LOG_ERR("nonce cannot be NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ ctx->nonceSize = NONCE_SIZE_96;
+
+ CC_PalMemCopy(ctx->nonceBuf, nonce, CHACHA_IV_96_SIZE_BYTES);
+
+ ctx->blockCounterLsb = counter;
+ ctx->blockCounterMsb = 0;
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_chacha20_update(
+ ChachaContext_t *ctx,
+ size_t size,
+ const uint8_t *input,
+ unsigned char *output)
+{
+ drvError_t drvRc;
+ CCBuffInfo_t inBuffInfo;
+ CCBuffInfo_t outBuffInfo;
+
+ if (0 == size) {
+ return PSA_SUCCESS;
+ }
+
+ if (NULL == ctx || NULL == input || NULL == output) {
+ CC_PAL_LOG_ERR("Null pointer exception\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ drvRc = SetDataBuffersInfo( input, size, &inBuffInfo,
+ output, size, &outBuffInfo);
+ if (drvRc != 0) {
+ CC_PAL_LOG_ERR("Bad i/o buffers\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ drvRc = ProcessChacha(ctx, &inBuffInfo, &outBuffInfo, size);
+ if (drvRc != 0) {
+ CC_PAL_LOG_ERR("cc3xx_chacha20_update failed: %d\n", drvRc);
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ return PSA_SUCCESS;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_cipher.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_cipher.c
new file mode 100644
index 0000000..19673e2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_cipher.c
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_psa_cipher.h"
+#include "cc_pal_mem.h"
+
+/* FixMe: implement pkcs#7 padding in HW
+ * The function below was taken from Mbed TLS and implements pkcs#7
+ * padding in software. It might be possible to do this in HW using
+ * CC; however, we will need to modify the SW abstraction function:
+ * ProcessAesDrv, and others.
+ */
+
+static psa_status_t add_pkcs_padding(
+ uint8_t *output,
+ size_t output_size,
+ size_t data_size)
+{
+ if (NULL == output) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ uint8_t padding_size = output_size - data_size;
+
+ for (size_t i = 0; i < padding_size; i++) {
+ output[data_size + i] = padding_size;
+ }
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t cipher_setup(
+ cc3xx_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg,
+ psa_encrypt_or_decrypt_t dir)
+{
+ psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ size_t key_bits = psa_get_key_bits(attributes);
+
+ (void)key_length;
+
+ if (!PSA_ALG_IS_CIPHER(alg)) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ CC_PalMemSetZero(operation, sizeof(cc3xx_cipher_operation_t));
+
+ operation->alg = alg;
+ operation->key_type = key_type;
+ operation->dir = dir;
+ operation->iv_size = PSA_CIPHER_IV_LENGTH(key_type, alg);
+ operation->block_size = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
+ PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
+
+ switch (operation->key_type) {
+ case PSA_KEY_TYPE_AES:
+ cc3xx_aes_init(&operation->aes_ctx);
+
+ switch (operation->dir) {
+ case PSA_CRYPTO_DRIVER_ENCRYPT:
+ if (( ret = cc3xx_aes_setkey_enc(
+ &operation->aes_ctx,
+ key,
+ key_bits) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ break;
+ case PSA_CRYPTO_DRIVER_DECRYPT:
+ if (( ret = cc3xx_aes_setkey_dec(
+ &operation->aes_ctx,
+ key,
+ key_bits) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ break;
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ break;
+ case PSA_KEY_TYPE_CHACHA20:
+ cc3xx_chacha20_init(&operation->chacha_ctx);
+
+ if (( ret = cc3xx_chacha20_setkey(
+ &operation->chacha_ctx,
+ key) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ break;
+ default:
+ // Software fallback
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (operation->alg == PSA_ALG_CBC_PKCS7) {
+ operation->add_padding = add_pkcs_padding;
+ } else {
+ operation->add_padding = NULL;
+ }
+
+ return ret;
+}
+
+psa_status_t cc3xx_cipher_encrypt_setup(
+ cc3xx_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg)
+{
+ return cipher_setup(operation,
+ attributes,
+ key, key_length,
+ alg,
+ PSA_CRYPTO_DRIVER_ENCRYPT);
+}
+
+psa_status_t cc3xx_cipher_decrypt_setup(
+ cc3xx_cipher_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg)
+{
+ return cipher_setup(operation,
+ attributes,
+ key, key_length,
+ alg,
+ PSA_CRYPTO_DRIVER_DECRYPT);
+}
+
+psa_status_t cc3xx_cipher_set_iv(
+ cc3xx_cipher_operation_t *operation,
+ const uint8_t *iv, size_t iv_length)
+{
+ psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
+
+ if (iv_length > AES_IV_SIZE) {
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (iv_length != 0) {
+ CC_PalMemCopy(operation->iv, iv, iv_length);
+ operation->iv_size = iv_length;
+ }
+
+ ret = PSA_SUCCESS;
+
+ if (operation->key_type == PSA_KEY_TYPE_CHACHA20) {
+ if (( ret = cc3xx_chacha20_starts(
+ &operation->chacha_ctx,
+ iv,
+ 0U) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+psa_status_t cc3xx_cipher_update(
+ cc3xx_cipher_operation_t *operation,
+ const uint8_t *input, size_t input_length,
+ uint8_t *output, size_t output_size, size_t *output_length)
+{
+ psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
+ size_t block_size = operation->block_size;
+ size_t expected_output_size;
+
+ if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
+ expected_output_size =
+ ( operation->unprocessed_size + input_length )
+ / operation->block_size * operation->block_size;
+ } else {
+ expected_output_size = input_length;
+ }
+
+ if (output_size < expected_output_size) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+
+ *output_length = 0;
+
+ size_t copy_len;
+
+ switch (operation->key_type) {
+ case PSA_KEY_TYPE_AES:
+ switch (operation->alg) {
+ case PSA_ALG_CBC_NO_PADDING:
+ case PSA_ALG_CBC_PKCS7:
+ if ((operation->dir == PSA_CRYPTO_DRIVER_DECRYPT &&
+ NULL != operation->add_padding &&
+ input_length <= block_size -
+ operation->unprocessed_size) ||
+ (operation->dir == PSA_CRYPTO_DRIVER_DECRYPT &&
+ NULL == operation->add_padding &&
+ input_length < block_size -
+ operation->unprocessed_size) ||
+ (operation->dir == PSA_CRYPTO_DRIVER_ENCRYPT &&
+ input_length < block_size -
+ operation->unprocessed_size)) {
+ CC_PalMemCopy(&(operation->unprocessed_data
+ [operation->unprocessed_size]),
+ input,
+ input_length);
+
+ operation->unprocessed_size += input_length;
+ return PSA_SUCCESS;
+ }
+
+ if (0 != operation->unprocessed_size) {
+ copy_len = block_size
+ - operation->unprocessed_size;
+
+ CC_PalMemCopy(&(operation->unprocessed_data
+ [operation->unprocessed_size]),
+ input,
+ copy_len);
+
+ if (( ret = cc3xx_aes_crypt(
+ &operation->aes_ctx,
+ CIPHER_CBC,
+ block_size,
+ operation->iv,
+ operation->unprocessed_data,
+ output) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ operation->unprocessed_size = 0;
+
+ *output_length = block_size;
+ output += block_size;
+
+ input += copy_len;
+ input_length -= copy_len;
+ }
+
+ if (0 != input_length) {
+ copy_len = input_length % block_size;
+
+ if (copy_len == 0 &&
+ operation->dir==PSA_CRYPTO_DRIVER_DECRYPT &&
+ operation->add_padding != NULL) {
+ copy_len = block_size;
+ }
+
+ CC_PalMemCopy(operation->unprocessed_data,
+ &(input[copy_len]),
+ copy_len);
+
+ operation->unprocessed_size += copy_len;
+ input_length -= copy_len;
+ }
+
+ if (0 != input_length) {
+ if (( ret = cc3xx_aes_crypt(
+ &operation->aes_ctx,
+ CIPHER_CBC,
+ input_length,
+ operation->iv,
+ input,
+ output) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ *output_length = input_length;
+ }
+
+ break;
+ case PSA_ALG_CTR:
+ if (( ret = cc3xx_aes_crypt(
+ &operation->aes_ctx,
+ CIPHER_CTR,
+ input_length,
+ operation->iv,
+ input,
+ output) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ *output_length = input_length;
+
+ break;
+ case PSA_ALG_OFB:
+ if (( ret = cc3xx_aes_crypt(
+ &operation->aes_ctx,
+ CIPHER_OFB,
+ input_length,
+ operation->iv,
+ input,
+ output) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ *output_length = input_length;
+
+ break;
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (*output_length > output_size) {
+ return PSA_ERROR_CORRUPTION_DETECTED;
+ }
+
+ break;
+ case PSA_KEY_TYPE_CHACHA20:
+ if (( ret = cc3xx_chacha20_update(
+ &operation->chacha_ctx,
+ input_length,
+ input,
+ output) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ *output_length = input_length;
+
+ break;
+ default:
+ // Software fallback
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ return ret;
+}
+
+psa_status_t cc3xx_cipher_finish(
+ cc3xx_cipher_operation_t *operation,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
+
+ *output_length = 0;
+
+ switch (operation->key_type) {
+ case PSA_KEY_TYPE_AES:
+ switch (operation->alg) {
+ case PSA_ALG_CBC_NO_PADDING:
+ case PSA_ALG_CBC_PKCS7:
+ if (operation->dir == PSA_CRYPTO_DRIVER_ENCRYPT) {
+ if (operation->add_padding == NULL) {
+ if (operation->unprocessed_size != 0) {
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ return PSA_SUCCESS;
+ }
+
+ if (( ret = operation->add_padding(
+ operation->unprocessed_data,
+ operation->block_size,
+ operation->unprocessed_size) )
+ != PSA_SUCCESS) {
+ return ret;
+ }
+ } else if (operation->block_size !=
+ operation->unprocessed_size) {
+ if (operation->add_padding == NULL &&
+ operation->unprocessed_size == 0) {
+ return PSA_SUCCESS;
+ }
+
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ if (( ret = cc3xx_aes_crypt(
+ &operation->aes_ctx,
+ CIPHER_CBC,
+ output_size,
+ operation->iv,
+ operation->unprocessed_data,
+ output ))
+ != PSA_SUCCESS) {
+ return ret;
+ }
+
+ *output_length = operation->block_size;
+
+ break;
+ case PSA_ALG_CTR:
+ case PSA_ALG_OFB:
+ return PSA_SUCCESS;
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+ break;
+ case PSA_KEY_TYPE_CHACHA20:
+ return PSA_SUCCESS;
+ default:
+ // Software fallback
+ ret = PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ return ret;
+}
+
+psa_status_t cc3xx_cipher_abort(cc3xx_cipher_operation_t *operation)
+{
+ switch (operation->key_type) {
+ case PSA_KEY_TYPE_AES:
+ cc3xx_aes_free(&operation->aes_ctx);
+ break;
+ case PSA_KEY_TYPE_CHACHA20:
+ cc3xx_chacha20_free(&operation->chacha_ctx);
+ return PSA_ERROR_NOT_SUPPORTED;
+ default:
+ // Software fallback
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ CC_PalMemSetZero(operation, sizeof(cc3xx_cipher_operation_t));
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_psa_cipher_encrypt(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
+ cc3xx_cipher_operation_t operation = {0};
+ size_t olength, accumulated_length;
+
+ if ( (ret = cc3xx_cipher_encrypt_setup(
+ &operation,
+ attributes,
+ key_buffer,
+ key_buffer_size,
+ alg) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+
+ accumulated_length = 0;
+ if (operation.iv_size > 0) {
+ if ( (ret = cc3xx_cipher_set_iv(
+ &operation,
+ output,
+ operation.iv_size) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+
+ accumulated_length = operation.iv_size;
+ }
+
+ if ( (ret = cc3xx_cipher_update(
+ &operation,
+ input,
+ input_length,
+ output + operation.iv_size,
+ output_size - operation.iv_size,
+ &olength) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+
+ accumulated_length += olength;
+
+ if ( (ret = cc3xx_cipher_finish(
+ &operation,
+ output + accumulated_length,
+ output_size - accumulated_length,
+ &olength) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+
+ *output_length = accumulated_length + olength;
+
+ ret = cc3xx_cipher_abort(&operation);
+
+ return ret;
+}
+
+psa_status_t cc3xx_psa_cipher_decrypt(
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size,
+ psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ uint8_t *output,
+ size_t output_size,
+ size_t *output_length)
+{
+ psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
+ cc3xx_cipher_operation_t operation = {0};
+ size_t olength, accumulated_length;
+
+ if ( (ret = cc3xx_cipher_decrypt_setup(
+ &operation,
+ attributes,
+ key_buffer,
+ key_buffer_size,
+ alg) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+
+ if (operation.iv_size > 0) {
+ if ( (ret = cc3xx_cipher_set_iv(
+ &operation,
+ input,
+ operation.iv_size) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+ }
+
+ if ( (ret = cc3xx_cipher_update(
+ &operation,
+ input + operation.iv_size,
+ input_length - operation.iv_size,
+ output,
+ output_size,
+ &olength) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+
+ accumulated_length = olength;
+
+ if ( (ret = cc3xx_cipher_finish(
+ &operation,
+ output + accumulated_length,
+ output_size - accumulated_length,
+ &olength) )
+ != PSA_SUCCESS) {
+ cc3xx_cipher_abort(&operation);
+ return ret;
+ }
+
+ *output_length = accumulated_length + olength;
+
+ ret = cc3xx_cipher_abort(&operation);
+
+ return ret;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_hash.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_hash.c
new file mode 100644
index 0000000..1e61354
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_hash.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_psa_hash.h"
+#include "cc_pal_log.h"
+#include "cc_pal_mem.h"
+
+#define MAX_HASH_CHUNK_SIZE 0xffff
+
+/*!
+ * \defgroup private Private functions
+ *
+ */
+/*!@{*/
+
+/**
+ * \brief Update a hash operation
+ *
+ * In CC312, DMA (i.e. for hash module input ) needs access to physical and
+ * continues memory. In order to assure the DMA can access the residue data saved
+ * in the hashCtx, it is being to copied to a local stack variable. In case memory
+ * is guaranteed to be DMAable, this copy can be removed, and hashCtx->prevData can
+ * be used.
+ */
+static psa_status_t hashUpdate(cc3xx_hash_operation_t *pHashUserCtx,
+ uint8_t *pDataIn, size_t dataInSize)
+{
+ uint32_t rc = 0;
+ size_t bytesToAdd = 0;
+ uint32_t localPrevDataIn[HASH_SHA512_BLOCK_SIZE_IN_WORDS];
+ CCBuffInfo_t inBuffInfo;
+
+ /* If pHashUserCtx->prevDataInSize > 0, fill it with with the current data
+ */
+ bytesToAdd = CC_MIN(
+ ((pHashUserCtx->blockSizeInBytes - pHashUserCtx->prevDataInSize) %
+ pHashUserCtx->blockSizeInBytes),
+ dataInSize);
+ if (bytesToAdd > 0) {
+ /* add the data to the remaining buffer */
+ CC_PalMemCopy(
+ &(((uint8_t *)(pHashUserCtx
+ ->prevDataIn))[pHashUserCtx->prevDataInSize]),
+ pDataIn, bytesToAdd);
+ pHashUserCtx->prevDataInSize += bytesToAdd;
+ pDataIn += bytesToAdd;
+ dataInSize -= bytesToAdd;
+ }
+
+ /* If the remaining buffer is full, process the block (else, the remaining
+ buffer will be processed in the next update or finish) */
+ if (pHashUserCtx->prevDataInSize == pHashUserCtx->blockSizeInBytes) {
+ /* Copy prevDataIn to stack, in order to ensure continues and physical
+ memory access. That way, DMA will be able to access the data on any
+ platform.*/
+ CC_PalMemCopy(localPrevDataIn, pHashUserCtx->prevDataIn,
+ CC_MIN(HASH_SHA512_BLOCK_SIZE_IN_WORDS * sizeof(uint32_t),
+ pHashUserCtx->prevDataInSize));
+
+ rc = SetDataBuffersInfo((uint8_t *)localPrevDataIn,
+ pHashUserCtx->blockSizeInBytes, &inBuffInfo,
+ NULL, 0, NULL);
+ if (rc != 0) {
+ CC_PAL_LOG_ERR("illegal data buffers\n");
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ rc = ProcessHashDrv(pHashUserCtx, &inBuffInfo,
+ pHashUserCtx->blockSizeInBytes);
+ if (rc != CC_OK) {
+ CC_PAL_LOG_ERR("ProcessHashDrv failed, ret = %d\n", rc);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+ pHashUserCtx->prevDataInSize = 0;
+ }
+
+ /* Process all the blocks that remain in the data */
+ bytesToAdd = (dataInSize / pHashUserCtx->blockSizeInBytes) *
+ pHashUserCtx->blockSizeInBytes;
+ if (bytesToAdd > 0) {
+
+ rc =
+ SetDataBuffersInfo(pDataIn, bytesToAdd, &inBuffInfo, NULL, 0, NULL);
+ if (rc != 0) {
+ CC_PAL_LOG_ERR("illegal data buffers\n");
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ rc = ProcessHashDrv(pHashUserCtx, &inBuffInfo, bytesToAdd);
+ if (rc != CC_OK) {
+ CC_PAL_LOG_ERR("ProcessHashDrv failed, ret = %d\n", rc);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+ pDataIn += bytesToAdd;
+ dataInSize -= bytesToAdd;
+ }
+
+ /* Copy the remaining partial block to prevDataIn */
+ bytesToAdd = dataInSize;
+ if (bytesToAdd > 0) {
+ CC_PalMemCopy(
+ (uint8_t *)&(
+ (pHashUserCtx->prevDataIn)[pHashUserCtx->prevDataInSize]),
+ pDataIn, bytesToAdd);
+ pHashUserCtx->prevDataInSize += bytesToAdd;
+ }
+ return PSA_SUCCESS;
+}
+
+/*!@}*/
+
+psa_status_t cc3xx_hash_setup(cc3xx_hash_operation_t *operation,
+ psa_algorithm_t alg)
+{
+ /* Init context */
+ HashContext_t *pHashCtx = NULL;
+
+ if (NULL == operation) {
+ CC_PAL_LOG_ERR("hash operation is NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ pHashCtx = (HashContext_t *)operation;
+ CC_PalMemSetZero(pHashCtx, sizeof(HashContext_t));
+ switch (alg) {
+#if defined MBEDTLS_SHA1_C
+ case PSA_ALG_SHA_1:
+ pHashCtx->mode = HASH_SHA1;
+ break;
+#endif
+#if defined MBEDTLS_SHA256_C
+ case PSA_ALG_SHA_224:
+ pHashCtx->mode = HASH_SHA224;
+ break;
+ case PSA_ALG_SHA_256:
+ pHashCtx->mode = HASH_SHA256;
+ break;
+#endif
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+ pHashCtx->blockSizeInBytes = HASH_BLOCK_SIZE_IN_BYTES;
+ drvError_t ret = InitHashDrv(operation);
+ if (ret == HASH_DRV_OK) {
+ return PSA_SUCCESS;
+ } else { /* change PSA error code? */
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+}
+
+psa_status_t cc3xx_hash_clone(const cc3xx_hash_operation_t *source_operation,
+ cc3xx_hash_operation_t *target_operation)
+{
+ if (source_operation == NULL || target_operation == NULL) {
+ CC_PAL_LOG_ERR("source or target operation is NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+ CC_PalMemCopy(target_operation, source_operation,
+ sizeof(cc3xx_hash_operation_t));
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_hash_update(cc3xx_hash_operation_t *operation,
+ const uint8_t *input, size_t input_length)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ if (NULL == operation) {
+ CC_PAL_LOG_ERR("ctx is NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (0 == input_length) {
+ /* This is a valid situation, no need to call hashUpdate.
+ HashFinish will produce the result. */
+ return PSA_SUCCESS;
+ }
+
+ /* if len not zero, but pointer is NULL */
+ if (NULL == input) {
+ CC_PAL_LOG_ERR("input is NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ while (input_length > MAX_HASH_CHUNK_SIZE) {
+ status = hashUpdate(operation, (uint8_t *)input, MAX_HASH_CHUNK_SIZE);
+
+ input_length -= MAX_HASH_CHUNK_SIZE;
+ input += MAX_HASH_CHUNK_SIZE;
+
+ if (status != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("hashUpdate failed, status = %d\n", status);
+ return status;
+ }
+ }
+
+ status = hashUpdate(operation, (uint8_t *)input, input_length);
+ if (status != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("hashUpdate failed, status = %d\n", status);
+ return status;
+ }
+
+ return status;
+}
+
+psa_status_t cc3xx_hash_finish(cc3xx_hash_operation_t *operation, uint8_t *hash,
+ size_t hash_size, size_t *hash_length)
+{
+ uint32_t localPrevDataIn[HASH_SHA512_BLOCK_SIZE_IN_WORDS];
+ size_t dataInSize = 0;
+ drvError_t drvRc = HASH_DRV_OK;
+ CCBuffInfo_t inBuffInfo;
+ HashContext_t *pHashCtx = NULL;
+
+ if (operation == NULL || hash == NULL) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ pHashCtx = (HashContext_t *)operation;
+ if (pHashCtx->prevDataInSize != 0) {
+ /* Copy prevDataIn to stack, in order to ensure continues and physical
+ memory access. That way, DMA will be able to access the data on any
+ platform.*/
+ CC_PalMemCopy(localPrevDataIn, pHashCtx->prevDataIn,
+ CC_MIN(HASH_SHA512_BLOCK_SIZE_IN_WORDS * sizeof(uint32_t),
+ pHashCtx->prevDataInSize));
+ dataInSize = pHashCtx->prevDataInSize;
+ }
+ pHashCtx->isLastBlockProcessed = 1;
+
+ drvRc = SetDataBuffersInfo((uint8_t *)localPrevDataIn, dataInSize,
+ &inBuffInfo, NULL, 0, NULL);
+ if (drvRc != 0) {
+ CC_PAL_LOG_ERR("illegal data buffers\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ drvRc = ProcessHashDrv(pHashCtx, &inBuffInfo, dataInSize);
+ if (drvRc != HASH_DRV_OK) {
+ CC_PAL_LOG_ERR("ProcessHashDrv failed, ret = %d\n", drvRc);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+ drvRc = FinishHashDrv(pHashCtx);
+ if (drvRc != HASH_DRV_OK) {
+ CC_PAL_LOG_ERR("FinishHashDrv failed, ret = %d\n", drvRc);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+ pHashCtx->prevDataInSize = 0;
+
+ /* Copy the result to the user buffer */
+ switch (pHashCtx->mode) {
+ case HASH_SHA1:
+ if (SHA1_DIGEST_SIZE_IN_BYTES > hash_size) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ CC_PalMemCopy(hash, pHashCtx->digest, SHA1_DIGEST_SIZE_IN_BYTES);
+ *hash_length = SHA1_DIGEST_SIZE_IN_BYTES;
+ break;
+ case HASH_SHA224:
+ if (SHA224_DIGEST_SIZE_IN_BYTES > hash_size) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ CC_PalMemCopy(hash, pHashCtx->digest, SHA224_DIGEST_SIZE_IN_BYTES);
+ *hash_length = SHA224_DIGEST_SIZE_IN_BYTES;
+ break;
+ case HASH_SHA256:
+ if (SHA256_DIGEST_SIZE_IN_BYTES > hash_size) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+ CC_PalMemCopy(hash, pHashCtx->digest, SHA256_DIGEST_SIZE_IN_BYTES);
+ *hash_length = SHA256_DIGEST_SIZE_IN_BYTES;
+ break;
+ default:
+ CC_PAL_LOG_ERR("Unsupported HASH type (%d)\n", pHashCtx->mode);
+ }
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_hash_abort(cc3xx_hash_operation_t *operation)
+{
+ /* The object has not been used yet, there is nothing to do */
+ if (operation->mode == 0) {
+ return PSA_SUCCESS;
+ }
+
+ CC_PalMemSetZero(operation, sizeof(cc3xx_hash_operation_t));
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_hash_compute(psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, uint8_t *hash,
+ size_t hash_size, size_t *hash_length)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED;
+ cc3xx_hash_operation_t operation = {0};
+
+ status = cc3xx_hash_setup(&operation, alg);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+ status = cc3xx_hash_update(&operation, input, input_length);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+ status = cc3xx_hash_finish(&operation, hash, hash_size, hash_length);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+exit:
+ cc3xx_hash_abort(&operation);
+ if (status != PSA_SUCCESS) {
+ *hash_length = 0;
+ }
+ return status;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_mac.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_mac.c
new file mode 100644
index 0000000..df44f12
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_mac.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_psa_mac.h"
+#include "cc3xx_psa_cipher.h"
+#include "cc3xx_psa_hash.h"
+#include "aes_driver.h"
+#include "cc_pal_log.h"
+#include "cc_pal_mem.h"
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/* SHA512 is not supported, this is the only size we will need */
+#define MD_MAX_SIZE 32
+
+/*!
+ * \defgroup private Private functions
+ *
+ */
+/*!@{*/
+
+static size_t psa_get_hash_block_size(psa_algorithm_t alg)
+{
+ switch (alg) {
+ case PSA_ALG_MD5:
+ return (64);
+ case PSA_ALG_SHA_1:
+ return (64);
+ case PSA_ALG_SHA_224:
+ return (64);
+ case PSA_ALG_SHA_256:
+ return (64);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * Initialize a context
+ */
+static psa_status_t cmac_init(AesContext_t *ctx)
+{
+ if (ctx == NULL) {
+ CC_PAL_LOG_ERR("NULL pointer exception\n");
+ return (PSA_ERROR_INVALID_ARGUMENT);
+ }
+
+ CC_PalMemSetZero(ctx, sizeof(AesContext_t));
+
+ ctx->mode = CIPHER_CMAC;
+ ctx->padType = CRYPTO_PADDING_NONE;
+ ctx->dir = CRYPTO_DIRECTION_ENCRYPT;
+ ctx->inputDataAddrType = DLLI_ADDR;
+ ctx->outputDataAddrType = DLLI_ADDR;
+ ctx->dataBlockType = FIRST_BLOCK;
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t cmac_setkey(AesContext_t *ctx, const unsigned char *key,
+ unsigned int keybits)
+{
+ if (ctx == NULL || key == NULL) {
+ CC_PAL_LOG_ERR("Null pointer, ctx or key are NULL\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ switch (keybits) {
+ case 128:
+ ctx->keySizeId = KEY_SIZE_128_BIT;
+ break;
+ case 192:
+ ctx->keySizeId = KEY_SIZE_192_BIT;
+ break;
+ case 256:
+ ctx->keySizeId = KEY_SIZE_256_BIT;
+ break;
+ default:
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ /* update key information in the context */
+ ctx->cryptoKey = USER_KEY;
+
+ /* Copy user key to context */
+ CC_PalMemCopy(ctx->keyBuf, key, PSA_BITS_TO_BYTES(keybits));
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t cmac_setup(cc3xx_cipher_operation_t *cmac,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, psa_algorithm_t alg)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ /* call psa cipher setup */
+ status = cc3xx_cipher_encrypt_setup(cmac, attributes, key_buffer,
+ key_buffer_size, alg);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ status = cmac_init(&(cmac->aes_ctx));
+ if (status != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR(" 'cmac_init' failed with psa return code %d\n", status);
+ return status;
+ }
+
+ status = cmac_setkey(&(cmac->aes_ctx), key_buffer,
+ psa_get_key_bits(attributes));
+ if (status != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR(" 'cmac_setkey' failed with psa return code %d\n",
+ status);
+ return status;
+ }
+ return PSA_SUCCESS;
+}
+
+static psa_status_t cmac_update(cc3xx_cipher_operation_t *cmac_ctx,
+ const unsigned char *input, size_t ilen)
+{
+ drvError_t ret = 0;
+ unsigned int block_size;
+ size_t blocks_num;
+ size_t main_chunk_in_bytes = 0;
+ CCBuffInfo_t inBuffInfo;
+ CCBuffInfo_t outBuffInfo;
+ block_size = cmac_ctx->block_size;
+
+ if ((cmac_ctx->unprocessed_size > 0) &&
+ (ilen > (block_size - cmac_ctx->unprocessed_size))) {
+ CC_PalMemCopy(
+ &(cmac_ctx)->unprocessed_data[cmac_ctx->unprocessed_size],
+ input, block_size - cmac_ctx->unprocessed_size);
+
+ ret = SetDataBuffersInfo(
+ (const uint8_t *)&(cmac_ctx)->unprocessed_data, block_size,
+ &inBuffInfo, NULL, 0, &outBuffInfo);
+ if (ret != CC_OK) {
+ CC_PAL_LOG_ERR("illegal data buffers\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ ret = ProcessAesDrv(&(cmac_ctx->aes_ctx), &inBuffInfo, &outBuffInfo,
+ block_size);
+
+ if (ret != AES_DRV_OK) {
+ CC_PAL_LOG_ERR("ProcessAesDrv failed with return code %d\n", ret);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ input += (block_size - cmac_ctx->unprocessed_size);
+ ilen -= (block_size - cmac_ctx->unprocessed_size);
+ cmac_ctx->unprocessed_size = 0;
+ }
+
+ /* blocks_num is the number of blocks including any final partial block */
+ blocks_num = (ilen + block_size - 1) / block_size;
+ if (1 < blocks_num) {
+ main_chunk_in_bytes = (blocks_num - 1) * block_size;
+
+ ret = SetDataBuffersInfo(input, main_chunk_in_bytes, &inBuffInfo, NULL,
+ 0, &outBuffInfo);
+ if (ret != CC_OK) {
+ CC_PAL_LOG_ERR("illegal data buffers\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ /* Process the input data, excluding any final partial or complete block
+ */
+ ret = ProcessAesDrv(&(cmac_ctx->aes_ctx), &inBuffInfo, &outBuffInfo,
+ main_chunk_in_bytes);
+ if (ret != AES_DRV_OK) {
+ CC_PAL_LOG_ERR("ProcessAesDrv failed with return code %d\n", ret);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ ilen -= main_chunk_in_bytes;
+ input += main_chunk_in_bytes;
+ }
+
+ /* If there is data left over that wasn't aligned to a block */
+ if (ilen > 0) {
+ CC_PalMemCopy(
+ &(cmac_ctx)->unprocessed_data[cmac_ctx->unprocessed_size],
+ input, ilen);
+ cmac_ctx->unprocessed_size += ilen;
+ }
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t cmac_finish(cc3xx_cipher_operation_t *cmac_ctx,
+ unsigned char *output)
+{
+ drvError_t ret = 0;
+ CCBuffInfo_t inBuffInfo;
+ CCBuffInfo_t outBuffInfo;
+
+ if (cmac_ctx == NULL || output == NULL) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ ret = SetDataBuffersInfo((const uint8_t *)&(cmac_ctx)->unprocessed_data,
+ cmac_ctx->unprocessed_size, &inBuffInfo, NULL,
+ 0, &outBuffInfo);
+ if (ret != CC_OK) {
+ CC_PAL_LOG_ERR("illegal data buffers\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ ret = FinishAesDrv(&(cmac_ctx->aes_ctx), &inBuffInfo, &outBuffInfo,
+ (uint32_t)(cmac_ctx)->unprocessed_size);
+
+ if (ret != AES_DRV_OK) {
+ CC_PAL_LOG_ERR("FinishAesDrv failed with return code 0x%x\n", ret);
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ CC_PalMemCopy(output, cmac_ctx->aes_ctx.ivBuf, AES_IV_SIZE);
+
+ CC_PalMemSetZero(cmac_ctx, sizeof(cc3xx_cipher_operation_t));
+
+ return PSA_SUCCESS;
+}
+
+static psa_status_t hmac_setup(cc3xx_mac_operation_t *operation,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, psa_algorithm_t hash_alg)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
+ size_t i;
+ size_t hash_size = PSA_HASH_LENGTH(hash_alg);
+ size_t block_size = psa_get_hash_block_size(hash_alg);
+ cc3xx_hash_operation_t *hmac = &(operation->hmac);
+
+ switch (hash_alg) {
+#if defined MBEDTLS_SHA1_C
+ case PSA_ALG_SHA_1:
+ hmac->mode = HASH_SHA1;
+ break;
+#endif
+#if defined MBEDTLS_SHA256_C
+ case PSA_ALG_SHA_224:
+ hmac->mode = HASH_SHA224;
+ break;
+ case PSA_ALG_SHA_256:
+ hmac->mode = HASH_SHA256;
+ break;
+#endif
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ if (block_size > sizeof(ipad)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+ if (block_size > sizeof(operation->opad)) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+ if (block_size < hash_size) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (key_buffer_size > block_size) {
+ status = cc3xx_hash_compute(hash_alg, key_buffer, key_buffer_size, ipad,
+ sizeof(ipad), &key_buffer_size);
+ if (status != PSA_SUCCESS) {
+ goto cleanup;
+ }
+ } else if (key_buffer_size != 0) {
+ CC_PalMemCopy(ipad, key_buffer, key_buffer_size);
+ }
+
+ for (i = 0; i < key_buffer_size; i++) {
+ ipad[i] ^= 0x36;
+ }
+ CC_PalMemSet(ipad + key_buffer_size, 0x36, block_size - key_buffer_size);
+
+ for (i = 0; i < key_buffer_size; i++) {
+ operation->opad[i] = ipad[i] ^ 0x36 ^ 0x5C;
+ }
+ CC_PalMemSet(operation->opad + key_buffer_size, 0x5C,
+ block_size - key_buffer_size);
+
+ status = cc3xx_hash_setup(hmac, hash_alg);
+ if (status != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ status = cc3xx_hash_update(hmac, ipad, block_size);
+
+cleanup:
+ CC_PalMemSetZero(ipad, sizeof(ipad));
+
+ return status;
+}
+
+static psa_status_t hmac_finish(cc3xx_mac_operation_t *operation, uint8_t *mac,
+ size_t mac_size)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ uint8_t tmp[MD_MAX_SIZE];
+ cc3xx_hash_operation_t *hmac = &(operation->hmac);
+ psa_algorithm_t hash_alg;
+ size_t hash_size = 0;
+ size_t block_size;
+
+ switch (hmac->mode) {
+ case HASH_SHA1:
+ hash_alg = PSA_ALG_SHA_1;
+ break;
+ case HASH_SHA224:
+ hash_alg = PSA_ALG_SHA_224;
+ break;
+ case HASH_SHA256:
+ hash_alg = PSA_ALG_SHA_256;
+ break;
+ default:
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ block_size = psa_get_hash_block_size(hash_alg);
+
+ status = cc3xx_hash_finish(hmac, tmp, sizeof(tmp), &hash_size);
+ if (status != PSA_SUCCESS) {
+ return status;
+ }
+
+ status = cc3xx_hash_setup(hmac, hash_alg);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ status = cc3xx_hash_update(hmac, operation->opad, block_size);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ status = cc3xx_hash_update(hmac, tmp, hash_size);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ status = cc3xx_hash_finish(hmac, tmp, sizeof(tmp), &hash_size);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ CC_PalMemCopy(mac, tmp, mac_size);
+
+exit:
+ CC_PalMemSetZero(tmp, hash_size);
+ return status;
+}
+
+static psa_status_t mac_setup(cc3xx_mac_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer, size_t key_buffer_size,
+ psa_algorithm_t alg)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ if (operation->alg != 0) {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ CC_PalMemSetZero(operation, sizeof(cc3xx_mac_operation_t));
+ if (PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) {
+ status = cmac_setup(&(operation->cmac), attributes, key_buffer,
+ key_buffer_size, alg);
+ } else if (PSA_ALG_IS_HMAC(alg)) {
+ status = hmac_setup(operation, key_buffer, key_buffer_size,
+ PSA_ALG_HMAC_GET_HASH(alg));
+ } else {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (status != PSA_SUCCESS) {
+ CC_PalMemSetZero(operation, sizeof(cc3xx_mac_operation_t));
+ } else {
+ operation->alg = alg;
+ }
+ return status;
+}
+
+/*!@}*/
+
+psa_status_t cc3xx_mac_sign_setup(cc3xx_mac_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, psa_algorithm_t alg)
+{
+ return mac_setup(operation, attributes, key_buffer, key_buffer_size, alg);
+}
+
+psa_status_t cc3xx_mac_verify_setup(cc3xx_mac_operation_t *operation,
+ const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, psa_algorithm_t alg)
+{
+ return mac_setup(operation, attributes, key_buffer, key_buffer_size, alg);
+}
+
+psa_status_t cc3xx_mac_update(cc3xx_mac_operation_t *operation,
+ const uint8_t *input, size_t input_length)
+{
+ if (operation == NULL || input == NULL) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+ if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
+ return cmac_update(&(operation->cmac), input, input_length);
+ } else if (PSA_ALG_IS_HMAC(operation->alg)) {
+ return cc3xx_hash_update(&(operation->hmac), input, input_length);
+ } else {
+ return PSA_ERROR_BAD_STATE;
+ }
+}
+
+psa_status_t cc3xx_mac_sign_finish(cc3xx_mac_operation_t *operation,
+ uint8_t *mac, size_t mac_size,
+ size_t *mac_length)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+
+ if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
+ status = cmac_finish(&(operation->cmac), mac);
+ } else if (PSA_ALG_IS_HMAC(operation->alg)) {
+ status = hmac_finish(operation, mac, mac_size);
+ } else {
+ return PSA_ERROR_BAD_STATE;
+ }
+
+ if (status != PSA_SUCCESS) {
+ CC_PalMemSetZero(mac, *mac_length);
+ return status;
+ } else {
+ *mac_length = mac_size;
+ }
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_mac_verify_finish(cc3xx_mac_operation_t *operation,
+ const uint8_t *mac, size_t mac_length)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ uint8_t actual_mac[PSA_MAC_MAX_SIZE];
+
+ if (mac_length > sizeof(actual_mac)) {
+ return (PSA_ERROR_INVALID_ARGUMENT);
+ }
+ if (PSA_ALG_FULL_LENGTH_MAC(operation->alg) == PSA_ALG_CMAC) {
+ status = cmac_finish(&(operation->cmac), actual_mac);
+ } else if (PSA_ALG_IS_HMAC(operation->alg)) {
+ status = hmac_finish(operation, actual_mac, mac_length);
+ }
+ if (status != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ if (CC_PalMemCmp(mac, actual_mac, mac_length)) {
+ status = PSA_ERROR_INVALID_SIGNATURE;
+ }
+
+cleanup:
+ CC_PalMemSetZero(actual_mac, sizeof(actual_mac));
+ return status;
+}
+
+psa_status_t cc3xx_mac_abort(cc3xx_mac_operation_t *operation)
+{
+ /* if alg is not set the operation has not been setup yet, nothing to do */
+ if (operation->alg == 0) {
+ return PSA_SUCCESS;
+ }
+ CC_PalMemSetZero(operation, sizeof(cc3xx_mac_operation_t));
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_mac_compute(const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ uint8_t *mac, size_t mac_size,
+ size_t *mac_length)
+{
+ psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
+ cc3xx_mac_operation_t operation = {0};
+
+ status = cc3xx_mac_sign_setup(&operation, attributes, key_buffer,
+ key_buffer_size, alg);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ if (input_length > 0) {
+ status = cc3xx_mac_update(&operation, input, input_length);
+ }
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+ status = cc3xx_mac_sign_finish(&operation, mac, mac_size, mac_length);
+ if (status != PSA_SUCCESS) {
+ goto exit;
+ }
+
+exit:
+ cc3xx_mac_abort(&operation);
+ return status;
+}
diff --git a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
index 1d90e92..b0e27ff 100644
--- a/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
+++ b/secure_fw/partitions/crypto/tfm_crypto_secure_api.c
@@ -1067,10 +1067,7 @@
status = API_DISPATCH(tfm_crypto_sign_message,
TFM_CRYPTO_SIGN_MESSAGE);
- if (status == PSA_SUCCESS) {
- *signature_length = out_vec[0].len;
- }
-
+ *signature_length = out_vec[0].len;
return status;
#endif /* TFM_CRYPTO_ASYM_SIGN_MODULE_DISABLED */
}
@@ -1555,10 +1552,7 @@
status = API_DISPATCH(tfm_crypto_mac_compute,
TFM_CRYPTO_MAC_COMPUTE);
- if (status == PSA_SUCCESS) {
- *mac_length = out_vec[0].len;
- }
-
+ *mac_length = out_vec[0].len;
return status;
#endif /* TFM_CRYPTO_MAC_MODULE_DISABLED */
}
@@ -1622,10 +1616,7 @@
status = API_DISPATCH(tfm_crypto_cipher_encrypt,
TFM_CRYPTO_CIPHER_ENCRYPT);
- if (status == PSA_SUCCESS) {
- *output_length = out_vec[0].len;
- }
-
+ *output_length = out_vec[0].len;
return status;
#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
}
@@ -1659,10 +1650,7 @@
status = API_DISPATCH(tfm_crypto_cipher_decrypt,
TFM_CRYPTO_CIPHER_DECRYPT);
- if (status == PSA_SUCCESS) {
- *output_length = out_vec[0].len;
- }
-
+ *output_length = out_vec[0].len;
return status;
#endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
}