Merge pull request #1007 from soby-mathew/sm/ccint

Enable integration of ARM TrustZone Cryptocell for TBB
This commit is contained in:
danh-arm 2017-06-28 16:29:55 +01:00 committed by GitHub
commit aa5b843fe8
26 changed files with 1171 additions and 14 deletions

View File

@ -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:

View File

@ -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].

View File

@ -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);

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 - \

View File

@ -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 $$@"

View File

@ -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 */

View File

@ -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

View File

@ -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
*/

View File

@ -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 */

View File

@ -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})

View File

@ -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. */

View File

@ -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 */