diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index c7b9e89c8859eb5776c52574ef0a7be07391a7d4..047e225008b2e8e6a43bf9c86548f45968a5ecc7 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 29691c5be9601f9f729ae508cb22ec6c22455d0f..ea2874d8fc5e8dc6d72386b652b3d5f34b91a633 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 0000000000000000000000000000000000000000..05462bea12347022d2a3b89e0b221f8f12765df3
--- /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 0000000000000000000000000000000000000000..a88dcfc5798af9004ac3a211ae6240ed93d224da
--- /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 0000000000000000000000000000000000000000..2cb8938d2b149e70385b28e92e2e1283ab9f4c9f
--- /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 0000000000000000000000000000000000000000..212a710be032a8e61695e92d819ebb1aceb019b3
--- /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 0000000000000000000000000000000000000000..8c09b23cc7e2f9fa21913bea32b59be87c045b3c
--- /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 0000000000000000000000000000000000000000..d8ed3e1d31858a078b55888bb25e49c0f6e70879
--- /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 0000000000000000000000000000000000000000..d41921855bc50955c73c9502df15bac7282a704e
--- /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 0000000000000000000000000000000000000000..18104dd7d43b7a41b654926079de922857ff50f8
--- /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 0000000000000000000000000000000000000000..f806d3d42bb424b8082636c0356ec929df342aa8
--- /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 0000000000000000000000000000000000000000..390d62bc1d9de27f1774ba57c877816041b34132
--- /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 0000000000000000000000000000000000000000..cd9925b3250769ef6ccaef657098d7020c470618
--- /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 0000000000000000000000000000000000000000..de835461fd54aba56a402a790856d5b106febe67
--- /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 0000000000000000000000000000000000000000..6db596e0d78519eb954df9e95b8042c0e06d9511
--- /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 0000000000000000000000000000000000000000..68b9ef8aecc53c2607c7cc4d36f10a0e5d519283
--- /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 0000000000000000000000000000000000000000..18fb5999dcd46010b24bae3a9ce6369ea19c4815
--- /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 ea309547611bfef7831ad7c7b8f5df898db44cd3..5dae30ec72f12914528e72fa900c029bca22cee2 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 aee045dee8d2bbee396202c83e6c178c75048999..e59a64b42bdcd0ecfe2639ddfae632a475872d23 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 5df1cc014f293d80a9eceb664eb86812835888ac..5d36d1780ef1f7a020ba81d56a655d5e82feeabe 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 84729b6e6dd5162f6c9205b9e1f6eabd78ab91ef..46672982c3f3dd65679ae78f12e6529ff03f7961 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 68c38ee1c2865dd59e9fd0b70ee83b427675d1bb..ea128b6e569592b146fa4d12ee5adf4747b54b3c 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 86565f5745fbc3d9b11c0587698c07cbaac46dc5..b53e60dba151d6c2c62ee9f9b184f50a86ad1183 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 5cc1a0ac721d3ccdc456863c87623f25dcb0a422..e0b7af409752f608d96351533f4d62ea90499fb7 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 c09814e079da121179233657324d8a9ead6b61df..1d61c576fbc24136ee2a7257f02463d1ac4a7c42 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 f6dc95bb0b9017abb202ea10a88fccd678ad0998..21ca4e8d54dec103a84d7f1e5023387217aa8cd0 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 */