aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Vasilakis <georgios.vasilakis@nordicsemi.no>2021-08-23 23:10:22 +0200
committerGeorgios Vasilakis <georgios.vasilakis@nordicsemi.no>2021-10-15 00:36:17 +0200
commit4f1aef6a2bab189ed08588b1d6f15338990064dc (patch)
treecee475557ca0b5d8721ac57d9811b60b3f8543db
parentfaa8ec7ddf6ef76205f383aad5b993ee9e84a608 (diff)
downloadtrusted-firmware-m-feature-cc-psa-crypto-drivers.tar.gz
CC3XX: Asymetric signing/verificationfeature-cc-psa-crypto-drivers
-This adds the assymetric/signing verification capabilities using ECDSA random and koblitz curves and RSA in both supported modes Signed-off-by: Georgios Vasilakis <georgios.vasilakis@nordicsemi.no> Change-Id: Iaf0ab59fdd2c68103ed3644dbda1dd43ce344f73
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/CMakeLists.txt8
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/cc3xx.h2
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_asn1_util.h163
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_drbg_util.h30
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc.h63
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc_util.h112
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_rsa_util.h67
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_asymmetric_signature.h38
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_agreement.h2
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_generation.h22
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_asn1_util.c276
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_drbg_util.c121
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc.c134
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc_util.c347
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_rsa_util.c669
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_asymmetric_signature.c549
-rw-r--r--lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_key_generation.c352
17 files changed, 2756 insertions, 199 deletions
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
index 1a47810f65..de28014705 100644
--- 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
@@ -20,9 +20,15 @@ target_sources(${CC312_LIB_TARGET}
src/cc3xx_psa_entropy.c
src/cc3xx_psa_key_agreement.c
+ src/cc3xx_internal_asn1_util.c
+ src/cc3xx_internal_ecc_util.c
+ src/cc3xx_internal_rsa_util.c
+ src/cc3xx_psa_asymmetric_signature.c
+ src/cc3xx_psa_key_generation.c
+ src/cc3xx_internal_drbg_util.c
+
src/cc3xx_internal_aes.c
src/cc3xx_internal_chacha20.c
- src/cc3xx_internal_ecc.c
src/cc3xx_internal_ecdh.c
src/aead/cc3xx_psa_aead.c
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
index 573c84aa46..150cf070fc 100644
--- 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
@@ -14,5 +14,7 @@
#include "cc3xx_psa_mac.h"
#include "cc3xx_psa_aead.h"
#include "cc3xx_psa_key_agreement.h"
+#include "cc3xx_psa_key_generation.h"
+#include "cc3xx_psa_asymmetric_signature.h"
#endif /* CC3XX_DRIVER_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_asn1_util.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_asn1_util.h
new file mode 100644
index 0000000000..dc20233653
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_asn1_util.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_INTERNAL_ASN1_UTIL_H
+#define CC3XX_INTERNAL_ASN1_UTIL_H
+
+#include "psa/crypto.h"
+
+#include "cc_common.h"
+#include "cc_ecc_internal.h"
+#include "cc_ecpki_error.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "mbedtls_cc_ec_mont_edw_error.h"
+
+#include "cc_ecpki_build.h"
+#include "cc_ecpki_domain.h"
+#include "cc_ecpki_ecdsa.h"
+#include "cc_ecpki_kg.h"
+#include "cc_ecpki_local.h"
+#include "pka_ec_wrst.h"
+
+/**
+ * \name DER constants
+ * These constants comply with the DER encoded ASN.1 type tags.
+ * DER encoding uses hexadecimal representation.
+ * An example DER sequence is:\n
+ * - 0x02 -- tag indicating INTEGER
+ * - 0x01 -- length in octets
+ * - 0x05 -- value
+ * Such sequences are typically read into \c ::mbedtls_x509_buf.
+ */
+#define CC3XX_TAG_ASN1_INTEGER 0x02
+#define CC3XX_TAG_ASN1_SEQUENCE 0x10
+#define CC3XX_TAG_ASN1_CONSTRUCTED 0x20
+
+/**
+ * \brief Write a length field in ASN.1 format.
+ *
+ * \note This function works backwards in data buffer.
+ *
+ * \param p The reference to the current position pointer.
+ * \param start The start of the buffer, for bounds-checking.
+ * \param len The length value to write.
+ *
+ * \return The number of bytes written to \p p on success.
+ * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small.
+ * \return PSA_ERROR_GENERIC_ERROR if any other error occured.
+ */
+int cc3xx_asn1_write_len(unsigned char **p, const unsigned char *start, size_t len);
+
+/**
+ * \brief Write an ASN.1 tag in ASN.1 format.
+ *
+ * \note This function works backwards in data buffer.
+ *
+ * \param p The reference to the current position pointer.
+ * \param start The start of the buffer, for bounds-checking.
+ * \param tag The tag to write.
+ *
+ * \return The number of bytes written to \p p on success.
+ * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small.
+ */
+int cc3xx_asn1_write_tag(unsigned char **p, const unsigned char *start,
+ unsigned char tag);
+
+/**
+ * \brief Write an int tag and value in ASN.1 format represented as a uint8_t array.
+ *
+ * \note This function works backwards in data buffer.
+ *
+ * \param p The reference to the current position pointer.
+ * \param start The start of the buffer, for bounds-checking.
+ * \param val The integer value to write.
+ * It must be non-negative.
+ *
+ * \return The number of bytes written to \p p on success.
+ * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small.
+ * \return PSA_ERROR_GENERIC_ERROR if any other error occured.
+ */
+int cc3xx_asn1_write_big_integer(unsigned char **p, const unsigned char *start,
+ uint8_t *data, size_t data_size);
+
+/**
+ * \brief Write an int tag and value in ASN.1 format.
+ *
+ * \note This function works backwards in data buffer.
+ *
+ * \param p The reference to the current position pointer.
+ * \param start The start of the buffer, for bounds-checking.
+ * \param val The integer value to write.
+ * It must be non-negative.
+ *
+ * \return The number of bytes written to \p p on success.
+ * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small.
+ * \return PSA_ERROR_GENERIC_ERROR if any other error occured.
+ */
+int cc3xx_asn1_write_int(unsigned char **p, unsigned char *start, int val);
+
+/**
+ * \brief Get the tag and length of the element.
+ * Check for the requested tag.
+ * Updates the pointer to immediately behind the tag and length.
+ *
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
+ * \param tag The expected tag.
+ *
+ * \return PSA_SUCCESS if successful.
+ * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small.
+ * \return PSA_ERROR_GENERIC_ERROR if any other error occured.
+ */
+psa_status_t cc3xx_asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len,
+ int tag);
+
+/**
+ * \brief Get the length of an ASN.1 element.
+ * Updates the pointer to immediately behind the length.
+ *
+ * \param p On entry, \c *p points to the first byte of the length,
+ * i.e. immediately after the tag.
+ * On successful completion, \c *p points to the first byte
+ * after the length, i.e. the first byte of the content.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param len On successful completion, \c *len contains the length
+ * read from the ASN.1 input.
+ *
+ * \return PSA_SUCCESS if successful.
+ * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small.
+ * \return PSA_ERROR_GENERIC_ERROR if any other error occured.
+ */
+psa_status_t cc3xx_asn1_get_len(unsigned char **p, const unsigned char *end,
+ size_t *len);
+
+/**
+ * \brief Retrieve an integer ASN.1 tag and its value.
+ * Updates the pointer to immediately behind the full tag.
+ *
+ * \param p On entry, \c *p points to the start of the ASN.1 element.
+ * On successful completion, \c *p points to the first byte
+ * beyond the ASN.1 element.
+ * On error, the value of \c *p is undefined.
+ * \param end End of data.
+ * \param val On success, the parsed value.
+ *
+ * \return PSA_SUCCESS if successful.
+ * \return PSA_ERROR_BUFFER_TOO_SMALL if the buffer is too small.
+ * \return PSA_ERROR_GENERIC_ERROR if any other error occured.
+ */
+psa_status_t cc3xx_asn1_get_int(unsigned char **p, const unsigned char *end, int *val);
+
+#endif /* CC3XX_INTERNAL_ASN1_UTIL_H */ \ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_drbg_util.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_drbg_util.h
new file mode 100644
index 0000000000..f356b8204e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_drbg_util.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_INTERNAL_DRBG_UTIL_H
+#define CC3XX_INTERNAL_DRBG_UTIL_H
+
+#include "cc_ecpki_types.h"
+#include "cc_rnd_common.h"
+#include "psa/crypto.h"
+#include "mbedtls/hmac_drbg.h"
+
+#define CC3XX_CTR_DRBG_INITIALIZED 0x5A44A5A8
+
+psa_status_t cc3xx_ctr_drbg_get_ctx(CCRndContext_t *rnd_ctx);
+
+psa_status_t cc3xx_hmac_drbg_get_ctx(CCRndContext_t *rnd_ctx,
+ mbedtls_hmac_drbg_context *hmac_drbg_ctx);
+
+psa_status_t cc3xx_hmac_drbg_init_with_params(mbedtls_hmac_drbg_context *hmac_drbg_ctx,
+ const uint8_t *hash,
+ size_t hash_len,
+ const uint8_t *key_buffer,
+ size_t key_len,
+ const CCEcpkiDomain_t *pDomain);
+
+#endif /* CC3XX_INTERNAL_DRBG_UTIL_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc.h
deleted file mode 100644
index 45e6d13ff4..0000000000
--- a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef CC3XX_INTERNAL_ECC_H
-#define CC3XX_INTERNAL_ECC_H
-
-#include "psa/crypto.h"
-
-#include "cc_ecpki_types.h"
-
-/**
- * @brief Extract domain ID from PSA
- *
- * @param[in] curve Curve extracted from EC key type
- * @param[in] key_bits Size of key in bits
- * @param[out] pDomainId EC domain identifier
- *
- * @retval PSA_SUCCESS
- * @retval PSA_ERROR_NOT_SUPPORTED
- */
-psa_status_t cc3xx_ecc_psa_domain_to_cc_domain(
- psa_ecc_family_t curve, psa_key_bits_t key_bits,
- CCEcpkiDomainID_t *pDomainId);
-
-/**
- * @brief Import private key using a domain ID and key buffer
- *
- * @param[in] DomainId EC domain identifier
- * @param[in] priv_key Private key buffer
- * @param[in] priv_key_size Private key buffer size
- * @param[out] pUserPrivKey ECPKI private key
- *
- * @retval PSA_SUCCESS
- * @retval PSA_ERROR_NOT_SUPPORTED
- * @retval PSA_ERROR_INVALID_ARGUMENT
- */
-psa_status_t cc3xx_ecc_psa_priv_to_cc_priv(
- CCEcpkiDomainID_t DomainId,
- const uint8_t *priv_key, size_t priv_key_size,
- CCEcpkiUserPrivKey_t *pUserPrivKey);
-
-/**
- * @brief Import public key using a domain ID and key buffer
- *
- * @param[in] DomainId EC domain identifier
- * @param[in] publ_key Public key buffer
- * @param[in] publ_key_size Public key buffer size
- * @param[out] pUserPublKey ECPKI public key
- *
- * @retval PSA_SUCCESS
- * @retval PSA_ERROR_NOT_SUPPORTED
- * @retval PSA_ERROR_INVALID_ARGUMENT
- */
-psa_status_t cc3xx_ecc_psa_publ_to_cc_publ(
- CCEcpkiDomainID_t DomainId,
- const uint8_t *publ_key, size_t publ_key_size,
- CCEcpkiUserPublKey_t *pUserPrivKey);
-
-#endif /* CC3XX_INTERNAL_ECC_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc_util.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc_util.h
new file mode 100644
index 0000000000..0e1afaf916
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_ecc_util.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_INTERNAL_ECC_UTIL_H
+#define CC3XX_INTERNAL_ECC_UTIL_H
+
+#include "psa/crypto.h"
+
+//#include "cc_common.h"
+//#include "cc_pal_abort.h"
+//#include "cc_pal_mem.h"
+//#include "cc_pal_types.h"
+
+//#include "cc_ecpki_build.h"
+#include "cc_ecpki_domain.h"
+//#include "cc_ecpki_ecdsa.h"
+//#include "cc_ecpki_error.h"
+//#include "cc_ecpki_kg.h"
+//#include "cc_ecpki_local.h"
+//#include "pka_ec_wrst.h"
+#include "cc_ecpki_types.h"
+
+/**
+ * @brief Convert CC error code to PSA error
+ *
+ * @param[in] cc_error The CryptoCell error
+ *
+ * @return A PSA error code
+ */
+psa_status_t cc3xx_ecc_cc_error_to_psa_error(CCError_t cc_error);
+
+/**
+ * @brief Convert ECPKI private key to ECKPKI public key
+ *
+ * @param[in] pUserPrivKey ECPKI public key
+ * @param[out] pUserPublKey ECPKI public key
+ *
+ * @retval PSA_SUCCESS
+ * @retval PSA_ERROR_NOT_SUPPORTED
+ * @retval PSA_ERROR_INVALID_ARGUMENT
+ */
+psa_status_t cc3xx_ecc_cc_priv_to_cc_publ(CCEcpkiUserPrivKey_t *pUserPrivKey,
+ CCEcpkiUserPublKey_t *pUserPublKey);
+
+/**
+ * @brief Convert ECPKI to PSA public key buffer
+ *
+ * @param[in] publ_key Public key buffer
+ * @param[in] publ_key_size Public key buffer size
+ * @param[out] pUserPublKey ECPKI public key
+ *
+ * @retval PSA_SUCCESS
+ * @retval PSA_ERROR_NOT_SUPPORTED
+ * @retval PSA_ERROR_INVALID_ARGUMENT
+ */
+psa_status_t cc3xx_ecc_cc_publ_to_psa_publ(CCEcpkiUserPublKey_t *pUserPublKey,
+ uint8_t *publ_key,
+ size_t publ_key_size);
+
+/**
+ * @brief Extract domain ID from PSA
+ *
+ * @param[in] curve Curve extracted from EC key type
+ * @param[in] key_bits Size of key in bits
+ * @param[out] pDomainId EC domain identifier
+ *
+ * @retval PSA_SUCCESS
+ * @retval PSA_ERROR_NOT_SUPPORTED
+ */
+psa_status_t cc3xx_ecc_psa_domain_to_cc_domain(psa_ecc_family_t curve,
+ psa_key_bits_t key_bits,
+ CCEcpkiDomainID_t *pDomainId);
+
+/**
+ * @brief Import private key using a domain ID and key buffer
+ *
+ * @param[in] DomainId EC domain identifier
+ * @param[in] priv_key Private key buffer
+ * @param[in] priv_key_size Private key buffer size
+ * @param[out] pUserPrivKey ECPKI private key
+ *
+ * @retval PSA_SUCCESS
+ * @retval PSA_ERROR_NOT_SUPPORTED
+ * @retval PSA_ERROR_INVALID_ARGUMENT
+ */
+psa_status_t cc3xx_ecc_psa_priv_to_cc_priv(CCEcpkiDomainID_t DomainId,
+ const uint8_t *priv_key,
+ size_t priv_key_size,
+ CCEcpkiUserPrivKey_t *pUserPrivKey);
+
+/**
+ * @brief Import public key using a domain ID and key buffer
+ *
+ * @param[in] DomainId EC domain identifier
+ * @param[in] publ_key Public key buffer
+ * @param[in] publ_key_size Public key buffer size
+ * @param[out] pUserPublKey ECPKI public key
+ *
+ * @retval PSA_SUCCESS
+ * @retval PSA_ERROR_NOT_SUPPORTED
+ * @retval PSA_ERROR_INVALID_ARGUMENT
+ */
+psa_status_t cc3xx_ecc_psa_publ_to_cc_publ(CCEcpkiDomainID_t DomainId,
+ const uint8_t *publ_key,
+ size_t publ_key_size,
+ CCEcpkiUserPublKey_t *pUserPublKey);
+
+#endif /* CC3XX_INTERNAL_ECC_UTIL_H */ \ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_rsa_util.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_rsa_util.h
new file mode 100644
index 0000000000..33d6df81b8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_internal_rsa_util.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_INTERNAL_RSA_UTIL_H
+#define CC3XX_INTERNAL_RSA_UTIL_H
+
+#include "psa/crypto.h"
+
+#include "cc_common.h"
+#include "cc_ecpki_error.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+
+#include "cc_ecpki_build.h"
+#include "cc_ecpki_domain.h"
+#include "cc_ecpki_ecdsa.h"
+#include "cc_ecpki_kg.h"
+#include "cc_ecpki_local.h"
+#include "pka_ec_wrst.h"
+
+#include "cc_rsa_types.h"
+
+/* Minimal and maximal size of RSA modulus in bits
+ * According to FIPS 186-4 size in bits should be in range [1024...3072] */
+#if defined(ARCH_IS_CC310)
+#define CC3XX_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS 1024
+#define CC3XX_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS 2048
+#define CC3XX_RSA_MIN_VALID_KEYGEN_SIZE_VALUE_IN_BITS 1024
+#define CC3XX_RSA_MAX_VALID_KEYGEN_SIZE_VALUE_IN_BITS 2048
+#else
+#define CC3XX_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS 1024
+#define CC3XX_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS 4096
+#define CC3XX_RSA_MIN_VALID_KEYGEN_SIZE_VALUE_IN_BITS 1024
+#define CC3XX_RSA_MAX_VALID_KEYGEN_SIZE_VALUE_IN_BITS 3072
+#endif
+
+psa_status_t cc3xx_rsa_cc_error_to_psa_error(CCError_t cc_error);
+
+CCError_t cc3xx_rsa_save_der_priv_key(uint8_t *key_buffer,
+ size_t key_buffer_size, uint32_t *n,
+ uint32_t *e, uint32_t *d, uint32_t *p,
+ uint32_t *q, uint32_t *dP, uint32_t *dQ,
+ uint32_t *qInv, size_t d_size_bytes);
+
+CCError_t cc3xx_rsa_psa_priv_to_psa_publ(uint8_t *priv_key_buffer,
+ size_t priv_key_buffer_size,
+ uint8_t *publ_key_buffer,
+ size_t publ_key_buffer_size);
+
+CCError_t cc3xx_rsa_psa_priv_to_cc_priv(const uint8_t *psa_priv_key_buffer,
+ size_t psa_priv_key_buffer_size,
+ CCRsaUserPrivKey_t *UserPrivKey_ptr);
+
+CCError_t cc3xx_rsa_psa_priv_to_cc_pub(const uint8_t *psa_pub_key_buffer,
+ size_t psa_pub_key_buffer_size,
+ CCRsaUserPubKey_t *UserPubKey_ptr);
+
+CCError_t cc3xx_rsa_psa_pub_to_cc_pub(const uint8_t *psa_pub_key_buffer,
+ size_t psa_pub_key_buffer_size,
+ CCRsaUserPubKey_t *UserPubKey_ptr);
+
+#endif /* CC3XX_INTERNAL_RSA_UTIL_H */ \ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_asymmetric_signature.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_asymmetric_signature.h
new file mode 100644
index 0000000000..02fb960e78
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_asymmetric_signature.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_PSA_ASYMMETRIC_SIGNATURE_H
+#define CC3XX_PSA_ASYMMETRIC_SIGNATURE_H
+
+#include "psa/crypto.h"
+
+psa_status_t cc3xx_sign_message(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, uint8_t *signature,
+ size_t signature_size,
+ size_t *signature_length);
+
+psa_status_t cc3xx_verify_message(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, const uint8_t *signature,
+ size_t signature_length);
+
+psa_status_t cc3xx_sign_hash(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, uint8_t *signature,
+ size_t signature_size, size_t *signature_length);
+
+psa_status_t cc3xx_verify_hash(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *hash,
+ size_t hash_length, const uint8_t *signature,
+ size_t signature_length);
+
+#endif /* CC3XX_PSA_ASYMMETRIC_SIGNATURE_H */ \ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_agreement.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_agreement.h
index a005e6d78b..ddd43d5ee6 100644
--- a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_agreement.h
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_agreement.h
@@ -10,7 +10,7 @@
#include "psa/crypto.h"
-#include "cc3xx_internal_ecc.h"
+#include "cc3xx_internal_ecc_util.h"
#include "cc3xx_internal_ecdh.h"
psa_status_t cc3xx_key_agreement(
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_generation.h b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_generation.h
new file mode 100644
index 0000000000..1f013a1dc5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/include/cc3xx_psa_key_generation.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CC3XX_PSA_KEY_GENERATION_H
+#define CC3XX_PSA_KEY_GENERATION_H
+
+#include "psa/crypto.h"
+
+psa_status_t cc3xx_generate_key(const psa_key_attributes_t *attributes,
+ uint8_t *key_buffer, size_t key_buffer_size,
+ size_t *key_buffer_length);
+
+psa_status_t cc3xx_export_public_key(const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, uint8_t *data,
+ size_t data_size, size_t *data_length);
+
+#endif /* CC3XX_PSA_KEY_GENERATION_H */ \ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_asn1_util.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_asn1_util.c
new file mode 100644
index 0000000000..62e0dba08f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_asn1_util.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_internal_asn1_util.h"
+#include "psa/crypto.h"
+
+#define CC3XX_ASN1_CHK_ADD(g, f) \
+ do { \
+ if ((ret = (f)) < 0) \
+ return (ret); \
+ else \
+ (g) += ret; \
+ } while (0)
+
+int cc3xx_asn1_write_len(unsigned char **p, const unsigned char *start,
+ size_t len)
+{
+ if (len < 0x80) {
+ if (*p - start < 1) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *--(*p) = (unsigned char)len;
+ return (1);
+ }
+
+ if (len <= 0xFF) {
+ if (*p - start < 2) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *--(*p) = (unsigned char)len;
+ *--(*p) = 0x81;
+ return (2);
+ }
+
+ if (len <= 0xFFFF) {
+ if (*p - start < 3) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *--(*p) = (len)&0xFF;
+ *--(*p) = (len >> 8) & 0xFF;
+ *--(*p) = 0x82;
+ return (3);
+ }
+
+ if (len <= 0xFFFFFF) {
+ if (*p - start < 4) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *--(*p) = (len)&0xFF;
+ *--(*p) = (len >> 8) & 0xFF;
+ *--(*p) = (len >> 16) & 0xFF;
+ *--(*p) = 0x83;
+ return (4);
+ }
+
+ return PSA_ERROR_GENERIC_ERROR;
+}
+
+int cc3xx_asn1_write_tag(unsigned char **p, const unsigned char *start,
+ unsigned char tag)
+{
+ if (*p - start < 1) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *--(*p) = tag;
+
+ return (1);
+}
+
+int cc3xx_asn1_write_big_integer(unsigned char **p, const unsigned char *start,
+ uint8_t *data, size_t data_size)
+{
+ int ret = PSA_ERROR_GENERIC_ERROR;
+ size_t len = data_size;
+
+ if (*p < start || (size_t)(*p - start) < len) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ (*p) -= len;
+ CC_PalMemCopy(*p, data, data_size);
+
+ /* DER format assumes 2s complement for numbers, so the leftmost bit
+ * should be 0 for positive numbers and 1 for negative numbers.
+ *
+ * FIXME: Check if there is any chance that we will use negative numbers. If
+ * so this should be done (was X->s == 1)
+ */
+ if (**p & 0x80) {
+ if (*p - start < 1) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *--(*p) = 0x00;
+ len += 1;
+ }
+
+ CC3XX_ASN1_CHK_ADD(len, cc3xx_asn1_write_len(p, start, len));
+ CC3XX_ASN1_CHK_ADD(len,
+ cc3xx_asn1_write_tag(p, start, CC3XX_TAG_ASN1_INTEGER));
+
+ ret = (int)len;
+
+ return (ret);
+}
+
+static int asn1_write_tagged_int(unsigned char **p, unsigned char *start,
+ int val, int tag)
+{
+ int ret = PSA_ERROR_GENERIC_ERROR;
+ size_t len = 0;
+
+ do {
+ if (*p - start < 1) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+ len += 1;
+ *--(*p) = val & 0xff;
+ val >>= 8;
+ } while (val > 0);
+
+ if (**p & 0x80) {
+ if (*p - start < 1) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+ *--(*p) = 0x00;
+ len += 1;
+ }
+
+ CC3XX_ASN1_CHK_ADD(len, cc3xx_asn1_write_len(p, start, len));
+ CC3XX_ASN1_CHK_ADD(len, cc3xx_asn1_write_tag(p, start, tag));
+
+ return (len);
+}
+
+static int asn1_get_tagged_int(unsigned char **p, const unsigned char *end,
+ int tag, int *val)
+{
+ int ret = PSA_ERROR_CORRUPTION_DETECTED;
+ size_t len;
+
+ if ((ret = cc3xx_asn1_get_tag(p, end, &len, tag)) != 0) {
+ return (ret);
+ }
+
+ /*
+ * len==0 is malformed (0 must be represented as 020100 for INTEGER,
+ * or 0A0100 for ENUMERATED tags
+ */
+ if (len == 0) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ if ((**p & 0x80) != 0) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ /* Skip leading zeros. */
+ while (len > 0 && **p == 0) {
+ ++(*p);
+ --len;
+ }
+
+ /* Reject integers that don't fit in an int. This code assumes that
+ * the int type has no padding bit. */
+ if (len > sizeof(int)) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+ if (len == sizeof(int) && (**p & 0x80) != 0) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *val = 0;
+ while (len-- > 0) {
+ *val = (*val << 8) | **p;
+ (*p)++;
+ }
+
+ return (PSA_SUCCESS);
+}
+
+psa_status_t cc3xx_asn1_get_tag(unsigned char **p, const unsigned char *end,
+ size_t *len, int tag)
+{
+ if ((end - *p) < 1) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ if (**p != tag) {
+ return (PSA_ERROR_GENERIC_ERROR);
+ }
+
+ (*p)++;
+
+ return (cc3xx_asn1_get_len(p, end, len));
+}
+
+psa_status_t cc3xx_asn1_get_len(unsigned char **p, const unsigned char *end,
+ size_t *len)
+{
+ if ((end - *p) < 1) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ if ((**p & 0x80) == 0) {
+ *len = *(*p)++;
+ } else {
+ switch (**p & 0x7F) {
+ case 1:
+ if ((end - *p) < 2) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *len = (*p)[1];
+ (*p) += 2;
+ break;
+
+ case 2:
+ if ((end - *p) < 3) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *len = ((size_t)(*p)[1] << 8) | (*p)[2];
+ (*p) += 3;
+ break;
+
+ case 3:
+ if ((end - *p) < 4) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *len = ((size_t)(*p)[1] << 16) | ((size_t)(*p)[2] << 8) | (*p)[3];
+ (*p) += 4;
+ break;
+
+ case 4:
+ if ((end - *p) < 5) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ *len = ((size_t)(*p)[1] << 24) | ((size_t)(*p)[2] << 16) |
+ ((size_t)(*p)[3] << 8) | (*p)[4];
+ (*p) += 5;
+ break;
+
+ default:
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+ }
+
+ if (*len > (size_t)(end - *p)) {
+ return (PSA_ERROR_BUFFER_TOO_SMALL);
+ }
+
+ return (PSA_SUCCESS);
+}
+
+psa_status_t cc3xx_asn1_get_int(unsigned char **p, const unsigned char *end,
+ int *val)
+{
+ return (asn1_get_tagged_int(p, end, CC3XX_TAG_ASN1_INTEGER, val));
+}
+
+int cc3xx_asn1_write_int(unsigned char **p, unsigned char *start, int val)
+{
+ return (asn1_write_tagged_int(p, start, val, CC3XX_TAG_ASN1_INTEGER));
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_drbg_util.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_drbg_util.c
new file mode 100644
index 0000000000..ca34af82e4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_drbg_util.c
@@ -0,0 +1,121 @@
+#include "cc3xx_internal_drbg_util.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "cc_pal_mem.h"
+#include "cc_rnd_common.h"
+#include "psa/crypto.h"
+
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/hmac_drbg.h"
+
+mbedtls_ctr_drbg_context global_ctr_drbg_ctx;
+mbedtls_hmac_drbg_context global_hmac_drbg_ctx;
+mbedtls_entropy_context global_entropy_ctx;
+
+size_t cc3xx_ctr_drbg_initialized;
+size_t cc3xx_hmac_drbg_initialized;
+
+psa_status_t cc3xx_ctr_drbg_get_ctx(CCRndContext_t *rnd_ctx)
+{
+
+ int error;
+ CCError_t cc_error;
+
+ if (cc3xx_ctr_drbg_initialized != CC3XX_CTR_DRBG_INITIALIZED) {
+ CC_PalMemSetZero(&global_ctr_drbg_ctx,
+ sizeof(mbedtls_ctr_drbg_context));
+ CC_PalMemSetZero(&global_entropy_ctx, sizeof(mbedtls_entropy_context));
+
+ mbedtls_ctr_drbg_init(&global_ctr_drbg_ctx);
+ mbedtls_entropy_init(&global_entropy_ctx);
+
+ error =
+ mbedtls_ctr_drbg_seed(&global_ctr_drbg_ctx, mbedtls_entropy_func,
+ &global_entropy_ctx, NULL, 0);
+ if (error != 0) {
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ cc3xx_ctr_drbg_initialized = CC3XX_CTR_DRBG_INITIALIZED;
+ }
+
+ rnd_ctx->rndState = &global_ctr_drbg_ctx;
+ rnd_ctx->entropyCtx = &global_entropy_ctx;
+
+ cc_error = CC_RndSetGenerateVectorFunc(rnd_ctx, mbedtls_ctr_drbg_random);
+ if (cc_error != 0) {
+ cc3xx_ctr_drbg_initialized = 0;
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t
+cc3xx_hmac_drbg_init_with_params(mbedtls_hmac_drbg_context *hmac_drbg_ctx,
+ const uint8_t *hash, size_t hash_len,
+ const uint8_t *key_buffer, size_t key_len,
+ const CCEcpkiDomain_t *pDomain)
+{
+
+ int error;
+ /* This seed should be double the size of the maximum order size to store
+ * the hash + */
+ uint8_t seed_buff[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS * 4 * 2] = {0};
+ size_t hash_bits = PSA_BYTES_TO_BITS(hash_len);
+ size_t hash_bytes_used = 0;
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+
+ if (hmac_drbg_ctx == NULL) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ mbedtls_hmac_drbg_init(hmac_drbg_ctx);
+
+ if (hash_bits > pDomain->ordSizeInBits) {
+ hash_bytes_used = PSA_BITS_TO_BYTES(pDomain->ordSizeInBits);
+ } else {
+ hash_bytes_used = hash_len;
+ }
+
+ if (2 * key_len > sizeof(seed_buff)) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ /* FIXME: A test is needed to verify that the seed_buff < pDomain->ecR */
+ CC_PalMemCopy(seed_buff + key_len + (key_len - hash_bytes_used), hash,
+ hash_bytes_used);
+
+ CC_PalMemCopy(seed_buff, key_buffer, key_len);
+
+ error = mbedtls_hmac_drbg_seed_buf(hmac_drbg_ctx, md_info, seed_buff, 2 * key_len);
+ if (error != 0) {
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_hmac_drbg_get_ctx(CCRndContext_t *rnd_ctx,
+ mbedtls_hmac_drbg_context *hmac_drbg_ctx)
+{
+
+ int error;
+
+ if (hmac_drbg_ctx == NULL) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ } else {
+ rnd_ctx->rndState = hmac_drbg_ctx;
+ }
+
+ rnd_ctx->entropyCtx = &global_entropy_ctx;
+
+ error = CC_RndSetGenerateVectorFunc(rnd_ctx, mbedtls_hmac_drbg_random);
+ if (error != 0) {
+ return PSA_ERROR_GENERIC_ERROR;
+ }
+
+ return PSA_SUCCESS;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc.c
deleted file mode 100644
index a659666dc6..0000000000
--- a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "cc3xx_internal_ecc.h"
-
-#include <cc_ecpki_domain.h>
-#include <cc_ecpki_build.h>
-#include <cc_pal_log.h>
-#include <cc_pal_mem.h>
-
-psa_status_t cc3xx_ecc_psa_domain_to_cc_domain(
- psa_ecc_family_t curve, psa_key_bits_t key_bits,
- CCEcpkiDomainID_t *pDomainId)
-{
- switch (curve) {
- case PSA_ECC_FAMILY_SECP_K1:
- switch (key_bits) {
- case 192:
- *pDomainId = CC_ECPKI_DomainID_secp192k1;
- break;
- case 224:
- *pDomainId = CC_ECPKI_DomainID_secp224k1;
- break;
- case 256:
- *pDomainId = CC_ECPKI_DomainID_secp256k1;
- break;
- default:
- return PSA_ERROR_NOT_SUPPORTED;
- }
- break;
- case PSA_ECC_FAMILY_SECP_R1:
- switch (key_bits) {
- case 192:
- *pDomainId = CC_ECPKI_DomainID_secp192r1;
- break;
- case 224:
- *pDomainId = CC_ECPKI_DomainID_secp224r1;
- break;
- case 256:
- *pDomainId = CC_ECPKI_DomainID_secp256r1;
- break;
- case 384:
- *pDomainId = CC_ECPKI_DomainID_secp384r1;
- break;
- case 521:
- *pDomainId = CC_ECPKI_DomainID_secp521r1;
- break;
- default:
- return PSA_ERROR_NOT_SUPPORTED;
- }
- break;
- default:
- return PSA_ERROR_NOT_SUPPORTED;
- }
-
- return PSA_SUCCESS;
-}
-
-psa_status_t cc3xx_ecc_psa_priv_to_cc_priv(
- CCEcpkiDomainID_t DomainId,
- const uint8_t *priv_key, size_t priv_key_size,
- CCEcpkiUserPrivKey_t *pUserPrivKey)
-{
- CCError_t status;
- const CCEcpkiDomain_t *pDomain;
-
- if (NULL == priv_key || NULL == pUserPrivKey) {
- CC_PAL_LOG_ERR("Null pointer exception\n");
- return PSA_ERROR_INVALID_ARGUMENT;
- }
-
- pDomain = CC_EcpkiGetEcDomain(DomainId);
- if (NULL == pDomain) {
- CC_PAL_LOG_ERR("Domain ID %d is not supported\n", DomainId);
- return PSA_ERROR_NOT_SUPPORTED;
- }
-
- status = CC_EcpkiPrivKeyBuild(pDomain,
- priv_key,
- priv_key_size,
- pUserPrivKey);
- if (status != CC_OK) {
- CC_PAL_LOG_ERR("Error building private key\n");
- return PSA_ERROR_INVALID_ARGUMENT;
- }
-
- return PSA_SUCCESS;
-}
-
-psa_status_t cc3xx_ecc_psa_publ_to_cc_publ(
- CCEcpkiDomainID_t DomainId,
- const uint8_t *publ_key, size_t publ_key_size,
- CCEcpkiUserPublKey_t *pUserPublKey)
-{
- psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
- CCError_t status;
- const CCEcpkiDomain_t *pDomain;
- CCEcpkiBuildTempData_t BuildTempData;
-
- if (NULL == publ_key || NULL == pUserPublKey) {
- CC_PAL_LOG_ERR("Null pointer exception\n");
- ret = PSA_ERROR_INVALID_ARGUMENT;
- goto exit;
- }
-
- pDomain = CC_EcpkiGetEcDomain(DomainId);
- if (NULL == pDomain) {
- CC_PAL_LOG_ERR("Domain ID %d is not supported\n", DomainId);
- ret = PSA_ERROR_NOT_SUPPORTED;
- goto exit;
- }
-
- status = CC_EcpkiPublKeyBuildAndCheck(pDomain,
- (uint8_t *)publ_key,
- publ_key_size,
- ECpublKeyFullCheck,
- pUserPublKey,
- &BuildTempData);
- if (status != CC_OK) {
- CC_PAL_LOG_ERR("Error building public key\n");
- ret = PSA_ERROR_INVALID_ARGUMENT;
- goto exit;
- }
-
- ret = PSA_SUCCESS;
-
-exit:
- CC_PalMemSetZero(&BuildTempData, sizeof(CCEcpkiBuildTempData_t));
- return ret;
-}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc_util.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc_util.c
new file mode 100644
index 0000000000..ca47e7171d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_ecc_util.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_internal_ecc_util.h"
+#include "psa/crypto.h"
+
+#include "cc_ecpki_error.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+
+#include "cc_ecpki_build.h"
+#include "cc_ecpki_domain.h"
+#include "cc_ecpki_local.h"
+#include "pka_ec_wrst.h"
+
+#include "mbedtls_cc_ec_mont_edw_error.h"
+
+psa_status_t cc3xx_ecc_cc_error_to_psa_error(CCError_t cc_error)
+{
+ psa_status_t err;
+
+ switch (cc_error) {
+
+ case CC_SUCCESS:
+ err = PSA_SUCCESS;
+ break;
+ case CC_ECPKI_ILLEGAL_DOMAIN_ID_ERROR:
+ case CC_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR:
+ case CC_ECPKI_BUILD_DOMAIN_ID_IS_NOT_VALID_ERROR:
+ case CC_ECDH_SVDP_DH_ILLEGAL_DOMAIN_ID_ERROR:
+ case CC_ECDSA_SIGN_INVALID_DOMAIN_ID_ERROR:
+ case CC_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR:
+ case CC_ECPKI_INVALID_DOMAIN_ID_ERROR:
+ case CC_EC_MONT_IS_NOT_SUPPORTED:
+ case CC_EC_EDW_IS_NOT_SUPPORTED:
+
+ err = PSA_ERROR_NOT_SUPPORTED;
+ break;
+
+ case CC_ECPKI_INTERNAL_ERROR:
+ case CC_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR:
+ case CC_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR:
+ case CC_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR:
+ case CC_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR:
+ case CC_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
+ case CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR:
+ case CC_ECPKI_INVALID_PRIV_KEY_TAG_ERROR:
+ case CC_ECPKI_INVALID_PUBL_KEY_TAG_ERROR:
+ case CC_ECIES_INVALID_PUBL_KEY_TAG_ERROR:
+ case CC_ECIES_INVALID_PRIV_KEY_TAG_ERROR:
+ case CC_ECIES_INVALID_PRIV_KEY_VALUE_ERROR:
+
+ err = PSA_ERROR_INVALID_ARGUMENT;
+ break;
+
+ case CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
+ case CC_EC_EDW_SIGN_VERIFY_FAILED_ERROR:
+ err = PSA_ERROR_GENERIC_ERROR;
+ break;
+
+ case CC_ECPKI_DOMAIN_PTR_ERROR:
+ case CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR:
+ case CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR:
+ case CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR:
+ case CC_ECPKI_RND_CONTEXT_PTR_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR:
+ case CC_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_VALIDATION_TAG_ERROR:
+ case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR:
+ case CC_ECPKI_BUILD_DOMAIN_DOMAIN_PTR_ERROR:
+ case CC_ECPKI_BUILD_DOMAIN_EC_PARAMETR_PTR_ERROR:
+ case CC_ECPKI_BUILD_DOMAIN_EC_PARAMETR_SIZE_ERROR:
+ case CC_ECPKI_BUILD_DOMAIN_COFACTOR_PARAMS_ERROR:
+ case CC_ECPKI_BUILD_DOMAIN_SECURITY_STRENGTH_ERROR:
+ case CC_ECPKI_BUILD_SCA_RESIST_ILLEGAL_MODE_ERROR:
+ case CC_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR:
+ case CC_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR:
+ case CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR:
+ case CC_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR:
+ case CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR:
+ case CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR:
+ case CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR:
+ case CC_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR:
+ case CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR:
+ case CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
+ case CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
+ case CC_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR:
+ case CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR:
+ case CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR:
+ case CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR:
+ case CC_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR:
+ case CC_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR:
+ case CC_ECDSA_SIGN_INVALID_RND_FUNCTION_PTR_ERROR:
+ case CC_ECDSA_SIGN_SIGNING_ERROR:
+ case CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR:
+ case CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR:
+ case CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR:
+ case CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR:
+ case CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR:
+ case CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
+ case CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
+ case CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR:
+ case CC_ECC_ILLEGAL_HASH_MODE_ERROR:
+ case CC_ECPKI_INVALID_RND_FUNC_PTR_ERROR:
+ case CC_ECPKI_INVALID_RND_CTX_PTR_ERROR:
+ case CC_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR:
+ case CC_ECPKI_INVALID_BASE_POINT_PTR_ERROR:
+ case CC_ECIES_INVALID_PUBL_KEY_PTR_ERROR:
+ case CC_ECIES_INVALID_PRIV_KEY_PTR_ERROR:
+ case CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR:
+ case CC_ECIES_INVALID_KDF_HASH_MODE_ERROR:
+ case CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR:
+ case CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR:
+ case CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR:
+ case CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR:
+ case CC_ECIES_INVALID_CIPHER_DATA_SIZE_ERROR:
+ case CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR:
+ case CC_ECIES_INVALID_EPHEM_KEY_PAIR_PTR_ERROR:
+ case CC_EC_EDW_INVALID_INPUT_POINTER_ERROR:
+ case CC_EC_EDW_INVALID_INPUT_SIZE_ERROR:
+ case CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR:
+ case CC_EC_EDW_INVALID_SCALAR_DATA_ERROR:
+ case CC_EC_EDW_RND_CONTEXT_PTR_INVALID_ERROR:
+ case CC_EC_EDW_RND_GEN_VECTOR_FUNC_ERROR:
+ case CC_EC_MONT_INVALID_INPUT_POINTER_ERROR:
+ case CC_EC_MONT_INVALID_INPUT_SIZE_ERROR:
+ case CC_EC_MONT_INVALID_DOMAIN_ID_ERROR:
+ case CC_ECEDW_INTERNAL_ERROR:
+ case CC_ECMONT_INTERNAL_ERROR:
+
+ err = PSA_ERROR_INVALID_ARGUMENT;
+ break;
+
+ default:
+ err = PSA_ERROR_GENERIC_ERROR;
+ CC_PAL_LOG_ERR("Unknown CC_ERROR %d\n", cc_error);
+ break;
+ }
+
+ CC_PAL_LOG_DEBUG("Converted CC_ERROR %d to PSA_ERROR %d\n", cc_error, err);
+ return err;
+}
+
+psa_status_t cc3xx_ecc_cc_priv_to_cc_publ(CCEcpkiUserPrivKey_t *pUserPrivKey,
+ CCEcpkiUserPublKey_t *pUserPublKey)
+{
+ psa_status_t err = PSA_ERROR_GENERIC_ERROR;
+ CCError_t cc_err;
+ CCEcpkiPublKey_t *pPublKey;
+ CCEcpkiPrivKey_t *pPrivKey;
+ uint32_t orderSizeInWords;
+ /* In the ecp_wrst_mul the temp_buffer seems zero initialized */
+ CCEcpkiKgTempData_t temp_buffer;
+ CC_PalMemSetZero(&temp_buffer, sizeof(temp_buffer));
+
+ pPublKey = (CCEcpkiPublKey_t *)&pUserPublKey->PublKeyDbBuff;
+ pPrivKey = (CCEcpkiPrivKey_t *)&pUserPrivKey->PrivKeyDbBuff;
+
+ orderSizeInWords =
+ (pPrivKey->domain.ordSizeInBits + CC_BITS_IN_32BIT_WORD - 1) /
+ CC_BITS_IN_32BIT_WORD;
+
+ cc_err = PkaEcWrstScalarMult(
+ &pPrivKey->domain, /*!< [in] Pointer to EC domain. */
+ pPrivKey->PrivKey, /*!< [in] Pointer to the scalsr buffer. */
+ orderSizeInWords, /*!< [in] Size of the scalsr in 32-bit words. */
+ pPrivKey->domain.ecGx, /*!< [in] Pointer to input point X coordinate. */
+ pPrivKey->domain.ecGy, /*!< [in] Pointer to input point Y coordinate. */
+ pPublKey->x, /*!< [out] Pointer to output point X coordinate. */
+ pPublKey->y, /*!< [out] Pointer to output point Y coordinate. */
+ (uint32_t
+ *)&temp_buffer); /*!< [in] The pointer to the temp buffer of
+ size not less, than
+ CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS.
+ */
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("Error building private key with error code %d\n",
+ cc_err);
+ return err;
+ }
+
+ pPublKey->domain = pPrivKey->domain;
+ pUserPublKey->valid_tag = CC_ECPKI_PUBL_KEY_VALIDATION_TAG;
+
+ return err;
+}
+
+psa_status_t cc3xx_ecc_cc_publ_to_psa_publ(CCEcpkiUserPublKey_t *pUserPublKey,
+ uint8_t *publ_key,
+ size_t publ_key_size)
+{
+ psa_status_t err = PSA_ERROR_CORRUPTION_DETECTED;
+ CCError_t cc_err;
+
+ if (publ_key == NULL) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ cc_err = CC_EcpkiPubKeyExport(pUserPublKey, CC_EC_PointUncompressed,
+ publ_key, &publ_key_size);
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("Error building public key failed with error code %d\n",
+ cc_err);
+ }
+
+ return err;
+}
+
+psa_status_t cc3xx_ecc_psa_domain_to_cc_domain(psa_ecc_family_t curve,
+ psa_key_bits_t key_bits,
+ CCEcpkiDomainID_t *pDomainId)
+{
+ switch (curve) {
+ case PSA_ECC_FAMILY_SECP_K1:
+ switch (key_bits) {
+ case 192:
+ *pDomainId = CC_ECPKI_DomainID_secp192k1;
+ break;
+ case 224:
+ *pDomainId = CC_ECPKI_DomainID_secp224k1;
+ break;
+ case 256:
+ *pDomainId = CC_ECPKI_DomainID_secp256k1;
+ break;
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+ break;
+ case PSA_ECC_FAMILY_SECP_R1:
+ switch (key_bits) {
+ case 192:
+ *pDomainId = CC_ECPKI_DomainID_secp192r1;
+ break;
+ case 224:
+ *pDomainId = CC_ECPKI_DomainID_secp224r1;
+ break;
+ case 256:
+ *pDomainId = CC_ECPKI_DomainID_secp256r1;
+ break;
+ case 384:
+ *pDomainId = CC_ECPKI_DomainID_secp384r1;
+ break;
+ case 521:
+ *pDomainId = CC_ECPKI_DomainID_secp521r1;
+ break;
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+ break;
+ default:
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_ecc_psa_priv_to_cc_priv(CCEcpkiDomainID_t DomainId,
+ const uint8_t *priv_key,
+ size_t priv_key_size,
+ CCEcpkiUserPrivKey_t *pUserPrivKey)
+{
+ CCError_t status;
+ const CCEcpkiDomain_t *pDomain;
+
+ if (NULL == priv_key || NULL == pUserPrivKey) {
+ CC_PAL_LOG_ERR("Null pointer exception\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ pDomain = CC_EcpkiGetEcDomain(DomainId);
+ if (NULL == pDomain) {
+ CC_PAL_LOG_ERR("Domain ID %d is not supported\n", DomainId);
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ status =
+ CC_EcpkiPrivKeyBuild(pDomain, priv_key, priv_key_size, pUserPrivKey);
+ if (status != CC_OK) {
+ CC_PAL_LOG_ERR("Error building private key\n");
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ return PSA_SUCCESS;
+}
+
+psa_status_t cc3xx_ecc_psa_publ_to_cc_publ(CCEcpkiDomainID_t DomainId,
+ const uint8_t *publ_key,
+ size_t publ_key_size,
+ CCEcpkiUserPublKey_t *pUserPublKey)
+{
+ psa_status_t ret = PSA_ERROR_CORRUPTION_DETECTED;
+ CCError_t status;
+ const CCEcpkiDomain_t *pDomain;
+ CCEcpkiBuildTempData_t BuildTempData;
+
+ if (NULL == publ_key || NULL == pUserPublKey) {
+ CC_PAL_LOG_ERR("Null pointer exception\n");
+ ret = PSA_ERROR_INVALID_ARGUMENT;
+ goto exit;
+ }
+
+ pDomain = CC_EcpkiGetEcDomain(DomainId);
+ if (NULL == pDomain) {
+ CC_PAL_LOG_ERR("Domain ID %d is not supported\n", DomainId);
+ ret = PSA_ERROR_NOT_SUPPORTED;
+ goto exit;
+ }
+
+ status = CC_EcpkiPublKeyBuildAndCheck(pDomain, (uint8_t *)publ_key,
+ publ_key_size, ECpublKeyFullCheck,
+ pUserPublKey, &BuildTempData);
+ if (status != CC_OK) {
+ CC_PAL_LOG_ERR("Error building public key\n");
+ ret = PSA_ERROR_INVALID_ARGUMENT;
+ goto exit;
+ }
+
+ ret = PSA_SUCCESS;
+
+exit:
+ CC_PalMemSetZero(&BuildTempData, sizeof(CCEcpkiBuildTempData_t));
+ return ret;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_rsa_util.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_rsa_util.c
new file mode 100644
index 0000000000..9e27033400
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_internal_rsa_util.c
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_internal_rsa_util.h"
+#include "cc3xx_internal_asn1_util.h"
+
+#include "cc_common.h"
+#include "cc_rnd_error.h"
+#include "cc_rsa_build.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_types.h"
+#include "psa/crypto.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+CCError_t cc3xx_rsa_psa_pub_to_cc_pub(const uint8_t *psa_pub_key_buffer,
+ size_t psa_pub_key_buffer_size,
+ CCRsaUserPubKey_t *UserPubKey_ptr)
+
+{
+ uint8_t *pub_key_buffer_start_pnt = (uint8_t *)psa_pub_key_buffer;
+ uint8_t **pub_key_buffer_start = &pub_key_buffer_start_pnt;
+ uint8_t *pub_key_buffer_end =
+ (uint8_t *)psa_pub_key_buffer + psa_pub_key_buffer_size;
+ uint8_t *n_ptr;
+ size_t n_len;
+ uint8_t *e_ptr;
+ size_t e_len;
+ size_t len;
+ int ret;
+
+ /* Move the pointer after the sequence */
+ ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_CONSTRUCTED |
+ CC3XX_TAG_ASN1_SEQUENCE);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ /* Get the modulus n */
+ ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ n_ptr = *pub_key_buffer_start;
+ n_len = len;
+
+ *pub_key_buffer_start += len;
+
+ /* Get the exponent e */
+ ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ e_ptr = *pub_key_buffer_start;
+ e_len = len;
+ *pub_key_buffer_start += len;
+
+ return CC_RsaPubKeyBuild(UserPubKey_ptr, e_ptr, e_len, n_ptr, n_len);
+}
+
+CCError_t cc3xx_rsa_psa_priv_to_cc_pub(const uint8_t *psa_pub_key_buffer,
+ size_t psa_pub_key_buffer_size,
+ CCRsaUserPubKey_t *UserPubKey_ptr)
+
+{
+ uint8_t *pub_key_buffer_start_pnt = (uint8_t *)psa_pub_key_buffer;
+ uint8_t **pub_key_buffer_start = &pub_key_buffer_start_pnt;
+ uint8_t *pub_key_buffer_end =
+ (uint8_t *)psa_pub_key_buffer + psa_pub_key_buffer_size;
+ uint8_t *n_ptr;
+ size_t n_len;
+ uint8_t *e_ptr;
+ size_t e_len;
+ size_t len;
+ int dummy;
+ int ret;
+
+ /* Move the pointer after the sequence */
+ ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_CONSTRUCTED |
+ CC3XX_TAG_ASN1_SEQUENCE);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ /* Move the pointer after the version */
+ ret = cc3xx_asn1_get_int(pub_key_buffer_start, pub_key_buffer_end, &dummy);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ /* Get the modulus n */
+ ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ n_ptr = *pub_key_buffer_start;
+ n_len = len;
+ *pub_key_buffer_start += len;
+
+ /* Get the exponent e */
+ ret = cc3xx_asn1_get_tag(pub_key_buffer_start, pub_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ e_ptr = *pub_key_buffer_start;
+ e_len = len;
+ *pub_key_buffer_start += len;
+
+ return CC_RsaPubKeyBuild(UserPubKey_ptr, e_ptr, e_len, n_ptr, n_len);
+}
+
+CCError_t cc3xx_rsa_psa_priv_to_cc_priv(const uint8_t *psa_priv_key_buffer,
+ size_t psa_priv_key_buffer_size,
+ CCRsaUserPrivKey_t *UserPrivKey_ptr)
+
+{
+ uint8_t *p_ptr;
+ size_t p_len;
+ uint8_t *q_ptr;
+ size_t q_len;
+ uint8_t *dP_ptr;
+ size_t dP_len;
+ uint8_t *dQ_ptr;
+ size_t dQ_len;
+ uint8_t *qInv_ptr;
+ size_t qInv_len;
+ int ret;
+ size_t len;
+ int dummy;
+ CCError_t cc_err = CC_SUCCESS;
+
+ uint8_t *priv_key_buffer_start_pnt = (uint8_t *)psa_priv_key_buffer;
+ uint8_t **priv_key_buffer_start = &priv_key_buffer_start_pnt;
+ uint8_t *priv_key_buffer_end =
+ (uint8_t *)psa_priv_key_buffer + psa_priv_key_buffer_size;
+
+ /* Move the pointer after the sequence */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_CONSTRUCTED |
+ CC3XX_TAG_ASN1_SEQUENCE);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ /* Move the pointer after the version */
+ ret =
+ cc3xx_asn1_get_int(priv_key_buffer_start, priv_key_buffer_end, &dummy);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ /* Move the pointer after the modulus n */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+ *priv_key_buffer_start += len;
+
+ /* Move the pointer after the publicExponent e*/
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+ *priv_key_buffer_start += len;
+
+ /* Move the pointer after the privateExponent d */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+ *priv_key_buffer_start += len;
+
+ /* Get the P */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ p_ptr = *priv_key_buffer_start;
+ p_len = len;
+
+ *priv_key_buffer_start += len;
+
+ /* Get the Q */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ q_ptr = *priv_key_buffer_start;
+ q_len = len;
+
+ *priv_key_buffer_start += len;
+
+ /* Get the dP */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ dP_ptr = *priv_key_buffer_start;
+ dP_len = len;
+
+ *priv_key_buffer_start += len;
+
+ /* Get the dQ */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ dQ_ptr = *priv_key_buffer_start;
+ dQ_len = len;
+
+ *priv_key_buffer_start += len;
+
+ /* Get the dInv */
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ qInv_ptr = *priv_key_buffer_start;
+ qInv_len = len;
+
+ *priv_key_buffer_start += len;
+
+ cc_err = CC_RsaPrivKeyCrtBuild(UserPrivKey_ptr, p_ptr, p_len, q_ptr, q_len,
+ dP_ptr, dP_len, dQ_ptr, dQ_len, qInv_ptr,
+ qInv_len);
+ return cc_err;
+}
+
+CCError_t cc3xx_rsa_psa_priv_to_psa_publ(uint8_t *priv_key_buffer,
+ size_t priv_key_buffer_size,
+ uint8_t *publ_key_buffer,
+ size_t publ_key_buffer_size)
+{
+
+ uint8_t *priv_key_buffer_start_pnt = priv_key_buffer;
+ uint8_t **priv_key_buffer_start = &priv_key_buffer_start_pnt;
+ uint8_t *priv_key_buffer_end = priv_key_buffer + priv_key_buffer_size;
+ uint8_t *n_pnt;
+ size_t n_len;
+ uint8_t *e_pnt;
+ size_t e_len;
+
+ uint8_t *pub_key_buffer_end_pnt = publ_key_buffer + publ_key_buffer_size;
+ uint8_t **pub_key_buffer_end = &pub_key_buffer_end_pnt;
+
+ CCError_t cc_err = CC_OK;
+ int bytes_written;
+ size_t buffer_used;
+ size_t len;
+ int ret;
+ int dummy;
+
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_CONSTRUCTED |
+ CC3XX_TAG_ASN1_SEQUENCE);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ ret =
+ cc3xx_asn1_get_int(priv_key_buffer_start, priv_key_buffer_end, &dummy);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ n_pnt = *priv_key_buffer_start;
+ n_len = len;
+
+ *priv_key_buffer_start += len;
+
+ ret = cc3xx_asn1_get_tag(priv_key_buffer_start, priv_key_buffer_end, &len,
+ CC3XX_TAG_ASN1_INTEGER);
+ if (ret < 0) {
+ return CC_FAIL;
+ }
+
+ e_pnt = *priv_key_buffer_start;
+ e_len = len;
+
+ bytes_written = cc3xx_asn1_write_big_integer(pub_key_buffer_end,
+ publ_key_buffer, e_pnt, e_len);
+ buffer_used = bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(pub_key_buffer_end,
+ publ_key_buffer, n_pnt, n_len);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ bytes_written =
+ cc3xx_asn1_write_len(pub_key_buffer_end, publ_key_buffer, buffer_used);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_tag(pub_key_buffer_end, publ_key_buffer,
+ CC3XX_TAG_ASN1_SEQUENCE |
+ CC3XX_TAG_ASN1_CONSTRUCTED);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ /* The asn1 functions write to the end of the buffer.
+ * Move the data to the beginning and erase remaining data
+ * at the original location. */
+
+ if (2 * buffer_used <= publ_key_buffer_size) {
+ CC_PalMemMove(publ_key_buffer,
+ publ_key_buffer + publ_key_buffer_size - buffer_used,
+ buffer_used);
+ CC_PalMemSetZero(publ_key_buffer + publ_key_buffer_size - buffer_used,
+ buffer_used);
+ } else if ((size_t)buffer_used < publ_key_buffer_size) {
+ CC_PalMemMove(publ_key_buffer,
+ publ_key_buffer + publ_key_buffer_size - buffer_used,
+ buffer_used);
+ CC_PalMemSetZero(publ_key_buffer + buffer_used,
+ publ_key_buffer_size - buffer_used);
+ }
+
+End:
+ return cc_err;
+}
+
+CCError_t cc3xx_rsa_save_der_priv_key(uint8_t *key_buffer,
+ size_t key_buffer_size, uint32_t *n,
+ uint32_t *e, uint32_t *d, uint32_t *p,
+ uint32_t *q, uint32_t *dP, uint32_t *dQ,
+ uint32_t *qInv, size_t d_size_bytes)
+{
+
+ uint8_t *key_buffer_end_pnt = key_buffer + key_buffer_size;
+ uint8_t **key_buffer_end = &key_buffer_end_pnt;
+ CCError_t cc_err = CC_OK;
+ uint8_t *temp_buff;
+ int bytes_written;
+ size_t buffer_used;
+
+ temp_buff = (uint8_t *)mbedtls_calloc(1, d_size_bytes);
+ if (temp_buff == NULL) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
+ qInv, d_size_bytes / 2);
+ if (cc_err != CC_OK) {
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
+ temp_buff, d_size_bytes / 2);
+ buffer_used = bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
+ dQ, d_size_bytes / 2);
+ if (cc_err != CC_OK) {
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
+ temp_buff, d_size_bytes / 2);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
+ dP, d_size_bytes / 2);
+ if (cc_err != CC_OK) {
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
+ temp_buff, d_size_bytes / 2);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
+ q, d_size_bytes / 2);
+ if (cc_err != CC_OK) {
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
+ temp_buff, d_size_bytes / 2);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
+ p, d_size_bytes / 2);
+ if (cc_err != CC_OK) {
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
+ temp_buff, d_size_bytes / 2);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
+ d, d_size_bytes);
+ if (cc_err != CC_OK) {
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
+ temp_buff, d_size_bytes);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ CC_PalMemCopy(temp_buff, (uint8_t *)e, 3);
+
+ bytes_written =
+ cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer, temp_buff, 3);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ cc_err = CC_CommonConvertLswMswWordsToMsbLsbBytes(temp_buff, d_size_bytes,
+ n, d_size_bytes);
+ if (cc_err != CC_OK) {
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_big_integer(key_buffer_end, key_buffer,
+ temp_buff, d_size_bytes);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_int(key_buffer_end, key_buffer, 0);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ bytes_written =
+ cc3xx_asn1_write_len(key_buffer_end, key_buffer, buffer_used);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ bytes_written = cc3xx_asn1_write_tag(key_buffer_end, key_buffer,
+ CC3XX_TAG_ASN1_SEQUENCE |
+ CC3XX_TAG_ASN1_CONSTRUCTED);
+ buffer_used += bytes_written;
+ if (bytes_written < 0) {
+ cc_err = CC_OUT_OF_RESOURCE_ERROR;
+ goto End;
+ }
+
+ /* The asn1 functions write to the end of the buffer.
+ * Move the data to the beginning and erase remaining data
+ * at the original location. */
+
+ if (2 * buffer_used <= key_buffer_size) {
+ CC_PalMemMove(key_buffer, key_buffer + key_buffer_size - buffer_used,
+ buffer_used);
+ CC_PalMemSetZero(key_buffer + key_buffer_size - buffer_used,
+ buffer_used);
+ } else if ((size_t)buffer_used < key_buffer_size) {
+ CC_PalMemMove(key_buffer, key_buffer + key_buffer_size - buffer_used,
+ buffer_used);
+ CC_PalMemSetZero(key_buffer + buffer_used,
+ key_buffer_size - buffer_used);
+ }
+
+End:
+ /* zeroing temp buffers */
+ CC_PalMemSetZero(temp_buff, d_size_bytes);
+ mbedtls_free(temp_buff);
+
+ return cc_err;
+}
+
+psa_status_t cc3xx_rsa_cc_error_to_psa_error(CCError_t cc_error)
+{
+ psa_status_t err;
+ switch (cc_error) {
+ case CC_SUCCESS:
+ return PSA_SUCCESS;
+ break;
+
+ case CC_RSA_BASE_MGF_MASK_TOO_LONG:
+ case CC_RSA_BASE_OAEP_DECODE_MESSAGE_TOO_LONG:
+ case CC_RSA_BASE_OAEP_DECODE_PARAMETER_STRING_TOO_LONG:
+ case CC_RSA_BASE_OAEP_ENCODE_MESSAGE_TOO_LONG:
+ case CC_RSA_BASE_OAEP_ENCODE_PARAMETER_STRING_TOO_LONG:
+ case CC_RSA_CONV_TO_CRT_INVALID_TEMP_BUFF_POINTER_ERROR:
+ case CC_RSA_DATA_POINTER_INVALID_ERROR:
+ case CC_RSA_DECRYPT_INVALID_OUTPUT_SIZE:
+ case CC_RSA_DECRYPT_OUTPUT_SIZE_POINTER_ERROR:
+ case CC_RSA_ENCODE_15_MSG_OUT_OF_RANGE:
+ case CC_RSA_GET_DER_HASH_MODE_ILLEGAL:
+ case CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR:
+ case CC_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR:
+ case CC_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR:
+ case CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_ERROR:
+ case CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_PTR_ERROR:
+ case CC_RSA_INVALID_CRT_COEFF_VAL:
+ case CC_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_ERROR:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_PTR_ERROR:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_ERROR:
+ case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_POINTER_ERROR:
+ case CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_ERROR:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_PTR_ERROR:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_ERROR:
+ case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_POINTER_ERROR:
+ case CC_RSA_INVALID_DECRYPRION_MODE_ERROR:
+ case CC_RSA_INVALID_EXPONENT_POINTER_ERROR:
+ case CC_RSA_INVALID_EXPONENT_SIZE:
+ case CC_RSA_INVALID_EXPONENT_VAL:
+ case CC_RSA_INVALID_EXP_BUFFER_SIZE_POINTER:
+ case CC_RSA_INVALID_MESSAGE_BUFFER_SIZE:
+ case CC_RSA_INVALID_MESSAGE_DATA_SIZE:
+ case CC_RSA_INVALID_MODULUS_ERROR:
+ case CC_RSA_INVALID_MODULUS_POINTER_ERROR:
+ case CC_RSA_INVALID_MODULUS_SIZE:
+ case CC_RSA_INVALID_MOD_BUFFER_SIZE_POINTER:
+ case CC_RSA_INVALID_OUTPUT_POINTER_ERROR:
+ case CC_RSA_INVALID_OUTPUT_SIZE_POINTER_ERROR:
+ case CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR:
+ case CC_RSA_INVALID_PTR_ERROR:
+ case CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR:
+ case CC_RSA_INVALID_SIGNATURE_BUFFER_POINTER:
+ case CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE:
+ case CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR:
+ case CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID:
+ case CC_RSA_MGF_ILLEGAL_ARG_ERROR:
+ case CC_RSA_MODULUS_EVEN_ERROR:
+ case CC_RSA_PKCS1_VER_ARG_ERROR:
+ case CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID:
+ case CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR:
+ case CC_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR:
+ case CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR:
+ case CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR:
+ case CC_RSA_WRONG_PRIVATE_KEY_TYPE:
+ case CC_RSA_INVALID_MESSAGE_VAL:
+ case CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE:
+ case CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING:
+ case CC_RSA_OAEP_DECODE_ERROR:
+ err = PSA_ERROR_INVALID_ARGUMENT;
+ break;
+
+ case CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE:
+ err = PSA_ERROR_BUFFER_TOO_SMALL;
+ break;
+
+ case CC_RSA_KEY_GEN_CONDITIONAL_TEST_FAIL_ERROR:
+ case CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW:
+ case CC_RSA_KEY_GENERATION_FAILURE_ERROR:
+ err = PSA_ERROR_GENERIC_ERROR;
+ break;
+
+ case CC_RSA_CAN_NOT_GENERATE_RAND_IN_RANGE:
+ case CC_RSA_ERROR_IN_RANDOM_OPERATION_FOR_ENCODE:
+ case CC_RND_STATE_PTR_INVALID_ERROR:
+ case CC_RND_GEN_VECTOR_FUNC_ERROR:
+ err = PSA_ERROR_GENERIC_ERROR;
+ break;
+
+ case CC_RSA_ERROR_VER15_INCONSISTENT_VERIFY:
+ case CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY:
+ err = PSA_ERROR_INVALID_SIGNATURE;
+ break;
+
+ /* For now, there is no better error code for malloc failure, both in CC and
+ * mbedtls
+ */
+ case CC_OUT_OF_RESOURCE_ERROR:
+ err = PSA_ERROR_INSUFFICIENT_MEMORY;
+ break;
+
+ default:
+ CC_PAL_LOG_ERR("Unknown CC_ERROR= 0x%08X\n", cc_error, cc_error);
+ err = PSA_ERROR_GENERIC_ERROR;
+ break;
+ }
+
+ CC_PAL_LOG_INFO("Converted CC_ERROR %d (0x%08x) to MBEDTLS_ERR %d\n",
+ cc_error, cc_error, err);
+ return err;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_asymmetric_signature.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_asymmetric_signature.c
new file mode 100644
index 0000000000..2062a1974a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_asymmetric_signature.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_psa_asymmetric_signature.h"
+#include "cc3xx_internal_drbg_util.h"
+#include "cc3xx_internal_ecc_util.h"
+#include "cc3xx_internal_rsa_util.h"
+#include "cc3xx_psa_hash.h"
+#include "mbedtls/hmac_drbg.h"
+#include "psa/crypto.h"
+
+#include "cc_common.h"
+#include "cc_ecc_internal.h"
+#include "cc_ecpki_build.h"
+#include "cc_ecpki_domain.h"
+#include "cc_ecpki_ecdsa.h"
+#include "cc_ecpki_local.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_rsa_schemes.h"
+#include "cc_rsa_types.h"
+#include "ecp_common.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+static void psa_hash_mode_to_cc_hash_mode(psa_algorithm_t alg,
+ bool performHashing, void *hash_mode)
+{
+
+ psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
+
+ switch (hash_alg) {
+
+ case PSA_ALG_SHA_1:
+
+ if (PSA_ALG_IS_ECDSA(alg)) {
+ *(CCEcpkiHashOpMode_t *)hash_mode =
+ performHashing ? CC_ECPKI_HASH_SHA1_mode
+ : CC_ECPKI_AFTER_HASH_SHA1_mode;
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
+ PSA_ALG_IS_RSA_PSS(alg)) {
+ *(CCRsaHashOpMode_t *)hash_mode =
+ performHashing ? CC_RSA_HASH_SHA1_mode : CC_RSA_After_SHA1_mode;
+ }
+ break;
+
+ case PSA_ALG_SHA_224:
+
+ if (PSA_ALG_IS_ECDSA(alg)) {
+ *(CCEcpkiHashOpMode_t *)hash_mode =
+ performHashing ? CC_ECPKI_HASH_SHA224_mode
+ : CC_ECPKI_AFTER_HASH_SHA224_mode;
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
+ PSA_ALG_IS_RSA_PSS(alg)) {
+ *(CCRsaHashOpMode_t *)hash_mode = performHashing
+ ? CC_RSA_HASH_SHA224_mode
+ : CC_RSA_After_SHA224_mode;
+ }
+ break;
+
+ case PSA_ALG_SHA_256:
+
+ if (PSA_ALG_IS_ECDSA(alg)) {
+ *(CCEcpkiHashOpMode_t *)hash_mode =
+ performHashing ? CC_ECPKI_HASH_SHA256_mode
+ : CC_ECPKI_AFTER_HASH_SHA256_mode;
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
+ PSA_ALG_IS_RSA_PSS(alg)) {
+ *(CCRsaHashOpMode_t *)hash_mode = performHashing
+ ? CC_RSA_HASH_SHA256_mode
+ : CC_RSA_After_SHA256_mode;
+ }
+ break;
+
+ case PSA_ALG_SHA_384:
+
+ if (PSA_ALG_IS_ECDSA(alg)) {
+ *(CCEcpkiHashOpMode_t *)hash_mode =
+ performHashing ? CC_ECPKI_HASH_SHA384_mode
+ : CC_ECPKI_AFTER_HASH_SHA384_mode;
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
+ PSA_ALG_IS_RSA_PSS(alg)) {
+ *(CCRsaHashOpMode_t *)hash_mode = performHashing
+ ? CC_RSA_HASH_SHA384_mode
+ : CC_RSA_After_SHA384_mode;
+ }
+ break;
+
+ case PSA_ALG_SHA_512:
+
+ if (PSA_ALG_IS_ECDSA(alg)) {
+ *(CCEcpkiHashOpMode_t *)hash_mode =
+ performHashing ? CC_ECPKI_HASH_SHA512_mode
+ : CC_ECPKI_AFTER_HASH_SHA512_mode;
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
+ PSA_ALG_IS_RSA_PSS(alg)) {
+ *(CCRsaHashOpMode_t *)hash_mode = performHashing
+ ? CC_RSA_HASH_SHA512_mode
+ : CC_RSA_After_SHA512_mode;
+ }
+ break;
+
+ default:
+
+ if (PSA_ALG_IS_ECDSA(alg)) {
+ *(CCEcpkiHashOpMode_t *)hash_mode = CC_ECPKI_HASH_OpModeLast;
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) ||
+ PSA_ALG_IS_RSA_PSS(alg)) {
+ *(CCRsaHashOpMode_t *)hash_mode = CC_RSA_HASH_OpModeLast;
+ }
+ break;
+ }
+}
+
+psa_status_t cc3xx_internal_ecdsa_verify(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg,
+ const uint8_t *input, size_t input_len,
+ const uint8_t *signature,
+ size_t signature_length,
+ bool do_hashing)
+{
+
+ CCEcpkiHashOpMode_t hash_mode;
+ CCEcdsaVerifyUserContext_t pVerifyUserContext;
+ CCEcpkiUserPublKey_t pUserPublKey;
+ CCEcpkiUserPrivKey_t pUserPrivKey;
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ psa_key_type_t key_bits = psa_get_key_bits(attributes);
+ psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
+ CCEcpkiDomainID_t domainId;
+ const CCEcpkiDomain_t *pDomain;
+ CCEcpkiBuildTempData_t temp_data;
+ psa_status_t err = PSA_ERROR_CORRUPTION_DETECTED;
+ CCError_t cc_err;
+
+ err = cc3xx_ecc_psa_domain_to_cc_domain(curve, key_bits, &domainId);
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("Error - curve is not supported\n");
+ return err;
+ }
+
+ pDomain = CC_EcpkiGetEcDomain(domainId);
+ if (NULL == pDomain) {
+ CC_PAL_LOG_ERR("Error - domain id %d is not supported\n", domainId);
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ /* FIXME: From here the code is only applicable to weistrass keys, add
+ * conditional when other curves are ready
+ */
+ if (PSA_KEY_TYPE_IS_KEY_PAIR(key_type)) {
+ cc_err = cc3xx_ecc_psa_priv_to_cc_priv(domainId, key, key_length,
+ &pUserPrivKey);
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+ if (err == PSA_SUCCESS) {
+ cc_err = cc3xx_ecc_cc_priv_to_cc_publ(&pUserPrivKey, &pUserPublKey);
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+ }
+ } else {
+ cc_err = CC_EcpkiPublKeyBuildAndCheck(pDomain, (uint8_t *)key,
+ key_length, CheckPointersAndSizesOnly,
+ &pUserPublKey, &temp_data);
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+ }
+
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR(
+ "Error - building public key failed with return code 0x%08x\n",
+ cc_err);
+ return err;
+ }
+
+ psa_hash_mode_to_cc_hash_mode(alg, do_hashing, &hash_mode);
+
+ cc_err = CC_EcdsaVerify(&pVerifyUserContext, &pUserPublKey, hash_mode,
+ (uint8_t *)signature, signature_length,
+ (uint8_t *)input, input_len);
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR(
+ "Error - ecdsa signacture verification failed with return "
+ "code 0x%08x\n",
+ cc_err);
+ return err;
+ }
+
+ return err;
+}
+
+psa_status_t cc3xx_internal_ecdsa_sign(
+ const psa_key_attributes_t *attributes, const uint8_t *key_buffer,
+ size_t key_length, psa_algorithm_t alg, const uint8_t *input,
+ size_t input_len, uint8_t *signature, size_t signature_size,
+ size_t *signature_length, bool do_hashing)
+
+{
+
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ psa_key_type_t key_bits = psa_get_key_bits(attributes);
+ psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
+ psa_status_t err = PSA_ERROR_CORRUPTION_DETECTED;
+ CCError_t cc_err;
+ CCEcpkiDomainID_t domainId;
+ const CCEcpkiDomain_t *pDomain;
+ CCEcdsaSignUserContext_t pSignUserContext;
+ EcdsaSignContext_t *pWorkingContext;
+ CCEcpkiUserPrivKey_t pUserPrivKey;
+ CCRndContext_t rnd_ctx;
+ CCEcpkiHashOpMode_t hash_mode;
+ mbedtls_hmac_drbg_context hmac_drbg_ctx;
+
+ pWorkingContext = (EcdsaSignContext_t *)&pSignUserContext.context_buff;
+ CC_PalMemSetZero(pWorkingContext, sizeof(EcdsaSignContext_t));
+
+ /* FixMe: 521 bits keys are not producing the correct result with CC3XX */
+ if (key_bits == 521) {
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ err = cc3xx_ecc_psa_domain_to_cc_domain(curve, key_bits, &domainId);
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("Error - curve is not supported\n");
+ return err;
+ }
+
+ pDomain = CC_EcpkiGetEcDomain(domainId);
+ if (NULL == pDomain) {
+ CC_PAL_LOG_ERR("Error - domain id %d is not supported\n", domainId);
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ /* The signature consists of two numbers with each having the length of the
+ * private key */
+ if (signature_size < (2 * PSA_BITS_TO_BYTES(pDomain->ordSizeInBits))) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+
+ cc_err =
+ CC_EcpkiPrivKeyBuild(pDomain, key_buffer, key_length, &pUserPrivKey);
+
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("Error building private key with error code %d\n",
+ cc_err);
+ goto cleanup;
+ }
+
+ psa_hash_mode_to_cc_hash_mode(alg, do_hashing, &hash_mode);
+
+ if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
+ /* When deterministic ECDSA is used we don't support
+ * doing the hashing at the same time. We need alwas have
+ * the hash as the input.
+ */
+ if (do_hashing) {
+ return PSA_ERROR_INVALID_ARGUMENT;
+ }
+
+ err = cc3xx_hmac_drbg_init_with_params(&hmac_drbg_ctx, input, input_len,
+ key_buffer, key_length, pDomain);
+ if (err != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ err = cc3xx_hmac_drbg_get_ctx(&rnd_ctx, &hmac_drbg_ctx);
+ } else {
+ err = cc3xx_ctr_drbg_get_ctx(&rnd_ctx);
+ }
+
+ if (err != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ *signature_length = signature_size;
+ /***** EcdsaSignFinish ********/
+ cc_err =
+ CC_EcdsaSign(&rnd_ctx, &pSignUserContext, &pUserPrivKey, hash_mode,
+ (uint8_t *)input, input_len, signature, signature_length);
+
+ err = cc3xx_ecc_cc_error_to_psa_error(cc_err);
+ if (err != PSA_SUCCESS) {
+ *signature_length = 0;
+ CC_PAL_LOG_ERR("Error ecdsa signing with error code %d\n", cc_err);
+ goto cleanup;
+ }
+
+cleanup:
+ return err;
+}
+
+psa_status_t cc3xx_internal_rsa_verify(const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_length, psa_algorithm_t alg,
+ const uint8_t *input,
+ size_t input_length,
+ const uint8_t *signature,
+ size_t signature_length, bool do_hashing)
+
+{
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ size_t hash_bytes = PSA_HASH_LENGTH(PSA_ALG_SIGN_GET_HASH(alg));
+ psa_status_t err = PSA_ERROR_CORRUPTION_DETECTED;
+ CCError_t cc_err;
+
+ CCRsaPubUserContext_t *pPubUserContext;
+ CCRsaUserPubKey_t *pUserPubKey;
+ CCRsaHashOpMode_t hash_mode;
+
+ pPubUserContext = (CCRsaPubUserContext_t *)mbedtls_calloc(
+ 1, sizeof(CCRsaPubUserContext_t));
+ if (pPubUserContext == NULL) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ pUserPubKey =
+ (CCRsaUserPubKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPubKey_t));
+ if (pUserPubKey == NULL) {
+ mbedtls_free(pPubUserContext);
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ if (PSA_KEY_TYPE_IS_KEY_PAIR(key_type)) {
+ cc_err =
+ cc3xx_rsa_psa_priv_to_cc_pub(key_buffer, key_length, pUserPubKey);
+ } else {
+ cc_err =
+ cc3xx_rsa_psa_pub_to_cc_pub(key_buffer, key_length, pUserPubKey);
+ }
+ if (cc_err != CC_SUCCESS) {
+ err = cc3xx_rsa_cc_error_to_psa_error(cc_err);
+ goto cleanup;
+ }
+
+ psa_hash_mode_to_cc_hash_mode(alg, do_hashing, &hash_mode);
+
+ if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
+ cc_err = CC_RsaPkcs1V15Verify(pPubUserContext, pUserPubKey, hash_mode,
+ (uint8_t *)input, input_length,
+ (uint8_t *)signature);
+ } else if (PSA_ALG_IS_RSA_PSS(alg)) {
+ cc_err = CC_RsaPssVerify(pPubUserContext, pUserPubKey, hash_mode,
+ CC_PKCS1_MGF1, hash_bytes, (uint8_t *)input,
+ input_length, (uint8_t *)signature);
+ }
+
+ err = cc3xx_rsa_cc_error_to_psa_error(cc_err);
+
+cleanup:
+ CC_PalMemSetZero(pPubUserContext, sizeof(CCRsaPubUserContext_t));
+ CC_PalMemSetZero(pUserPubKey, sizeof(CCRsaUserPubKey_t));
+ mbedtls_free(pPubUserContext);
+ mbedtls_free(pUserPubKey);
+ return err;
+}
+
+psa_status_t cc3xx_internal_rsa_sign(const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_length, psa_algorithm_t alg,
+ const uint8_t *input, size_t input_length,
+ uint8_t *signature, size_t signature_size,
+ size_t *signature_length, bool do_hashing)
+
+{
+ psa_key_type_t key_bits = psa_get_key_bits(attributes);
+ psa_status_t err = PSA_ERROR_CORRUPTION_DETECTED;
+ CCError_t cc_err = CC_FATAL_ERROR;
+
+ CCRndContext_t rnd_ctx;
+ CCRsaPrivUserContext_t *user_context_ptr;
+ CCRsaUserPrivKey_t *user_priv_key_ptr;
+ CCRsaHashOpMode_t hash_mode;
+
+ user_priv_key_ptr =
+ (CCRsaUserPrivKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPrivKey_t));
+ if (user_priv_key_ptr == NULL) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ user_context_ptr = (CCRsaPrivUserContext_t *)mbedtls_calloc(
+ 1, sizeof(CCRsaPrivUserContext_t));
+ if (user_context_ptr == NULL) {
+ mbedtls_free(user_priv_key_ptr);
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ cc_err = cc3xx_rsa_psa_priv_to_cc_priv(key_buffer, key_length,
+ user_priv_key_ptr);
+ if (cc_err != CC_SUCCESS) {
+ err = cc3xx_rsa_cc_error_to_psa_error(cc_err);
+ goto cleanup;
+ }
+
+ psa_hash_mode_to_cc_hash_mode(alg, do_hashing, &hash_mode);
+
+ err = cc3xx_ctr_drbg_get_ctx(&rnd_ctx);
+ if (err != PSA_SUCCESS) {
+ goto cleanup;
+ }
+
+ *signature_length = signature_size;
+
+ if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg)) {
+ cc_err =
+ CC_RsaPkcs1V15Sign(&rnd_ctx, user_context_ptr, user_priv_key_ptr,
+ hash_mode, (uint8_t *)input, input_length,
+ (uint8_t *)signature, signature_length);
+ } else if (PSA_ALG_IS_RSA_PSS(alg)) {
+ /* Calculate the largest possible salt length. Normally this is the hash
+ * length, which is the maximum length the salt can have. If there is
+ * not enough room, use the maximum salt length that fits. The
+ * constraint is that the hash length plus the salt length plus 2 bytes
+ * must be at most the key length. This complies with FIPS 186-4 §5.5
+ * (e) and RFC 8017 (PKCS#1 v2.2) §9.1.1 step 3. */
+ size_t hash_len = PSA_HASH_LENGTH(PSA_ALG_SIGN_GET_HASH(alg));
+ size_t output_len = PSA_BITS_TO_BYTES(key_bits);
+ size_t salt_len;
+
+ if (output_len < 2 * hash_len) {
+ err = PSA_ERROR_INVALID_ARGUMENT;
+ goto cleanup;
+ } else if (output_len >= 2 * hash_len + 2) {
+ salt_len = hash_len;
+ } else {
+ salt_len = output_len - hash_len - 2;
+ }
+
+ cc_err =
+ CC_RsaPssSign(&rnd_ctx, user_context_ptr, user_priv_key_ptr,
+ hash_mode, CC_PKCS1_MGF1, salt_len, (uint8_t *)input,
+ input_length, (uint8_t *)signature, signature_length);
+ }
+
+ err = cc3xx_rsa_cc_error_to_psa_error(cc_err);
+
+cleanup:
+ CC_PalMemSetZero(user_priv_key_ptr, sizeof(CCRsaUserPrivKey_t));
+ CC_PalMemSetZero(user_context_ptr, sizeof(CCRsaPrivUserContext_t));
+ mbedtls_free(user_priv_key_ptr);
+ mbedtls_free(user_context_ptr);
+ return err;
+}
+
+psa_status_t cc3xx_sign_hash(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, uint8_t *signature,
+ size_t signature_size, size_t *signature_length)
+{
+
+ if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
+ return cc3xx_internal_ecdsa_sign(
+ attributes, key, key_length, alg, input, input_length, signature,
+ signature_size, signature_length, false);
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) {
+ return cc3xx_internal_rsa_sign(attributes, key, key_length, alg, input,
+ input_length, signature, signature_size,
+ signature_length, false);
+ }
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t cc3xx_verify_hash(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *hash,
+ size_t hash_length, const uint8_t *signature,
+ size_t signature_length)
+{
+ if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
+ return cc3xx_internal_ecdsa_verify(attributes, key, key_length, alg,
+ hash, hash_length, signature,
+ signature_length, false);
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) {
+ return cc3xx_internal_rsa_verify(attributes, key, key_length, alg, hash,
+ hash_length, signature,
+ signature_length, false);
+ }
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t cc3xx_sign_message(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, uint8_t *signature,
+ size_t signature_size, size_t *signature_length)
+{
+ psa_status_t ret;
+ uint8_t hash[HASH_SHA512_BLOCK_SIZE_IN_BYTES];
+ size_t hash_len;
+
+ if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
+ ret = cc3xx_hash_compute(PSA_ALG_SIGN_GET_HASH(alg), input,
+ input_length, hash, sizeof(hash), &hash_len);
+ if (ret != PSA_SUCCESS) {
+ return ret;
+ }
+
+ return cc3xx_internal_ecdsa_sign(attributes, key, key_length, alg, hash,
+ hash_len, signature, signature_size,
+ signature_length, false);
+ } else if (PSA_ALG_IS_ECDSA(alg)) {
+ return cc3xx_internal_ecdsa_sign(
+ attributes, key, key_length, alg, input, input_length, signature,
+ signature_size, signature_length, true);
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) {
+ return cc3xx_internal_rsa_sign(attributes, key, key_length, alg, input,
+ input_length, signature, signature_size,
+ signature_length, true);
+ }
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}
+
+psa_status_t cc3xx_verify_message(const psa_key_attributes_t *attributes,
+ const uint8_t *key, size_t key_length,
+ psa_algorithm_t alg, const uint8_t *input,
+ size_t input_length, const uint8_t *signature,
+ size_t signature_length)
+{
+ if (PSA_ALG_IS_ECDSA(alg) || PSA_ALG_IS_DETERMINISTIC_ECDSA(alg)) {
+ return cc3xx_internal_ecdsa_verify(attributes, key, key_length, alg,
+ input, input_length, signature,
+ signature_length, true);
+ } else if (PSA_ALG_IS_RSA_PKCS1V15_SIGN(alg) || PSA_ALG_IS_RSA_PSS(alg)) {
+ return cc3xx_internal_rsa_verify(attributes, key, key_length, alg,
+ input, input_length, signature,
+ signature_length, true);
+ }
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_key_generation.c b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_key_generation.c
new file mode 100644
index 0000000000..b2fac96820
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/psa_driver_api/src/cc3xx_psa_key_generation.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cc3xx_psa_key_generation.h"
+#include "cc3xx_internal_asn1_util.h"
+#include "cc3xx_internal_drbg_util.h"
+#include "cc3xx_internal_ecc_util.h"
+#include "cc3xx_internal_rsa_util.h"
+#include "cc3xx_psa_hash.h"
+#include "psa/crypto.h"
+
+#include "cc_common.h"
+#include "cc_ecc_internal.h"
+#include "cc_ecpki_build.h"
+#include "cc_ecpki_domain.h"
+#include "cc_ecpki_ecdsa.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_kg.h"
+#include "cc_ecpki_local.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_kg.h"
+#include "cc_rsa_types.h"
+#include "pka_ec_wrst.h"
+#include "pki.h"
+#include "rsa.h"
+#include "rsa_private.h"
+#include "rsa_public.h"
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free free
+#endif
+
+/* Based on ecp_wrst_gen_keypair_base */
+static psa_status_t
+cc3xx_internal_gen_ecc_wstr_keypair(const psa_key_attributes_t *attributes,
+ uint8_t *key_buffer, size_t key_buffer_size)
+{
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ psa_key_type_t key_bits = psa_get_key_bits(attributes);
+ psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
+ psa_status_t ret;
+ CCError_t rc;
+ const CCEcpkiDomain_t *pDomain;
+ CCEcpkiDomainID_t domainId;
+ CCEcpkiUserPrivKey_t *pUserPrivKey;
+ CCEcpkiUserPublKey_t *pUserPublKey;
+ CCEcpkiPrivKey_t *pPrivKey;
+ CCEcpkiKgTempData_t *pTempBuff = NULL;
+ CCRndContext_t *pRndContext;
+ uint32_t pTempBuffsize =
+ sizeof(CCEcpkiKgTempData_t) + sizeof(CCRndContext_t) +
+ sizeof(CCEcpkiUserPrivKey_t) + sizeof(CCEcpkiUserPublKey_t);
+
+ ret = cc3xx_ecc_psa_domain_to_cc_domain(curve, key_bits, &domainId);
+ if (ret != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("Error - curve is not supported\n");
+ return ret;
+ }
+
+ pDomain = CC_EcpkiGetEcDomain(domainId);
+ if (NULL == pDomain) {
+ CC_PAL_LOG_ERR("Error - domain id %d is not supported\n", domainId);
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ pTempBuff = mbedtls_calloc(1, pTempBuffsize);
+ if (NULL == pTempBuff) {
+ CC_PAL_LOG_ERR(
+ "Error - failed to allocate memory for temporary buffer\n");
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ pRndContext = (CCRndContext_t *)(pTempBuff + 1);
+ pUserPrivKey = (CCEcpkiUserPrivKey_t *)(pRndContext + 1);
+ pUserPublKey = (CCEcpkiUserPublKey_t *)(pUserPrivKey + 1);
+
+ ret = cc3xx_ctr_drbg_get_ctx(pRndContext);
+ if (ret != PSA_SUCCESS) {
+ goto end;
+ }
+
+ pPrivKey = (CCEcpkiPrivKey_t *)&pUserPrivKey->PrivKeyDbBuff;
+
+ rc = CC_EcpkiKeyPairGenerate(pRndContext, pDomain, pUserPrivKey,
+ pUserPublKey, pTempBuff, NULL);
+
+ if (rc != CC_SUCCESS) {
+ CC_PAL_LOG_ERR("Error - Key generation ended with result: %d\n", rc);
+ ret = cc3xx_ecc_cc_error_to_psa_error(rc);
+ goto end;
+ }
+
+ CC_CommonReverseMemcpy(key_buffer, (uint8_t *)pPrivKey->PrivKey,
+ PSA_BITS_TO_BYTES(key_bits));
+
+ ret = PSA_SUCCESS;
+
+end:
+ CC_PalMemSetZero(pTempBuff, pTempBuffsize);
+ mbedtls_free(pTempBuff);
+ return ret;
+}
+
+static psa_status_t
+cc3xx_internal_gen_rsa_keypair(const psa_key_attributes_t *attributes,
+ uint8_t *key_buffer, size_t key_buffer_size)
+{
+ CCError_t cc_err = CC_FAIL;
+ psa_status_t status;
+ psa_key_type_t key_bits = psa_get_key_bits(attributes);
+ uint32_t pubExpSizeBits, mask;
+ CCRndContext_t rndContext;
+ CCRsaPubKey_t *pCcPubKey = NULL;
+ CCRsaPrivKey_t *pCcPrivKey = NULL;
+ CCRsaKgData_t *pKeyGenData = NULL;
+ uint32_t *d_buff = NULL;
+
+ /* PSA apis states that the public exponent is 65537 */
+ uint32_t pubExp = CC_RSA_KG_PUB_EXP_ALLOW_VAL_3;
+
+ uint32_t keySizeBytes = CALC_FULL_BYTES(key_bits);
+
+ /* check that the key size allowed by CRYS requirements */
+ if ((key_bits < CC3XX_RSA_MIN_VALID_KEYGEN_SIZE_VALUE_IN_BITS) ||
+ (key_bits > CC3XX_RSA_MAX_VALID_KEYGEN_SIZE_VALUE_IN_BITS) ||
+ (key_bits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)) {
+ return PSA_ERROR_DATA_INVALID;
+ }
+
+ pCcPubKey = (CCRsaPubKey_t *)mbedtls_calloc(1, sizeof(CCRsaPubKey_t));
+ if (pCcPubKey == NULL) {
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ pCcPrivKey = (CCRsaPrivKey_t *)mbedtls_calloc(1, sizeof(CCRsaPrivKey_t));
+ if (pCcPubKey == NULL) {
+ mbedtls_free(pCcPubKey);
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ pKeyGenData = (CCRsaKgData_t *)mbedtls_calloc(1, sizeof(CCRsaKgData_t));
+ if (pCcPubKey == NULL) {
+ mbedtls_free(pCcPubKey);
+ mbedtls_free(pCcPrivKey);
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ d_buff = (uint32_t *)mbedtls_calloc(1, PSA_BITS_TO_BYTES(key_bits));
+ if (pCcPubKey == NULL) {
+ mbedtls_free(pKeyGenData);
+ mbedtls_free(pCcPubKey);
+ mbedtls_free(pCcPrivKey);
+ return PSA_ERROR_INSUFFICIENT_MEMORY;
+ }
+
+ status = cc3xx_ctr_drbg_get_ctx(&rndContext);
+ if (status != PSA_SUCCESS) {
+ cc_err = CC_FAIL;
+ goto end;
+ }
+
+ /* get pub.exp size in bits */
+ pubExpSizeBits = 32;
+ mask = 1UL << 31;
+ while ((pubExp & mask) == 0) {
+ pubExpSizeBits--;
+ mask >>= 1;
+ }
+
+ /* init sizes */
+ pCcPubKey->nSizeInBits = key_bits;
+ pCcPubKey->eSizeInBits = pubExpSizeBits;
+ pCcPrivKey->nSizeInBits = key_bits;
+ pCcPubKey->e[0] = pubExp;
+
+ /* set params for non CRT */
+ pCcPrivKey->OperationMode = CC_RSA_NoCrt; /* default mode */
+ pCcPrivKey->PriveKeyDb.NonCrt.eSizeInBits = pCcPubKey->eSizeInBits;
+ pCcPrivKey->PriveKeyDb.NonCrt.e[0] = pubExp;
+
+ /* ..... calculate primes (P, Q) and nonCRT key (N, D) ..... */
+ do {
+ cc_err = RsaGenPandQ(&rndContext, key_bits, pubExpSizeBits,
+ (uint32_t *)&pubExp, pKeyGenData);
+ if (cc_err != CC_OK) {
+ goto end;
+ }
+
+ /* calculate modulus n and private nonCRT exponent d */
+ cc_err =
+ RsaCalculateNandD(pCcPubKey, pCcPrivKey, pKeyGenData, key_bits / 2);
+
+ if (cc_err != CC_OK) {
+ goto end;
+ }
+
+ /* repeat the loop if D is too low */
+ } while (cc_err == CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW);
+
+ /* calculate Barr. tag for modulus N */
+ cc_err = PkiCalcNp(((RsaPubKeyDb_t *)(pCcPubKey->ccRSAIntBuff))->NP, /*out*/
+ pCcPubKey->n, key_bits); /*in*/
+
+ if (cc_err != CC_OK) {
+ goto end;
+ }
+
+ /* The NonCrt.d will be discarded when we caclulate the Crt parameterers so
+ * we need to keep it */
+ CC_PalMemCopy(d_buff, pCcPrivKey->PriveKeyDb.NonCrt.d, keySizeBytes);
+
+ /* calculate Barrett tags for P,Q and set into context */
+ cc_err = PkiCalcNp(
+ ((RsaPrivKeyDb_t *)(pCcPrivKey->ccRSAPrivKeyIntBuff))->Crt.PP, /*out*/
+ pKeyGenData->KGData.p, key_bits / 2); /*in*/
+ if (cc_err != CC_OK) {
+ goto end;
+ }
+ cc_err = PkiCalcNp(
+ ((RsaPrivKeyDb_t *)(pCcPrivKey->ccRSAPrivKeyIntBuff))->Crt.QP, /*out*/
+ pKeyGenData->KGData.q, key_bits / 2); /*in*/
+ if (cc_err != CC_OK) {
+ goto end;
+ }
+
+ /* calculate CRT parameters */
+ pCcPrivKey->OperationMode = CC_RSA_Crt;
+ cc_err = RsaCalculateCrtParams(
+ (uint32_t *)&pubExp, pubExpSizeBits, key_bits, pKeyGenData->KGData.p,
+ pKeyGenData->KGData.q, pCcPrivKey->PriveKeyDb.Crt.dP,
+ pCcPrivKey->PriveKeyDb.Crt.dQ, pCcPrivKey->PriveKeyDb.Crt.qInv);
+
+ if (cc_err != CC_OK) {
+ goto end;
+ }
+
+ CC_PalMemSetZero(key_buffer, key_buffer_size);
+ cc_err = cc3xx_rsa_save_der_priv_key(
+ key_buffer, key_buffer_size, pCcPubKey->n, pCcPubKey->e, d_buff,
+ pKeyGenData->KGData.p, pKeyGenData->KGData.q,
+ pCcPrivKey->PriveKeyDb.Crt.dP, pCcPrivKey->PriveKeyDb.Crt.dQ,
+ pCcPrivKey->PriveKeyDb.Crt.qInv, keySizeBytes);
+
+ if (cc_err != CC_OK) {
+ CC_PalMemSetZero(key_buffer, key_buffer_size);
+ }
+
+end:
+ /* zeroing temp buffers */
+ CC_PalMemSetZero(d_buff, sizeof(PSA_BITS_TO_BYTES(key_bits)));
+ CC_PalMemSetZero(pCcPrivKey, sizeof(CCRsaPrivKey_t));
+ CC_PalMemSetZero(pCcPubKey, sizeof(CCRsaPubKey_t));
+ CC_PalMemSetZero(pKeyGenData, sizeof(CCRsaKgData_t));
+
+ mbedtls_free(d_buff);
+ mbedtls_free(pKeyGenData);
+ mbedtls_free(pCcPubKey);
+ mbedtls_free(pCcPrivKey);
+
+ return cc3xx_rsa_cc_error_to_psa_error(cc_err);
+}
+
+psa_status_t cc3xx_generate_key(const psa_key_attributes_t *attributes,
+ uint8_t *key_buffer, size_t key_buffer_size,
+ size_t *key_buffer_length)
+{
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ psa_key_type_t key_bits = psa_get_key_bits(attributes);
+ psa_status_t err = PSA_ERROR_NOT_SUPPORTED;
+
+ if (key_buffer_size < PSA_BITS_TO_BYTES(key_bits)) {
+ return PSA_ERROR_BUFFER_TOO_SMALL;
+ }
+
+ if (PSA_KEY_TYPE_IS_KEY_PAIR(key_type)) {
+ if (PSA_KEY_TYPE_IS_ECC(key_type)) {
+ if (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) ==
+ PSA_ECC_FAMILY_SECP_K1 ||
+ PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) ==
+ PSA_ECC_FAMILY_SECP_R1 ||
+ PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) ==
+ PSA_ECC_FAMILY_SECP_R2) {
+ err = cc3xx_internal_gen_ecc_wstr_keypair(
+ attributes, key_buffer, key_buffer_size);
+ }
+ } else if (PSA_KEY_TYPE_IS_RSA(key_type)) {
+ err = cc3xx_internal_gen_rsa_keypair(attributes, key_buffer,
+ key_buffer_size);
+ }
+ } else if (PSA_KEY_TYPE_IS_UNSTRUCTURED(key_type)) {
+ err = psa_generate_random(key_buffer, key_buffer_size);
+ }
+
+ return err;
+}
+
+psa_status_t cc3xx_export_public_key(const psa_key_attributes_t *attributes,
+ const uint8_t *key_buffer,
+ size_t key_buffer_size, uint8_t *data,
+ size_t data_size, size_t *data_length)
+{
+ psa_key_type_t key_type = psa_get_key_type(attributes);
+ psa_key_type_t key_bits = psa_get_key_bits(attributes);
+ psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(key_type);
+ CCEcpkiUserPrivKey_t pUserPrivKey;
+ CCEcpkiUserPublKey_t pUserPublKey;
+ psa_status_t err;
+ CCEcpkiDomainID_t domainId;
+
+ if (PSA_KEY_TYPE_IS_ECC(key_type) && PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type)) {
+ err = cc3xx_ecc_psa_domain_to_cc_domain(curve, key_bits, &domainId);
+ if (err != PSA_SUCCESS) {
+ CC_PAL_LOG_ERR("Error - curve is not supported\n");
+ return err;
+ }
+
+ err = cc3xx_ecc_psa_priv_to_cc_priv(domainId, key_buffer,
+ key_buffer_size, &pUserPrivKey);
+
+ if (err != PSA_SUCCESS) {
+ return err;
+ }
+
+ err = cc3xx_ecc_cc_priv_to_cc_publ(&pUserPrivKey, &pUserPublKey);
+ if (err != PSA_SUCCESS) {
+ return err;
+ }
+
+ err = cc3xx_ecc_cc_publ_to_psa_publ(&pUserPublKey, data, data_size);
+ return err;
+ } else if (PSA_KEY_TYPE_IS_RSA(key_type) &&
+ PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type)) {
+ err = cc3xx_rsa_psa_priv_to_psa_publ((uint8_t *)key_buffer,
+ key_buffer_size, data, data_size);
+ return err;
+ }
+
+ return PSA_ERROR_NOT_SUPPORTED;
+}