aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanh-arm <dan.handley@arm.com>2017-06-28 16:29:55 +0100
committerGitHub <noreply@github.com>2017-06-28 16:29:55 +0100
commitaa5b843fe8f2d8cea80fd1c06e7fc6b7c18f265c (patch)
tree1c5cc6c6be6194bf767237b7b6a00e2c67d3a450
parent1979ee13a5806f8f203dd056b4124949ab58df17 (diff)
parentf143cafe2c7a23b073b568aff159aea1c797c100 (diff)
downloadtrusted-firmware-a-aa5b843fe8f2d8cea80fd1c06e7fc6b7c18f265c.tar.gz
Merge pull request #1007 from soby-mathew/sm/ccintv1.4-rc0
Enable integration of ARM TrustZone Cryptocell for TBB
-rw-r--r--docs/porting-guide.md6
-rw-r--r--docs/user-guide.md5
-rw-r--r--drivers/auth/cryptocell/cryptocell_crypto.c304
-rw-r--r--drivers/auth/cryptocell/cryptocell_crypto.mk28
-rw-r--r--include/drivers/arm/cryptocell/cc_crypto_boot_defs.h34
-rw-r--r--include/drivers/arm/cryptocell/cc_pal_sb_plat.h33
-rw-r--r--include/drivers/arm/cryptocell/cc_pal_types.h40
-rw-r--r--include/drivers/arm/cryptocell/cc_pal_types_plat.h25
-rw-r--r--include/drivers/arm/cryptocell/cc_sec_defs.h34
-rw-r--r--include/drivers/arm/cryptocell/crypto_driver.h35
-rw-r--r--include/drivers/arm/cryptocell/nvm.h55
-rw-r--r--include/drivers/arm/cryptocell/nvm_otp.h59
-rw-r--r--include/drivers/arm/cryptocell/rsa.h55
-rw-r--r--include/drivers/arm/cryptocell/sbrom_bsv_api.h72
-rw-r--r--include/drivers/arm/cryptocell/secureboot_base_func.h49
-rw-r--r--include/drivers/arm/cryptocell/secureboot_gen_defs.h56
-rw-r--r--include/drivers/arm/cryptocell/util.h72
-rw-r--r--include/plat/arm/common/arm_def.h12
-rw-r--r--make_helpers/build_macros.mk2
-rw-r--r--plat/arm/board/common/board_arm_trusted_boot.c132
-rw-r--r--plat/arm/board/common/board_common.mk8
-rw-r--r--plat/arm/board/juno/include/platform_def.h3
-rw-r--r--plat/arm/common/aarch64/arm_helpers.S48
-rw-r--r--plat/arm/common/arm_common.mk9
-rw-r--r--plat/arm/common/arm_tzc400.c5
-rw-r--r--plat/arm/common/arm_tzc_dmc500.c4
26 files changed, 1171 insertions, 14 deletions
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index c7b9e89c88..047e225008 100644
--- a/docs/porting-guide.md
+++ b/docs/porting-guide.md
@@ -299,6 +299,12 @@ also be defined:
Firmware Update (FWU) certificate identifier, used by NS_BL1U to load the
FWU content certificate.
+* **#define : PLAT_CRYPTOCELL_BASE**
+
+ This defines the base address of ARM® TrustZone® CryptoCell and must be
+ defined if CryptoCell crypto driver is used for Trusted Board Boot. For
+ capable ARM platforms, this driver is used if `ARM_CRYPTOCELL_INTEG` is
+ set.
If the AP Firmware Updater Configuration image, BL2U is used, the following
must also be defined:
diff --git a/docs/user-guide.md b/docs/user-guide.md
index 29691c5be9..ea2874d8fc 100644
--- a/docs/user-guide.md
+++ b/docs/user-guide.md
@@ -623,6 +623,11 @@ performed.
with version 1 of the translation tables library instead of version 2. It is
set to 0 by default, which selects version 2.
+* `ARM_CRYPTOCELL_INTEG` : bool option to enable Trusted Firmware to invoke
+ ARM® TrustZone® CryptoCell functionality for Trusted Board Boot on capable
+ ARM platforms. If this option is specified, then the path to the CryptoCell
+ SBROM library must be specified via `CCSBROM_LIB_PATH` flag.
+
For a better understanding of these options, the ARM development platform memory
map is explained in the [Firmware Design].
diff --git a/drivers/auth/cryptocell/cryptocell_crypto.c b/drivers/auth/cryptocell/cryptocell_crypto.c
new file mode 100644
index 0000000000..05462bea12
--- /dev/null
+++ b/drivers/auth/cryptocell/cryptocell_crypto.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <crypto_mod.h>
+#include <crypto_driver.h>
+#include <debug.h>
+#include <mbedtls_common.h>
+#include <platform_def.h>
+#include <rsa.h>
+#include <sbrom_bsv_api.h>
+#include <secureboot_base_func.h>
+#include <secureboot_gen_defs.h>
+#include <stddef.h>
+#include <string.h>
+#include <utils.h>
+#include <util.h>
+
+#include <mbedtls/oid.h>
+
+#define LIB_NAME "CryptoCell SBROM"
+#define RSA_SALT_LEN 32
+#define RSA_EXPONENT 65537
+
+/*
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ *
+ * RSASSA-PSS-params ::= SEQUENCE {
+ * hashAlgorithm [0] HashAlgorithm,
+ * maskGenAlgorithm [1] MaskGenAlgorithm,
+ * saltLength [2] INTEGER,
+ * trailerField [3] TrailerField DEFAULT trailerFieldBC
+ * }
+ */
+
+/*
+ * Initialize the library and export the descriptor
+ */
+static void init(void)
+{
+ CCError_t ret;
+ uint32_t lcs;
+
+ /* Initialize CC SBROM */
+ ret = CC_BsvSbromInit((uintptr_t)PLAT_CRYPTOCELL_BASE);
+ if (ret != CC_OK) {
+ ERROR("CryptoCell CC_BsvSbromInit() error %x\n", ret);
+ panic();
+ }
+
+ /* Initialize lifecycle state */
+ ret = CC_BsvLcsGetAndInit((uintptr_t)PLAT_CRYPTOCELL_BASE, &lcs);
+ if (ret != CC_OK) {
+ ERROR("CryptoCell CC_BsvLcsGetAndInit() error %x\n", ret);
+ panic();
+ }
+
+ /* If the lifecyclestate is `SD`, then stop further execution */
+ if (lcs == CC_BSV_SECURITY_DISABLED_LCS) {
+ ERROR("CryptoCell LCS is security-disabled\n");
+ panic();
+ }
+}
+
+/*
+ * Verify a signature.
+ *
+ * Parameters are passed using the DER encoding format following the ASN.1
+ * structures detailed above.
+ */
+static int verify_signature(void *data_ptr, unsigned int data_len,
+ void *sig_ptr, unsigned int sig_len,
+ void *sig_alg, unsigned int sig_alg_len,
+ void *pk_ptr, unsigned int pk_len)
+{
+ CCError_t error;
+ CCSbNParams_t pk;
+ CCSbSignature_t signature;
+ int rc, exp;
+ mbedtls_asn1_buf sig_oid, alg_oid, params;
+ mbedtls_md_type_t md_alg;
+ mbedtls_pk_type_t pk_alg;
+ mbedtls_pk_rsassa_pss_options pss_opts;
+ size_t len;
+ uint8_t *p, *end;
+ /* Temp buf to store the public key modulo (N) in LE format */
+ uint32_t RevN[SB_RSA_MOD_SIZE_IN_WORDS];
+
+ /* Verify the signature algorithm */
+ /* Get pointers to signature OID and parameters */
+ p = sig_alg;
+ end = p + sig_alg_len;
+ rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &params);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ /* Get the actual signature algorithm (MD + PK) */
+ rc = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ /* The CryptoCell only supports RSASSA-PSS signature */
+ if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE)
+ return CRYPTO_ERR_SIGNATURE;
+
+ /* Verify the RSASSA-PSS params */
+ /* The trailer field is verified to be 0xBC internally by this API */
+ rc = mbedtls_x509_get_rsassa_pss_params(&params, &md_alg,
+ &pss_opts.mgf1_hash_id,
+ &pss_opts.expected_salt_len);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ /* The CryptoCell only supports SHA256 as hash algorithm */
+ if (md_alg != MBEDTLS_MD_SHA256 || pss_opts.mgf1_hash_id != MBEDTLS_MD_SHA256)
+ return CRYPTO_ERR_SIGNATURE;
+
+ if (pss_opts.expected_salt_len != RSA_SALT_LEN)
+ return CRYPTO_ERR_SIGNATURE;
+
+ /* Parse the public key */
+ p = pk_ptr;
+ end = p + pk_len;
+ rc = mbedtls_asn1_get_tag(&p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ end = p + len;
+ rc = mbedtls_asn1_get_alg_null(&p, end, &alg_oid);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ if (pk_alg != MBEDTLS_PK_RSA)
+ return CRYPTO_ERR_SIGNATURE;
+
+ rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ rc = mbedtls_asn1_get_tag(&p, end, &len,
+ MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ if (*p == 0) {
+ p++; len--;
+ }
+ if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end))
+ return CRYPTO_ERR_SIGNATURE;
+
+ /*
+ * The CCSbVerifySignature() API expects N and Np in BE format and
+ * the signature in LE format. Copy N from certificate.
+ */
+ memcpy(pk.N, p, RSA_MOD_SIZE_IN_BYTES);
+
+ /* Verify the RSA exponent */
+ p += len;
+ rc = mbedtls_asn1_get_int(&p, end, &exp);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ if (exp != RSA_EXPONENT)
+ return CRYPTO_ERR_SIGNATURE;
+
+ /*
+ * Calculate the Np (Barrett n' value). The RSA_CalcNp() API expects
+ * N in LE format. Hence reverse N into a temporary buffer `RevN`.
+ */
+ UTIL_ReverseMemCopy((uint8_t *)RevN, (uint8_t *)pk.N, sizeof(RevN));
+
+ RSA_CalcNp((uintptr_t)PLAT_CRYPTOCELL_BASE, RevN, pk.Np);
+
+ /* Np is in LE format. Reverse it to BE */
+ UTIL_ReverseBuff((uint8_t *)pk.Np, sizeof(pk.Np));
+
+ /* Get the signature (bitstring) */
+ p = sig_ptr;
+ end = p + sig_len;
+ rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
+ if (rc != 0)
+ return CRYPTO_ERR_SIGNATURE;
+
+ if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end))
+ return CRYPTO_ERR_SIGNATURE;
+
+ /*
+ * The signature is BE format. Convert it to LE before calling
+ * CCSbVerifySignature().
+ */
+ UTIL_ReverseMemCopy((uint8_t *)signature.sig, p, RSA_MOD_SIZE_IN_BYTES);
+
+ /*
+ * CryptoCell utilises DMA internally to transfer data. Flush the data
+ * from caches.
+ */
+ flush_dcache_range((uintptr_t)data_ptr, data_len);
+
+ /* Verify the signature */
+ error = CCSbVerifySignature((uintptr_t)PLAT_CRYPTOCELL_BASE,
+ (uint32_t *)data_ptr, &pk, &signature,
+ data_len, RSA_PSS_2048);
+ if (error != CC_OK)
+ return CRYPTO_ERR_SIGNATURE;
+
+ /* Signature verification success */
+ return CRYPTO_SUCCESS;
+}
+
+/*
+ * Match a hash
+ *
+ * Digest info is passed in DER format following the ASN.1 structure detailed
+ * above.
+ */
+static int verify_hash(void *data_ptr, unsigned int data_len,
+ void *digest_info_ptr, unsigned int digest_info_len)
+{
+ mbedtls_asn1_buf hash_oid, params;
+ mbedtls_md_type_t md_alg;
+ uint8_t *p, *end, *hash;
+ CCHashResult_t pubKeyHash;
+ size_t len;
+ int rc;
+ CCError_t error;
+
+ /* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
+ p = digest_info_ptr;
+ end = p + digest_info_len;
+ rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
+ MBEDTLS_ASN1_SEQUENCE);
+ if (rc != 0)
+ return CRYPTO_ERR_HASH;
+
+ /* Get the hash algorithm */
+ rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, &params);
+ if (rc != 0)
+ return CRYPTO_ERR_HASH;
+
+ rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
+ if (rc != 0)
+ return CRYPTO_ERR_HASH;
+ /* Verify that hash algorithm is SHA256 */
+ if (md_alg != MBEDTLS_MD_SHA256)
+ return CRYPTO_ERR_HASH;
+
+ /* Hash should be octet string type */
+ rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
+ if (rc != 0)
+ return CRYPTO_ERR_HASH;
+
+ /* Length of hash must match the algorithm's size */
+ if (len != HASH_RESULT_SIZE_IN_BYTES)
+ return CRYPTO_ERR_HASH;
+
+ /*
+ * CryptoCell utilises DMA internally to transfer data. Flush the data
+ * from caches.
+ */
+ flush_dcache_range((uintptr_t)data_ptr, data_len);
+
+ hash = p;
+ error = SBROM_CryptoHash((uintptr_t)PLAT_CRYPTOCELL_BASE,
+ (uintptr_t)data_ptr, data_len, pubKeyHash);
+ if (error != CC_OK)
+ return CRYPTO_ERR_HASH;
+
+ rc = memcmp(pubKeyHash, hash, HASH_RESULT_SIZE_IN_BYTES);
+ if (rc != 0)
+ return CRYPTO_ERR_HASH;
+
+ return CRYPTO_SUCCESS;
+}
+
+/*
+ * Register crypto library descriptor
+ */
+REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash);
+
+
diff --git a/drivers/auth/cryptocell/cryptocell_crypto.mk b/drivers/auth/cryptocell/cryptocell_crypto.mk
new file mode 100644
index 0000000000..a88dcfc579
--- /dev/null
+++ b/drivers/auth/cryptocell/cryptocell_crypto.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include drivers/auth/mbedtls/mbedtls_common.mk
+
+# The algorithm is RSA when using Cryptocell crypto driver
+TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA
+
+# Needs to be set to drive mbed TLS configuration correctly
+$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
+
+# CCSBROM_LIB_PATH must be set to the Cryptocell SBROM library path
+ifeq (${CCSBROM_LIB_PATH},)
+ $(error Error: CCSBROM_LIB_PATH not set)
+endif
+
+TF_LDFLAGS += -L$(CCSBROM_LIB_PATH)
+LDLIBS += -lcc_712sbromx509
+
+INCLUDES += -Iinclude/drivers/arm/cryptocell
+
+CRYPTOCELL_SOURCES := drivers/auth/cryptocell/cryptocell_crypto.c
+
+BL1_SOURCES += ${CRYPTOCELL_SOURCES}
+BL2_SOURCES += ${CRYPTOCELL_SOURCES} \ No newline at end of file
diff --git a/include/drivers/arm/cryptocell/cc_crypto_boot_defs.h b/include/drivers/arm/cryptocell/cc_crypto_boot_defs.h
new file mode 100644
index 0000000000..2cb8938d2b
--- /dev/null
+++ b/include/drivers/arm/cryptocell/cc_crypto_boot_defs.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_CRYPTO_BOOT_DEFS_H
+#define _CC_CRYPTO_BOOT_DEFS_H
+
+/*! @file
+@brief This file contains SBROM definitions
+*/
+
+/*! Version counters value. */
+typedef enum {
+
+ CC_SW_VERSION_COUNTER1 = 1, /*!< Counter 1 - trusted version. */
+ CC_SW_VERSION_COUNTER2, /*!< Counter 2 - non trusted version. */
+
+ CC_SW_VERSION_MAX = 0x7FFFFFFF
+
+} CCSbSwVersionId_t;
+
+/* HASH boot key definition */
+typedef enum {
+ CC_SB_HASH_BOOT_KEY_0_128B = 0, /*!< 128-bit truncated SHA256 digest of public key 0. */
+ CC_SB_HASH_BOOT_KEY_1_128B = 1, /*!< 128-bit truncated SHA256 digest of public key 1. */
+ CC_SB_HASH_BOOT_KEY_256B = 2, /*!< 256-bit SHA256 digest of public key. */
+ CC_SB_HASH_BOOT_NOT_USED = 0xFF,
+ CC_SB_HASH_MAX_NUM = 0x7FFFFFFF, /*!\internal use external 128-bit truncated SHA256 digest */
+} CCSbPubKeyIndexType_t;
+
+
+#endif
diff --git a/include/drivers/arm/cryptocell/cc_pal_sb_plat.h b/include/drivers/arm/cryptocell/cc_pal_sb_plat.h
new file mode 100644
index 0000000000..212a710be0
--- /dev/null
+++ b/include/drivers/arm/cryptocell/cc_pal_sb_plat.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+@file
+@brief This file contains the platform-dependent definitions that are used in the SBROM code.
+*/
+
+#ifndef _CC_PAL_SB_PLAT_H
+#define _CC_PAL_SB_PLAT_H
+
+#include "cc_pal_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! Definition of DMA address type, can be 32 bits or 64 bits according to CryptoCell's HW. */
+typedef uint64_t CCDmaAddr_t;
+/*! Definition of CryptoCell address type, can be 32 bits or 64 bits according to platform. */
+typedef uintptr_t CCAddr_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/cc_pal_types.h b/include/drivers/arm/cryptocell/cc_pal_types.h
new file mode 100644
index 0000000000..8c09b23cc7
--- /dev/null
+++ b/include/drivers/arm/cryptocell/cc_pal_types.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_PAL_TYPES_H
+#define CC_PAL_TYPES_H
+
+/*!
+@file
+@brief This file contains platform-dependent definitions and types.
+*/
+
+#include "cc_pal_types_plat.h"
+
+typedef enum {
+ CC_FALSE = 0,
+ CC_TRUE = 1
+} CCBool;
+
+#define CC_SUCCESS 0UL
+#define CC_FAIL 1UL
+
+#define CC_1K_SIZE_IN_BYTES 1024
+#define CC_BITS_IN_BYTE 8
+#define CC_BITS_IN_32BIT_WORD 32
+#define CC_32BIT_WORD_SIZE (sizeof(uint32_t))
+
+#define CC_OK CC_SUCCESS
+
+#define CC_UNUSED_PARAM(prm) ((void)prm)
+
+#define CC_MAX_UINT32_VAL (0xFFFFFFFF)
+
+#define CALC_FULL_BYTES(numBits) (((numBits) + (CC_BITS_IN_BYTE - 1))/CC_BITS_IN_BYTE)
+#define CALC_FULL_32BIT_WORDS(numBits) (((numBits) + (CC_BITS_IN_32BIT_WORD - 1))/CC_BITS_IN_32BIT_WRD)
+#define CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) (((sizeBytes) + CC_32BIT_WORD_SIZE - 1)/CC_32BIT_WORD_SIZE)
+
+#endif
diff --git a/include/drivers/arm/cryptocell/cc_pal_types_plat.h b/include/drivers/arm/cryptocell/cc_pal_types_plat.h
new file mode 100644
index 0000000000..d8ed3e1d31
--- /dev/null
+++ b/include/drivers/arm/cryptocell/cc_pal_types_plat.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*! @file
+@brief This file contains basic type definitions that are platform-dependent.
+*/
+#ifndef _CC_PAL_TYPES_PLAT_H
+#define _CC_PAL_TYPES_PLAT_H
+/* Host specific types for standard (ISO-C99) compilant platforms */
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef uint32_t CCStatus;
+
+#define CCError_t CCStatus
+#define CC_INFINITE 0xFFFFFFFF
+
+#define CEXPORT_C
+#define CIMPORT_C
+
+#endif /*_CC_PAL_TYPES_PLAT_H*/
diff --git a/include/drivers/arm/cryptocell/cc_sec_defs.h b/include/drivers/arm/cryptocell/cc_sec_defs.h
new file mode 100644
index 0000000000..d41921855b
--- /dev/null
+++ b/include/drivers/arm/cryptocell/cc_sec_defs.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_SEC_DEFS_H
+#define _CC_SEC_DEFS_H
+
+/*!
+@file
+@brief This file contains general hash definitions and types.
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! The hashblock size in words. */
+#define HASH_BLOCK_SIZE_IN_WORDS 16
+/*! The hash - SHA2 results in words. */
+#define HASH_RESULT_SIZE_IN_WORDS 8
+#define HASH_RESULT_SIZE_IN_BYTES 32
+
+/*! Definition for hash result array. */
+typedef uint32_t CCHashResult_t[HASH_RESULT_SIZE_IN_WORDS];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/crypto_driver.h b/include/drivers/arm/cryptocell/crypto_driver.h
new file mode 100644
index 0000000000..18104dd7d4
--- /dev/null
+++ b/include/drivers/arm/cryptocell/crypto_driver.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CRYPTO_DRIVER_H
+#define _CRYPTO_DRIVER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_sb_plat.h"
+#include "cc_sec_defs.h"
+
+/*----------------------------
+ PUBLIC FUNCTIONS
+-----------------------------------*/
+/*!
+ * @brief This function gives the functionality of integrated hash
+ *
+ * @param[in] hwBaseAddress - CryptoCell base address
+ * @param[out] hashResult - the HASH result.
+ *
+ */
+CCError_t SBROM_CryptoHash(unsigned long hwBaseAddress, CCDmaAddr_t inputDataAddr, uint32_t BlockSize,
+ CCHashResult_t hashResult);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/nvm.h b/include/drivers/arm/cryptocell/nvm.h
new file mode 100644
index 0000000000..f806d3d42b
--- /dev/null
+++ b/include/drivers/arm/cryptocell/nvm.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _NVM__H
+#define _NVM__H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_crypto_boot_defs.h"
+#include "cc_sec_defs.h"
+#include "cc_pal_types.h"
+
+/*------------------------------------
+ DEFINES
+-------------------------------------*/
+
+/**
+ * @brief This function reads the LCS from the SRAM/NVM
+ *
+ * @param[in] hwBaseAddress - CryptoCell base address
+ *
+ * @param[in/out] lcs_ptr - pointer to memory to store the LCS
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
+ */
+CCError_t NVM_GetLCS(unsigned long hwBaseAddress, uint32_t *lcs_ptr);
+
+/**
+ * @brief The NVM_ReadHASHPubKey function is a NVM interface function -
+ * The function retrieves the HASH of the device Public key from the SRAM/NVM
+ *
+ * @param[in] hwBaseAddress - CryptoCell base address
+ *
+ * @param[in] pubKeyIndex - Index of HASH in the OTP
+ *
+ * @param[out] PubKeyHASH - the public key HASH.
+ *
+ * @param[in] hashSizeInWords - hash size (valid values: 4W, 8W)
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
+ */
+
+CCError_t NVM_ReadHASHPubKey(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t pubKeyIndex, CCHashResult_t PubKeyHASH, uint32_t hashSizeInWords);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/nvm_otp.h b/include/drivers/arm/cryptocell/nvm_otp.h
new file mode 100644
index 0000000000..390d62bc1d
--- /dev/null
+++ b/include/drivers/arm/cryptocell/nvm_otp.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _NVM_OTP_H
+#define _NVM_OTP_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_crypto_boot_defs.h"
+#include "cc_pal_types.h"
+
+/*------------------------------------
+ DEFINES
+-------------------------------------*/
+
+
+
+/**
+ * @brief The NVM_GetSwVersion function is a NVM interface function -
+ * The function retrieves the SW version from the SRAM/NVM.
+ * In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate)
+ *
+ * @param[in] hwBaseAddress - CryptoCell base address
+ *
+ * @param[in] counterId - relevant only for OTP (valid values: 1,2)
+ *
+ * @param[out] swVersion - the minimum SW version
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
+ */
+CCError_t NVM_GetSwVersion(unsigned long hwBaseAddress, CCSbSwVersionId_t counterId, uint32_t *swVersion);
+
+
+/**
+ * @brief The NVM_SetSwVersion function is a NVM interface function -
+ * The function writes the SW version into the SRAM/NVM.
+ * In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate)
+ *
+ * @param[in] hwBaseAddress - CryptoCell base address
+ *
+ * @param[in] counterId - relevant only for OTP (valid values: 1,2)
+ *
+ * @param[in] swVersion - the minimum SW version
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure -a value from NVM_error.h
+ */
+CCError_t NVM_SetSwVersion(unsigned long hwBaseAddress, CCSbSwVersionId_t counterId, uint32_t swVersion);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/rsa.h b/include/drivers/arm/cryptocell/rsa.h
new file mode 100644
index 0000000000..cd9925b325
--- /dev/null
+++ b/include/drivers/arm/cryptocell/rsa.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RSA_H
+#define RSA_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+
+/************************ Defines ******************************/
+
+/* the modulus size ion bits */
+#define RSA_MOD_SIZE_IN_BITS 2048UL
+#define RSA_MOD_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_MOD_SIZE_IN_BITS))
+#define RSA_MOD_SIZE_IN_WORDS (CALC_FULL_32BIT_WORDS(RSA_MOD_SIZE_IN_BITS))
+#define RSA_MOD_SIZE_IN_256BITS (RSA_MOD_SIZE_IN_WORDS/8)
+#define RSA_EXP_SIZE_IN_BITS 17UL
+#define RSA_EXP_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_EXP_SIZE_IN_BITS))
+
+/* size of buffer for Barrett modulus tag NP, used in PKA algorithms */
+#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS 132
+#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
+#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS (CALC_FULL_32BIT_WORDS(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
+
+/*
+ * @brief The RSA_CalcNp calculates Np value and saves it into Np_ptr:
+ *
+ *
+
+ * @param[in] hwBaseAddress - HW base address. Relevant for HW
+ * implementation, for SW it is ignored.
+ * @N_ptr[in] - The pointer to the modulus buffer.
+ * @Np_ptr[out] - pointer to Np vector buffer. Its size must be >= 160.
+ */
+void RSA_CalcNp(unsigned long hwBaseAddress,
+ uint32_t *N_ptr,
+ uint32_t *Np_ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/sbrom_bsv_api.h b/include/drivers/arm/cryptocell/sbrom_bsv_api.h
new file mode 100644
index 0000000000..de835461fd
--- /dev/null
+++ b/include/drivers/arm/cryptocell/sbrom_bsv_api.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SBROM_BSV_API_H
+#define _SBROM_BSV_API_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains all SBROM library APIs and definitions.
+*/
+#include "cc_pal_types.h"
+
+/* Life cycle state definitions */
+#define CC_BSV_CHIP_MANUFACTURE_LCS 0x0 /*!< CM lifecycle value. */
+#define CC_BSV_DEVICE_MANUFACTURE_LCS 0x1 /*!< DM lifecycle value. */
+#define CC_BSV_SECURITY_DISABLED_LCS 0x3 /*!< SD lifecycle value. */
+#define CC_BSV_SECURE_LCS 0x5 /*!< Secure lifecycle value. */
+#define CC_BSV_RMA_LCS 0x7 /*!< RMA lifecycle value. */
+
+/*----------------------------
+ PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+@brief This function should be the first ARM TrustZone CryptoCell TEE SBROM library API called.
+It verifies the HW product and version numbers.
+
+@return CC_OK On success.
+@return A non-zero value from sbrom_bsv_error.h on failure.
+*/
+CCError_t CC_BsvSbromInit(
+ unsigned long hwBaseAddress /*!< [in] HW registers base address. */
+ );
+
+
+/*!
+@brief This function can be used for checking the LCS value, after CC_BsvLcsGetAndInit was called by the Boot ROM.
+
+@return CC_OK On success.
+@return A non-zero value from sbrom_bsv_error.h on failure.
+*/
+CCError_t CC_BsvLcsGet(
+ unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
+ uint32_t *pLcs /*!< [out] Returned lifecycle state. */
+ );
+
+/*!
+@brief This function retrieves the HW security lifecycle state, performs validity checks,
+and additional initializations in case the LCS is RMA (sets the Kce to fixed value).
+\note Invalid LCS results in an error returned.
+In this case, the customer's code must completely disable the device.
+
+@return CC_OK On success.
+@return A non-zero value from sbrom_bsv_error.h on failure.
+*/
+CCError_t CC_BsvLcsGetAndInit(
+ unsigned long hwBaseAddress, /*!< [in] HW registers base address. */
+ uint32_t *pLcs /*!< [out] Returned lifecycle state. */
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/secureboot_base_func.h b/include/drivers/arm/cryptocell/secureboot_base_func.h
new file mode 100644
index 0000000000..6db596e0d7
--- /dev/null
+++ b/include/drivers/arm/cryptocell/secureboot_base_func.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SECURE_BOOT_BASE_FUNC_H
+#define _SECURE_BOOT_BASE_FUNC_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "secureboot_gen_defs.h"
+
+
+/*----------------------------
+ PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/**
+ * @brief This function calculates the HASH over the given data and than verify
+ * RSA signature on that hashed data
+ *
+ * @param[in] hwBaseAddr - CryptoCell base address
+ * @param[in] pData - pointer to the data to be verified
+ * @param[in] pNParams - a pointer to the public key parameters
+ * @param[in] pSignature - a pointer to the signature structure
+ * @param[in] sizeOfData - size of the data to calculate the HASH on (in bytes)
+ * @param[in] RSAAlg - RSA algorithm to use
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ * on failure - a value from BootImagesVerifier_error.h
+ */
+CCError_t CCSbVerifySignature(unsigned long hwBaseAddress,
+ uint32_t *pData,
+ CCSbNParams_t *pNParams,
+ CCSbSignature_t *pSignature,
+ uint32_t sizeOfData,
+ CCSbRsaAlg_t RSAAlg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/secureboot_gen_defs.h b/include/drivers/arm/cryptocell/secureboot_gen_defs.h
new file mode 100644
index 0000000000..68b9ef8aec
--- /dev/null
+++ b/include/drivers/arm/cryptocell/secureboot_gen_defs.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SECURE_BOOT_GEN_DEFS_H
+#define _SECURE_BOOT_GEN_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains all of the definitions and structures that are used for the secure boot.
+*/
+
+#include "cc_pal_sb_plat.h"
+#include "cc_sec_defs.h"
+
+
+/* General definitions */
+/***********************/
+
+/*RSA definitions*/
+#define SB_RSA_MOD_SIZE_IN_WORDS 64
+#define SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS 5
+
+
+/*! Public key data structure. */
+typedef struct {
+ uint32_t N[SB_RSA_MOD_SIZE_IN_WORDS]; /*!< N public key, big endian representation. */
+ uint32_t Np[SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS]; /*!< Np (Barrett n' value). */
+} CCSbNParams_t;
+
+/*! Signature structure. */
+typedef struct {
+ uint32_t sig[SB_RSA_MOD_SIZE_IN_WORDS]; /*!< RSA PSS signature. */
+} CCSbSignature_t;
+
+
+/********* Supported algorithms definitions ***********/
+
+/*! RSA supported algorithms */
+typedef enum {
+ RSA_PSS_2048 = 0x01, /*!< RSA PSS 2048 after hash SHA 256 */
+ RSA_PKCS15_2048 = 0x02, /*!< RSA PKX15 */
+ RSA_Last = 0x7FFFFFFF
+} CCSbRsaAlg_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/drivers/arm/cryptocell/util.h b/include/drivers/arm/cryptocell/util.h
new file mode 100644
index 0000000000..18fb5999dc
--- /dev/null
+++ b/include/drivers/arm/cryptocell/util.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/* invers the bytes on a word- used for output from HASH */
+#ifdef BIG__ENDIAN
+#define UTIL_INVERSE_UINT32_BYTES(val) (val)
+#else
+#define UTIL_INVERSE_UINT32_BYTES(val) \
+ (((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24))
+#endif
+
+/* invers the bytes on a word - used for input data for HASH */
+#ifdef BIG__ENDIAN
+#define UTIL_REVERT_UINT32_BYTES(val) \
+ (((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24))
+#else
+#define UTIL_REVERT_UINT32_BYTES(val) (val)
+#endif
+
+ /* ------------------------------------------------------------
+ **
+ * @brief This function executes a reverse bytes copying from one buffer to another buffer.
+ *
+ * @param[in] dst_ptr - The pointer to destination buffer.
+ * @param[in] src_ptr - The pointer to source buffer.
+ * @param[in] size - The size in bytes.
+ *
+ */
+
+void UTIL_ReverseMemCopy(uint8_t *dst_ptr, uint8_t *src_ptr, uint32_t size);
+
+
+ /* ------------------------------------------------------------
+ **
+ * @brief This function executes a reversed byte copy on a specified buffer.
+ *
+ * on a 6 byte byffer:
+ *
+ * buff[5] <---> buff[0]
+ * buff[4] <---> buff[1]
+ * buff[3] <---> buff[2]
+ *
+ * @param[in] dst_ptr - The counter buffer.
+ * @param[in] src_ptr - The counter size in bytes.
+ *
+ */
+void UTIL_ReverseBuff(uint8_t *buff_ptr, uint32_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index ea30954761..5dae30ec72 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -83,6 +83,18 @@
#define ARM_AP_TZC_DRAM1_END (ARM_AP_TZC_DRAM1_BASE + \
ARM_AP_TZC_DRAM1_SIZE - 1)
+/* Define the Access permissions for Secure peripherals to NS_DRAM */
+#if ARM_CRYPTOCELL_INTEG
+/*
+ * Allow Secure peripheral to read NS DRAM when integrated with CryptoCell.
+ * This is required by CryptoCell to authenticate BL33 which is loaded
+ * into the Non Secure DDR.
+ */
+#define ARM_TZC_NS_DRAM_S_ACCESS TZC_REGION_S_RD
+#else
+#define ARM_TZC_NS_DRAM_S_ACCESS TZC_REGION_S_NONE
+#endif
+
#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE
#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index aee045dee8..e59a64b42b 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -314,7 +314,7 @@ else
$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
endif
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \
- --script $(LINKERFILE) $(BUILD_DIR)/build_message.o $(OBJS)
+ --script $(LINKERFILE) $(BUILD_DIR)/build_message.o $(OBJS) $(LDLIBS)
$(DUMP): $(ELF)
@echo " OD $$@"
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index 5df1cc014f..5d36d1780e 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -6,15 +6,12 @@
#include <arm_def.h>
#include <assert.h>
+#include <cassert.h>
#include <platform.h>
#include <stdint.h>
#include <string.h>
#include <tbbr_oid.h>
-/* Weak definition may be overridden in specific platform */
-#pragma weak plat_get_nv_ctr
-#pragma weak plat_set_nv_ctr
-
/* SHA256 algorithm */
#define SHA256_BYTES 32
@@ -22,16 +19,22 @@
#define ARM_ROTPK_REGS_ID 1
#define ARM_ROTPK_DEVEL_RSA_ID 2
-#if !ARM_ROTPK_LOCATION_ID
- #error "ARM_ROTPK_LOCATION_ID not defined"
-#endif
-
static const unsigned char rotpk_hash_hdr[] = \
"\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \
"\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
+/* Use the cryptocell variants if Cryptocell is present */
+#if !ARM_CRYPTOCELL_INTEG
+#if !ARM_ROTPK_LOCATION_ID
+ #error "ARM_ROTPK_LOCATION_ID not defined"
+#endif
+
+/* Weak definition may be overridden in specific platform */
+#pragma weak plat_get_nv_ctr
+#pragma weak plat_set_nv_ctr
+
#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
static const unsigned char arm_devel_rotpk_hash[] = \
"\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \
@@ -166,3 +169,116 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 1;
}
+#else /* ARM_CRYPTOCELL_INTEG */
+
+#include <nvm.h>
+#include <nvm_otp.h>
+#include <sbrom_bsv_api.h>
+
+CASSERT(HASH_RESULT_SIZE_IN_BYTES == SHA256_BYTES,
+ assert_mismatch_in_hash_result_size);
+
+/*
+ * Return the ROTPK hash in the following ASN.1 structure in DER format:
+ *
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL
+ * }
+ *
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm AlgorithmIdentifier,
+ * digest OCTET STRING
+ * }
+ */
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ unsigned char *dst;
+ CCError_t error;
+ uint32_t lcs;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ error = NVM_GetLCS(PLAT_CRYPTOCELL_BASE, &lcs);
+ if (error != CC_OK)
+ return 1;
+
+ /* If the lifecycle state is `SD`, return failure */
+ if (lcs == CC_BSV_SECURITY_DISABLED_LCS)
+ return 1;
+
+ /*
+ * If the lifecycle state is `CM` or `DM`, ROTPK shouldn't be verified.
+ * Return success after setting ROTPK_NOT_DEPLOYED flag
+ */
+ if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) ||
+ (lcs == CC_BSV_DEVICE_MANUFACTURE_LCS)) {
+ *key_len = 0;
+ *flags = ROTPK_NOT_DEPLOYED;
+ return 0;
+ }
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
+ dst = &rotpk_hash_der[rotpk_hash_hdr_len];
+ error = NVM_ReadHASHPubKey(PLAT_CRYPTOCELL_BASE,
+ CC_SB_HASH_BOOT_KEY_256B,
+ (uint32_t *)dst, HASH_RESULT_SIZE_IN_WORDS);
+ if (error != CC_OK)
+ return 1;
+
+ *key_ptr = rotpk_hash_der;
+ *key_len = sizeof(rotpk_hash_der);
+ *flags = ROTPK_IS_HASH;
+ return 0;
+}
+
+/*
+ * Return the non-volatile counter value stored in the platform. The cookie
+ * specifies the OID of the counter in the certificate.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ CCError_t error = CC_FAIL;
+
+ if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
+ CC_SW_VERSION_COUNTER1, nv_ctr);
+ } else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
+ CC_SW_VERSION_COUNTER2, nv_ctr);
+ }
+
+ return (error != CC_OK);
+}
+
+/*
+ * Store a new non-volatile counter value in the counter specified by the OID
+ * in the cookie. This function is not expected to be called if the Lifecycle
+ * state is RMA as the values in the certificate are expected to always match
+ * the nvcounter values. But if called when the LCS is RMA, the underlying
+ * helper functions will return success but without updating the counter.
+ *
+ * Return: 0 = success, Otherwise = error
+ */
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ CCError_t error = CC_FAIL;
+
+ if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
+ CC_SW_VERSION_COUNTER1, nv_ctr);
+ } else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
+ error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
+ CC_SW_VERSION_COUNTER2, nv_ctr);
+ }
+
+ return (error != CC_OK);
+}
+
+#endif /* ARM_CRYPTOCELL_INTEG */
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 84729b6e6d..46672982c3 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -17,6 +17,7 @@ BL2_SOURCES += plat/arm/board/common/drivers/norflash/norflash.c
#BL31_SOURCES +=
ifneq (${TRUSTED_BOARD_BOOT},0)
+ ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
# ROTPK hash location
ifeq (${ARM_ROTPK_LOCATION}, regs)
ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
@@ -31,7 +32,12 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
# ARM development platforms
TFW_NVCTR_VAL ?= 31
NTFW_NVCTR_VAL ?= 223
-
+ else
+ # Certificate NV-Counters when CryptoCell is integrated. For development
+ # platforms we set the counter to first valid value.
+ TFW_NVCTR_VAL ?= 0
+ NTFW_NVCTR_VAL ?= 0
+ endif
BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
endif
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 68c38ee1c2..ea128b6e56 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -26,6 +26,9 @@
#define PLATFORM_CORE_COUNT (JUNO_CLUSTER0_CORE_COUNT + \
JUNO_CLUSTER1_CORE_COUNT)
+/* Cryptocell HW Base address */
+#define PLAT_CRYPTOCELL_BASE 0x60050000
+
/*
* Other platform porting definitions are provided by included headers
*/
diff --git a/plat/arm/common/aarch64/arm_helpers.S b/plat/arm/common/aarch64/arm_helpers.S
index 86565f5745..b53e60dba1 100644
--- a/plat/arm/common/aarch64/arm_helpers.S
+++ b/plat/arm/common/aarch64/arm_helpers.S
@@ -115,3 +115,51 @@ func arm_disable_spe
ret
endfunc arm_disable_spe
#endif
+
+/*
+ * Need to use coherent stack when ARM Cryptocell is used to autheticate images
+ * since Cryptocell uses DMA to transfer data and it is not coherent with the
+ * AP CPU.
+ */
+#if ARM_CRYPTOCELL_INTEG
+#if defined(IMAGE_BL1) || defined(IMAGE_BL2)
+ .globl plat_get_my_stack
+ .globl plat_set_my_stack
+ .local platform_coherent_stacks
+
+ /* -------------------------------------------------------
+ * uintptr_t plat_get_my_stack ()
+ *
+ * For cold-boot BL images, only the primary CPU needs a
+ * stack. This function returns the stack pointer for a
+ * stack allocated in coherent memory.
+ * -------------------------------------------------------
+ */
+func plat_get_my_stack
+ get_up_stack platform_coherent_stacks, PLATFORM_STACK_SIZE
+ ret
+endfunc plat_get_my_stack
+
+ /* -------------------------------------------------------
+ * void plat_set_my_stack ()
+ *
+ * For cold-boot BL images, only the primary CPU needs a
+ * stack. This function sets the stack pointer to a stack
+ * allocated in coherent memory.
+ * -------------------------------------------------------
+ */
+func plat_set_my_stack
+ get_up_stack platform_coherent_stacks, PLATFORM_STACK_SIZE
+ mov sp, x0
+ ret
+endfunc plat_set_my_stack
+
+ /* ----------------------------------------------------
+ * Single cpu stack in coherent memory.
+ * ----------------------------------------------------
+ */
+declare_stack platform_coherent_stacks, tzfw_coherent_mem, \
+ PLATFORM_STACK_SIZE, 1, CACHE_WRITEBACK_GRANULE
+
+#endif /* defined(IMAGE_BL1) || defined(IMAGE_BL2) */
+#endif /* ARM_CRYPTOCELL_INTEG */
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 5cc1a0ac72..e0b7af4097 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -94,6 +94,11 @@ LOAD_IMAGE_V2 := 1
# Use generic OID definition (tbbr_oid.h)
USE_TBBR_DEFS := 1
+# Disable ARM Cryptocell by default
+ARM_CRYPTOCELL_INTEG := 0
+$(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG))
+$(eval $(call add_define,ARM_CRYPTOCELL_INTEG))
+
PLAT_INCLUDES += -Iinclude/common/tbbr \
-Iinclude/plat/arm/common
@@ -181,7 +186,11 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
TF_MBEDTLS_KEY_ALG := ${KEY_ALG}
# We expect to locate the *.mk files under the directories specified below
+ifeq (${ARM_CRYPTOCELL_INTEG},0)
CRYPTO_LIB_MK := drivers/auth/mbedtls/mbedtls_crypto.mk
+else
+ CRYPTO_LIB_MK := drivers/auth/cryptocell/cryptocell_crypto.mk
+endif
IMG_PARSER_LIB_MK := drivers/auth/mbedtls/mbedtls_x509.mk
$(info Including ${CRYPTO_LIB_MK})
diff --git a/plat/arm/common/arm_tzc400.c b/plat/arm/common/arm_tzc400.c
index c09814e079..1d61c576fb 100644
--- a/plat/arm/common/arm_tzc400.c
+++ b/plat/arm/common/arm_tzc400.c
@@ -34,6 +34,7 @@ void arm_tzc400_setup(void)
tzc400_disable_filters();
#ifndef EL3_PAYLOAD_BASE
+
/* Region 0 set to no access by default */
tzc400_configure_region0(TZC_REGION_S_NONE, 0);
@@ -47,13 +48,13 @@ void arm_tzc400_setup(void)
* Apply the same configuration to given filters in the TZC. */
tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 2,
ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_END,
- TZC_REGION_S_NONE,
+ ARM_TZC_NS_DRAM_S_ACCESS,
PLAT_ARM_TZC_NS_DEV_ACCESS);
/* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
tzc400_configure_region(PLAT_ARM_TZC_FILTERS, 3,
ARM_DRAM2_BASE, ARM_DRAM2_END,
- TZC_REGION_S_NONE,
+ ARM_TZC_NS_DRAM_S_ACCESS,
PLAT_ARM_TZC_NS_DEV_ACCESS);
#else
/* Allow secure access only to DRAM for EL3 payloads. */
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index f6dc95bb0b..21ca4e8d54 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -41,14 +41,14 @@ void arm_tzc_dmc500_setup(tzc_dmc500_driver_data_t *plat_driver_data)
tzc_dmc500_configure_region(2,
ARM_NS_DRAM1_BASE,
ARM_NS_DRAM1_END,
- TZC_REGION_S_NONE,
+ ARM_TZC_NS_DRAM_S_ACCESS,
PLAT_ARM_TZC_NS_DEV_ACCESS);
/* Region 3 set to cover Non-Secure access to 2nd DRAM address range */
tzc_dmc500_configure_region(3,
ARM_DRAM2_BASE,
ARM_DRAM2_END,
- TZC_REGION_S_NONE,
+ ARM_TZC_NS_DRAM_S_ACCESS,
PLAT_ARM_TZC_NS_DEV_ACCESS);
#else
/* Allow secure access only to DRAM for EL3 payloads */