diff --git a/Makefile b/Makefile index e6abc182f..4a1e17dc7 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,8 @@ ASM_ASSERTION := ${DEBUG} USE_COHERENT_MEM := 1 # Default FIP file name FIP_NAME := fip.bin +# By default, use the -pedantic option in the gcc command line +DISABLE_PEDANTIC := 0 # Flags to generate the Chain of Trust GENERATE_COT := 0 CREATE_KEYS := 1 @@ -253,7 +255,7 @@ ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \ -Werror -Wmissing-include-dirs \ -mgeneral-regs-only -D__ASSEMBLY__ \ ${DEFINES} ${INCLUDES} -CFLAGS += -nostdinc -pedantic -ffreestanding -Wall \ +CFLAGS += -nostdinc -ffreestanding -Wall \ -Werror -Wmissing-include-dirs \ -mgeneral-regs-only -std=c99 -c -Os \ ${DEFINES} ${INCLUDES} @@ -304,6 +306,11 @@ ifneq (${GENERATE_COT},0) $(eval CRT_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT}) endif +# Check if -pedantic option should be used +ifeq (${DISABLE_PEDANTIC},0) + CFLAGS += -pedantic +endif + locate-checkpatch: ifndef CHECKPATCH $(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/script/checkpatch.pl") diff --git a/common/auth/polarssl/polarssl.c b/common/auth/polarssl/polarssl.c new file mode 100644 index 000000000..e099f50cd --- /dev/null +++ b/common/auth/polarssl/polarssl.c @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Authentication module based on PolarSSL */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * At each authentication stage, the module is responsible for extracting and + * storing those elements (keys, hashes, etc.) that will be needed later on + * during the Trusted Boot process. + */ + +/* SHA256 algorithm */ +#define SHA_BYTES 32 + +/* + * An 8 KB stack has been proven to be enough for the current Trusted Boot + * process + */ +#define POLARSSL_HEAP_SIZE (8*1024) +static unsigned char heap[POLARSSL_HEAP_SIZE]; + +/* + * RSA public keys: + * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 + * algorithm AlgorithmIdentifier, 1 + 1 (sequence) + * + 1 + 1 + 9 (rsa oid) + * + 1 + 1 (params null) + * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) + * RSAPublicKey ::= SEQUENCE { 1 + 3 + * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 + * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 + * } + * + * POLARSSL_MPI_MAX_SIZE is set to 256 bytes (RSA-2048 bit keys) in the + * configuration file + */ +#define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE + +/* + * Buffer for storing public keys extracted from certificates while they are + * verified + */ +static unsigned char pk_buf[RSA_PUB_DER_MAX_BYTES]; + +/* We use this variable to parse and authenticate the certificates */ +static x509_crt cert; + +/* BL specific variables */ +#if IMAGE_BL1 +static unsigned char sha_bl2[SHA_BYTES]; +#elif IMAGE_BL2 +/* Buffers to store the hash of BL3-x images */ +static unsigned char sha_bl30[SHA_BYTES]; +static unsigned char sha_bl31[SHA_BYTES]; +static unsigned char sha_bl32[SHA_BYTES]; +static unsigned char sha_bl33[SHA_BYTES]; +/* Buffers to store the Trusted and Non-Trusted world public keys */ +static unsigned char tz_world_pk[RSA_PUB_DER_MAX_BYTES]; +static unsigned char ntz_world_pk[RSA_PUB_DER_MAX_BYTES]; +static size_t tz_world_pk_len, ntz_world_pk_len; +/* Buffer to store the BL3-x public keys */ +static unsigned char content_pk[RSA_PUB_DER_MAX_BYTES]; +static size_t content_pk_len; +#endif + + +static int x509_get_crt_ext_data(const unsigned char **ext_data, + size_t *ext_len, + x509_crt *crt, + const char *oid) +{ + int ret; + size_t len; + unsigned char *end_ext_data, *end_ext_octet; + unsigned char *p; + const unsigned char *end; + char oid_str[64]; + + p = crt->v3_ext.p; + end = crt->v3_ext.p + crt->v3_ext.len; + + ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + if (end != p + len) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + while (p < end) { + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + x509_buf extn_oid = {0, 0, NULL}; + int is_critical = 0; /* DEFAULT FALSE */ + + ret = asn1_get_tag(&p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + end_ext_data = p + len; + + /* Get extension ID */ + extn_oid.tag = *p; + + ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + extn_oid.p = p; + p += extn_oid.len; + + if ((end - p) < 1) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_OUT_OF_DATA; + + /* Get optional critical */ + ret = asn1_get_bool(&p, end_ext_data, &is_critical); + if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG)) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + /* Data should be octet string type */ + ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + end_ext_octet = p + len; + + if (end_ext_octet != end_ext_data) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + /* Detect requested extension */ + oid_get_numeric_string(oid_str, 64, &extn_oid); + if (memcmp(oid, oid_str, sizeof(oid)) == 0) { + *ext_data = p; + *ext_len = len; + return 0; + } + + /* Next */ + p = end_ext_octet; + } + + if (p != end) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + return POLARSSL_ERR_X509_UNKNOWN_OID; +} + +#if IMAGE_BL1 +/* + * Parse and verify the BL2 certificate + * + * This function verifies the integrity of the BL2 certificate, checks that it + * has been signed with the ROT key and extracts the BL2 hash stored in the + * certificate so it can be matched later against the calculated hash. + * + * Return: 0 = success, Otherwise = error + */ +static int check_bl2_cert(unsigned char *buf, size_t len) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse the BL2 certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("BL2 certificate parse error %d.\n", err); + goto error; + } + + /* Check that it has been signed with the ROT key */ + err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + if (err < 0) { + ERROR("Error loading ROT key in DER format %d.\n", err); + goto error; + } + + sz = (size_t)err; + p = pk_buf + sizeof(pk_buf) - sz; + + err = plat_match_rotpk(p, sz); + if (err) { + ERROR("ROT and BL2 certificate key mismatch\n"); + goto error; + } + + /* Verify certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("BL2 certificate verification error %d. Flags: 0x%x.\n", + err, flags); + goto error; + } + + /* Extract BL2 image hash from certificate */ + err = x509_get_crt_ext_data(&p, &sz, &cert, BL2_HASH_OID); + if (err) { + ERROR("Cannot read BL2 hash from certificate\n"); + goto error; + } + + assert(sz == SHA_BYTES + 2); + + /* Skip the tag and length bytes and copy the hash */ + p += 2; + memcpy(sha_bl2, p, SHA_BYTES); + +error: + x509_crt_free(&cert); + + return err; +} +#endif /* IMAGE_BL1 */ + +#if IMAGE_BL2 +static int check_trusted_key_cert(unsigned char *buf, size_t len) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse the Trusted Key certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("Trusted Key certificate parse error %d.\n", err); + goto error; + } + + /* Verify Trusted Key certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("Trusted Key certificate verification error %d. Flags: " + "0x%x.\n", err, flags); + goto error; + } + + /* Check that it has been signed with the ROT key */ + err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + if (err < 0) { + ERROR("Error loading ROT key in DER format %d.\n", err); + goto error; + } + + sz = (size_t)err; + p = pk_buf + sizeof(pk_buf) - sz; + + if (plat_match_rotpk(p, sz)) { + ERROR("ROT and Trusted Key certificate key mismatch\n"); + goto error; + } + + /* Extract Trusted World key from extensions */ + err = x509_get_crt_ext_data(&p, &tz_world_pk_len, + &cert, TZ_WORLD_PK_OID); + if (err) { + ERROR("Cannot read Trusted World key\n"); + goto error; + } + + assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES); + memcpy(tz_world_pk, p, tz_world_pk_len); + + /* Extract Non-Trusted World key from extensions */ + err = x509_get_crt_ext_data(&p, &ntz_world_pk_len, + &cert, NTZ_WORLD_PK_OID); + if (err) { + ERROR("Cannot read Non-Trusted World key\n"); + goto error; + } + + assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES); + memcpy(ntz_world_pk, p, ntz_world_pk_len); + +error: + x509_crt_free(&cert); + + return err; +} + +static int check_bl3x_key_cert(const unsigned char *buf, size_t len, + const unsigned char *i_key, size_t i_key_len, + unsigned char *s_key, size_t *s_key_len, + const char *key_oid) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse key certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("Key certificate parse error %d.\n", err); + goto error; + } + + /* Verify certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("Key certificate verification error %d. Flags: " + "0x%x.\n", err, flags); + goto error; + } + + /* Check that the certificate has been signed by the issuer */ + err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + if (err < 0) { + ERROR("Error loading key in DER format %d.\n", err); + goto error; + } + + sz = (size_t)err; + p = pk_buf + sizeof(pk_buf) - sz; + if ((sz != i_key_len) || memcmp(p, i_key, sz)) { + ERROR("Key certificate not signed with issuer key\n"); + err = 1; + goto error; + } + + /* Get the content certificate key */ + err = x509_get_crt_ext_data(&p, &sz, &cert, key_oid); + if (err) { + ERROR("Extension %s not found in Key certificate\n", key_oid); + goto error; + } + + assert(sz <= RSA_PUB_DER_MAX_BYTES); + memcpy(s_key, p, sz); + *s_key_len = sz; + +error: + x509_crt_free(&cert); + + return err; +} + +static int check_bl3x_cert(unsigned char *buf, size_t len, + const unsigned char *i_key, size_t i_key_len, + const char *hash_oid, unsigned char *sha) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse BL31 content certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("Content certificate parse error %d.\n", err); + goto error; + } + + /* Verify certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("Content certificate verification error %d. Flags: " + "0x%x.\n", err, flags); + goto error; + } + + /* Check that content certificate has been signed with the content + * certificate key corresponding to this image */ + sz = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + p = pk_buf + sizeof(pk_buf) - sz; + + if ((sz != i_key_len) || memcmp(p, i_key, sz)) { + ERROR("Content certificate not signed with content " + "certificate key\n"); + err = 1; + goto error; + } + + /* Extract image hash from certificate */ + err = x509_get_crt_ext_data(&p, &sz, &cert, hash_oid); + if (err) { + ERROR("Cannot read hash from certificate\n"); + goto error; + } + + assert(sz == SHA_BYTES + 2); + + /* Skip the tag and length bytes and copy the hash */ + p += 2; + memcpy(sha, p, SHA_BYTES); + +error: + x509_crt_free(&cert); + + return err; +} +#endif /* IMAGE_BL2 */ + +/* + * Calculate the hash of the image and check it against the hash extracted + * previously from the certificate + * + * Parameters: + * buf: buffer where image is loaded + * len: size of the image + * sha: matching hash (extracted from the image certificate) + * + * Return: 0 = match, Otherwise = mismatch + */ +static int check_bl_img(unsigned char *buf, size_t len, + const unsigned char *sha) +{ + unsigned char img_sha[SHA_BYTES]; + + /* Calculate the hash of the image */ + sha256(buf, len, img_sha, 0); + + /* Match the hash with the one extracted from the certificate */ + if (memcmp(img_sha, sha, SHA_BYTES)) { + ERROR("Image hash mismatch\n"); + return 1; + } + + return 0; +} + +/* + * Object verification function + * + * The id parameter will indicate the expected format of the object + * (certificate, image, etc). + * + * Return: 0 = success, Otherwise = error + */ +static int polarssl_mod_verify(unsigned int id, uintptr_t obj, size_t len) +{ + int ret; + + switch (id) { +#if IMAGE_BL1 + case AUTH_BL2_IMG_CERT: + ret = check_bl2_cert((unsigned char *)obj, len); + break; + case AUTH_BL2_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl2); + break; +#endif /* IMAGE_BL1 */ + +#if IMAGE_BL2 + case AUTH_TRUSTED_KEY_CERT: + ret = check_trusted_key_cert((unsigned char *)obj, len); + break; + case AUTH_BL30_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + tz_world_pk, tz_world_pk_len, + content_pk, &content_pk_len, + BL30_CONTENT_CERT_PK_OID); + break; + case AUTH_BL31_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + tz_world_pk, tz_world_pk_len, + content_pk, &content_pk_len, + BL31_CONTENT_CERT_PK_OID); + break; + case AUTH_BL32_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + tz_world_pk, tz_world_pk_len, + content_pk, &content_pk_len, + BL32_CONTENT_CERT_PK_OID); + break; + case AUTH_BL33_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + ntz_world_pk, ntz_world_pk_len, + content_pk, &content_pk_len, + BL33_CONTENT_CERT_PK_OID); + break; + case AUTH_BL30_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL30_HASH_OID, sha_bl30); + break; + case AUTH_BL31_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL31_HASH_OID, sha_bl31); + break; + case AUTH_BL32_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL32_HASH_OID, sha_bl32); + break; + case AUTH_BL33_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL33_HASH_OID, sha_bl33); + break; + case AUTH_BL30_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl30); + break; + case AUTH_BL31_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl31); + break; + case AUTH_BL32_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl32); + break; + case AUTH_BL33_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl33); + break; +#endif /* IMAGE_BL2 */ + default: + ret = -1; + break; + } + + return ret; +} + +/* + * Module initialization function + * + * Return: 0 = success, Otherwise = error + */ +static int polarssl_mod_init(void) +{ + /* Initialize the PolarSSL heap */ + return memory_buffer_alloc_init(heap, POLARSSL_HEAP_SIZE); +} + +const auth_mod_t auth_mod = { + .name = "PolarSSL", + .init = polarssl_mod_init, + .verify = polarssl_mod_verify +}; diff --git a/common/auth/polarssl/polarssl.mk b/common/auth/polarssl/polarssl.mk new file mode 100644 index 000000000..f7d92ea8d --- /dev/null +++ b/common/auth/polarssl/polarssl.mk @@ -0,0 +1,69 @@ +# +# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# POLARSSL_DIR must be set to the PolarSSL main directory (it must contain +# the 'include' and 'library' subdirectories). +ifeq (${POLARSSL_DIR},) + $(error Error: POLARSSL_DIR not set) +endif + +INCLUDES += -I${POLARSSL_DIR}/include \ + -Icommon/auth/polarssl + +POLARSSL_CONFIG_FILE := "" +$(eval $(call add_define,POLARSSL_CONFIG_FILE)) + +POLARSSL_SOURCES := $(addprefix ${POLARSSL_DIR}/library/, \ + asn1parse.c \ + asn1write.c \ + bignum.c \ + md.c \ + md_wrap.c \ + memory_buffer_alloc.c \ + oid.c \ + pk.c \ + pk_wrap.c \ + pkparse.c \ + pkwrite.c \ + platform.c \ + rsa.c \ + sha1.c \ + sha256.c \ + x509.c \ + x509_crt.c \ + ) + +BL1_SOURCES += ${POLARSSL_SOURCES} \ + common/auth/polarssl/polarssl.c + +BL2_SOURCES += ${POLARSSL_SOURCES} \ + common/auth/polarssl/polarssl.c + +DISABLE_PEDANTIC := 1 diff --git a/common/auth/polarssl/polarssl_config.h b/common/auth/polarssl/polarssl_config.h new file mode 100644 index 000000000..531e08453 --- /dev/null +++ b/common/auth/polarssl/polarssl_config.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __POLARSSL_CONFIG_H__ +#define __POLARSSL_CONFIG_H__ + + +/* + * Configuration file to build PolarSSL with the required features for + * Trusted Boot + */ + +#define POLARSSL_PLATFORM_MEMORY +#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS + +#define POLARSSL_PKCS1_V15 +#define POLARSSL_PKCS1_V21 + +#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION +#define POLARSSL_X509_CHECK_KEY_USAGE +#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE + +#define POLARSSL_ASN1_PARSE_C +#define POLARSSL_ASN1_WRITE_C + +#define POLARSSL_BASE64_C +#define POLARSSL_BIGNUM_C + +#define POLARSSL_ERROR_C +#define POLARSSL_MD_C + +#define POLARSSL_MEMORY_BUFFER_ALLOC_C +#define POLARSSL_OID_C + +#define POLARSSL_PK_C +#define POLARSSL_PK_PARSE_C +#define POLARSSL_PK_WRITE_C + +#define POLARSSL_PLATFORM_C + +#define POLARSSL_RSA_C +#define POLARSSL_SHA1_C +#define POLARSSL_SHA256_C + +#define POLARSSL_VERSION_C + +#define POLARSSL_X509_USE_C +#define POLARSSL_X509_CRT_PARSE_C + +/* MPI / BIGNUM options */ +#define POLARSSL_MPI_WINDOW_SIZE 2 +#define POLARSSL_MPI_MAX_SIZE 256 + +/* Memory buffer allocator options */ +#define POLARSSL_MEMORY_ALIGN_MULTIPLE 8 + +#include "polarssl/check_config.h" + +#endif /* __POLARSSL_CONFIG_H__ */ diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index b0460e08f..bd53bc7b7 100644 --- a/plat/fvp/include/platform_def.h +++ b/plat/fvp/include/platform_def.h @@ -49,9 +49,17 @@ #if DEBUG_XLAT_TABLE #define PLATFORM_STACK_SIZE 0x800 #elif IMAGE_BL1 +#if TRUSTED_BOARD_BOOT +#define PLATFORM_STACK_SIZE 0x1000 +#else #define PLATFORM_STACK_SIZE 0x440 +#endif #elif IMAGE_BL2 +#if TRUSTED_BOARD_BOOT +#define PLATFORM_STACK_SIZE 0x1000 +#else #define PLATFORM_STACK_SIZE 0x400 +#endif #elif IMAGE_BL31 #define PLATFORM_STACK_SIZE 0x400 #elif IMAGE_BL32 @@ -96,8 +104,13 @@ * Put BL1 RW at the top of the Trusted SRAM. BL1_RW_BASE is calculated using * the current BL1 RW debug size plus a little space for growth. */ +#if TRUSTED_BOARD_BOOT +#define BL1_RW_BASE (FVP_TRUSTED_SRAM_BASE \ + + FVP_TRUSTED_SRAM_SIZE - 0x8000) +#else #define BL1_RW_BASE (FVP_TRUSTED_SRAM_BASE \ + FVP_TRUSTED_SRAM_SIZE - 0x6000) +#endif #define BL1_RW_LIMIT (FVP_TRUSTED_SRAM_BASE \ + FVP_TRUSTED_SRAM_SIZE) @@ -108,7 +121,11 @@ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug * size plus a little space for growth. */ +#if TRUSTED_BOARD_BOOT +#define BL2_BASE (BL31_BASE - 0x1C000) +#else #define BL2_BASE (BL31_BASE - 0xC000) +#endif #define BL2_LIMIT BL31_BASE /******************************************************************************* diff --git a/plat/juno/include/platform_def.h b/plat/juno/include/platform_def.h index cd077021e..c64b68297 100644 --- a/plat/juno/include/platform_def.h +++ b/plat/juno/include/platform_def.h @@ -45,7 +45,11 @@ ******************************************************************************/ /* Size of cacheable stacks */ -#define PLATFORM_STACK_SIZE 0x800 +#if TRUSTED_BOARD_BOOT && (IMAGE_BL1 || IMAGE_BL2) +#define PLATFORM_STACK_SIZE 0x1000 +#else +#define PLATFORM_STACK_SIZE 0x800 +#endif #define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" @@ -87,7 +91,11 @@ * Put BL1 RW at the top of the Trusted SRAM. BL1_RW_BASE is calculated using * the current BL1 RW debug size plus a little space for growth. */ +#if TRUSTED_BOARD_BOOT +#define BL1_RW_BASE (TZRAM_BASE + TZRAM_SIZE - 0x8000) +#else #define BL1_RW_BASE (TZRAM_BASE + TZRAM_SIZE - 0x6000) +#endif #define BL1_RW_LIMIT (TZRAM_BASE + TZRAM_SIZE) /******************************************************************************* @@ -97,7 +105,11 @@ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug * size plus a little space for growth. */ +#if TRUSTED_BOARD_BOOT +#define BL2_BASE (BL31_BASE - 0x1D000) +#else #define BL2_BASE (BL31_BASE - 0xC000) +#endif #define BL2_LIMIT BL31_BASE /******************************************************************************* diff --git a/plat/juno/juno_def.h b/plat/juno/juno_def.h index 8e1a83df8..8a85aecde 100644 --- a/plat/juno/juno_def.h +++ b/plat/juno/juno_def.h @@ -47,7 +47,13 @@ /* Use the bypass address */ #define TZROM_BASE FLASH_BASE + BL1_ROM_BYPASS_OFFSET #endif +/* Actual ROM size on Juno is 64 KB, but TBB requires at least 80 KB in debug + * mode. We can test TBB on Juno bypassing the ROM and using 128 KB of flash */ +#if TRUSTED_BOARD_BOOT +#define TZROM_SIZE 0x00020000 +#else #define TZROM_SIZE 0x00010000 +#endif #define TZRAM_BASE 0x04001000 #define TZRAM_SIZE 0x0003F000