summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanh-arm <dan.handley@arm.com>2015-01-28 18:41:12 +0000
committerdanh-arm <dan.handley@arm.com>2015-01-28 18:41:12 +0000
commit2d017e2241fd091a0926394c3e08eb362f77679d (patch)
tree0338507519574f6f86cd77f31f1ec956d5729429
parent03b2370386f5acbb4fb11614825c67ff38ef9edc (diff)
parentdec840af4b2d071516863faa274e9fa68a72d42a (diff)
Merge pull request #249 from danh-arm/jc/tbb_prototypev1.1-rc0
Trusted Board Boot Prototype
-rw-r--r--.gitignore2
-rw-r--r--Makefile140
-rw-r--r--bl1/bl1_main.c43
-rw-r--r--bl2/bl2_main.c215
-rw-r--r--common/auth.c61
-rw-r--r--common/auth/polarssl/polarssl.c583
-rw-r--r--common/auth/polarssl/polarssl.mk69
-rw-r--r--common/auth/polarssl/polarssl_config.h85
-rw-r--r--common/bl_common.c11
-rw-r--r--docs/porting-guide.md11
-rw-r--r--drivers/io/io_fip.c17
-rw-r--r--include/common/auth.h88
-rw-r--r--include/common/firmware_image_package.h26
-rw-r--r--include/plat/common/platform.h5
-rw-r--r--include/stdlib/inttypes.h52
-rw-r--r--include/stdlib/machine/_inttypes.h39
-rw-r--r--include/stdlib/stdio.h2
-rw-r--r--include/stdlib/stdlib.h313
-rw-r--r--include/stdlib/string.h1
-rw-r--r--include/stdlib/strings.h71
-rw-r--r--include/stdlib/sys/_timespec.h49
-rw-r--r--include/stdlib/sys/timespec.h63
-rw-r--r--include/stdlib/sys/types.h245
-rw-r--r--include/stdlib/time.h204
-rw-r--r--include/stdlib/xlocale/_strings.h48
-rw-r--r--include/stdlib/xlocale/_time.h58
-rw-r--r--lib/stdlib/exit.c37
-rw-r--r--lib/stdlib/sscanf.c50
-rw-r--r--lib/stdlib/std.c2
-rw-r--r--lib/stdlib/strcmp.c15
-rw-r--r--plat/fvp/bl2_fvp_setup.c6
-rw-r--r--plat/fvp/fvp_io_storage.c104
-rw-r--r--plat/fvp/fvp_trusted_boot.c45
-rw-r--r--plat/fvp/include/platform_def.h33
-rw-r--r--plat/fvp/include/platform_oid.h69
-rw-r--r--plat/fvp/platform.mk5
-rw-r--r--plat/juno/include/platform_def.h30
-rw-r--r--plat/juno/include/platform_oid.h69
-rw-r--r--plat/juno/juno_def.h6
-rw-r--r--plat/juno/juno_trusted_boot.c45
-rw-r--r--plat/juno/plat_io_storage.c104
-rw-r--r--plat/juno/platform.mk5
-rw-r--r--tools/cert_create/Makefile92
-rw-r--r--tools/cert_create/include/cert.h69
-rw-r--r--tools/cert_create/include/debug.h83
-rw-r--r--tools/cert_create/include/ext.h70
-rw-r--r--tools/cert_create/include/key.h57
-rw-r--r--tools/cert_create/include/sha.h36
-rw-r--r--tools/cert_create/include/tbb_cert.h58
-rw-r--r--tools/cert_create/include/tbb_ext.h38
-rw-r--r--tools/cert_create/include/tbb_key.h55
-rw-r--r--tools/cert_create/src/cert.c180
-rw-r--r--tools/cert_create/src/ext.c233
-rw-r--r--tools/cert_create/src/key.c131
-rw-r--r--tools/cert_create/src/main.c719
-rw-r--r--tools/cert_create/src/sha.c64
-rw-r--r--tools/cert_create/src/tbb_cert.c111
-rw-r--r--tools/cert_create/src/tbb_ext.c118
-rw-r--r--tools/cert_create/src/tbb_key.c67
-rw-r--r--tools/fip_create/fip_create.c24
-rw-r--r--tools/fip_create/fip_create.h2
61 files changed, 5312 insertions, 21 deletions
diff --git a/.gitignore b/.gitignore
index 42200188..d3567bcb 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 c59cdb49..9d4206c6 100644
--- a/Makefile
+++ b/Makefile
@@ -67,6 +67,14 @@ 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
+# Flags to build TF with Trusted Boot support
+TRUSTED_BOARD_BOOT := 0
+AUTH_MOD := none
# Checkpatch ignores
CHECK_IGNORE = --ignore COMPLEX_MACRO
@@ -182,7 +190,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,11 +244,19 @@ $(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))
+
+# 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__ \
${DEFINES} ${INCLUDES}
-CFLAGS += -nostdinc -pedantic -ffreestanding -Wall \
+CFLAGS += -nostdinc -ffreestanding -Wall \
-Werror -Wmissing-include-dirs \
-mgeneral-regs-only -std=c99 -c -Os \
${DEFINES} ${INCLUDES}
@@ -266,6 +282,53 @@ 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)
+
+ $(eval FIP_DEPS += certificates)
+ $(eval FIP_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT})
+
+ 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
+
+# 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
+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 +342,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 +363,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 +470,39 @@ 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 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),)))
+$(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 +543,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 +553,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 +583,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 +596,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 +639,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/bl1/bl1_main.c b/bl1/bl1_main.c
index a5bd648c..491fd5cf 100644
--- a/bl1/bl1_main.c
+++ b/bl1/bl1_main.c
@@ -31,6 +31,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
+#include <auth.h>
#include <bl_common.h>
#include <debug.h>
#include <platform.h>
@@ -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/bl2/bl2_main.c b/bl2/bl2_main.c
index b7e2cff4..29ca0a5a 100644
--- a/bl2/bl2_main.c
+++ b/bl2/bl2_main.c
@@ -31,12 +31,149 @@
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
+#include <auth.h>
#include <bl_common.h>
#include <debug.h>
#include <platform.h>
#include <platform_def.h>
#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/common/auth.c b/common/auth.c
new file mode 100644
index 00000000..37234b8e
--- /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 <assert.h>
+#include <auth.h>
+#include <debug.h>
+
+/*
+ * 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/common/auth/polarssl/polarssl.c b/common/auth/polarssl/polarssl.c
new file mode 100644
index 00000000..e099f50c
--- /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 <stddef.h>
+
+#include <assert.h>
+#include <auth.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <platform_oid.h>
+
+#include <polarssl/memory_buffer_alloc.h>
+#include <polarssl/oid.h>
+#include <polarssl/platform.h>
+#include <polarssl/sha256.h>
+#include <polarssl/x509_crt.h>
+
+/*
+ * 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 00000000..f7d92ea8
--- /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 := "<polarssl_config.h>"
+$(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 00000000..531e0845
--- /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/common/bl_common.c b/common/bl_common.c
index 60f8b2f7..8c241ec4 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;
diff --git a/docs/porting-guide.md b/docs/porting-guide.md
index 747cb005..a30535d7 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/drivers/io/io_fip.c b/drivers/io/io_fip.c
index 4262a9de..0cec8044 100644
--- a/drivers/io/io_fip.c
+++ b/drivers/io/io_fip.c
@@ -76,6 +76,23 @@ 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},
+ {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 */
};
static const uuid_t uuid_null = {0};
diff --git a/include/common/auth.h b/include/common/auth.h
new file mode 100644
index 00000000..3c3a6bd0
--- /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 <stddef.h>
+#include <stdint.h>
+
+/*
+ * 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_ */
diff --git a/include/common/firmware_image_package.h b/include/common/firmware_image_package.h
index f4554ecc..8fb669e3 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/include/plat/common/platform.h b/include/plat/common/platform.h
index 69bb749a..18b7eae2 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/include/stdlib/inttypes.h b/include/stdlib/inttypes.h
new file mode 100644
index 00000000..269f3e7c
--- /dev/null
+++ b/include/stdlib/inttypes.h
@@ -0,0 +1,52 @@
+/*-
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * 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 <machine/_inttypes.h>
+#include <sys/stdint.h>
+
+typedef struct {
+ intmax_t quot; /* Quotient. */
+ intmax_t rem; /* Remainder. */
+} imaxdiv_t;
+
+__BEGIN_DECLS
+#ifdef _XLOCALE_H_
+#include <xlocale/_inttypes.h>
+#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 00000000..8dd07d64
--- /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 1b8429b6..60e081b4 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 00000000..b1ac1bf9
--- /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 <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#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 <xlocale/_stdlib.h>
+#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 <sys/wait.h> 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 00a5dcd9..61e8102c 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 00000000..2210df04
--- /dev/null
+++ b/include/stdlib/strings.h
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * 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 <sys/cdefs.h>
+#include <sys/_types.h>
+
+#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 <xlocale/_strings.h>
+#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 00000000..d51559c2
--- /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 <sys/_types.h>
+
+#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 00000000..2505cef8
--- /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 <sys/cdefs.h>
+#include <sys/_timespec.h>
+
+#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 00000000..ae2ea33a
--- /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 <sys/cdefs.h>
+
+/* Machine type dependent parameters. */
+#include <sys/_types.h>
+
+#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 <sys/stdint.h>.
+ */
+#include <sys/_stdint.h>
+
+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 00000000..08200cfb
--- /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 <sys/cdefs.h>
+#include <sys/_null.h>
+#include <sys/_types.h>
+
+#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 <sys/timespec.h>
+#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 <xlocale/_time.h>
+#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 00000000..da1cff3e
--- /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 00000000..6da49a42
--- /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 00000000..3e775914
--- /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 <debug.h>
+
+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 00000000..e9f5c4a1
--- /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 <sys/cdefs.h>
+
+/*
+ * 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 46087549..5f6ef752 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 1d26f2bd..bb86e0f2 100644
--- a/lib/stdlib/strcmp.c
+++ b/lib/stdlib/strcmp.c
@@ -36,6 +36,7 @@
*/
#include <sys/cdefs.h>
+#include <sys/ctype.h>
#include <string.h>
/*
@@ -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);
+}
diff --git a/plat/fvp/bl2_fvp_setup.c b/plat/fvp/bl2_fvp_setup.c
index 5764b6a9..364833fe 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 */
diff --git a/plat/fvp/fvp_io_storage.c b/plat/fvp/fvp_io_storage.c
index b4a04f19..ec1fe584 100644
--- a/plat/fvp/fvp_io_storage.c
+++ b/plat/fvp/fvp_io_storage.c
@@ -77,6 +77,58 @@ 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
+};
+
+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);
static int open_memmap(const uintptr_t spec);
@@ -114,6 +166,58 @@ 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
+ }, {
+ 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/fvp_trusted_boot.c b/plat/fvp/fvp_trusted_boot.c
new file mode 100644
index 00000000..e7dcc019
--- /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 <assert.h>
+#include <debug.h>
+#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/include/platform_def.h b/plat/fvp/include/platform_def.h
index b0460e08..326ba9d9 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
@@ -72,6 +80,22 @@
/* Non-Trusted Firmware BL33 */
#define BL33_IMAGE_NAME "bl33.bin" /* e.g. UEFI */
+#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
#define PLATFORM_CLUSTER_COUNT 2ull
#define PLATFORM_CLUSTER0_CORE_COUNT 4
@@ -96,8 +120,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 +137,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/fvp/include/platform_oid.h b/plat/fvp/include/platform_oid.h
new file mode 100644
index 00000000..38aca120
--- /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/fvp/platform.mk b/plat/fvp/platform.mk
index 892e43ca..bcee3286 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/include/platform_def.h b/plat/juno/include/platform_def.h
index cd077021..1071d120 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"
@@ -67,6 +71,22 @@
/* Firmware Image Package */
#define FIP_IMAGE_NAME "fip.bin"
+#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
#define PLATFORM_CLUSTER_COUNT 2
#define PLATFORM_CORE_COUNT 6
@@ -87,7 +107,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 +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 - 0x1D000)
+#else
#define BL2_BASE (BL31_BASE - 0xC000)
+#endif
#define BL2_LIMIT BL31_BASE
/*******************************************************************************
diff --git a/plat/juno/include/platform_oid.h b/plat/juno/include/platform_oid.h
new file mode 100644
index 00000000..38aca120
--- /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/plat/juno/juno_def.h b/plat/juno/juno_def.h
index 8e1a83df..8a85aecd 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
diff --git a/plat/juno/juno_trusted_boot.c b/plat/juno/juno_trusted_boot.c
new file mode 100644
index 00000000..e63d4b24
--- /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 <assert.h>
+#include <debug.h>
+#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/plat_io_storage.c b/plat/juno/plat_io_storage.c
index 83d7e43b..b31865e4 100644
--- a/plat/juno/plat_io_storage.c
+++ b/plat/juno/plat_io_storage.c
@@ -77,6 +77,58 @@ 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
+};
+
+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);
static int open_memmap(const uintptr_t spec);
@@ -119,6 +171,58 @@ 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
+ }, {
+ 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/juno/platform.mk b/plat/juno/platform.mk
index 158e3ace..8beaecf0 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.")
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
new file mode 100644
index 00000000..f1aa7974
--- /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=<platform>.)
+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 00000000..48a41462
--- /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 <openssl/ossl_typ.h>
+#include <openssl/x509.h>
+#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 00000000..dd0510a5
--- /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 <stdio.h>
+
+/* 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 00000000..d73f5734
--- /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 <openssl/x509v3.h>
+
+/*
+ * 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 00000000..88197500
--- /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 <openssl/ossl_typ.h>
+
+#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 00000000..466d6689
--- /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 00000000..4e481258
--- /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 00000000..155d3cb4
--- /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 00000000..cc927d1e
--- /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 00000000..9705643d
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/sha.h>
+#include <openssl/x509v3.h>
+
+#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 00000000..31f84a86
--- /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 <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#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 00000000..b5737d93
--- /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 <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+#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 00000000..6df367a2
--- /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 <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/sha.h>
+#include <openssl/x509v3.h>
+
+#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 <file> \\\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 00000000..57026b56
--- /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 <stdio.h>
+#include <openssl/sha.h>
+
+#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 00000000..8dfda605
--- /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 00000000..0022611c
--- /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 <stdio.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#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 00000000..140aeda1
--- /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"
+ }
+};
diff --git a/tools/fip_create/fip_create.c b/tools/fip_create/fip_create.c
index c940c5b0..c6869f95 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 ef321cd3..32583352 100644
--- a/tools/fip_create/fip_create.h
+++ b/tools/fip_create/fip_create.h
@@ -34,7 +34,7 @@
#include <stdint.h>
#include <uuid.h>
-#define MAX_FILES 10
+#define MAX_FILES 20
/* TODO: Update this number as required */
#define TOC_HEADER_SERIAL_NUMBER 0x12345678