From c5fb47c389000c7a5189c0ad28a26bf50bf7e65c Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Mon, 19 Jan 2015 16:51:21 +0000 Subject: [PATCH 01/10] Skip reserving memory for non-executable and BL3-0 images This patch adds support to not reserve the memory where an image is loaded if the image is: 1. A non-executable image e.g. a certificate 2. An executable image which is not meant to run on the application CPU (e.g. BL3-0) Both types of images are characterized by a NULL entrypoint argument to the load_image() function. It is used to distinguish them from other type of images. Important: Use this feature carefully. The caller is responsible for providing a valid entrypoint while loading images which will execute on the application CPU to prevent a potential overwrite of the corresponding memory region. Change-Id: Ied482280d9db714c529ec12c33a6c1d918d77a4e --- common/bl_common.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common/bl_common.c b/common/bl_common.c index 60f8b2f7d..8c241ec48 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -275,9 +275,16 @@ int load_image(meminfo_t *mem_layout, * Update the memory usage info. * This is done after the actual loading so that it is not updated when * the load is unsuccessful. + * If the caller does not provide an entry point, bypass the memory + * reservation. */ - reserve_mem(&mem_layout->free_base, &mem_layout->free_size, - image_base, image_size); + if (entry_point_info != NULL) { + reserve_mem(&mem_layout->free_base, &mem_layout->free_size, + image_base, image_size); + } else { + INFO("Skip reserving memory: 0x%lx - 0x%lx\n", + image_base, image_base + image_size); + } image_data->image_base = image_base; image_data->image_size = image_size; From 6f97162237603eb6e5c497e5ba903512bdd428a9 Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Tue, 21 Oct 2014 11:30:42 +0100 Subject: [PATCH 02/10] TBB: add tool to generate certificates This patch adds a tool that generates all the necessary elements to establish the chain of trust (CoT) between the images. The tool reads the binary images and signing keys and outputs the corresponding certificates that will be used by the target at run time to verify the authenticity of the images. Note: the platform port must provide the file platform_oid.h. This file will define the OIDs of the x509 extensions that will be added to the certificates in order to establish the CoT. Change-Id: I2734d6808b964a2107ab3a4805110698066a04be --- .gitignore | 2 + Makefile | 102 +++- plat/fvp/include/platform_oid.h | 69 +++ plat/juno/include/platform_oid.h | 69 +++ tools/cert_create/Makefile | 92 ++++ tools/cert_create/include/cert.h | 69 +++ tools/cert_create/include/debug.h | 83 ++++ tools/cert_create/include/ext.h | 70 +++ tools/cert_create/include/key.h | 57 +++ tools/cert_create/include/sha.h | 36 ++ tools/cert_create/include/tbb_cert.h | 58 +++ tools/cert_create/include/tbb_ext.h | 38 ++ tools/cert_create/include/tbb_key.h | 55 ++ tools/cert_create/src/cert.c | 180 +++++++ tools/cert_create/src/ext.c | 233 +++++++++ tools/cert_create/src/key.c | 131 +++++ tools/cert_create/src/main.c | 719 +++++++++++++++++++++++++++ tools/cert_create/src/sha.c | 64 +++ tools/cert_create/src/tbb_cert.c | 111 +++++ tools/cert_create/src/tbb_ext.c | 118 +++++ tools/cert_create/src/tbb_key.c | 67 +++ 21 files changed, 2412 insertions(+), 11 deletions(-) create mode 100644 plat/fvp/include/platform_oid.h create mode 100644 plat/juno/include/platform_oid.h create mode 100644 tools/cert_create/Makefile create mode 100644 tools/cert_create/include/cert.h create mode 100644 tools/cert_create/include/debug.h create mode 100644 tools/cert_create/include/ext.h create mode 100644 tools/cert_create/include/key.h create mode 100644 tools/cert_create/include/sha.h create mode 100644 tools/cert_create/include/tbb_cert.h create mode 100644 tools/cert_create/include/tbb_ext.h create mode 100644 tools/cert_create/include/tbb_key.h create mode 100644 tools/cert_create/src/cert.c create mode 100644 tools/cert_create/src/ext.c create mode 100644 tools/cert_create/src/key.c create mode 100644 tools/cert_create/src/main.c create mode 100644 tools/cert_create/src/sha.c create mode 100644 tools/cert_create/src/tbb_cert.c create mode 100644 tools/cert_create/src/tbb_ext.c create mode 100644 tools/cert_create/src/tbb_key.c diff --git a/.gitignore b/.gitignore index 422001885..d3567bcb1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ build/ # Ignore build products from tools tools/**/*.o tools/fip_create/fip_create +tools/cert_create/src/*.o +tools/cert_create/cert_create diff --git a/Makefile b/Makefile index c59cdb490..777e3308e 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,9 @@ ASM_ASSERTION := ${DEBUG} USE_COHERENT_MEM := 1 # Default FIP file name FIP_NAME := fip.bin +# Flags to generate the Chain of Trust +GENERATE_COT := 0 +CREATE_KEYS := 1 # Checkpatch ignores CHECK_IGNORE = --ignore COMPLEX_MACRO @@ -182,7 +185,7 @@ ifneq (${SPD},none) # fip, then the NEED_BL32 needs to be set and BL3-2 would need to point to the bin. endif -.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip +.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip certtool .SUFFIXES: INCLUDES += -Iinclude/bl31 \ @@ -236,6 +239,10 @@ $(eval $(call add_define,LOG_LEVEL)) $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call add_define,USE_COHERENT_MEM)) +# Process Generate CoT flags +$(eval $(call assert_boolean,GENERATE_COT)) +$(eval $(call assert_boolean,CREATE_KEYS)) + ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \ -Werror -Wmissing-include-dirs \ -mgeneral-regs-only -D__ASSEMBLY__ \ @@ -266,6 +273,28 @@ FIPTOOL ?= ${FIPTOOLPATH}/fip_create fiptool: ${FIPTOOL} fip: ${BUILD_PLAT}/${FIP_NAME} +# Variables for use with Certificate Generation Tool +CRTTOOLPATH ?= tools/cert_create +CRTTOOL ?= ${CRTTOOLPATH}/cert_create +certtool: ${CRTTOOL} + +# CoT generation tool default parameters +TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt + +# Pass the private keys to the CoT generation tool in the command line +# If CREATE_KEYS is set, the '-n' option will be added, indicating the tool to create new keys +ifneq (${GENERATE_COT},0) + $(eval CERTS := yes) + + ifneq (${CREATE_KEYS},0) + $(eval CRT_ARGS += -n) + endif + $(eval CRT_ARGS += $(if ${ROT_KEY}, --rot-key ${ROT_KEY})) + $(eval CRT_ARGS += $(if ${TRUSTED_WORLD_KEY}, --trusted-world-key ${TRUSTED_WORLD_KEY})) + $(eval CRT_ARGS += $(if ${NON_TRUSTED_WORLD_KEY}, --non-trusted-world-key ${NON_TRUSTED_WORLD_KEY})) + $(eval CRT_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT}) +endif + locate-checkpatch: ifndef CHECKPATCH $(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/script/checkpatch.pl") @@ -279,12 +308,14 @@ clean: @echo " CLEAN" ${Q}rm -rf ${BUILD_PLAT} ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean realclean distclean: @echo " REALCLEAN" ${Q}rm -rf ${BUILD_BASE} ${Q}rm -f ${CURDIR}/cscope.* ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean checkcodebase: locate-checkpatch @echo " CHECKING STYLE" @@ -298,6 +329,13 @@ checkpatch: locate-checkpatch @echo " CHECKING STYLE" @git format-patch --stdout ${BASE_COMMIT} | ${CHECKPATCH} ${CHECKPATCH_ARGS} - || true +.PHONY: ${CRTTOOL} +${CRTTOOL}: + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} + @echo + @echo "Built $@ successfully" + @echo + .PHONY: ${FIPTOOL} ${FIPTOOL}: ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} @@ -398,6 +436,37 @@ define SOURCES_TO_OBJS $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1)))) endef + +# MAKE_TOOL_ARGS macro defines the command line arguments for the FIP and CRT +# tools at each BL stage. Arguments: +# $(1) = BL stage (2, 30, 31, 32, 33) +# $(2) = Binary file +# $(3) = In FIP (false if empty) +# $(4) = Create certificates (false if empty) +# $(5) = Create key certificate (false if empty) +# $(6) = Private key (optional) +define MAKE_TOOL_ARGS + +$(eval FIP_DEPS += $(if $3,$(2),)) +$(eval FIP_ARGS += $(if $3,--bl$(1) $(2),)) + +$(eval CRT_DEPS += $(if $4,$(2),)) +$(eval CRT_DEPS += $(if $4,$(if $6,$(6),))) +$(eval CRT_ARGS += $(if $4,--bl$(1) $(2))) +$(eval CRT_ARGS += $(if $4,$(if $6,--bl$(1)-key $(6)))) +$(eval CRT_ARGS += $(if $4,--bl$(1)-cert $(BUILD_PLAT)/bl$(1).crt)) +$(eval CRT_ARGS += $(if $4,$(if $5,--bl$(1)-key-cert $(BUILD_PLAT)/bl$(1)_key.crt))) + +endef + + +# MAKE_BL macro defines the targets and options to build each BL image. +# Arguments: +# $(1) = BL stage (2, 30, 31, 32, 33) +# $(2) = In FIP (false if empty) +# $(3) = Create certificates (false if empty) +# $(4) = Create key certificate (false if empty) +# $(5) = Private key (optional) define MAKE_BL $(eval BUILD_DIR := ${BUILD_PLAT}/bl$(1)) $(eval SOURCES := $(BL$(1)_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)) @@ -438,8 +507,7 @@ bl$(1) : $(BUILD_DIR) $(BIN) $(DUMP) all : bl$(1) -$(eval FIP_DEPS += $(if $2,$(BIN),)) -$(eval FIP_ARGS += $(if $2,--bl$(1) $(BIN),)) +$(eval $(call MAKE_TOOL_ARGS,$(1),$(BIN),$(2),$(3),$(4),$(5))) endef @@ -449,23 +517,23 @@ $(eval $(call MAKE_BL,1)) endif ifeq (${NEED_BL2},yes) -$(if ${BL2}, $(eval FIP_DEPS += ${BL2}) $(eval FIP_ARGS += --bl2 ${BL2}),\ - $(eval $(call MAKE_BL,2,in_fip))) +$(if ${BL2}, $(eval $(call MAKE_TOOL_ARGS,2,${BL2},in_fip,${CERTS})),\ + $(eval $(call MAKE_BL,2,in_fip,${CERTS}))) endif ifeq (${NEED_BL31},yes) BL31_SOURCES += ${SPD_SOURCES} -$(if ${BL31}, $(eval FIP_DEPS += ${BL31}) $(eval FIP_ARGS += --bl31 ${BL31}),\ - $(eval $(call MAKE_BL,31,in_fip))) +$(if ${BL31}, $(eval $(call MAKE_TOOL_ARGS,31,${BL31},in_fip,${CERTS},${CERTS},${BL31_KEY})),\ + $(eval $(call MAKE_BL,31,in_fip,${CERTS},${CERTS},${BL31_KEY}))) endif ifeq (${NEED_BL32},yes) -$(if ${BL32}, $(eval FIP_DEPS += ${BL32}) $(eval FIP_ARGS += --bl32 ${BL32}),\ - $(eval $(call MAKE_BL,32,in_fip))) +$(if ${BL32}, $(eval $(call MAKE_TOOL_ARGS,32,${BL32},in_fip,${CERTS},${CERTS},${BL32_KEY})),\ + $(eval $(call MAKE_BL,32,in_fip,${CERTS},${CERTS},${BL32_KEY}))) endif ifeq (${NEED_BL30},yes) -$(if ${BL30}, $(eval FIP_DEPS += ${BL30}) $(eval FIP_ARGS += --bl30 ${BL30}), ) +$(if ${BL30}, $(eval $(call MAKE_TOOL_ARGS,30,${BL30},in_fip,${CERTS},${CERTS},${BL30_KEY}))) # If BL3-0 is needed by the platform then 'BL30' variable must be defined. check_bl30: @@ -479,7 +547,7 @@ check_bl30: endif ifeq (${NEED_BL33},yes) -$(if ${BL33}, $(eval FIP_DEPS += ${BL33}) $(eval FIP_ARGS += --bl33 ${BL33}), ) +$(if ${BL33}, $(eval $(call MAKE_TOOL_ARGS,33,${BL33},in_fip,${CERTS},${CERTS},${BL33_KEY}))) # If BL3-3 is needed by the platform then 'BL33' variable must be defined. check_bl33: @@ -492,6 +560,17 @@ check_bl33: $(if ${BL33},$(warning "BL3-3 is not supported on platform ${PLAT}, it will just be ignored"),) endif +# Add the dependency on the certificates +ifneq (${GENERATE_COT},0) + all: certificates +endif + +certificates: ${CRT_DEPS} ${CRTTOOL} check_bl30 check_bl33 + ${Q}${CRTTOOL} ${CRT_ARGS} + @echo + @echo "Built $@ successfully" + @echo "Certificates can be found in ${BUILD_PLAT}" + @echo ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL} check_bl30 check_bl33 ${Q}${FIPTOOL} --dump \ @@ -524,6 +603,7 @@ help: @echo " clean Clean the build for the selected platform" @echo " cscope Generate cscope index" @echo " distclean Remove all build artifacts for all platforms" + @echo " certtool Build the Certificate generation tool" @echo " fiptool Build the Firmware Image Package(FIP) creation tool" @echo "" @echo "note: most build targets require PLAT to be set to a specific platform." diff --git a/plat/fvp/include/platform_oid.h b/plat/fvp/include/platform_oid.h new file mode 100644 index 000000000..38aca120f --- /dev/null +++ b/plat/fvp/include/platform_oid.h @@ -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. + */ + +#ifndef PLATFORM_OID_H_ +#define PLATFORM_OID_H_ + +/* + * This is the list of the different extensions containing relevant information + * to establish the chain of trust. + * + * The OIDs shown here are just an example. Real OIDs should be obtained from + * the ITU-T. + */ + +/* Non-volatile counter extensions */ +#define TZ_FW_NVCOUNTER_OID "1.2.3.1" +#define NTZ_FW_NVCOUNTER_OID "1.2.3.2" + +/* BL2 extensions */ +#define BL2_HASH_OID "1.2.3.3" + +/* Trusted Key extensions */ +#define TZ_WORLD_PK_OID "1.2.3.4" +#define NTZ_WORLD_PK_OID "1.2.3.5" + +/* BL3-1 extensions */ +#define BL31_CONTENT_CERT_PK_OID "1.2.3.6" +#define BL31_HASH_OID "1.2.3.7" + +/* BL3-0 extensions */ +#define BL30_CONTENT_CERT_PK_OID "1.2.3.8" +#define BL30_HASH_OID "1.2.3.9" + +/* BL3-2 extensions */ +#define BL32_CONTENT_CERT_PK_OID "1.2.3.10" +#define BL32_HASH_OID "1.2.3.11" + +/* BL3-3 extensions */ +#define BL33_CONTENT_CERT_PK_OID "1.2.3.12" +#define BL33_HASH_OID "1.2.3.13" + +#endif /* PLATFORM_OID_H_ */ diff --git a/plat/juno/include/platform_oid.h b/plat/juno/include/platform_oid.h new file mode 100644 index 000000000..38aca120f --- /dev/null +++ b/plat/juno/include/platform_oid.h @@ -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. + */ + +#ifndef PLATFORM_OID_H_ +#define PLATFORM_OID_H_ + +/* + * This is the list of the different extensions containing relevant information + * to establish the chain of trust. + * + * The OIDs shown here are just an example. Real OIDs should be obtained from + * the ITU-T. + */ + +/* Non-volatile counter extensions */ +#define TZ_FW_NVCOUNTER_OID "1.2.3.1" +#define NTZ_FW_NVCOUNTER_OID "1.2.3.2" + +/* BL2 extensions */ +#define BL2_HASH_OID "1.2.3.3" + +/* Trusted Key extensions */ +#define TZ_WORLD_PK_OID "1.2.3.4" +#define NTZ_WORLD_PK_OID "1.2.3.5" + +/* BL3-1 extensions */ +#define BL31_CONTENT_CERT_PK_OID "1.2.3.6" +#define BL31_HASH_OID "1.2.3.7" + +/* BL3-0 extensions */ +#define BL30_CONTENT_CERT_PK_OID "1.2.3.8" +#define BL30_HASH_OID "1.2.3.9" + +/* BL3-2 extensions */ +#define BL32_CONTENT_CERT_PK_OID "1.2.3.10" +#define BL32_HASH_OID "1.2.3.11" + +/* BL3-3 extensions */ +#define BL33_CONTENT_CERT_PK_OID "1.2.3.12" +#define BL33_HASH_OID "1.2.3.13" + +#endif /* PLATFORM_OID_H_ */ diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile new file mode 100644 index 000000000..f1aa79743 --- /dev/null +++ b/tools/cert_create/Makefile @@ -0,0 +1,92 @@ +# +# 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. +# + +PROJECT := cert_create +PLAT := none +V := 0 +DEBUG := 0 +BINARY := ${PROJECT} + +OBJECTS := src/cert.o \ + src/ext.o \ + src/key.o \ + src/main.o \ + src/tbb_cert.o \ + src/tbb_ext.o \ + src/tbb_key.o \ + src/sha.o + +CFLAGS := -Wall -std=c99 + +# Check the platform +ifeq (${PLAT},none) + $(error Error: No platform defined. Use PLAT=.) +endif + +ifeq (${DEBUG},1) + CFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40 +else + CFLAGS += -O2 -DLOG_LEVEL=20 +endif +ifeq (${V},0) + Q := @ +else + Q := +endif + +# Make soft links and include from local directory otherwise wrong headers +# could get pulled in from firmware tree. +INC_DIR := -I ./include -I ../../plat/${PLAT}/include +LIB_DIR := +LIB := -lssl -lcrypto + +CC := gcc +RM := rm -rf + +.PHONY: all clean + +all: clean ${BINARY} + +${BINARY}: ${OBJECTS} Makefile + @echo " LD $@" + @echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \ + const char platform_msg[] = "${PLAT}";' | \ + ${CC} -c ${CFLAGS} -xc - -o src/build_msg.o + ${Q}${CC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@ + +%.o: %.c + @echo " CC $<" + ${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@ + +clean: + ${Q}${RM} -f src/build_msg.o ${OBJECTS} + +realclean: clean + ${Q}${RM} -f ${BINARY} diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h new file mode 100644 index 000000000..48a414624 --- /dev/null +++ b/tools/cert_create/include/cert.h @@ -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. + */ + +#ifndef CERT_H_ +#define CERT_H_ + +#include +#include +#include "key.h" + +/* + * This structure contains information related to the generation of the + * certificates. All these fields must be known and specified at build time + * except for the file name, which is picked up from the command line at + * run time. + * + * One instance of this structure must be created for each of the certificates + * present in the chain of trust. + * + * If the issuer points to this same instance, the generated certificate will + * be self-signed. + */ +typedef struct cert_s cert_t; +struct cert_s { + int id; /* Unique identifier */ + + const char *fn; /* Filename to save the certificate */ + const char *bin; /* Image associated to this certificate */ + + const char *cn; /* Subject CN (Company Name) */ + + X509 *x; /* X509 certificate container */ + key_t *key; /* Key to be signed */ + + cert_t *issuer; /* Issuer certificate */ +}; + +int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value); + +int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk); + +#endif /* CERT_H_ */ diff --git a/tools/cert_create/include/debug.h b/tools/cert_create/include/debug.h new file mode 100644 index 000000000..dd0510a5b --- /dev/null +++ b/tools/cert_create/include/debug.h @@ -0,0 +1,83 @@ +/* + * 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 __DEBUG_H__ +#define __DEBUG_H__ + +#include + +/* The log output macros print output to the console. These macros produce + * compiled log output only if the LOG_LEVEL defined in the makefile (or the + * make command line) is greater or equal than the level required for that + * type of log output. + * The format expected is the same as for printf(). For example: + * INFO("Info %s.\n", "message") -> INFO: Info message. + * WARN("Warning %s.\n", "message") -> WARNING: Warning message. + */ + +#define LOG_LEVEL_NONE 0 +#define LOG_LEVEL_ERROR 10 +#define LOG_LEVEL_NOTICE 20 +#define LOG_LEVEL_WARNING 30 +#define LOG_LEVEL_INFO 40 +#define LOG_LEVEL_VERBOSE 50 + + +#if LOG_LEVEL >= LOG_LEVEL_NOTICE +# define NOTICE(...) printf("NOTICE: " __VA_ARGS__) +#else +# define NOTICE(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_ERROR +# define ERROR(...) printf("ERROR: " __VA_ARGS__) +#else +# define ERROR(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_WARNING +# define WARN(...) printf("WARNING: " __VA_ARGS__) +#else +# define WARN(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_INFO +# define INFO(...) printf("INFO: " __VA_ARGS__) +#else +# define INFO(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE +# define VERBOSE(...) printf("VERBOSE: " __VA_ARGS__) +#else +# define VERBOSE(...) +#endif + +#endif /* __DEBUG_H__ */ diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h new file mode 100644 index 000000000..d73f5734f --- /dev/null +++ b/tools/cert_create/include/ext.h @@ -0,0 +1,70 @@ +/* + * 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 EXT_H_ +#define EXT_H_ + +#include + +/* + * This structure contains the relevant information to create the extensions + * to be included in the certificates. This extensions will be used to + * establish the chain of trust. + */ +typedef struct ext_s { + const char *oid; /* OID of the extension */ + const char *sn; /* Short name */ + const char *ln; /* Long description */ + int type; /* OpenSSL ASN1 type of the extension data. + * Supported types are: + * - V_ASN1_INTEGER + * - V_ASN1_OCTET_STRING + */ + int alias; /* In case OpenSSL provides an standard + * extension of the same type, add the new + * extension as an alias of this one + */ + + X509V3_EXT_METHOD method; /* This field may be used to define a custom + * function to print the contents of the + * extension */ +} ext_t; + +enum { + EXT_NON_CRIT = 0, + EXT_CRIT = !EXT_NON_CRIT, +}; + +int ext_init(ext_t *tbb_ext); +X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len); +X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value); +X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k); + +#endif /* EXT_H_ */ diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h new file mode 100644 index 000000000..881975005 --- /dev/null +++ b/tools/cert_create/include/key.h @@ -0,0 +1,57 @@ +/* + * 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 KEY_H_ +#define KEY_H_ + +#include + +#define RSA_KEY_BITS 2048 + +/* + * This structure contains the relevant information to create the keys + * required to sign the certificates. + * + * One instance of this structure must be created for each key, usually in an + * array fashion. The filename is obtained at run time from the command line + * parameters + */ +typedef struct key_s { + int id; /* Key id */ + const char *desc; /* Key description (debug purposes) */ + char *fn; /* Filename to load/store the key */ + EVP_PKEY *key; /* Key container */ +} key_t; + +int key_new(key_t *key); +int key_load(key_t *key); +int key_store(key_t *key); + +#endif /* KEY_H_ */ diff --git a/tools/cert_create/include/sha.h b/tools/cert_create/include/sha.h new file mode 100644 index 000000000..466d6689b --- /dev/null +++ b/tools/cert_create/include/sha.h @@ -0,0 +1,36 @@ +/* + * 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 SHA_H_ +#define SHA_H_ + +int sha_file(const char *filename, unsigned char *md); + +#endif /* SHA_H_ */ diff --git a/tools/cert_create/include/tbb_cert.h b/tools/cert_create/include/tbb_cert.h new file mode 100644 index 000000000..4e481258f --- /dev/null +++ b/tools/cert_create/include/tbb_cert.h @@ -0,0 +1,58 @@ +/* + * 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 TBB_CERT_H_ +#define TBB_CERT_H_ + +#include "cert.h" + +/* + * Enumerate the certificates that are used to establish the chain of trust + */ +enum { + BL2_CERT, + TRUSTED_KEY_CERT, + BL30_KEY_CERT, + BL30_CERT, + BL31_KEY_CERT, + BL31_CERT, + BL32_KEY_CERT, + BL32_CERT, + BL33_KEY_CERT, + BL33_CERT, + NUM_CERTIFICATES, +}; + +/* + * Array containing the certificate instances + */ +extern cert_t certs[NUM_CERTIFICATES]; + +#endif /* TBB_CERT_H_ */ diff --git a/tools/cert_create/include/tbb_ext.h b/tools/cert_create/include/tbb_ext.h new file mode 100644 index 000000000..155d3cb47 --- /dev/null +++ b/tools/cert_create/include/tbb_ext.h @@ -0,0 +1,38 @@ +/* + * 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 TBB_EXT_H_ +#define TBB_EXT_H_ + +#include "ext.h" + +/* Array containing the extensions used in the chain of trust */ +extern ext_t tbb_ext[]; + +#endif /* TBB_EXT_H_ */ diff --git a/tools/cert_create/include/tbb_key.h b/tools/cert_create/include/tbb_key.h new file mode 100644 index 000000000..cc927d1e5 --- /dev/null +++ b/tools/cert_create/include/tbb_key.h @@ -0,0 +1,55 @@ +/* + * 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 TBB_KEY_H_ +#define TBB_KEY_H_ + +#include "key.h" + +/* + * Enumerate the keys that are used to establish the chain of trust + */ +enum { + ROT_KEY, + TRUSTED_WORLD_KEY, + NON_TRUSTED_WORLD_KEY, + BL30_KEY, + BL31_KEY, + BL32_KEY, + BL33_KEY, + NUM_KEYS +}; + +/* + * Array containing the key instances + */ +extern key_t keys[]; + +#endif /* TBB_KEY_H_ */ diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c new file mode 100644 index 000000000..9705643d4 --- /dev/null +++ b/tools/cert_create/src/cert.c @@ -0,0 +1,180 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "cert.h" +#include "debug.h" +#include "key.h" +#include "platform_oid.h" +#include "sha.h" + +#define SERIAL_RAND_BITS 64 + +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) +{ + BIGNUM *btmp; + int ret = 0; + if (b) + btmp = b; + else + btmp = BN_new(); + + if (!btmp) + return 0; + + if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) + goto error; + if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) + goto error; + + ret = 1; + +error: + + if (!b) + BN_free(btmp); + + return ret; +} + +int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value) +{ + X509_EXTENSION *ex; + X509V3_CTX ctx; + + /* No configuration database */ + X509V3_set_ctx_nodb(&ctx); + + /* Set issuer and subject certificates in the context */ + X509V3_set_ctx(&ctx, issuer, subject, NULL, NULL, 0); + ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value); + if (!ex) { + ERR_print_errors_fp(stdout); + return 0; + } + + X509_add_ext(subject, ex, -1); + X509_EXTENSION_free(ex); + + return 1; +} + + +int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) +{ + EVP_PKEY *pkey = cert->key->key; + EVP_PKEY *ikey = cert->issuer->key->key; + X509 *issuer = cert->issuer->x; + X509 *x = NULL; + X509_EXTENSION *ex = NULL; + X509_NAME *name = NULL; + ASN1_INTEGER *sno = NULL; + int i, num; + + /* Create the certificate structure */ + x = X509_new(); + if (!x) { + return 0; + } + + /* If we do not have a key, use the issuer key (the certificate will + * become self signed). This happens in content certificates. */ + if (!pkey) { + pkey = ikey; + } + + /* If we do not have an issuer certificate, use our own (the certificate + * will become self signed) */ + if (!issuer) { + issuer = x; + } + + /* x509.v3 */ + X509_set_version(x, 2); + + /* Random serial number */ + sno = ASN1_INTEGER_new(); + rand_serial(NULL, sno); + X509_set_serialNumber(x, sno); + ASN1_INTEGER_free(sno); + + X509_gmtime_adj(X509_get_notBefore(x), 0); + X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days); + X509_set_pubkey(x, pkey); + + /* Subject name */ + name = X509_get_subject_name(x); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)cert->cn, -1, -1, 0); + X509_set_subject_name(x, name); + + /* Issuer name */ + name = X509_get_issuer_name(x); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)cert->issuer->cn, -1, -1, 0); + X509_set_issuer_name(x, name); + + /* Add various extensions: standard extensions */ + cert_add_ext(issuer, x, NID_subject_key_identifier, "hash"); + cert_add_ext(issuer, x, NID_authority_key_identifier, "keyid:always"); + if (ca) { + cert_add_ext(issuer, x, NID_basic_constraints, "CA:TRUE"); + cert_add_ext(issuer, x, NID_key_usage, "keyCertSign"); + } else { + cert_add_ext(issuer, x, NID_basic_constraints, "CA:FALSE"); + } + + /* Add custom extensions */ + if (sk != NULL) { + num = sk_X509_EXTENSION_num(sk); + for (i = 0; i < num; i++) { + ex = sk_X509_EXTENSION_value(sk, i); + X509_add_ext(x, ex, -1); + } + } + + /* Sign the certificate with the issuer key */ + if (!X509_sign(x, ikey, EVP_sha1())) { + ERR_print_errors_fp(stdout); + return 0; + } + + cert->x = x; + return 1; +} diff --git a/tools/cert_create/src/ext.c b/tools/cert_create/src/ext.c new file mode 100644 index 000000000..31f84a86b --- /dev/null +++ b/tools/cert_create/src/ext.c @@ -0,0 +1,233 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include +#include "ext.h" + +DECLARE_ASN1_ITEM(ASN1_INTEGER) +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING) + +/* + * This function adds the TBB extensions to the internal extension list + * maintained by OpenSSL so they can be used later. + * + * It also initializes the methods to print the contents of the extension. If an + * alias is specified in the TBB extension, we reuse the methods of the alias. + * Otherwise, only methods for V_ASN1_INTEGER and V_ASN1_OCTET_STRING are + * provided. Any other type will be printed as a raw ascii string. + * + * Return: 0 = success, Otherwise: error + */ +int ext_init(ext_t *tbb_ext) +{ + ext_t *ext; + X509V3_EXT_METHOD *m; + int i = 0, nid, ret; + + while ((ext = &tbb_ext[i++]) && ext->oid) { + nid = OBJ_create(ext->oid, ext->sn, ext->ln); + if (ext->alias) { + X509V3_EXT_add_alias(nid, ext->alias); + } else { + m = &ext->method; + memset(m, 0x0, sizeof(X509V3_EXT_METHOD)); + switch (ext->type) { + case V_ASN1_INTEGER: + m->it = ASN1_ITEM_ref(ASN1_INTEGER); + m->i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER; + m->s2i = (X509V3_EXT_S2I)s2i_ASN1_INTEGER; + break; + case V_ASN1_OCTET_STRING: + m->it = ASN1_ITEM_ref(ASN1_OCTET_STRING); + m->i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING; + m->s2i = (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING; + break; + default: + continue; + } + m->ext_nid = nid; + ret = X509V3_EXT_add(m); + if (!ret) { + ERR_print_errors_fp(stdout); + return 1; + } + } + } + return 0; +} + +/* + * Create a new extension + * + * Extension ::= SEQUENCE { + * id OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * value OCTET STRING } + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * data: extension data. This data will be encapsulated in an Octet String + * + * Return: Extension address, NULL if error + */ +static +X509_EXTENSION *ext_new(int nid, int crit, unsigned char *data, int len) +{ + X509_EXTENSION *ex; + ASN1_OCTET_STRING *ext_data; + + /* Octet string containing the extension data */ + ext_data = ASN1_OCTET_STRING_new(); + ASN1_OCTET_STRING_set(ext_data, data, len); + + /* Create the extension */ + ex = X509_EXTENSION_create_by_NID(NULL, nid, crit, ext_data); + + /* The extension makes a copy of the data, so we can free this object */ + ASN1_OCTET_STRING_free(ext_data); + + return ex; +} + +/* + * Creates a x509v3 extension containing a hash encapsulated in an ASN1 Octet + * String + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * buf: pointer to the buffer that contains the hash + * len: size of the hash in bytes + * + * Return: Extension address, NULL if error + */ +X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len) +{ + X509_EXTENSION *ex = NULL; + ASN1_OCTET_STRING *hash = NULL; + unsigned char *p = NULL; + int sz = -1; + + /* Encode Hash */ + hash = ASN1_OCTET_STRING_new(); + ASN1_OCTET_STRING_set(hash, buf, len); + sz = i2d_ASN1_OCTET_STRING(hash, NULL); + i2d_ASN1_OCTET_STRING(hash, &p); + + /* Create the extension */ + ex = ext_new(nid, crit, p, sz); + + /* Clean up */ + OPENSSL_free(p); + ASN1_OCTET_STRING_free(hash); + + return ex; +} + +/* + * Creates a x509v3 extension containing a nvcounter encapsulated in an ASN1 + * Integer + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * value: nvcounter value + * + * Return: Extension address, NULL if error + */ +X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value) +{ + X509_EXTENSION *ex = NULL; + ASN1_INTEGER *counter = NULL; + unsigned char *p = NULL; + int sz = -1; + + /* Encode counter */ + counter = ASN1_INTEGER_new(); + ASN1_INTEGER_set(counter, value); + sz = i2d_ASN1_INTEGER(counter, NULL); + i2d_ASN1_INTEGER(counter, &p); + + /* Create the extension */ + ex = ext_new(nid, crit, p, sz); + + /* Free objects */ + OPENSSL_free(p); + ASN1_INTEGER_free(counter); + + return ex; +} + +/* + * Creates a x509v3 extension containing a public key in DER format: + * + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * k: key + * + * Return: Extension address, NULL if error + */ +X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k) +{ + X509_EXTENSION *ex = NULL; + unsigned char *p = NULL; + int sz = -1; + + /* Encode key */ + BIO *mem = BIO_new(BIO_s_mem()); + if (i2d_PUBKEY_bio(mem, k) <= 0) { + ERR_print_errors_fp(stderr); + return NULL; + } + p = (unsigned char *)OPENSSL_malloc(4096); + sz = BIO_read(mem, p, 4096); + + /* Create the extension */ + ex = ext_new(nid, crit, p, sz); + + /* Clean up */ + OPENSSL_free(p); + + return ex; +} diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c new file mode 100644 index 000000000..b5737d93e --- /dev/null +++ b/tools/cert_create/src/key.c @@ -0,0 +1,131 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "cert.h" +#include "debug.h" +#include "key.h" +#include "platform_oid.h" +#include "sha.h" + +#define MAX_FILENAME_LEN 1024 + +/* + * Create a new key + */ +int key_new(key_t *key) +{ + RSA *rsa = NULL; + EVP_PKEY *k = NULL; + + /* Create key pair container */ + k = EVP_PKEY_new(); + if (k == NULL) { + return 0; + } + + /* Generate a new RSA key */ + rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL); + if (EVP_PKEY_assign_RSA(k, rsa)) { + key->key = k; + return 1; + } else { + printf("Cannot assign RSA key\n"); + } + + if (k) + EVP_PKEY_free(k); + return 0; +} + +int key_load(key_t *key) +{ + FILE *fp = NULL; + EVP_PKEY *k = NULL; + + /* Create key pair container */ + k = EVP_PKEY_new(); + if (k == NULL) { + return 0; + } + + if (key->fn) { + /* Load key from file */ + fp = fopen(key->fn, "r"); + if (fp) { + k = PEM_read_PrivateKey(fp, &k, NULL, NULL); + fclose(fp); + if (k) { + key->key = k; + return 1; + } else { + ERROR("Cannot read key from %s\n", key->fn); + } + } else { + ERROR("Cannot open file %s\n", key->fn); + } + } else { + ERROR("Key filename not specified\n"); + } + + if (k) + EVP_PKEY_free(k); + + return 0; +} + +int key_store(key_t *key) +{ + FILE *fp = NULL; + + if (key->fn) { + fp = fopen(key->fn, "w"); + if (fp) { + PEM_write_PrivateKey(fp, key->key, + NULL, NULL, 0, NULL, NULL); + fclose(fp); + return 1; + } else { + ERROR("Cannot create file %s\n", key->fn); + } + } else { + ERROR("Key filename not specified\n"); + } + + return 0; +} diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c new file mode 100644 index 000000000..6df367a24 --- /dev/null +++ b/tools/cert_create/src/main.c @@ -0,0 +1,719 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "cert.h" +#include "debug.h" +#include "ext.h" +#include "key.h" +#include "platform_oid.h" +#include "sha.h" +#include "tbb_ext.h" +#include "tbb_cert.h" +#include "tbb_key.h" + +/* + * Helper macros to simplify the code. This macro assigns the return value of + * the 'fn' function to 'v' and exits if the value is NULL. + */ +#define CHECK_NULL(v, fn) \ + do { \ + v = fn; \ + if (v == NULL) { \ + ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \ + exit(1); \ + } \ + } while (0) + +/* + * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the + * NID is undefined. + */ +#define CHECK_OID(v, oid) \ + do { \ + v = OBJ_txt2nid(oid); \ + if (v == NID_undef) { \ + ERROR("Cannot find TBB extension %s\n", oid); \ + exit(1); \ + } \ + } while (0) + +#define MAX_FILENAME_LEN 1024 +#define VAL_DAYS 7300 +#define ID_TO_BIT_MASK(id) (1 << id) +#define NVCOUNTER_VALUE 0 + +/* Files */ +enum { + /* Image file names (inputs) */ + BL2_ID = 0, + BL30_ID, + BL31_ID, + BL32_ID, + BL33_ID, + /* Certificate file names (outputs) */ + BL2_CERT_ID, + TRUSTED_KEY_CERT_ID, + BL30_KEY_CERT_ID, + BL30_CERT_ID, + BL31_KEY_CERT_ID, + BL31_CERT_ID, + BL32_KEY_CERT_ID, + BL32_CERT_ID, + BL33_KEY_CERT_ID, + BL33_CERT_ID, + /* Key file names (input/output) */ + ROT_KEY_ID, + TRUSTED_WORLD_KEY_ID, + NON_TRUSTED_WORLD_KEY_ID, + BL30_KEY_ID, + BL31_KEY_ID, + BL32_KEY_ID, + BL33_KEY_ID, + NUM_OPTS +}; + +/* Global options */ +static int new_keys; +static int save_keys; +static int print_cert; +static int bl30_present; +static int bl32_present; + +/* We are not checking nvcounters in TF. Include them in the certificates but + * the value will be set to 0 */ +static int tf_nvcounter; +static int non_tf_nvcounter; + +/* Info messages created in the Makefile */ +extern const char build_msg[]; +extern const char platform_msg[]; + + +static char *strdup(const char *str) +{ + int n = strlen(str) + 1; + char *dup = malloc(n); + if (dup) { + strcpy(dup, str); + } + return dup; +} + +/* Command line options */ +static const struct option long_opt[] = { + /* Binary images */ + {"bl2", required_argument, 0, BL2_ID}, + {"bl30", required_argument, 0, BL30_ID}, + {"bl31", required_argument, 0, BL31_ID}, + {"bl32", required_argument, 0, BL32_ID}, + {"bl33", required_argument, 0, BL33_ID}, + /* Certificate files */ + {"bl2-cert", required_argument, 0, BL2_CERT_ID}, + {"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID}, + {"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID}, + {"bl30-cert", required_argument, 0, BL30_CERT_ID}, + {"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID}, + {"bl31-cert", required_argument, 0, BL31_CERT_ID}, + {"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID}, + {"bl32-cert", required_argument, 0, BL32_CERT_ID}, + {"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID}, + {"bl33-cert", required_argument, 0, BL33_CERT_ID}, + /* Private key files */ + {"rot-key", required_argument, 0, ROT_KEY_ID}, + {"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID}, + {"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID}, + {"bl30-key", required_argument, 0, BL30_KEY_ID}, + {"bl31-key", required_argument, 0, BL31_KEY_ID}, + {"bl32-key", required_argument, 0, BL32_KEY_ID}, + {"bl33-key", required_argument, 0, BL33_KEY_ID}, + /* Common options */ + {"help", no_argument, 0, 'h'}, + {"save-keys", no_argument, 0, 'k'}, + {"new-chain", no_argument, 0, 'n'}, + {"print-cert", no_argument, 0, 'p'}, + {0, 0, 0, 0} +}; + +static void print_help(const char *cmd) +{ + int i = 0; + printf("\n\n"); + printf("The certificate generation tool loads the binary images and\n" + "optionally the RSA keys, and outputs the key and content\n" + "certificates properly signed to implement the chain of trust.\n" + "If keys are provided, they must be in PEM format.\n" + "Certificates are generated in DER format.\n"); + printf("\n"); + printf("Usage:\n\n"); + printf(" %s [-hknp] \\\n", cmd); + for (i = 0; i < NUM_OPTS; i++) { + printf(" --%s \\\n", long_opt[i].name); + } + printf("\n"); + printf("-h Print help and exit\n"); + printf("-k Save key pairs into files. Filenames must be provided\n"); + printf("-n Generate new key pairs if no key files are provided\n"); + printf("-p Print the certificates in the standard output\n"); + printf("\n"); + + exit(0); +} + +static void check_cmd_params(void) +{ + /* BL2, BL31 and BL33 are mandatory */ + if (certs[BL2_CERT].bin == NULL) { + ERROR("BL2 image not specified\n"); + exit(1); + } + + if (certs[BL31_CERT].bin == NULL) { + ERROR("BL31 image not specified\n"); + exit(1); + } + + if (certs[BL33_CERT].bin == NULL) { + ERROR("BL33 image not specified\n"); + exit(1); + } + + /* BL30 and BL32 are optional */ + if (certs[BL30_CERT].bin != NULL) { + bl30_present = 1; + } + + if (certs[BL32_CERT].bin != NULL) { + bl32_present = 1; + } + + /* TODO: Certificate filenames */ + + /* Filenames to store keys must be specified */ + if (save_keys || !new_keys) { + if (keys[ROT_KEY].fn == NULL) { + ERROR("ROT key not specified\n"); + exit(1); + } + + if (keys[TRUSTED_WORLD_KEY].fn == NULL) { + ERROR("Trusted World key not specified\n"); + exit(1); + } + + if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) { + ERROR("Non-trusted World key not specified\n"); + exit(1); + } + + if (keys[BL31_KEY].fn == NULL) { + ERROR("BL31 key not specified\n"); + exit(1); + } + + if (keys[BL33_KEY].fn == NULL) { + ERROR("BL33 key not specified\n"); + exit(1); + } + + if (bl30_present && (keys[BL30_KEY].fn == NULL)) { + ERROR("BL30 key not specified\n"); + exit(1); + } + + if (bl32_present && (keys[BL32_KEY].fn == NULL)) { + ERROR("BL32 key not specified\n"); + exit(1); + } + } +} + +int main(int argc, char *argv[]) +{ + STACK_OF(X509_EXTENSION) * sk = NULL; + X509_EXTENSION *hash_ext = NULL; + X509_EXTENSION *nvctr_ext = NULL; + X509_EXTENSION *trusted_key_ext = NULL; + X509_EXTENSION *non_trusted_key_ext = NULL; + FILE *file = NULL; + int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid; + int c, opt_idx = 0; + unsigned char md[SHA256_DIGEST_LENGTH]; + + NOTICE("CoT Generation Tool: %s\n", build_msg); + NOTICE("Target platform: %s\n", platform_msg); + + while (1) { + /* getopt_long stores the option index here. */ + c = getopt_long(argc, argv, "hknp", long_opt, &opt_idx); + + /* Detect the end of the options. */ + if (c == -1) { + break; + } + + switch (c) { + case 'h': + print_help(argv[0]); + break; + case 'k': + save_keys = 1; + break; + case 'n': + new_keys = 1; + break; + case 'p': + print_cert = 1; + break; + case BL2_ID: + certs[BL2_CERT].bin = strdup(optarg); + break; + case BL30_ID: + certs[BL30_CERT].bin = strdup(optarg); + break; + case BL31_ID: + certs[BL31_CERT].bin = strdup(optarg); + break; + case BL32_ID: + certs[BL32_CERT].bin = strdup(optarg); + break; + case BL33_ID: + certs[BL33_CERT].bin = strdup(optarg); + break; + case BL2_CERT_ID: + certs[BL2_CERT].fn = strdup(optarg); + break; + case TRUSTED_KEY_CERT_ID: + certs[TRUSTED_KEY_CERT].fn = strdup(optarg); + break; + case BL30_KEY_CERT_ID: + certs[BL30_KEY_CERT].fn = strdup(optarg); + break; + case BL30_CERT_ID: + certs[BL30_CERT].fn = strdup(optarg); + break; + case BL31_KEY_CERT_ID: + certs[BL31_KEY_CERT].fn = strdup(optarg); + break; + case BL31_CERT_ID: + certs[BL31_CERT].fn = strdup(optarg); + break; + case BL32_KEY_CERT_ID: + certs[BL32_KEY_CERT].fn = strdup(optarg); + break; + case BL32_CERT_ID: + certs[BL32_CERT].fn = strdup(optarg); + break; + case BL33_KEY_CERT_ID: + certs[BL33_KEY_CERT].fn = strdup(optarg); + break; + case BL33_CERT_ID: + certs[BL33_CERT].fn = strdup(optarg); + break; + case ROT_KEY_ID: + keys[ROT_KEY].fn = strdup(optarg); + break; + case TRUSTED_WORLD_KEY_ID: + keys[TRUSTED_WORLD_KEY].fn = strdup(optarg); + break; + case NON_TRUSTED_WORLD_KEY_ID: + keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg); + break; + case BL30_KEY_ID: + keys[BL30_KEY].fn = strdup(optarg); + break; + case BL31_KEY_ID: + keys[BL31_KEY].fn = strdup(optarg); + break; + case BL32_KEY_ID: + keys[BL32_KEY].fn = strdup(optarg); + break; + case BL33_KEY_ID: + keys[BL33_KEY].fn = strdup(optarg); + break; + case '?': + default: + printf("%s\n", optarg); + exit(1); + } + } + + /* Set the value of the NVCounters */ + tf_nvcounter = NVCOUNTER_VALUE; + non_tf_nvcounter = NVCOUNTER_VALUE; + + /* Check command line arguments */ + check_cmd_params(); + + /* Register the new types and OIDs for the extensions */ + if (ext_init(tbb_ext) != 0) { + ERROR("Cannot initialize TBB extensions\n"); + exit(1); + } + + /* Get non-volatile counters NIDs */ + CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID); + CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID); + + /* Load private keys from files (or generate new ones) */ + if (new_keys) { + for (i = 0 ; i < NUM_KEYS ; i++) { + if (!key_new(&keys[i])) { + ERROR("Error creating %s\n", keys[i].desc); + exit(1); + } + } + } else { + for (i = 0 ; i < NUM_KEYS ; i++) { + if (!key_load(&keys[i])) { + ERROR("Error loading %s\n", keys[i].desc); + exit(1); + } + } + } + + /* ********************************************************************* + * BL2 certificate (Trusted Boot Firmware certificate): + * - Self-signed with OEM ROT private key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - BL2 hash + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + + /* Add the NVCounter as a critical extension */ + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + /* Add hash of BL2 as an extension */ + if (!sha_file(certs[BL2_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL2_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + /* Create certificate. Signed with ROT key */ + if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL2_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * Trusted Key certificate: + * - Self-signed with OEM ROT private key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - TrustedWorldPK + * - NonTrustedWorldPK + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, TZ_WORLD_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[TRUSTED_WORLD_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + CHECK_OID(pk_nid, NTZ_WORLD_PK_OID); + CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[NON_TRUSTED_WORLD_KEY].key)); + sk_X509_EXTENSION_push(sk, non_trusted_key_ext); + if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL30 Key certificate (Trusted SCP Firmware Key certificate): + * - Self-signed with Trusted World key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - SCPFirmwareContentCertPK + **********************************************************************/ + if (bl30_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL30_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL30 certificate (SCP Firmware Content certificate): + * - Signed with Trusted World Key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - SCPFirmwareHash + **********************************************************************/ + if (bl30_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL30_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", + certs[BL30_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL30_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL30_CERT].cn); + exit(1); + } + + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL31 Key certificate (Trusted SoC Firmware Key certificate): + * - Self-signed with Trusted World key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - SoCFirmwareContentCertPK + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL31_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL31 certificate (SOC Firmware Content certificate): + * - Signed with Trusted World Key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - BL31 hash + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL31_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL31_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL31_CERT].cn); + exit(1); + } + + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL32 Key certificate (Trusted OS Firmware Key certificate): + * - Self-signed with Trusted World key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - TrustedOSFirmwareContentCertPK + **********************************************************************/ + if (bl32_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL32_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL32 certificate (TrustedOS Firmware Content certificate): + * - Signed with Trusted World Key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - BL32 hash + **********************************************************************/ + if (bl32_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL32_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", + certs[BL32_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL32_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL32_CERT].cn); + exit(1); + } + + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL33 Key certificate (Non Trusted Firmware Key certificate): + * - Self-signed with Non Trusted World key + * - Extensions: + * - NonTrustedFirmwareNVCounter (TODO) + * - NonTrustedFirmwareContentCertPK + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT, + non_tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID); + CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL33_KEY].key)); + sk_X509_EXTENSION_push(sk, non_trusted_key_ext); + if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL33 certificate (Non-Trusted World Content certificate): + * - Signed with Non-Trusted World Key + * - Extensions: + * - NonTrustedFirmwareNVCounter (TODO) + * - BL33 hash + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT, + non_tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL33_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL33_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL33_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* Print the certificates */ + if (print_cert) { + for (i = 0 ; i < NUM_CERTIFICATES ; i++) { + if (!certs[i].x) { + continue; + } + printf("\n\n=====================================\n\n"); + X509_print_fp(stdout, certs[i].x); + } + } + + /* Save created certificates to files */ + for (i = 0 ; i < NUM_CERTIFICATES ; i++) { + if (certs[i].x && certs[i].fn) { + file = fopen(certs[i].fn, "w"); + if (file != NULL) { + i2d_X509_fp(file, certs[i].x); + fclose(file); + } else { + ERROR("Cannot create file %s\n", certs[i].fn); + } + } + } + + /* Save keys */ + if (save_keys) { + for (i = 0 ; i < NUM_KEYS ; i++) { + if (!key_store(&keys[i])) { + ERROR("Cannot save %s\n", keys[i].desc); + } + } + } + + X509_EXTENSION_free(hash_ext); + X509_EXTENSION_free(nvctr_ext); + X509_EXTENSION_free(trusted_key_ext); + X509_EXTENSION_free(non_trusted_key_ext); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + CRYPTO_cleanup_all_ex_data(); + + return 0; +} diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c new file mode 100644 index 000000000..57026b56c --- /dev/null +++ b/tools/cert_create/src/sha.c @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#include +#include + +#include "debug.h" + +#define BUFFER_SIZE 256 + +int sha_file(const char *filename, unsigned char *md) +{ + FILE *inFile; + SHA256_CTX shaContext; + int bytes; + unsigned char data[BUFFER_SIZE]; + + if ((filename == NULL) || (md == NULL)) { + ERROR("%s(): NULL argument\n", __FUNCTION__); + return 0; + } + + inFile = fopen(filename, "rb"); + if (inFile == NULL) { + ERROR("Cannot read %s\n", filename); + return 0; + } + + SHA256_Init(&shaContext); + while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { + SHA256_Update(&shaContext, data, bytes); + } + SHA256_Final(md, &shaContext); + + fclose(inFile); + return 1; +} diff --git a/tools/cert_create/src/tbb_cert.c b/tools/cert_create/src/tbb_cert.c new file mode 100644 index 000000000..8dfda6056 --- /dev/null +++ b/tools/cert_create/src/tbb_cert.c @@ -0,0 +1,111 @@ +/* + * 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. + */ + +#include "tbb_cert.h" +#include "tbb_key.h" + +/* + * Certificates used in the chain of trust + * + * The order of the certificates must follow the enumeration specified in + * tbb_cert.h. All certificates are self-signed. + */ +cert_t certs[NUM_CERTIFICATES] = { + { + .id = BL2_CERT, + .fn = NULL, + .cn = "BL2 Certificate", + .key = &keys[ROT_KEY], + .issuer = &certs[BL2_CERT], + }, + { + .id = TRUSTED_KEY_CERT, + .fn = NULL, + .cn = "Trusted Key Certificate", + .key = &keys[ROT_KEY], + .issuer = &certs[TRUSTED_KEY_CERT], + }, + { + .id = BL30_KEY_CERT, + .fn = NULL, + .cn = "BL3-0 Key Certificate", + .key = &keys[TRUSTED_WORLD_KEY], + .issuer = &certs[BL30_KEY_CERT], + }, + { + .id = BL30_CERT, + .fn = NULL, + .cn = "BL3-0 Content Certificate", + .key = &keys[BL30_KEY], + .issuer = &certs[BL30_CERT], + }, + { + .id = BL31_KEY_CERT, + .fn = NULL, + .cn = "BL3-1 Key Certificate", + .key = &keys[TRUSTED_WORLD_KEY], + .issuer = &certs[BL31_KEY_CERT], + }, + { + .id = BL31_CERT, + .fn = NULL, + .cn = "BL3-1 Content Certificate", + .key = &keys[BL31_KEY], + .issuer = &certs[BL31_CERT], + }, + { + .id = BL32_KEY_CERT, + .fn = NULL, + .cn = "BL3-2 Key Certificate", + .key = &keys[TRUSTED_WORLD_KEY], + .issuer = &certs[BL32_KEY_CERT], + }, + { + .id = BL32_CERT, + .fn = NULL, + .cn = "BL3-2 Content Certificate", + .key = &keys[BL32_KEY], + .issuer = &certs[BL32_CERT], + }, + { + .id = BL33_KEY_CERT, + .fn = NULL, + .cn = "BL3-3 Key Certificate", + .key = &keys[NON_TRUSTED_WORLD_KEY], + .issuer = &certs[BL33_KEY_CERT], + }, + { + .id = BL33_CERT, + .fn = NULL, + .cn = "BL3-3 Content Certificate", + .key = &keys[BL33_KEY], + .issuer = &certs[BL33_CERT], + } +}; diff --git a/tools/cert_create/src/tbb_ext.c b/tools/cert_create/src/tbb_ext.c new file mode 100644 index 000000000..0022611cb --- /dev/null +++ b/tools/cert_create/src/tbb_ext.c @@ -0,0 +1,118 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include "ext.h" +#include "platform_oid.h" + +ext_t tbb_ext[] = { + { + .oid = TZ_FW_NVCOUNTER_OID, + .sn = "TrustedNvCounter", + .ln = "Non-volatile trusted counter", + .type = V_ASN1_INTEGER + }, + { + .oid = NTZ_FW_NVCOUNTER_OID, + .sn = "NonTrustedNvCounter", + .ln = "Non-volatile non-trusted counter", + .type = V_ASN1_INTEGER + }, + { + .oid = BL2_HASH_OID, + .sn = "TrustedBootFirmwareHash", + .ln = "Trusted Boot Firmware (BL2) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = TZ_WORLD_PK_OID, + .sn = "TrustedWorldPublicKey", + .ln = "Trusted World Public Key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = NTZ_WORLD_PK_OID, + .sn = "NonTrustedWorldPublicKey", + .ln = "Non-Trusted World Public Key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL31_CONTENT_CERT_PK_OID, + .sn = "SoCFirmwareContentCertPK", + .ln = "SoC Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL31_HASH_OID, + .sn = "APROMPatchHash", + .ln = "AP ROM patch hash", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL30_CONTENT_CERT_PK_OID, + .sn = "SCPFirmwareContentCertPK", + .ln = "SCP Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL30_HASH_OID, + .sn = "SCPFirmwareHash", + .ln = "SCP Firmware (BL30) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL32_CONTENT_CERT_PK_OID, + .sn = "TrustedOSFirmwareContentCertPK", + .ln = "Trusted OS Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL32_HASH_OID, + .sn = "TrustedOSHash", + .ln = "Trusted OS (BL32) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL33_CONTENT_CERT_PK_OID, + .sn = "NonTrustedFirmwareContentCertPK", + .ln = "Non-Trusted Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL33_HASH_OID, + .sn = "NonTrustedWorldBootloaderHash", + .ln = "Non-Trusted World (BL33) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { 0, 0, 0, 0 } +}; diff --git a/tools/cert_create/src/tbb_key.c b/tools/cert_create/src/tbb_key.c new file mode 100644 index 000000000..140aeda1a --- /dev/null +++ b/tools/cert_create/src/tbb_key.c @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#include "tbb_key.h" + +/* + * Keys used to establish the chain of trust + * + * The order of the keys must follow the enumeration specified in tbb_key.h + */ +key_t keys[NUM_KEYS] = { + { + .id = ROT_KEY, + .desc = "Root Of Trust key" + }, + { + .id = TRUSTED_WORLD_KEY, + .desc = "Trusted World key" + }, + { + .id = NON_TRUSTED_WORLD_KEY, + .desc = "Non Trusted World key" + }, + { + .id = BL30_KEY, + .desc = "BL30 key" + }, + { + .id = BL31_KEY, + .desc = "BL31 key" + }, + { + .id = BL32_KEY, + .desc = "BL32 key" + }, + { + .id = BL33_KEY, + .desc = "BL33 key" + } +}; From b7124ea7f6fe1e1e73a0975cfb0fa34cabd73b2a Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Tue, 4 Nov 2014 17:36:40 +0000 Subject: [PATCH 03/10] TBB: add support to include certificates in a FIP image This patch extends the FIP tool to include the certificates generated by the 'cert_create' tool. If GENERATE_COT build option is enabled, the Makefile adds the certificates as dependencies to create the FIP file. Thus, make target 'fip' will also build the certificates as part of the Trusted Firmware build process. Change-Id: I5eee500da7f7be6cfb6e3df0423599739d260074 --- Makefile | 5 +++++ include/common/firmware_image_package.h | 26 +++++++++++++++++++++++++ tools/fip_create/fip_create.c | 24 +++++++++++++++++++++++ tools/fip_create/fip_create.h | 2 +- 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 777e3308e..b5db6294b 100644 --- a/Makefile +++ b/Makefile @@ -286,6 +286,9 @@ TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt ifneq (${GENERATE_COT},0) $(eval CERTS := yes) + $(eval FIP_DEPS += certificates) + $(eval FIP_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT}) + ifneq (${CREATE_KEYS},0) $(eval CRT_ARGS += -n) endif @@ -449,6 +452,8 @@ define MAKE_TOOL_ARGS $(eval FIP_DEPS += $(if $3,$(2),)) $(eval FIP_ARGS += $(if $3,--bl$(1) $(2),)) +$(eval FIP_ARGS += $(if $4,--bl$(1)-cert $(BUILD_PLAT)/bl$(1).crt)) +$(eval FIP_ARGS += $(if $4,$(if $5,--bl$(1)-key-cert $(BUILD_PLAT)/bl$(1)_key.crt))) $(eval CRT_DEPS += $(if $4,$(2),)) $(eval CRT_DEPS += $(if $4,$(if $6,$(6),))) diff --git a/include/common/firmware_image_package.h b/include/common/firmware_image_package.h index f4554ecc6..8fb669e3d 100644 --- a/include/common/firmware_image_package.h +++ b/include/common/firmware_image_package.h @@ -49,6 +49,32 @@ {0x89e1d005, 0xdc53, 0x4713, 0x8d, 0x2b, {0x50, 0x0a, 0x4b, 0x7a, 0x3e, 0x38} } #define UUID_NON_TRUSTED_FIRMWARE_BL33 \ {0xa7eed0d6, 0xeafc, 0x4bd5, 0x97, 0x82, {0x99, 0x34, 0xf2, 0x34, 0xb6, 0xe4} } +/* Key certificates */ +#define UUID_ROT_KEY_CERT \ + {0x721d2d86, 0x60f8, 0x11e4, 0x92, 0x0b, {0x8b, 0xe7, 0x62, 0x16, 0x0f, 0x24} } +#define UUID_TRUSTED_KEY_CERT \ + {0x90e87e82, 0x60f8, 0x11e4, 0xa1, 0xb4, {0x77, 0x7a, 0x21, 0xb4, 0xf9, 0x4c} } +#define UUID_NON_TRUSTED_WORLD_KEY_CERT \ + {0x3d87671c, 0x635f, 0x11e4, 0x97, 0x8d, {0x27, 0xc0, 0xc7, 0x14, 0x8a, 0xbd} } +#define UUID_SCP_FIRMWARE_BL30_KEY_CERT \ + {0xa1214202, 0x60f8, 0x11e4, 0x8d, 0x9b, {0xf3, 0x3c, 0x0e, 0x15, 0xa0, 0x14} } +#define UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT \ + {0xccbeb88a, 0x60f9, 0x11e4, 0x9a, 0xd0, {0xeb, 0x48, 0x22, 0xd8, 0xdc, 0xf8} } +#define UUID_SECURE_PAYLOAD_BL32_KEY_CERT \ + {0x03d67794, 0x60fb, 0x11e4, 0x85, 0xdd, {0xb7, 0x10, 0x5b, 0x8c, 0xee, 0x04} } +#define UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT \ + {0x2a83d58a, 0x60fb, 0x11e4, 0x8a, 0xaf, {0xdf, 0x30, 0xbb, 0xc4, 0x98, 0x59} } +/* Content certificates */ +#define UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT \ + {0xea69e2d6, 0x635d, 0x11e4, 0x8d, 0x8c, {0x9f, 0xba, 0xbe, 0x99, 0x56, 0xa5} } +#define UUID_SCP_FIRMWARE_BL30_CERT \ + {0x046fbe44, 0x635e, 0x11e4, 0xb2, 0x8b, {0x73, 0xd8, 0xea, 0xae, 0x96, 0x56} } +#define UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT \ + {0x200cb2e2, 0x635e, 0x11e4, 0x9c, 0xe8, {0xab, 0xcc, 0xf9, 0x2b, 0xb6, 0x66} } +#define UUID_SECURE_PAYLOAD_BL32_CERT \ + {0x11449fa4, 0x635e, 0x11e4, 0x87, 0x28, {0x3f, 0x05, 0x72, 0x2a, 0xf3, 0x3d} } +#define UUID_NON_TRUSTED_FIRMWARE_BL33_CERT \ + {0xf3c1c48e, 0x635d, 0x11e4, 0xa7, 0xa9, {0x87, 0xee, 0x40, 0xb2, 0x3f, 0xa7} } typedef struct fip_toc_header { uint32_t name; diff --git a/tools/fip_create/fip_create.c b/tools/fip_create/fip_create.c index c940c5b0d..c6869f956 100644 --- a/tools/fip_create/fip_create.c +++ b/tools/fip_create/fip_create.c @@ -65,6 +65,30 @@ static entry_lookup_list_t toc_entry_lookup_list[] = { "bl32", NULL, FLAG_FILENAME}, { "Non-Trusted Firmware BL3-3", UUID_NON_TRUSTED_FIRMWARE_BL33, "bl33", NULL, FLAG_FILENAME}, + /* Key Certificates */ + { "Root Of Trust key certificate", UUID_ROT_KEY_CERT, + "rot-cert", NULL, FLAG_FILENAME }, + { "Trusted key certificate", UUID_TRUSTED_KEY_CERT, + "trusted-key-cert", NULL, FLAG_FILENAME}, + { "SCP Firmware BL3-0 key certificate", UUID_SCP_FIRMWARE_BL30_KEY_CERT, + "bl30-key-cert", NULL, FLAG_FILENAME}, + { "EL3 Runtime Firmware BL3-1 key certificate", UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT, + "bl31-key-cert", NULL, FLAG_FILENAME}, + { "Secure Payload BL3-2 (Trusted OS) key certificate", UUID_SECURE_PAYLOAD_BL32_KEY_CERT, + "bl32-key-cert", NULL, FLAG_FILENAME}, + { "Non-Trusted Firmware BL3-3 key certificate", UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT, + "bl33-key-cert", NULL, FLAG_FILENAME}, + /* Content certificates */ + { "Trusted Boot Firmware BL2 certificate", UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT, + "bl2-cert", NULL, FLAG_FILENAME }, + { "SCP Firmware BL3-0 certificate", UUID_SCP_FIRMWARE_BL30_CERT, + "bl30-cert", NULL, FLAG_FILENAME}, + { "EL3 Runtime Firmware BL3-1 certificate", UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT, + "bl31-cert", NULL, FLAG_FILENAME}, + { "Secure Payload BL3-2 (Trusted OS) certificate", UUID_SECURE_PAYLOAD_BL32_CERT, + "bl32-cert", NULL, FLAG_FILENAME}, + { "Non-Trusted Firmware BL3-3 certificate", UUID_NON_TRUSTED_FIRMWARE_BL33_CERT, + "bl33-cert", NULL, FLAG_FILENAME}, { NULL, {0}, 0 } }; diff --git a/tools/fip_create/fip_create.h b/tools/fip_create/fip_create.h index ef321cd3f..32583352f 100644 --- a/tools/fip_create/fip_create.h +++ b/tools/fip_create/fip_create.h @@ -34,7 +34,7 @@ #include #include -#define MAX_FILES 10 +#define MAX_FILES 20 /* TODO: Update this number as required */ #define TOC_HEADER_SERIAL_NUMBER 0x12345678 From 6eadf7627fe1c2adb10b720210293fceea503b23 Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Wed, 7 Jan 2015 10:39:25 +0000 Subject: [PATCH 04/10] TBB: add a platform specific function to validate the ROTPK This patch adds the function plat_match_rotpk() to the platform porting layer to provide a Root Of Trust Public key (ROTPK) verification mechanism. This function is called during the Trusted Board Boot process and receives a supposed valid copy of the ROTPK as a parameter, usually obtained from an external source (for instance, a certificate). It returns 0 (success) if that key matches the actual ROTPK stored in the system or any other value otherwise. The mechanism to access the actual ROTPK stored in the system is platform specific and should be implemented as part of this function. The format of the ROTPK is also platform specific (to save memory, some platforms might store a hash of the key instead of the whole key). TRUSTED_BOARD_BOOT build option has been added to allow the user to enable the Trusted Board Boot features. The implementation of the plat_match_rotpk() funtion is mandatory when Trusted Board Boot is enabled. For development purposes, FVP and Juno ports provide a dummy function that returns always success (valid key). A safe trusted boot implementation should provide a proper matching function. Documentation updated accordingly. Change-Id: I74ff12bc2b041556c48533375527d9e8c035b8c3 --- Makefile | 6 +++++ docs/porting-guide.md | 11 +++++++++ include/plat/common/platform.h | 5 ++++ plat/fvp/fvp_trusted_boot.c | 45 ++++++++++++++++++++++++++++++++++ plat/fvp/platform.mk | 5 ++++ plat/juno/juno_trusted_boot.c | 45 ++++++++++++++++++++++++++++++++++ plat/juno/platform.mk | 5 ++++ 7 files changed, 122 insertions(+) create mode 100644 plat/fvp/fvp_trusted_boot.c create mode 100644 plat/juno/juno_trusted_boot.c diff --git a/Makefile b/Makefile index b5db6294b..e6abc182f 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,8 @@ FIP_NAME := fip.bin # Flags to generate the Chain of Trust GENERATE_COT := 0 CREATE_KEYS := 1 +# Flags to build TF with Trusted Boot support +TRUSTED_BOARD_BOOT := 0 # Checkpatch ignores CHECK_IGNORE = --ignore COMPLEX_MACRO @@ -243,6 +245,10 @@ $(eval $(call add_define,USE_COHERENT_MEM)) $(eval $(call assert_boolean,GENERATE_COT)) $(eval $(call assert_boolean,CREATE_KEYS)) +# Process TRUSTED_BOARD_BOOT flag +$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT)) +$(eval $(call add_define,TRUSTED_BOARD_BOOT)) + ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \ -Werror -Wmissing-include-dirs \ -mgeneral-regs-only -D__ASSEMBLY__ \ diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 747cb005b..a30535d77 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -392,6 +392,17 @@ The ARM FVP port uses this function to initialize the mailbox memory used for providing the warm-boot entry-point addresses. +### Function: plat_match_rotpk() + + Argument : const unsigned char *, unsigned int + Return : int + +This function is mandatory when Trusted Board Boot is enabled. It receives a +pointer to a buffer containing a signing key and its size as parameters and +returns 0 (success) if that key matches the ROT (Root Of Trust) key stored in +the platform. Any other return value means a mismatch. + + 2.3 Common optional modifications --------------------------------- diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 69bb749ae..18b7eae22 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -191,4 +191,9 @@ void bl31_plat_enable_mmu(uint32_t flags); ******************************************************************************/ void bl32_plat_enable_mmu(uint32_t flags); +/******************************************************************************* + * Trusted Boot functions + ******************************************************************************/ +int plat_match_rotpk(const unsigned char *, unsigned int); + #endif /* __PLATFORM_H__ */ diff --git a/plat/fvp/fvp_trusted_boot.c b/plat/fvp/fvp_trusted_boot.c new file mode 100644 index 000000000..e7dcc0199 --- /dev/null +++ b/plat/fvp/fvp_trusted_boot.c @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#include +#include +#include "fvp_def.h" +#include "fvp_private.h" + +/* + * Check the validity of the key + * + * 0 = success, Otherwise = error + */ +int plat_match_rotpk(const unsigned char *key_buf, unsigned int key_len) +{ + /* TODO: check against the ROT key stored in the platform */ + return 0; +} diff --git a/plat/fvp/platform.mk b/plat/fvp/platform.mk index 892e43cae..bcee3286d 100644 --- a/plat/fvp/platform.mk +++ b/plat/fvp/platform.mk @@ -89,3 +89,8 @@ BL31_SOURCES += drivers/arm/cci400/cci400.c \ plat/fvp/aarch64/fvp_helpers.S \ plat/fvp/aarch64/fvp_common.c \ plat/fvp/drivers/pwrc/fvp_pwrc.c + +ifneq (${TRUSTED_BOARD_BOOT},0) + BL1_SOURCES += plat/fvp/fvp_trusted_boot.c + BL2_SOURCES += plat/fvp/fvp_trusted_boot.c +endif diff --git a/plat/juno/juno_trusted_boot.c b/plat/juno/juno_trusted_boot.c new file mode 100644 index 000000000..e63d4b242 --- /dev/null +++ b/plat/juno/juno_trusted_boot.c @@ -0,0 +1,45 @@ +/* + * 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. + */ + +#include +#include +#include "juno_def.h" +#include "juno_private.h" + +/* + * Check the validity of the key + * + * 0 = success, Otherwise = error + */ +int plat_match_rotpk(const unsigned char *key_buf, unsigned int key_len) +{ + /* TODO: check against the ROT key stored in the platform */ + return 0; +} diff --git a/plat/juno/platform.mk b/plat/juno/platform.mk index 158e3ace3..8beaecf0a 100644 --- a/plat/juno/platform.mk +++ b/plat/juno/platform.mk @@ -90,6 +90,11 @@ BL31_SOURCES += drivers/arm/cci400/cci400.c \ plat/juno/plat_topology.c \ plat/juno/scpi.c +ifneq (${TRUSTED_BOARD_BOOT},0) + BL1_SOURCES += plat/juno/juno_trusted_boot.c + BL2_SOURCES += plat/juno/juno_trusted_boot.c +endif + ifneq (${RESET_TO_BL31},0) $(error "Using BL3-1 as the reset vector is not supported on Juno. \ Please set RESET_TO_BL31 to 0.") From e509d05728ac0a625e67d62197ad8bef73db6d88 Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Mon, 17 Nov 2014 17:27:41 +0000 Subject: [PATCH 05/10] stdlib: add missing features to build PolarSSL This patch adds the missing features to the C library included in the Trusted Firmware to build PolarSSL: - strcasecmp() function - exit() function - sscanf()* function - time.h header file (and its dependencies) * NOTE: the sscanf() function is not a real implementation. It just returns the number of expected arguments by counting the number of '%' characters present in the formar string. This return value is good enough for PolarSSL because during the certificate parsing only the return value is checked. The certificate validity period is ignored. Change-Id: I43bb3742f26f0bd458272fccc3d72a7f2176ab3d --- include/stdlib/inttypes.h | 52 +++++ include/stdlib/machine/_inttypes.h | 39 ++++ include/stdlib/stdio.h | 2 + include/stdlib/stdlib.h | 313 +++++++++++++++++++++++++++++ include/stdlib/string.h | 1 + include/stdlib/strings.h | 71 +++++++ include/stdlib/sys/_timespec.h | 49 +++++ include/stdlib/sys/timespec.h | 63 ++++++ include/stdlib/sys/types.h | 245 ++++++++++++++++++++++ include/stdlib/time.h | 204 +++++++++++++++++++ include/stdlib/xlocale/_strings.h | 48 +++++ include/stdlib/xlocale/_time.h | 58 ++++++ lib/stdlib/exit.c | 37 ++++ lib/stdlib/sscanf.c | 50 +++++ lib/stdlib/std.c | 2 + lib/stdlib/strcmp.c | 15 ++ 16 files changed, 1249 insertions(+) create mode 100644 include/stdlib/inttypes.h create mode 100644 include/stdlib/machine/_inttypes.h create mode 100644 include/stdlib/stdlib.h create mode 100644 include/stdlib/strings.h create mode 100644 include/stdlib/sys/_timespec.h create mode 100644 include/stdlib/sys/timespec.h create mode 100644 include/stdlib/sys/types.h create mode 100644 include/stdlib/time.h create mode 100644 include/stdlib/xlocale/_strings.h create mode 100644 include/stdlib/xlocale/_time.h create mode 100644 lib/stdlib/exit.c create mode 100644 lib/stdlib/sscanf.c diff --git a/include/stdlib/inttypes.h b/include/stdlib/inttypes.h new file mode 100644 index 000000000..269f3e7c9 --- /dev/null +++ b/include/stdlib/inttypes.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _INTTYPES_H_ +#define _INTTYPES_H_ + +#include +#include + +typedef struct { + intmax_t quot; /* Quotient. */ + intmax_t rem; /* Remainder. */ +} imaxdiv_t; + +__BEGIN_DECLS +#ifdef _XLOCALE_H_ +#include +#endif +intmax_t imaxabs(intmax_t) __pure2; +imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2; + +intmax_t strtoimax(const char *__restrict, char **__restrict, int); +uintmax_t strtoumax(const char *__restrict, char **__restrict, int); + +__END_DECLS + +#endif /* !_INTTYPES_H_ */ diff --git a/include/stdlib/machine/_inttypes.h b/include/stdlib/machine/_inttypes.h new file mode 100644 index 000000000..8dd07d649 --- /dev/null +++ b/include/stdlib/machine/_inttypes.h @@ -0,0 +1,39 @@ +/* + * 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 _MACHINE_INTTYPES_H_ +#define _MACHINE_INTTYPES_H_ + +/* + * Trusted Firmware does not depend on any definitions in this file. Content + * will be added as needed. + */ + +#endif /* !_MACHINE_INTTYPES_H_ */ diff --git a/include/stdlib/stdio.h b/include/stdlib/stdio.h index 1b8429b66..60e081b43 100644 --- a/include/stdlib/stdio.h +++ b/include/stdlib/stdio.h @@ -65,6 +65,8 @@ int sprintf(char * __restrict, const char * __restrict, ...); int vsprintf(char * __restrict, const char * __restrict, __va_list); +int sscanf(const char *__restrict, char const *__restrict, ...); + #if __ISO_C_VISIBLE >= 1999 int snprintf(char * __restrict, size_t, const char * __restrict, ...) __printflike(3, 4); diff --git a/include/stdlib/stdlib.h b/include/stdlib/stdlib.h new file mode 100644 index 000000000..b1ac1bf94 --- /dev/null +++ b/include/stdlib/stdlib.h @@ -0,0 +1,313 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)stdlib.h 8.5 (Berkeley) 5/19/95 + * $FreeBSD$ + */ + +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + +#include +#include +#include + +#if __BSD_VISIBLE +#ifndef _RUNE_T_DECLARED +typedef __rune_t rune_t; +#define _RUNE_T_DECLARED +#endif +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +typedef struct { + int quot; /* quotient */ + int rem; /* remainder */ +} div_t; + +typedef struct { + long quot; + long rem; +} ldiv_t; + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +#define RAND_MAX 0x7ffffffd + +__BEGIN_DECLS +#ifdef _XLOCALE_H_ +#include +#endif +extern int __mb_cur_max; +extern int ___mb_cur_max(void); +#define MB_CUR_MAX (___mb_cur_max()) + +_Noreturn void abort(void); +int abs(int) __pure2; +int atexit(void (*)(void)); +double atof(const char *); +int atoi(const char *); +long atol(const char *); +void *bsearch(const void *, const void *, size_t, + size_t, int (*)(const void *, const void *)); +void *calloc(size_t, size_t) __malloc_like; +div_t div(int, int) __pure2; +_Noreturn void exit(int); +void free(void *); +char *getenv(const char *); +long labs(long) __pure2; +ldiv_t ldiv(long, long) __pure2; +void *malloc(size_t) __malloc_like; +int mblen(const char *, size_t); +void qsort(void *, size_t, size_t, + int (*)(const void *, const void *)); +int rand(void); +void *realloc(void *, size_t); +void srand(unsigned); +double strtod(const char *__restrict, char **__restrict); +float strtof(const char *__restrict, char **__restrict); +long strtol(const char *__restrict, char **__restrict, int); +long double + strtold(const char *__restrict, char **__restrict); +unsigned long + strtoul(const char *__restrict, char **__restrict, int); +int system(const char *); + +/* + * Functions added in C99 which we make conditionally available in the + * BSD^C89 namespace if the compiler supports `long long'. + * The #if test is more complicated than it ought to be because + * __BSD_VISIBLE implies __ISO_C_VISIBLE == 1999 *even if* `long long' + * is not supported in the compilation environment (which therefore means + * that it can't really be ISO C99). + * + * (The only other extension made by C99 in thie header is _Exit().) + */ +#if __ISO_C_VISIBLE >= 1999 +#ifdef __LONG_LONG_SUPPORTED +/* LONGLONG */ +typedef struct { + long long quot; + long long rem; +} lldiv_t; + +/* LONGLONG */ +long long + atoll(const char *); +/* LONGLONG */ +long long + llabs(long long) __pure2; +/* LONGLONG */ +lldiv_t lldiv(long long, long long) __pure2; +/* LONGLONG */ +long long + strtoll(const char *__restrict, char **__restrict, int); +/* LONGLONG */ +unsigned long long + strtoull(const char *__restrict, char **__restrict, int); +#endif /* __LONG_LONG_SUPPORTED */ + +_Noreturn void _Exit(int); +#endif /* __ISO_C_VISIBLE >= 1999 */ + +/* + * If we're in a mode greater than C99, expose C11 functions. + */ +#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L +void *aligned_alloc(size_t, size_t) __malloc_like; +int at_quick_exit(void (*)(void)); +_Noreturn void + quick_exit(int); +#endif /* __ISO_C_VISIBLE >= 2011 */ +/* + * Extensions made by POSIX relative to C. + */ +#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE +char *realpath(const char *__restrict, char *__restrict); +#endif +#if __POSIX_VISIBLE >= 199506 +int rand_r(unsigned *); /* (TSF) */ +#endif +#if __POSIX_VISIBLE >= 200112 +int posix_memalign(void **, size_t, size_t); /* (ADV) */ +int setenv(const char *, const char *, int); +int unsetenv(const char *); +#endif + +#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE +int getsubopt(char **, char *const *, char **); +#ifndef _MKDTEMP_DECLARED +char *mkdtemp(char *); +#define _MKDTEMP_DECLARED +#endif +#ifndef _MKSTEMP_DECLARED +int mkstemp(char *); +#define _MKSTEMP_DECLARED +#endif +#endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */ + +/* + * The only changes to the XSI namespace in revision 6 were the deletion + * of the ttyslot() and valloc() functions, which FreeBSD never declared + * in this header. For revision 7, ecvt(), fcvt(), and gcvt(), which + * FreeBSD also does not have, and mktemp(), are to be deleted. + */ +#if __XSI_VISIBLE +/* XXX XSI requires pollution from here. We'd rather not. */ +long a64l(const char *); +double drand48(void); +/* char *ecvt(double, int, int * __restrict, int * __restrict); */ +double erand48(unsigned short[3]); +/* char *fcvt(double, int, int * __restrict, int * __restrict); */ +/* char *gcvt(double, int, int * __restrict, int * __restrict); */ +int grantpt(int); +char *initstate(unsigned long /* XSI requires u_int */, char *, long); +long jrand48(unsigned short[3]); +char *l64a(long); +void lcong48(unsigned short[7]); +long lrand48(void); +#if !defined(_MKTEMP_DECLARED) && (__BSD_VISIBLE || __XSI_VISIBLE <= 600) +char *mktemp(char *); +#define _MKTEMP_DECLARED +#endif +long mrand48(void); +long nrand48(unsigned short[3]); +int posix_openpt(int); +char *ptsname(int); +int putenv(char *); +long random(void); +unsigned short + *seed48(unsigned short[3]); +#ifndef _SETKEY_DECLARED +int setkey(const char *); +#define _SETKEY_DECLARED +#endif +char *setstate(/* const */ char *); +void srand48(long); +void srandom(unsigned long); +int unlockpt(int); +#endif /* __XSI_VISIBLE */ + +#if __BSD_VISIBLE +extern const char *malloc_conf; +extern void (*malloc_message)(void *, const char *); + +/* + * The alloca() function can't be implemented in C, and on some + * platforms it can't be implemented at all as a callable function. + * The GNU C compiler provides a built-in alloca() which we can use; + * in all other cases, provide a prototype, mainly to pacify various + * incarnations of lint. On platforms where alloca() is not in libc, + * programs which use it will fail to link when compiled with non-GNU + * compilers. + */ +#if __GNUC__ >= 2 || defined(__INTEL_COMPILER) +#undef alloca /* some GNU bits try to get cute and define this on their own */ +#define alloca(sz) __builtin_alloca(sz) +#elif defined(lint) +void *alloca(size_t); +#endif + +void abort2(const char *, int, void **) __dead2; +__uint32_t + arc4random(void); +void arc4random_addrandom(unsigned char *, int); +void arc4random_buf(void *, size_t); +void arc4random_stir(void); +__uint32_t + arc4random_uniform(__uint32_t); +#ifdef __BLOCKS__ +int atexit_b(void (^)(void)); +void *bsearch_b(const void *, const void *, size_t, + size_t, int (^)(const void *, const void *)); +#endif +char *getbsize(int *, long *); + /* getcap(3) functions */ +char *cgetcap(char *, const char *, int); +int cgetclose(void); +int cgetent(char **, char **, const char *); +int cgetfirst(char **, char **); +int cgetmatch(const char *, const char *); +int cgetnext(char **, char **); +int cgetnum(char *, const char *, long *); +int cgetset(const char *); +int cgetstr(char *, const char *, char **); +int cgetustr(char *, const char *, char **); + +int daemon(int, int); +char *devname(__dev_t, __mode_t); +char *devname_r(__dev_t, __mode_t, char *, int); +char *fdevname(int); +char *fdevname_r(int, char *, int); +int getloadavg(double [], int); +const char * + getprogname(void); + +int heapsort(void *, size_t, size_t, int (*)(const void *, const void *)); +#ifdef __BLOCKS__ +int heapsort_b(void *, size_t, size_t, int (^)(const void *, const void *)); +void qsort_b(void *, size_t, size_t, + int (^)(const void *, const void *)); +#endif +int l64a_r(long, char *, int); +int mergesort(void *, size_t, size_t, int (*)(const void *, const void *)); +#ifdef __BLOCKS__ +int mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *)); +#endif +int mkostemp(char *, int); +int mkostemps(char *, int, int); +void qsort_r(void *, size_t, size_t, void *, + int (*)(void *, const void *, const void *)); +int radixsort(const unsigned char **, int, const unsigned char *, + unsigned); +void *reallocf(void *, size_t); +int rpmatch(const char *); +void setprogname(const char *); +int sradixsort(const unsigned char **, int, const unsigned char *, + unsigned); +void sranddev(void); +void srandomdev(void); +long long + strtonum(const char *, long long, long long, const char **); + +/* Deprecated interfaces, to be removed in FreeBSD 6.0. */ +__int64_t + strtoq(const char *, char **, int); +__uint64_t + strtouq(const char *, char **, int); + +extern char *suboptarg; /* getsubopt(3) external variable */ +#endif /* __BSD_VISIBLE */ +__END_DECLS + +#endif /* !_STDLIB_H_ */ diff --git a/include/stdlib/string.h b/include/stdlib/string.h index 00a5dcd93..61e8102c2 100644 --- a/include/stdlib/string.h +++ b/include/stdlib/string.h @@ -59,6 +59,7 @@ char *strchr(const char *, int) __pure; int strcmp(const char *, const char *) __pure; size_t strlen(const char *) __pure; int strncmp(const char *, const char *, size_t) __pure; +int strcasecmp(const char *, const char *); __END_DECLS diff --git a/include/stdlib/strings.h b/include/stdlib/strings.h new file mode 100644 index 000000000..2210df04f --- /dev/null +++ b/include/stdlib/strings.h @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _STRINGS_H_ +#define _STRINGS_H_ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +__BEGIN_DECLS +#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 +int bcmp(const void *, const void *, size_t) __pure; /* LEGACY */ +void bcopy(const void *, void *, size_t); /* LEGACY */ +void bzero(void *, size_t); /* LEGACY */ +#endif +#if __BSD_VISIBLE +void explicit_bzero(void *, size_t); +#endif +#if __XSI_VISIBLE +int ffs(int) __pure2; +#endif +#if __BSD_VISIBLE +int ffsl(long) __pure2; +int ffsll(long long) __pure2; +int fls(int) __pure2; +int flsl(long) __pure2; +int flsll(long long) __pure2; +#endif +#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 +char *index(const char *, int) __pure; /* LEGACY */ +char *rindex(const char *, int) __pure; /* LEGACY */ +#endif +int strcasecmp(const char *, const char *) __pure; +int strncasecmp(const char *, const char *, size_t) __pure; + +#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) +#include +#endif +__END_DECLS + +#endif /* _STRINGS_H_ */ diff --git a/include/stdlib/sys/_timespec.h b/include/stdlib/sys/_timespec.h new file mode 100644 index 000000000..d51559c2a --- /dev/null +++ b/include/stdlib/sys/_timespec.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)time.h 8.5 (Berkeley) 5/4/95 + * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp + * $FreeBSD$ + */ + +#ifndef _SYS__TIMESPEC_H_ +#define _SYS__TIMESPEC_H_ + +#include + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; + +#endif /* !_SYS__TIMESPEC_H_ */ diff --git a/include/stdlib/sys/timespec.h b/include/stdlib/sys/timespec.h new file mode 100644 index 000000000..2505cef89 --- /dev/null +++ b/include/stdlib/sys/timespec.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)time.h 8.5 (Berkeley) 5/4/95 + * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp + * $FreeBSD$ + */ + +#ifndef _SYS_TIMESPEC_H_ +#define _SYS_TIMESPEC_H_ + +#include +#include + +#if __BSD_VISIBLE +#define TIMEVAL_TO_TIMESPEC(tv, ts) \ + do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ + } while (0) +#define TIMESPEC_TO_TIMEVAL(tv, ts) \ + do { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ + } while (0) + +#endif /* __BSD_VISIBLE */ + +/* + * Structure defined by POSIX.1b to be like a itimerval, but with + * timespecs. Used in the timer_*() system calls. + */ +struct itimerspec { + struct timespec it_interval; + struct timespec it_value; +}; + +#endif /* _SYS_TIMESPEC_H_ */ diff --git a/include/stdlib/sys/types.h b/include/stdlib/sys/types.h new file mode 100644 index 000000000..ae2ea33a5 --- /dev/null +++ b/include/stdlib/sys/types.h @@ -0,0 +1,245 @@ +/*- + * Copyright (c) 1982, 1986, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)types.h 8.6 (Berkeley) 2/19/95 + * $FreeBSD$ + */ + +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +#include + +/* Machine type dependent parameters. */ +#include + +#if __BSD_VISIBLE +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +#ifndef _KERNEL +typedef unsigned short ushort; /* Sys V compatibility */ +typedef unsigned int uint; /* Sys V compatibility */ +#endif +#endif + +/* + * XXX POSIX sized integrals that should appear only in . + */ +#include + +typedef __uint8_t u_int8_t; /* unsigned integrals (deprecated) */ +typedef __uint16_t u_int16_t; +typedef __uint32_t u_int32_t; +typedef __uint64_t u_int64_t; + +typedef __uint64_t u_quad_t; /* quads (deprecated) */ +typedef __int64_t quad_t; +typedef quad_t *qaddr_t; + +typedef char *caddr_t; /* core address */ +typedef const char *c_caddr_t; /* core address, pointer to const */ + +#ifndef _BLKSIZE_T_DECLARED +typedef __blksize_t blksize_t; +#define _BLKSIZE_T_DECLARED +#endif + +typedef __cpuwhich_t cpuwhich_t; +typedef __cpulevel_t cpulevel_t; +typedef __cpusetid_t cpusetid_t; + +#ifndef _BLKCNT_T_DECLARED +typedef __blkcnt_t blkcnt_t; +#define _BLKCNT_T_DECLARED +#endif + +#ifndef _CLOCK_T_DECLARED +typedef __clock_t clock_t; +#define _CLOCK_T_DECLARED +#endif + +#ifndef _CLOCKID_T_DECLARED +typedef __clockid_t clockid_t; +#define _CLOCKID_T_DECLARED +#endif + +typedef __critical_t critical_t; /* Critical section value */ +typedef __int64_t daddr_t; /* disk address */ + +#ifndef _DEV_T_DECLARED +typedef __dev_t dev_t; /* device number or struct cdev */ +#define _DEV_T_DECLARED +#endif + +#ifndef _FFLAGS_T_DECLARED +typedef __fflags_t fflags_t; /* file flags */ +#define _FFLAGS_T_DECLARED +#endif + +typedef __fixpt_t fixpt_t; /* fixed point number */ + +#ifndef _FSBLKCNT_T_DECLARED /* for statvfs() */ +typedef __fsblkcnt_t fsblkcnt_t; +typedef __fsfilcnt_t fsfilcnt_t; +#define _FSBLKCNT_T_DECLARED +#endif + +#ifndef _GID_T_DECLARED +typedef __gid_t gid_t; /* group id */ +#define _GID_T_DECLARED +#endif + +#ifndef _IN_ADDR_T_DECLARED +typedef __uint32_t in_addr_t; /* base type for internet address */ +#define _IN_ADDR_T_DECLARED +#endif + +#ifndef _IN_PORT_T_DECLARED +typedef __uint16_t in_port_t; +#define _IN_PORT_T_DECLARED +#endif + +#ifndef _ID_T_DECLARED +typedef __id_t id_t; /* can hold a uid_t or pid_t */ +#define _ID_T_DECLARED +#endif + +#ifndef _INO_T_DECLARED +typedef __ino_t ino_t; /* inode number */ +#define _INO_T_DECLARED +#endif + +#ifndef _KEY_T_DECLARED +typedef __key_t key_t; /* IPC key (for Sys V IPC) */ +#define _KEY_T_DECLARED +#endif + +#ifndef _LWPID_T_DECLARED +typedef __lwpid_t lwpid_t; /* Thread ID (a.k.a. LWP) */ +#define _LWPID_T_DECLARED +#endif + +#ifndef _MODE_T_DECLARED +typedef __mode_t mode_t; /* permissions */ +#define _MODE_T_DECLARED +#endif + +#ifndef _ACCMODE_T_DECLARED +typedef __accmode_t accmode_t; /* access permissions */ +#define _ACCMODE_T_DECLARED +#endif + +#ifndef _NLINK_T_DECLARED +typedef __nlink_t nlink_t; /* link count */ +#define _NLINK_T_DECLARED +#endif + +#ifndef _OFF_T_DECLARED +typedef __off_t off_t; /* file offset */ +#define _OFF_T_DECLARED +#endif + +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; /* process id */ +#define _PID_T_DECLARED +#endif + +typedef __register_t register_t; + +#ifndef _RLIM_T_DECLARED +typedef __rlim_t rlim_t; /* resource limit */ +#define _RLIM_T_DECLARED +#endif + +typedef __int64_t sbintime_t; + +typedef __segsz_t segsz_t; /* segment size (in pages) */ + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef _SSIZE_T_DECLARED +typedef __ssize_t ssize_t; +#define _SSIZE_T_DECLARED +#endif + +#ifndef _SUSECONDS_T_DECLARED +typedef __suseconds_t suseconds_t; /* microseconds (signed) */ +#define _SUSECONDS_T_DECLARED +#endif + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +#ifndef _TIMER_T_DECLARED +typedef __timer_t timer_t; +#define _TIMER_T_DECLARED +#endif + +#ifndef _MQD_T_DECLARED +typedef __mqd_t mqd_t; +#define _MQD_T_DECLARED +#endif + +typedef __u_register_t u_register_t; + +#ifndef _UID_T_DECLARED +typedef __uid_t uid_t; /* user id */ +#define _UID_T_DECLARED +#endif + +#ifndef _USECONDS_T_DECLARED +typedef __useconds_t useconds_t; /* microseconds (unsigned) */ +#define _USECONDS_T_DECLARED +#endif + +#ifndef _CAP_RIGHTS_T_DECLARED +#define _CAP_RIGHTS_T_DECLARED +struct cap_rights; + +typedef struct cap_rights cap_rights_t; +#endif + +typedef __vm_offset_t vm_offset_t; +typedef __vm_ooffset_t vm_ooffset_t; +typedef __vm_paddr_t vm_paddr_t; +typedef __vm_pindex_t vm_pindex_t; +typedef __vm_size_t vm_size_t; + +#endif /* !_SYS_TYPES_H_ */ diff --git a/include/stdlib/time.h b/include/stdlib/time.h new file mode 100644 index 000000000..08200cfb2 --- /dev/null +++ b/include/stdlib/time.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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. + * + * @(#)time.h 8.3 (Berkeley) 1/21/94 + */ + +/* + * $FreeBSD$ + */ + +#ifndef _TIME_H_ +#define _TIME_H_ + +#include +#include +#include + +#if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE +/* + * Frequency of the clock ticks reported by times(). Deprecated - use + * sysconf(_SC_CLK_TCK) instead. (Removed in 1003.1-2001.) + */ +#define CLK_TCK 128 +#endif + +/* Frequency of the clock ticks reported by clock(). */ +#define CLOCKS_PER_SEC 128 + +#ifndef _CLOCK_T_DECLARED +typedef __clock_t clock_t; +#define _CLOCK_T_DECLARED +#endif + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#if __POSIX_VISIBLE >= 199309 +/* + * New in POSIX 1003.1b-1993. + */ +#ifndef _CLOCKID_T_DECLARED +typedef __clockid_t clockid_t; +#define _CLOCKID_T_DECLARED +#endif + +#ifndef _TIMER_T_DECLARED +typedef __timer_t timer_t; +#define _TIMER_T_DECLARED +#endif + +#include +#endif /* __POSIX_VISIBLE >= 199309 */ + +#if __POSIX_VISIBLE >= 200112 +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; +#define _PID_T_DECLARED +#endif +#endif + +/* These macros are also in sys/time.h. */ +#if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 +#define CLOCK_REALTIME 0 +#ifdef __BSD_VISIBLE +#define CLOCK_VIRTUAL 1 +#define CLOCK_PROF 2 +#endif +#define CLOCK_MONOTONIC 4 +#define CLOCK_UPTIME 5 /* FreeBSD-specific. */ +#define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */ +#define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */ +#define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */ +#define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */ +#define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */ +#define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */ +#define CLOCK_SECOND 13 /* FreeBSD-specific. */ +#define CLOCK_THREAD_CPUTIME_ID 14 +#define CLOCK_PROCESS_CPUTIME_ID 15 +#endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */ + +#if !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 +#if __BSD_VISIBLE +#define TIMER_RELTIME 0x0 /* relative timer */ +#endif +#define TIMER_ABSTIME 0x1 /* absolute timer */ +#endif /* !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 */ + +struct tm { + int tm_sec; /* seconds after the minute [0-60] */ + int tm_min; /* minutes after the hour [0-59] */ + int tm_hour; /* hours since midnight [0-23] */ + int tm_mday; /* day of the month [1-31] */ + int tm_mon; /* months since January [0-11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday [0-6] */ + int tm_yday; /* days since January 1 [0-365] */ + int tm_isdst; /* Daylight Savings Time flag */ + long tm_gmtoff; /* offset from UTC in seconds */ + char *tm_zone; /* timezone abbreviation */ +}; + +#if __POSIX_VISIBLE +extern char *tzname[]; +#endif + +__BEGIN_DECLS +char *asctime(const struct tm *); +clock_t clock(void); +char *ctime(const time_t *); +double difftime(time_t, time_t); +/* XXX missing: getdate() */ +struct tm *gmtime(const time_t *); +struct tm *localtime(const time_t *); +time_t mktime(struct tm *); +size_t strftime(char *__restrict, size_t, const char *__restrict, + const struct tm *__restrict); +time_t time(time_t *); +#if __POSIX_VISIBLE >= 200112 +struct sigevent; +int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict); +int timer_delete(timer_t); +int timer_gettime(timer_t, struct itimerspec *); +int timer_getoverrun(timer_t); +int timer_settime(timer_t, int, const struct itimerspec *__restrict, + struct itimerspec *__restrict); +#endif +#if __POSIX_VISIBLE +void tzset(void); +#endif + +#if __POSIX_VISIBLE >= 199309 +int clock_getres(clockid_t, struct timespec *); +int clock_gettime(clockid_t, struct timespec *); +int clock_settime(clockid_t, const struct timespec *); +/* XXX missing: clock_nanosleep() */ +int nanosleep(const struct timespec *, struct timespec *); +#endif /* __POSIX_VISIBLE >= 199309 */ + +#if __POSIX_VISIBLE >= 200112 +int clock_getcpuclockid(pid_t, clockid_t *); +#endif + +#if __POSIX_VISIBLE >= 199506 +char *asctime_r(const struct tm *, char *); +char *ctime_r(const time_t *, char *); +struct tm *gmtime_r(const time_t *, struct tm *); +struct tm *localtime_r(const time_t *, struct tm *); +#endif + +#if __XSI_VISIBLE +char *strptime(const char *__restrict, const char *__restrict, + struct tm *__restrict); +#endif + +#if __BSD_VISIBLE +char *timezone(int, int); /* XXX XSI conflict */ +void tzsetwall(void); +time_t timelocal(struct tm * const); +time_t timegm(struct tm * const); +#endif /* __BSD_VISIBLE */ + +#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) +#include +#endif +__END_DECLS + +#endif /* !_TIME_H_ */ diff --git a/include/stdlib/xlocale/_strings.h b/include/stdlib/xlocale/_strings.h new file mode 100644 index 000000000..da1cff3e7 --- /dev/null +++ b/include/stdlib/xlocale/_strings.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +/* + * This file is included from both strings.h and xlocale.h. We need to expose + * the declarations unconditionally if we are included from xlocale.h, but only + * if we are in POSIX2008 mode if included from string.h. + */ + +#ifndef _XLOCALE_STRINGS1_H +#define _XLOCALE_STRINGS1_H + +/* + * POSIX2008 functions + */ +int strcasecmp_l(const char *, const char *, locale_t); +int strncasecmp_l(const char *, const char *, size_t, locale_t); +#endif /* _XLOCALE_STRINGS1_H */ diff --git a/include/stdlib/xlocale/_time.h b/include/stdlib/xlocale/_time.h new file mode 100644 index 000000000..6da49a427 --- /dev/null +++ b/include/stdlib/xlocale/_time.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2011, 2012 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by David Chisnall under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _LOCALE_T_DEFINED +#define _LOCALE_T_DEFINED +typedef struct _xlocale *locale_t; +#endif + +/* + * This file is included from both locale.h and xlocale.h. We need to expose + * the declarations unconditionally if we are included from xlocale.h, but only + * if we are in POSIX2008 mode if included from locale.h. + */ +#ifndef _XLOCALE_LOCALE1_H +#define _XLOCALE_LOCALE1_H + +size_t strftime_l(char *__restrict, size_t, const char *__restrict, + const struct tm *__restrict, locale_t) __strftimelike(3, 0); + +#endif /* _XLOCALE_LOCALE1_H */ + +#ifdef _XLOCALE_H_ +#ifndef _XLOCALE_LOCALE2_H +#define _XLOCALE_LOCALE2_H + +char *strptime_l(const char *__restrict, const char *__restrict, + struct tm *__restrict, locale_t); + +#endif /* _XLOCALE_LOCALE2_H */ +#endif /* _XLOCALE_H_ */ diff --git a/lib/stdlib/exit.c b/lib/stdlib/exit.c new file mode 100644 index 000000000..3e775914f --- /dev/null +++ b/lib/stdlib/exit.c @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#include + +void exit(int v) +{ + ERROR("EXIT\n"); + panic(); +} diff --git a/lib/stdlib/sscanf.c b/lib/stdlib/sscanf.c new file mode 100644 index 000000000..e9f5c4a19 --- /dev/null +++ b/lib/stdlib/sscanf.c @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#include + +/* + * TODO: This is not a real implementation of the sscanf() function. It just + * returns the number of expected arguments based on the number of '%' found + * in the format string. + */ +int +sscanf(const char *__restrict str, char const *__restrict fmt, ...) +{ + int ret = 0; + + while (*fmt != '\0') { + if (*fmt++ == '%') { + ret++; + } + } + + return ret; +} diff --git a/lib/stdlib/std.c b/lib/stdlib/std.c index 460875493..5f6ef752e 100644 --- a/lib/stdlib/std.c +++ b/lib/stdlib/std.c @@ -32,10 +32,12 @@ /* Include the various implemented functions */ #include "abort.c" #include "assert.c" +#include "exit.c" #include "mem.c" #include "printf.c" #include "putchar.c" #include "puts.c" +#include "sscanf.c" #include "strchr.c" #include "strcmp.c" #include "strlen.c" diff --git a/lib/stdlib/strcmp.c b/lib/stdlib/strcmp.c index 1d26f2bd2..bb86e0f2c 100644 --- a/lib/stdlib/strcmp.c +++ b/lib/stdlib/strcmp.c @@ -36,6 +36,7 @@ */ #include +#include #include /* @@ -49,3 +50,17 @@ strcmp(const char *s1, const char *s2) return 0; return *(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1); } + +int +strcasecmp(const char *s1, const char *s2) +{ + const unsigned char *us1 = (const unsigned char *)s1; + const unsigned char *us2 = (const unsigned char *)s2; + + while (tolower(*us1) == tolower(*us2)) { + if (*us1++ == '\0') + return 0; + us2++; + } + return tolower(*us1) - tolower(*us2); +} From db6071c99b100e7393a769277d5b5dfdf43aaf9b Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Tue, 13 Jan 2015 12:21:04 +0000 Subject: [PATCH 06/10] TBB: add PolarSSL based authentication module This patch implements an authentication module based on the PolarSSL library (v1.3.9) to verify the Chain of Trust when Trusted Boot is enabled. PolarSSL sources must be fetched separately. The POLARSSL_DIR build option may be used to indicate the path to the PolarSSL main directory (this directory must contain the 'include' and 'library' subdirectories). To be able to build PolarSSL sources as a part of the Trusted Firmware build process, the DISABLE_PEDANTIC flag in polarssl.mk will tell the build system to remove the -pedantic option from the CFLAGS. Inclusion of PolarSSL increases the memory requirements of the BL1 and BL2 images. The following are the changes made to the FVP and Juno platforms to cater for this when TRUSTED_BOARD_BOOT is defined: Changes on FVP: - BL1 and BL2 stacks have been increased to 4 KB - BL1(rw) section has been increased to 32 KB. - BL2 memory region has been increased to 112 KB Changes on Juno: - BL1 and BL2 stacks have been increased to 4 KB - BL1(rw) section has been increased to 32 KB. - Trusted ROM region in Flash has been increased to 128 KB. - BL2 memory region has been increased to 116 KB Change-Id: Ie87d80d43408eb6239c4acd0ec5ab2120e4e9e80 --- Makefile | 9 +- common/auth/polarssl/polarssl.c | 583 +++++++++++++++++++++++++ common/auth/polarssl/polarssl.mk | 69 +++ common/auth/polarssl/polarssl_config.h | 85 ++++ plat/fvp/include/platform_def.h | 17 + plat/juno/include/platform_def.h | 14 +- plat/juno/juno_def.h | 6 + 7 files changed, 781 insertions(+), 2 deletions(-) create mode 100644 common/auth/polarssl/polarssl.c create mode 100644 common/auth/polarssl/polarssl.mk create mode 100644 common/auth/polarssl/polarssl_config.h 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 From 40febc3ac81c9255bd64848cef0a37c0376740fa Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Tue, 13 Jan 2015 10:37:27 +0000 Subject: [PATCH 07/10] TBB: add authentication module interface This patch provides an API to access the authentication module that will be used to verify the authenticity of the images loaded into memory as part of the Trusted Board Boot process. To include the authentication module as part of the build, set the boolean build option TRUSTED_BOARD_BOOT. One single authentication module must be registered at build time by setting the build option AUTH_MOD=. All authentication modules will be located in 'common/auth/' and must present the .mk file that will be included by the build system to compile the module sources. To create an authentication module, an instance of auth_mod_t called 'auth_mod' must be declared in the module sources. The initialization and verification functions provided by the module will be exported through the function pointers specified when declaring this instance. If an authentication module includes third party sources that do not adhere to the C99 standard, the -pedantic option may be removed from the build options by setting the flag DISABLE_PEDANTIC in the module file .mk. Change-Id: I080bb04bd421029bcdf22ec2c63807afbf061dcd --- Makefile | 18 +++++++++ common/auth.c | 61 ++++++++++++++++++++++++++++++ include/common/auth.h | 88 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 common/auth.c create mode 100644 include/common/auth.h diff --git a/Makefile b/Makefile index 4a1e17dc7..9d4206c6c 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,7 @@ GENERATE_COT := 0 CREATE_KEYS := 1 # Flags to build TF with Trusted Boot support TRUSTED_BOARD_BOOT := 0 +AUTH_MOD := none # Checkpatch ignores CHECK_IGNORE = --ignore COMPLEX_MACRO @@ -306,6 +307,23 @@ ifneq (${GENERATE_COT},0) $(eval CRT_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT}) endif +# Check Trusted Board Boot options +ifneq (${TRUSTED_BOARD_BOOT},0) + ifeq (${AUTH_MOD},none) + $(error Error: When TRUSTED_BOARD_BOOT=1, AUTH_MOD has to be the name of a valid authentication module) + else + # We expect to locate an *.mk file under the specified AUTH_MOD directory + AUTH_MAKE := $(shell m="common/auth/${AUTH_MOD}/${AUTH_MOD}.mk"; [ -f "$$m" ] && echo "$$m") + ifeq (${AUTH_MAKE},) + $(error Error: No common/auth/${AUTH_MOD}/${AUTH_MOD}.mk located) + endif + $(info Including ${AUTH_MAKE}) + include ${AUTH_MAKE} + endif + + BL_COMMON_SOURCES += common/auth.c +endif + # Check if -pedantic option should be used ifeq (${DISABLE_PEDANTIC},0) CFLAGS += -pedantic diff --git a/common/auth.c b/common/auth.c new file mode 100644 index 000000000..37234b8e8 --- /dev/null +++ b/common/auth.c @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#include +#include +#include + +/* + * Initialize the authentication module + */ +void auth_init(void) +{ + assert(auth_mod.name); + assert(auth_mod.init); + assert(auth_mod.verify); + + INFO("Using authentication module '%s'\n", auth_mod.name); + if (auth_mod.init() != 0) + assert(0); +} + +/* + * Authenticate a certificate/image + * + * Return: 0 = success, Otherwise = error + */ +int auth_verify_obj(unsigned int obj_id, uintptr_t obj_buf, size_t len) +{ + assert(obj_id < AUTH_NUM_OBJ); + assert(obj_buf != 0); + assert(auth_mod.verify); + + return auth_mod.verify(obj_id, obj_buf, len); +} diff --git a/include/common/auth.h b/include/common/auth.h new file mode 100644 index 000000000..3c3a6bd05 --- /dev/null +++ b/include/common/auth.h @@ -0,0 +1,88 @@ +/* + * 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 AUTH_H_ +#define AUTH_H_ + +#include +#include + +/* + * Authentication infrastructure for Trusted Boot + * + * This infrastructure provides an API to access the authentication module. This + * module will implement the required operations for Trusted Boot by creating an + * instance of the structure 'auth_mod_t'. This instance must be called + * 'auth_mod' and must provide the functions to initialize the module and + * verify the authenticity of the images. + */ + +/* Objects (images and certificates) involved in the TBB process */ +enum { + AUTH_BL2_IMG_CERT, + AUTH_BL2_IMG, + AUTH_TRUSTED_KEY_CERT, + AUTH_BL30_KEY_CERT, + AUTH_BL30_IMG_CERT, + AUTH_BL30_IMG, + AUTH_BL31_KEY_CERT, + AUTH_BL31_IMG_CERT, + AUTH_BL31_IMG, + AUTH_BL32_KEY_CERT, + AUTH_BL32_IMG_CERT, + AUTH_BL32_IMG, + AUTH_BL33_KEY_CERT, + AUTH_BL33_IMG_CERT, + AUTH_BL33_IMG, + AUTH_NUM_OBJ +}; + +/* Authentication module structure */ +typedef struct auth_mod_s { + /* [mandatory] Module name. Printed to the log during initialization */ + const char *name; + + /* [mandatory] Initialize the authentication module */ + int (*init)(void); + + /* [mandatory] This function will be called to authenticate a new + * object loaded into memory. The obj_id corresponds to one of the + * values in the enumeration above */ + int (*verify)(unsigned int obj_id, uintptr_t obj_buf, size_t len); +} auth_mod_t; + +/* This variable must be instantiated by the authentication module */ +extern const auth_mod_t auth_mod; + +/* Public functions */ +void auth_init(void); +int auth_verify_obj(unsigned int obj_id, uintptr_t obj_buf, size_t len); + +#endif /* AUTH_H_ */ From 01df3c14677db0eab68f088f2721542f88ea4004 Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Wed, 7 Jan 2015 13:49:59 +0000 Subject: [PATCH 08/10] TBB: authenticate BL2 image and certificate This patch adds support to authenticate the BL2 content certificate and image using the authentication module in BL1. The FIP driver has been extended to include the BL2 certificate UUID. FVP and Juno ports include the BL2 certificate FIP file definition. Change-Id: I32680e9bd123c8db4a4193c14448c9b32b0e9325 --- bl1/bl1_main.c | 43 ++++++++++++++++++++++++++++++++ drivers/io/io_fip.c | 4 +++ plat/fvp/fvp_io_storage.c | 14 +++++++++++ plat/fvp/include/platform_def.h | 5 ++++ plat/juno/include/platform_def.h | 5 ++++ plat/juno/plat_io_storage.c | 14 +++++++++++ 6 files changed, 85 insertions(+) diff --git a/bl1/bl1_main.c b/bl1/bl1_main.c index a5bd648c0..491fd5cfc 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -141,6 +142,34 @@ void bl1_main(void) /* Find out how much free trusted ram remains after BL1 load */ bl1_tzram_layout = bl1_plat_sec_mem_layout(); +#if TRUSTED_BOARD_BOOT + /* Initialize authentication module */ + auth_init(); + + /* + * Load the BL2 certificate into the BL2 region. This region will be + * overwritten by the image, so the authentication module is responsible + * for storing the relevant data from the certificate (keys, hashes, + * etc.) so it can be used later. + */ + err = load_image(bl1_tzram_layout, + BL2_CERT_NAME, + BL2_BASE, + &bl2_image_info, + NULL); + if (err) { + ERROR("Failed to load BL2 certificate.\n"); + panic(); + } + + err = auth_verify_obj(AUTH_BL2_IMG_CERT, bl2_image_info.image_base, + bl2_image_info.image_size); + if (err) { + ERROR("Failed to validate BL2 certificate.\n"); + panic(); + } +#endif /* TRUSTED_BOARD_BOOT */ + /* Load the BL2 image */ err = load_image(bl1_tzram_layout, BL2_IMAGE_NAME, @@ -155,6 +184,20 @@ void bl1_main(void) ERROR("Failed to load BL2 firmware.\n"); panic(); } + +#if TRUSTED_BOARD_BOOT + err = auth_verify_obj(AUTH_BL2_IMG, bl2_image_info.image_base, + bl2_image_info.image_size); + if (err) { + ERROR("Failed to validate BL2 image.\n"); + panic(); + } + + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_image_info.image_base, + (size_t)bl2_image_info.image_size); +#endif /* TRUSTED_BOARD_BOOT */ + /* * Create a new layout of memory for BL2 as seen by BL1 i.e. * tell it the amount of total and free memory available. diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c index 4262a9de4..7d2059076 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -76,6 +76,10 @@ static const plat_fip_name_uuid_t name_uuid[] = { {BL32_IMAGE_NAME, UUID_SECURE_PAYLOAD_BL32}, #endif /* BL32_IMAGE_NAME */ {BL33_IMAGE_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33}, +#if TRUSTED_BOARD_BOOT + /* Certificates */ + {BL2_CERT_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT}, +#endif /* TRUSTED_BOARD_BOOT */ }; static const uuid_t uuid_null = {0}; diff --git a/plat/fvp/fvp_io_storage.c b/plat/fvp/fvp_io_storage.c index b4a04f19c..b1e033ee4 100644 --- a/plat/fvp/fvp_io_storage.c +++ b/plat/fvp/fvp_io_storage.c @@ -77,6 +77,13 @@ static const io_file_spec_t bl33_file_spec = { .mode = FOPEN_MODE_RB }; +#if TRUSTED_BOARD_BOOT +static const io_file_spec_t bl2_cert_file_spec = { + .path = BL2_CERT_NAME, + .mode = FOPEN_MODE_RB +}; +#endif /* TRUSTED_BOARD_BOOT */ + static int open_fip(const uintptr_t spec); static int open_memmap(const uintptr_t spec); @@ -114,6 +121,13 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&bl33_file_spec, open_fip }, { +#if TRUSTED_BOARD_BOOT + BL2_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl2_cert_file_spec, + open_fip + }, { +#endif /* TRUSTED_BOARD_BOOT */ 0, 0, 0 } }; diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index bd53bc7b7..edbbdf31a 100644 --- a/plat/fvp/include/platform_def.h +++ b/plat/fvp/include/platform_def.h @@ -80,6 +80,11 @@ /* Non-Trusted Firmware BL33 */ #define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */ +#if TRUSTED_BOARD_BOOT +/* Certificates */ +# define BL2_CERT_NAME "bl2.crt" +#endif /* TRUSTED_BOARD_BOOT */ + #define PLATFORM_CACHE_LINE_SIZE 64 #define PLATFORM_CLUSTER_COUNT 2ull #define PLATFORM_CLUSTER0_CORE_COUNT 4 diff --git a/plat/juno/include/platform_def.h b/plat/juno/include/platform_def.h index c64b68297..748b32d9f 100644 --- a/plat/juno/include/platform_def.h +++ b/plat/juno/include/platform_def.h @@ -71,6 +71,11 @@ /* Firmware Image Package */ #define FIP_IMAGE_NAME "fip.bin" +#if TRUSTED_BOARD_BOOT +/* Certificates */ +# define BL2_CERT_NAME "bl2.crt" +#endif /* TRUSTED_BOARD_BOOT */ + #define PLATFORM_CACHE_LINE_SIZE 64 #define PLATFORM_CLUSTER_COUNT 2 #define PLATFORM_CORE_COUNT 6 diff --git a/plat/juno/plat_io_storage.c b/plat/juno/plat_io_storage.c index 83d7e43ba..dd9f048af 100644 --- a/plat/juno/plat_io_storage.c +++ b/plat/juno/plat_io_storage.c @@ -77,6 +77,13 @@ static const io_file_spec_t bl33_file_spec = { .mode = FOPEN_MODE_RB }; +#if TRUSTED_BOARD_BOOT +static const io_file_spec_t bl2_cert_file_spec = { + .path = BL2_CERT_NAME, + .mode = FOPEN_MODE_RB +}; +#endif /* TRUSTED_BOARD_BOOT */ + static int open_fip(const uintptr_t spec); static int open_memmap(const uintptr_t spec); @@ -119,6 +126,13 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&bl33_file_spec, open_fip }, { +#if TRUSTED_BOARD_BOOT + BL2_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl2_cert_file_spec, + open_fip + }, { +#endif /* TRUSTED_BOARD_BOOT */ 0, 0, 0 } }; From bed82ac9dfa856ff034491c68b66b3661766d26e Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Wed, 28 Jan 2015 16:42:41 +0000 Subject: [PATCH 09/10] FVP: initialize IO framework in bl2_early_platform_setup() This patch moves fvp_io_setup() to bl2_early_platform_setup() in order to allow BL2 to use the IO framework before bl2_platform_setup(). Change-Id: I75e1a772ab5f9b4727f6727822a2527c30f3c63d --- plat/fvp/bl2_fvp_setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plat/fvp/bl2_fvp_setup.c b/plat/fvp/bl2_fvp_setup.c index 5764b6a98..364833fe9 100644 --- a/plat/fvp/bl2_fvp_setup.c +++ b/plat/fvp/bl2_fvp_setup.c @@ -175,6 +175,9 @@ void bl2_early_platform_setup(meminfo_t *mem_layout) /* Initialize the platform config for future decision making */ fvp_config_setup(); + + /* Initialise the IO layer and register platform IO devices */ + fvp_io_setup(); } /******************************************************************************* @@ -190,9 +193,6 @@ void bl2_platform_setup(void) * present. */ fvp_security_setup(); - - /* Initialise the IO layer and register platform IO devices */ - fvp_io_setup(); } /* Flush the TF params and the TF plat params */ From dec840af4b2d071516863faa274e9fa68a72d42a Mon Sep 17 00:00:00 2001 From: Juan Castillo Date: Wed, 28 Jan 2015 16:46:57 +0000 Subject: [PATCH 10/10] TBB: authenticate BL3-x images and certificates This patch adds support to authenticate the Trusted Key certificate and the BL3-x certificates and images at BL2. Change-Id: I69a8c13a14c8da8b75f93097d3a4576aed71c5dd --- bl2/bl2_main.c | 215 ++++++++++++++++++++++++++++++- drivers/io/io_fip.c | 13 ++ plat/fvp/fvp_io_storage.c | 90 +++++++++++++ plat/fvp/include/platform_def.h | 11 ++ plat/juno/include/platform_def.h | 11 ++ plat/juno/plat_io_storage.c | 90 +++++++++++++ 6 files changed, 428 insertions(+), 2 deletions(-) diff --git a/bl2/bl2_main.c b/bl2/bl2_main.c index b7e2cff4f..29ca0a5ab 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -31,12 +31,149 @@ #include #include #include +#include #include #include #include #include #include "bl2_private.h" +#if TRUSTED_BOARD_BOOT + +#ifdef BL32_BASE +static int bl32_cert_error; +#endif + +/* + * Load and authenticate the key and content certificates for a BL3-x image + * + * Parameters: + * key_cert_blob: key certificate blob id (see auth.h) + * key_cert_name: key certificate filename + * cont_cert_blob: content certificate blob id (see auth.h) + * cont_cert_name: content certificate filename + * mem_layout: Trusted SRAM memory layout + * load_addr: load the certificates at this address + * + * Return: 0 = success, Otherwise = error + */ +static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name, + int cont_cert_blob, const char *cont_cert_name, + meminfo_t *mem_layout, uint64_t load_addr) +{ + image_info_t image_info; + int err; + + /* Load Key certificate */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, key_cert_name, load_addr, &image_info, NULL); + if (err) { + ERROR("Cannot load %s.\n", key_cert_name); + return err; + } + + err = auth_verify_obj(key_cert_blob, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid key certificate %s.\n", key_cert_name); + return err; + } + + /* Load Content certificate */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, cont_cert_name, load_addr, &image_info, NULL); + if (err) { + ERROR("Cannot load %s.\n", cont_cert_name); + return err; + } + + err = auth_verify_obj(cont_cert_blob, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid content certificate %s.\n", cont_cert_name); + return err; + } + + return 0; +} + +/* + * Load and authenticate the Trusted Key certificate the key and content + * certificates for each of the BL3-x images. + * + * Return: 0 = success, Otherwise = error + */ +static int load_certs(void) +{ + const uint64_t load_addr = BL31_BASE; + image_info_t image_info; + meminfo_t *mem_layout; + int err; + + /* Find out how much free trusted ram remains after BL2 load */ + mem_layout = bl2_plat_sec_mem_layout(); + + /* Load the Trusted Key certificate in the BL31 region */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, TRUSTED_KEY_CERT_NAME, load_addr, + &image_info, NULL); + if (err) { + ERROR("Failed to load Trusted Key certificate.\n"); + return err; + } + + /* Validate the certificate */ + err = auth_verify_obj(AUTH_TRUSTED_KEY_CERT, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid Trusted Key certificate.\n"); + return err; + } + + /* Load and validate Key and Content certificates for BL3-x images */ +#ifdef BL30_BASE + err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_NAME, + AUTH_BL30_IMG_CERT, BL30_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-0 authenticity\n"); + return err; + } +#endif /* BL30_BASE */ + + err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_NAME, + AUTH_BL31_IMG_CERT, BL31_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-1 authenticity\n"); + return err; + } + +#ifdef BL32_BASE + /* BL3-2 image is optional, but keep the return value in case the + * image is present but the certificate is missing */ + err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_NAME, + AUTH_BL32_IMG_CERT, BL32_CERT_NAME, + mem_layout, load_addr); + if (err) { + WARN("Failed to verify BL3-2 authenticity\n"); + } + bl32_cert_error = err; +#endif /* BL32_BASE */ + + err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_NAME, + AUTH_BL33_IMG_CERT, BL33_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-3 authenticity\n"); + return err; + } + + return 0; +} + +#endif /* TRUSTED_BOARD_BOOT */ + /******************************************************************************* * Load the BL3-0 image if there's one. * If a platform does not want to attempt to load BL3-0 image it must leave @@ -69,6 +206,20 @@ static int load_bl30(void) NULL); if (e == 0) { +#if TRUSTED_BOARD_BOOT + e = auth_verify_obj(AUTH_BL30_IMG, + bl30_image_info.image_base, + bl30_image_info.image_size); + if (e) { + ERROR("Failed to authenticate BL3-0 image.\n"); + panic(); + } + + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl30_image_info.image_base, + (size_t)bl30_image_info.image_size); +#endif /* TRUSTED_BOARD_BOOT */ + /* The subsequent handling of BL3-0 is platform specific */ bl2_plat_handle_bl30(&bl30_image_info); } @@ -106,9 +257,24 @@ static int load_bl31(bl31_params_t *bl2_to_bl31_params, bl2_to_bl31_params->bl31_image_info, bl31_ep_info); - if (e == 0) + if (e == 0) { +#if TRUSTED_BOARD_BOOT + e = auth_verify_obj(AUTH_BL31_IMG, + bl2_to_bl31_params->bl31_image_info->image_base, + bl2_to_bl31_params->bl31_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-1 image.\n"); + panic(); + } + + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl31_image_info->image_base, + (size_t)bl2_to_bl31_params->bl31_image_info->image_size); +#endif /* TRUSTED_BOARD_BOOT */ + bl2_plat_set_bl31_ep_info(bl2_to_bl31_params->bl31_image_info, bl31_ep_info); + } return e; } @@ -144,6 +310,25 @@ static int load_bl32(bl31_params_t *bl2_to_bl31_params) bl2_to_bl31_params->bl32_ep_info); if (e == 0) { +#if TRUSTED_BOARD_BOOT + /* Image is present. Check if there is a valid certificate */ + if (bl32_cert_error) { + ERROR("Failed to authenticate BL3-2 certificates.\n"); + panic(); + } + + e = auth_verify_obj(AUTH_BL32_IMG, + bl2_to_bl31_params->bl32_image_info->image_base, + bl2_to_bl31_params->bl32_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-2 image.\n"); + panic(); + } + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl32_image_info->image_base, + (size_t)bl2_to_bl31_params->bl32_image_info->image_size); +#endif /* TRUSTED_BOARD_BOOT */ + bl2_plat_set_bl32_ep_info( bl2_to_bl31_params->bl32_image_info, bl2_to_bl31_params->bl32_ep_info); @@ -176,9 +361,23 @@ static int load_bl33(bl31_params_t *bl2_to_bl31_params) bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info); - if (e == 0) + if (e == 0) { +#if TRUSTED_BOARD_BOOT + e = auth_verify_obj(AUTH_BL33_IMG, + bl2_to_bl31_params->bl33_image_info->image_base, + bl2_to_bl31_params->bl33_image_info->image_size); + if (e) { + ERROR("Failed to authenticate BL3-3 image.\n"); + panic(); + } + /* After working with data, invalidate the data cache */ + inv_dcache_range(bl2_to_bl31_params->bl33_image_info->image_base, + (size_t)bl2_to_bl31_params->bl33_image_info->image_size); +#endif /* TRUSTED_BOARD_BOOT */ + bl2_plat_set_bl33_ep_info(bl2_to_bl31_params->bl33_image_info, bl2_to_bl31_params->bl33_ep_info); + } return e; } @@ -200,6 +399,18 @@ void bl2_main(void) /* Perform remaining generic architectural setup in S-EL1 */ bl2_arch_setup(); +#if TRUSTED_BOARD_BOOT + /* Initialize authentication module */ + auth_init(); + + /* Validate the certificates involved in the Chain of Trust */ + e = load_certs(); + if (e) { + ERROR("Chain of Trust invalid. Aborting...\n"); + panic(); + } +#endif /* TRUSTED_BOARD_BOOT */ + /* * Load the subsequent bootloader images */ diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c index 7d2059076..0cec80448 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -79,6 +79,19 @@ static const plat_fip_name_uuid_t name_uuid[] = { #if TRUSTED_BOARD_BOOT /* Certificates */ {BL2_CERT_NAME, UUID_TRUSTED_BOOT_FIRMWARE_BL2_CERT}, + {TRUSTED_KEY_CERT_NAME, UUID_TRUSTED_KEY_CERT}, +#ifdef BL30_KEY_CERT_NAME + {BL30_KEY_CERT_NAME, UUID_SCP_FIRMWARE_BL30_KEY_CERT}, +#endif + {BL31_KEY_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_KEY_CERT}, + {BL32_KEY_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_KEY_CERT}, + {BL33_KEY_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_KEY_CERT}, +#ifdef BL30_CERT_NAME + {BL30_CERT_NAME, UUID_SCP_FIRMWARE_BL30_CERT}, +#endif + {BL31_CERT_NAME, UUID_EL3_RUNTIME_FIRMWARE_BL31_CERT}, + {BL32_CERT_NAME, UUID_SECURE_PAYLOAD_BL32_CERT}, + {BL33_CERT_NAME, UUID_NON_TRUSTED_FIRMWARE_BL33_CERT}, #endif /* TRUSTED_BOARD_BOOT */ }; diff --git a/plat/fvp/fvp_io_storage.c b/plat/fvp/fvp_io_storage.c index b1e033ee4..ec1fe584c 100644 --- a/plat/fvp/fvp_io_storage.c +++ b/plat/fvp/fvp_io_storage.c @@ -82,6 +82,51 @@ static const io_file_spec_t bl2_cert_file_spec = { .path = BL2_CERT_NAME, .mode = FOPEN_MODE_RB }; + +static const io_file_spec_t trusted_key_cert_file_spec = { + .path = TRUSTED_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_key_cert_file_spec = { + .path = BL30_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_key_cert_file_spec = { + .path = BL31_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_key_cert_file_spec = { + .path = BL32_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_key_cert_file_spec = { + .path = BL33_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_cert_file_spec = { + .path = BL30_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_cert_file_spec = { + .path = BL31_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_cert_file_spec = { + .path = BL32_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_cert_file_spec = { + .path = BL33_CERT_NAME, + .mode = FOPEN_MODE_RB +}; #endif /* TRUSTED_BOARD_BOOT */ static int open_fip(const uintptr_t spec); @@ -127,6 +172,51 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&bl2_cert_file_spec, open_fip }, { + TRUSTED_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&trusted_key_cert_file_spec, + open_fip + }, { + BL30_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_key_cert_file_spec, + open_fip + }, { + BL31_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_key_cert_file_spec, + open_fip + }, { + BL32_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_key_cert_file_spec, + open_fip + }, { + BL33_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_key_cert_file_spec, + open_fip + }, { + BL30_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_cert_file_spec, + open_fip + }, { + BL31_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_cert_file_spec, + open_fip + }, { + BL32_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_cert_file_spec, + open_fip + }, { + BL33_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_cert_file_spec, + open_fip + }, { #endif /* TRUSTED_BOARD_BOOT */ 0, 0, 0 } diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index edbbdf31a..326ba9d98 100644 --- a/plat/fvp/include/platform_def.h +++ b/plat/fvp/include/platform_def.h @@ -83,6 +83,17 @@ #if TRUSTED_BOARD_BOOT /* Certificates */ # define BL2_CERT_NAME "bl2.crt" +# define TRUSTED_KEY_CERT_NAME "trusted_key.crt" + +# define BL30_KEY_CERT_NAME "bl30_key.crt" +# define BL31_KEY_CERT_NAME "bl31_key.crt" +# define BL32_KEY_CERT_NAME "bl32_key.crt" +# define BL33_KEY_CERT_NAME "bl33_key.crt" + +# define BL30_CERT_NAME "bl30.crt" +# define BL31_CERT_NAME "bl31.crt" +# define BL32_CERT_NAME "bl32.crt" +# define BL33_CERT_NAME "bl33.crt" #endif /* TRUSTED_BOARD_BOOT */ #define PLATFORM_CACHE_LINE_SIZE 64 diff --git a/plat/juno/include/platform_def.h b/plat/juno/include/platform_def.h index 748b32d9f..1071d1205 100644 --- a/plat/juno/include/platform_def.h +++ b/plat/juno/include/platform_def.h @@ -74,6 +74,17 @@ #if TRUSTED_BOARD_BOOT /* Certificates */ # define BL2_CERT_NAME "bl2.crt" +# define TRUSTED_KEY_CERT_NAME "trusted_key.crt" + +# define BL30_KEY_CERT_NAME "bl30_key.crt" +# define BL31_KEY_CERT_NAME "bl31_key.crt" +# define BL32_KEY_CERT_NAME "bl32_key.crt" +# define BL33_KEY_CERT_NAME "bl33_key.crt" + +# define BL30_CERT_NAME "bl30.crt" +# define BL31_CERT_NAME "bl31.crt" +# define BL32_CERT_NAME "bl32.crt" +# define BL33_CERT_NAME "bl33.crt" #endif /* TRUSTED_BOARD_BOOT */ #define PLATFORM_CACHE_LINE_SIZE 64 diff --git a/plat/juno/plat_io_storage.c b/plat/juno/plat_io_storage.c index dd9f048af..b31865e44 100644 --- a/plat/juno/plat_io_storage.c +++ b/plat/juno/plat_io_storage.c @@ -82,6 +82,51 @@ static const io_file_spec_t bl2_cert_file_spec = { .path = BL2_CERT_NAME, .mode = FOPEN_MODE_RB }; + +static const io_file_spec_t trusted_key_cert_file_spec = { + .path = TRUSTED_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_key_cert_file_spec = { + .path = BL30_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_key_cert_file_spec = { + .path = BL31_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_key_cert_file_spec = { + .path = BL32_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_key_cert_file_spec = { + .path = BL33_KEY_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl30_cert_file_spec = { + .path = BL30_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl31_cert_file_spec = { + .path = BL31_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl32_cert_file_spec = { + .path = BL32_CERT_NAME, + .mode = FOPEN_MODE_RB +}; + +static const io_file_spec_t bl33_cert_file_spec = { + .path = BL33_CERT_NAME, + .mode = FOPEN_MODE_RB +}; #endif /* TRUSTED_BOARD_BOOT */ static int open_fip(const uintptr_t spec); @@ -132,6 +177,51 @@ static const struct plat_io_policy policies[] = { (uintptr_t)&bl2_cert_file_spec, open_fip }, { + TRUSTED_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&trusted_key_cert_file_spec, + open_fip + }, { + BL30_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_key_cert_file_spec, + open_fip + }, { + BL31_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_key_cert_file_spec, + open_fip + }, { + BL32_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_key_cert_file_spec, + open_fip + }, { + BL33_KEY_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_key_cert_file_spec, + open_fip + }, { + BL30_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl30_cert_file_spec, + open_fip + }, { + BL31_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl31_cert_file_spec, + open_fip + }, { + BL32_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl32_cert_file_spec, + open_fip + }, { + BL33_CERT_NAME, + &fip_dev_handle, + (uintptr_t)&bl33_cert_file_spec, + open_fip + }, { #endif /* TRUSTED_BOARD_BOOT */ 0, 0, 0 }