diff --git a/.gitignore b/.gitignore index 4220018..d3567bc 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ # 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 c59cdb4..9d4206c 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,14 @@ 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 @@ # 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 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: ${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 @@ @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 @@ @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 @@ $(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 @@ 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 @@ 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 @@ 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 @@ $(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 @@ @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 a5bd648..491fd5c 100644 --- a/bl1/bl1_main.c +++ b/bl1/bl1_main.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -141,6 +142,34 @@ /* 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 @@ 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 b7e2cff..29ca0a5 100644 --- a/bl2/bl2_main.c +++ b/bl2/bl2_main.c @@ -31,12 +31,149 @@ #include #include #include +#include #include #include #include #include #include "bl2_private.h" +#if TRUSTED_BOARD_BOOT + +#ifdef BL32_BASE +static int bl32_cert_error; +#endif + +/* + * Load and authenticate the key and content certificates for a BL3-x image + * + * Parameters: + * key_cert_blob: key certificate blob id (see auth.h) + * key_cert_name: key certificate filename + * cont_cert_blob: content certificate blob id (see auth.h) + * cont_cert_name: content certificate filename + * mem_layout: Trusted SRAM memory layout + * load_addr: load the certificates at this address + * + * Return: 0 = success, Otherwise = error + */ +static int load_cert_bl3x(int key_cert_blob, const char *key_cert_name, + int cont_cert_blob, const char *cont_cert_name, + meminfo_t *mem_layout, uint64_t load_addr) +{ + image_info_t image_info; + int err; + + /* Load Key certificate */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, key_cert_name, load_addr, &image_info, NULL); + if (err) { + ERROR("Cannot load %s.\n", key_cert_name); + return err; + } + + err = auth_verify_obj(key_cert_blob, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid key certificate %s.\n", key_cert_name); + return err; + } + + /* Load Content certificate */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, cont_cert_name, load_addr, &image_info, NULL); + if (err) { + ERROR("Cannot load %s.\n", cont_cert_name); + return err; + } + + err = auth_verify_obj(cont_cert_blob, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid content certificate %s.\n", cont_cert_name); + return err; + } + + return 0; +} + +/* + * Load and authenticate the Trusted Key certificate the key and content + * certificates for each of the BL3-x images. + * + * Return: 0 = success, Otherwise = error + */ +static int load_certs(void) +{ + const uint64_t load_addr = BL31_BASE; + image_info_t image_info; + meminfo_t *mem_layout; + int err; + + /* Find out how much free trusted ram remains after BL2 load */ + mem_layout = bl2_plat_sec_mem_layout(); + + /* Load the Trusted Key certificate in the BL31 region */ + image_info.h.version = VERSION_1; + err = load_image(mem_layout, TRUSTED_KEY_CERT_NAME, load_addr, + &image_info, NULL); + if (err) { + ERROR("Failed to load Trusted Key certificate.\n"); + return err; + } + + /* Validate the certificate */ + err = auth_verify_obj(AUTH_TRUSTED_KEY_CERT, image_info.image_base, + image_info.image_size); + if (err) { + ERROR("Invalid Trusted Key certificate.\n"); + return err; + } + + /* Load and validate Key and Content certificates for BL3-x images */ +#ifdef BL30_BASE + err = load_cert_bl3x(AUTH_BL30_KEY_CERT, BL30_KEY_CERT_NAME, + AUTH_BL30_IMG_CERT, BL30_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-0 authenticity\n"); + return err; + } +#endif /* BL30_BASE */ + + err = load_cert_bl3x(AUTH_BL31_KEY_CERT, BL31_KEY_CERT_NAME, + AUTH_BL31_IMG_CERT, BL31_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-1 authenticity\n"); + return err; + } + +#ifdef BL32_BASE + /* BL3-2 image is optional, but keep the return value in case the + * image is present but the certificate is missing */ + err = load_cert_bl3x(AUTH_BL32_KEY_CERT, BL32_KEY_CERT_NAME, + AUTH_BL32_IMG_CERT, BL32_CERT_NAME, + mem_layout, load_addr); + if (err) { + WARN("Failed to verify BL3-2 authenticity\n"); + } + bl32_cert_error = err; +#endif /* BL32_BASE */ + + err = load_cert_bl3x(AUTH_BL33_KEY_CERT, BL33_KEY_CERT_NAME, + AUTH_BL33_IMG_CERT, BL33_CERT_NAME, + mem_layout, load_addr); + if (err) { + ERROR("Failed to verify BL3-3 authenticity\n"); + return err; + } + + return 0; +} + +#endif /* TRUSTED_BOARD_BOOT */ + /******************************************************************************* * Load the BL3-0 image if there's one. * If a platform does not want to attempt to load BL3-0 image it must leave @@ -69,6 +206,20 @@ 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 @@ 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 @@ 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 @@ 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 @@ /* 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 0000000..37234b8 --- /dev/null +++ b/common/auth.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +/* + * Initialize the authentication module + */ +void auth_init(void) +{ + assert(auth_mod.name); + assert(auth_mod.init); + assert(auth_mod.verify); + + INFO("Using authentication module '%s'\n", auth_mod.name); + if (auth_mod.init() != 0) + assert(0); +} + +/* + * Authenticate a certificate/image + * + * Return: 0 = success, Otherwise = error + */ +int auth_verify_obj(unsigned int obj_id, uintptr_t obj_buf, size_t len) +{ + assert(obj_id < AUTH_NUM_OBJ); + assert(obj_buf != 0); + assert(auth_mod.verify); + + return auth_mod.verify(obj_id, obj_buf, len); +} diff --git a/common/auth/polarssl/polarssl.c b/common/auth/polarssl/polarssl.c new file mode 100644 index 0000000..e099f50 --- /dev/null +++ b/common/auth/polarssl/polarssl.c @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Authentication module based on PolarSSL */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * At each authentication stage, the module is responsible for extracting and + * storing those elements (keys, hashes, etc.) that will be needed later on + * during the Trusted Boot process. + */ + +/* SHA256 algorithm */ +#define SHA_BYTES 32 + +/* + * An 8 KB stack has been proven to be enough for the current Trusted Boot + * process + */ +#define POLARSSL_HEAP_SIZE (8*1024) +static unsigned char heap[POLARSSL_HEAP_SIZE]; + +/* + * RSA public keys: + * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 + * algorithm AlgorithmIdentifier, 1 + 1 (sequence) + * + 1 + 1 + 9 (rsa oid) + * + 1 + 1 (params null) + * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) + * RSAPublicKey ::= SEQUENCE { 1 + 3 + * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 + * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 + * } + * + * POLARSSL_MPI_MAX_SIZE is set to 256 bytes (RSA-2048 bit keys) in the + * configuration file + */ +#define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE + +/* + * Buffer for storing public keys extracted from certificates while they are + * verified + */ +static unsigned char pk_buf[RSA_PUB_DER_MAX_BYTES]; + +/* We use this variable to parse and authenticate the certificates */ +static x509_crt cert; + +/* BL specific variables */ +#if IMAGE_BL1 +static unsigned char sha_bl2[SHA_BYTES]; +#elif IMAGE_BL2 +/* Buffers to store the hash of BL3-x images */ +static unsigned char sha_bl30[SHA_BYTES]; +static unsigned char sha_bl31[SHA_BYTES]; +static unsigned char sha_bl32[SHA_BYTES]; +static unsigned char sha_bl33[SHA_BYTES]; +/* Buffers to store the Trusted and Non-Trusted world public keys */ +static unsigned char tz_world_pk[RSA_PUB_DER_MAX_BYTES]; +static unsigned char ntz_world_pk[RSA_PUB_DER_MAX_BYTES]; +static size_t tz_world_pk_len, ntz_world_pk_len; +/* Buffer to store the BL3-x public keys */ +static unsigned char content_pk[RSA_PUB_DER_MAX_BYTES]; +static size_t content_pk_len; +#endif + + +static int x509_get_crt_ext_data(const unsigned char **ext_data, + size_t *ext_len, + x509_crt *crt, + const char *oid) +{ + int ret; + size_t len; + unsigned char *end_ext_data, *end_ext_octet; + unsigned char *p; + const unsigned char *end; + char oid_str[64]; + + p = crt->v3_ext.p; + end = crt->v3_ext.p + crt->v3_ext.len; + + ret = asn1_get_tag(&p, end, &len, ASN1_CONSTRUCTED | ASN1_SEQUENCE); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + if (end != p + len) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + while (p < end) { + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + x509_buf extn_oid = {0, 0, NULL}; + int is_critical = 0; /* DEFAULT FALSE */ + + ret = asn1_get_tag(&p, end, &len, + ASN1_CONSTRUCTED | ASN1_SEQUENCE); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + end_ext_data = p + len; + + /* Get extension ID */ + extn_oid.tag = *p; + + ret = asn1_get_tag(&p, end, &extn_oid.len, ASN1_OID); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + extn_oid.p = p; + p += extn_oid.len; + + if ((end - p) < 1) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_OUT_OF_DATA; + + /* Get optional critical */ + ret = asn1_get_bool(&p, end_ext_data, &is_critical); + if (ret != 0 && (ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG)) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + /* Data should be octet string type */ + ret = asn1_get_tag(&p, end_ext_data, &len, ASN1_OCTET_STRING); + if (ret != 0) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret; + + end_ext_octet = p + len; + + if (end_ext_octet != end_ext_data) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + /* Detect requested extension */ + oid_get_numeric_string(oid_str, 64, &extn_oid); + if (memcmp(oid, oid_str, sizeof(oid)) == 0) { + *ext_data = p; + *ext_len = len; + return 0; + } + + /* Next */ + p = end_ext_octet; + } + + if (p != end) + return POLARSSL_ERR_X509_INVALID_EXTENSIONS + + POLARSSL_ERR_ASN1_LENGTH_MISMATCH; + + return POLARSSL_ERR_X509_UNKNOWN_OID; +} + +#if IMAGE_BL1 +/* + * Parse and verify the BL2 certificate + * + * This function verifies the integrity of the BL2 certificate, checks that it + * has been signed with the ROT key and extracts the BL2 hash stored in the + * certificate so it can be matched later against the calculated hash. + * + * Return: 0 = success, Otherwise = error + */ +static int check_bl2_cert(unsigned char *buf, size_t len) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse the BL2 certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("BL2 certificate parse error %d.\n", err); + goto error; + } + + /* Check that it has been signed with the ROT key */ + err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + if (err < 0) { + ERROR("Error loading ROT key in DER format %d.\n", err); + goto error; + } + + sz = (size_t)err; + p = pk_buf + sizeof(pk_buf) - sz; + + err = plat_match_rotpk(p, sz); + if (err) { + ERROR("ROT and BL2 certificate key mismatch\n"); + goto error; + } + + /* Verify certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("BL2 certificate verification error %d. Flags: 0x%x.\n", + err, flags); + goto error; + } + + /* Extract BL2 image hash from certificate */ + err = x509_get_crt_ext_data(&p, &sz, &cert, BL2_HASH_OID); + if (err) { + ERROR("Cannot read BL2 hash from certificate\n"); + goto error; + } + + assert(sz == SHA_BYTES + 2); + + /* Skip the tag and length bytes and copy the hash */ + p += 2; + memcpy(sha_bl2, p, SHA_BYTES); + +error: + x509_crt_free(&cert); + + return err; +} +#endif /* IMAGE_BL1 */ + +#if IMAGE_BL2 +static int check_trusted_key_cert(unsigned char *buf, size_t len) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse the Trusted Key certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("Trusted Key certificate parse error %d.\n", err); + goto error; + } + + /* Verify Trusted Key certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("Trusted Key certificate verification error %d. Flags: " + "0x%x.\n", err, flags); + goto error; + } + + /* Check that it has been signed with the ROT key */ + err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + if (err < 0) { + ERROR("Error loading ROT key in DER format %d.\n", err); + goto error; + } + + sz = (size_t)err; + p = pk_buf + sizeof(pk_buf) - sz; + + if (plat_match_rotpk(p, sz)) { + ERROR("ROT and Trusted Key certificate key mismatch\n"); + goto error; + } + + /* Extract Trusted World key from extensions */ + err = x509_get_crt_ext_data(&p, &tz_world_pk_len, + &cert, TZ_WORLD_PK_OID); + if (err) { + ERROR("Cannot read Trusted World key\n"); + goto error; + } + + assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES); + memcpy(tz_world_pk, p, tz_world_pk_len); + + /* Extract Non-Trusted World key from extensions */ + err = x509_get_crt_ext_data(&p, &ntz_world_pk_len, + &cert, NTZ_WORLD_PK_OID); + if (err) { + ERROR("Cannot read Non-Trusted World key\n"); + goto error; + } + + assert(tz_world_pk_len <= RSA_PUB_DER_MAX_BYTES); + memcpy(ntz_world_pk, p, ntz_world_pk_len); + +error: + x509_crt_free(&cert); + + return err; +} + +static int check_bl3x_key_cert(const unsigned char *buf, size_t len, + const unsigned char *i_key, size_t i_key_len, + unsigned char *s_key, size_t *s_key_len, + const char *key_oid) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse key certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("Key certificate parse error %d.\n", err); + goto error; + } + + /* Verify certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("Key certificate verification error %d. Flags: " + "0x%x.\n", err, flags); + goto error; + } + + /* Check that the certificate has been signed by the issuer */ + err = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + if (err < 0) { + ERROR("Error loading key in DER format %d.\n", err); + goto error; + } + + sz = (size_t)err; + p = pk_buf + sizeof(pk_buf) - sz; + if ((sz != i_key_len) || memcmp(p, i_key, sz)) { + ERROR("Key certificate not signed with issuer key\n"); + err = 1; + goto error; + } + + /* Get the content certificate key */ + err = x509_get_crt_ext_data(&p, &sz, &cert, key_oid); + if (err) { + ERROR("Extension %s not found in Key certificate\n", key_oid); + goto error; + } + + assert(sz <= RSA_PUB_DER_MAX_BYTES); + memcpy(s_key, p, sz); + *s_key_len = sz; + +error: + x509_crt_free(&cert); + + return err; +} + +static int check_bl3x_cert(unsigned char *buf, size_t len, + const unsigned char *i_key, size_t i_key_len, + const char *hash_oid, unsigned char *sha) +{ + const unsigned char *p; + size_t sz; + int err, flags; + + x509_crt_init(&cert); + + /* Parse BL31 content certificate */ + err = x509_crt_parse(&cert, buf, len); + if (err) { + ERROR("Content certificate parse error %d.\n", err); + goto error; + } + + /* Verify certificate */ + err = x509_crt_verify(&cert, &cert, NULL, NULL, &flags, NULL, NULL); + if (err) { + ERROR("Content certificate verification error %d. Flags: " + "0x%x.\n", err, flags); + goto error; + } + + /* Check that content certificate has been signed with the content + * certificate key corresponding to this image */ + sz = pk_write_pubkey_der(&cert.pk, pk_buf, sizeof(pk_buf)); + p = pk_buf + sizeof(pk_buf) - sz; + + if ((sz != i_key_len) || memcmp(p, i_key, sz)) { + ERROR("Content certificate not signed with content " + "certificate key\n"); + err = 1; + goto error; + } + + /* Extract image hash from certificate */ + err = x509_get_crt_ext_data(&p, &sz, &cert, hash_oid); + if (err) { + ERROR("Cannot read hash from certificate\n"); + goto error; + } + + assert(sz == SHA_BYTES + 2); + + /* Skip the tag and length bytes and copy the hash */ + p += 2; + memcpy(sha, p, SHA_BYTES); + +error: + x509_crt_free(&cert); + + return err; +} +#endif /* IMAGE_BL2 */ + +/* + * Calculate the hash of the image and check it against the hash extracted + * previously from the certificate + * + * Parameters: + * buf: buffer where image is loaded + * len: size of the image + * sha: matching hash (extracted from the image certificate) + * + * Return: 0 = match, Otherwise = mismatch + */ +static int check_bl_img(unsigned char *buf, size_t len, + const unsigned char *sha) +{ + unsigned char img_sha[SHA_BYTES]; + + /* Calculate the hash of the image */ + sha256(buf, len, img_sha, 0); + + /* Match the hash with the one extracted from the certificate */ + if (memcmp(img_sha, sha, SHA_BYTES)) { + ERROR("Image hash mismatch\n"); + return 1; + } + + return 0; +} + +/* + * Object verification function + * + * The id parameter will indicate the expected format of the object + * (certificate, image, etc). + * + * Return: 0 = success, Otherwise = error + */ +static int polarssl_mod_verify(unsigned int id, uintptr_t obj, size_t len) +{ + int ret; + + switch (id) { +#if IMAGE_BL1 + case AUTH_BL2_IMG_CERT: + ret = check_bl2_cert((unsigned char *)obj, len); + break; + case AUTH_BL2_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl2); + break; +#endif /* IMAGE_BL1 */ + +#if IMAGE_BL2 + case AUTH_TRUSTED_KEY_CERT: + ret = check_trusted_key_cert((unsigned char *)obj, len); + break; + case AUTH_BL30_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + tz_world_pk, tz_world_pk_len, + content_pk, &content_pk_len, + BL30_CONTENT_CERT_PK_OID); + break; + case AUTH_BL31_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + tz_world_pk, tz_world_pk_len, + content_pk, &content_pk_len, + BL31_CONTENT_CERT_PK_OID); + break; + case AUTH_BL32_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + tz_world_pk, tz_world_pk_len, + content_pk, &content_pk_len, + BL32_CONTENT_CERT_PK_OID); + break; + case AUTH_BL33_KEY_CERT: + ret = check_bl3x_key_cert((unsigned char *)obj, len, + ntz_world_pk, ntz_world_pk_len, + content_pk, &content_pk_len, + BL33_CONTENT_CERT_PK_OID); + break; + case AUTH_BL30_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL30_HASH_OID, sha_bl30); + break; + case AUTH_BL31_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL31_HASH_OID, sha_bl31); + break; + case AUTH_BL32_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL32_HASH_OID, sha_bl32); + break; + case AUTH_BL33_IMG_CERT: + ret = check_bl3x_cert((unsigned char *)obj, len, + content_pk, content_pk_len, + BL33_HASH_OID, sha_bl33); + break; + case AUTH_BL30_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl30); + break; + case AUTH_BL31_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl31); + break; + case AUTH_BL32_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl32); + break; + case AUTH_BL33_IMG: + ret = check_bl_img((unsigned char *)obj, len, sha_bl33); + break; +#endif /* IMAGE_BL2 */ + default: + ret = -1; + break; + } + + return ret; +} + +/* + * Module initialization function + * + * Return: 0 = success, Otherwise = error + */ +static int polarssl_mod_init(void) +{ + /* Initialize the PolarSSL heap */ + return memory_buffer_alloc_init(heap, POLARSSL_HEAP_SIZE); +} + +const auth_mod_t auth_mod = { + .name = "PolarSSL", + .init = polarssl_mod_init, + .verify = polarssl_mod_verify +}; diff --git a/common/auth/polarssl/polarssl.mk b/common/auth/polarssl/polarssl.mk new file mode 100644 index 0000000..f7d92ea --- /dev/null +++ b/common/auth/polarssl/polarssl.mk @@ -0,0 +1,69 @@ +# +# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +# POLARSSL_DIR must be set to the PolarSSL main directory (it must contain +# the 'include' and 'library' subdirectories). +ifeq (${POLARSSL_DIR},) + $(error Error: POLARSSL_DIR not set) +endif + +INCLUDES += -I${POLARSSL_DIR}/include \ + -Icommon/auth/polarssl + +POLARSSL_CONFIG_FILE := "" +$(eval $(call add_define,POLARSSL_CONFIG_FILE)) + +POLARSSL_SOURCES := $(addprefix ${POLARSSL_DIR}/library/, \ + asn1parse.c \ + asn1write.c \ + bignum.c \ + md.c \ + md_wrap.c \ + memory_buffer_alloc.c \ + oid.c \ + pk.c \ + pk_wrap.c \ + pkparse.c \ + pkwrite.c \ + platform.c \ + rsa.c \ + sha1.c \ + sha256.c \ + x509.c \ + x509_crt.c \ + ) + +BL1_SOURCES += ${POLARSSL_SOURCES} \ + common/auth/polarssl/polarssl.c + +BL2_SOURCES += ${POLARSSL_SOURCES} \ + common/auth/polarssl/polarssl.c + +DISABLE_PEDANTIC := 1 diff --git a/common/auth/polarssl/polarssl_config.h b/common/auth/polarssl/polarssl_config.h new file mode 100644 index 0000000..531e084 --- /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 60f8b2f..8c241ec 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -275,9 +275,16 @@ * 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 747cb00..a30535d 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -392,6 +392,17 @@ 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 4262a9d..0cec804 100644 --- a/drivers/io/io_fip.c +++ b/drivers/io/io_fip.c @@ -76,6 +76,23 @@ {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 0000000..3c3a6bd --- /dev/null +++ b/include/common/auth.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef AUTH_H_ +#define AUTH_H_ + +#include +#include + +/* + * Authentication infrastructure for Trusted Boot + * + * This infrastructure provides an API to access the authentication module. This + * module will implement the required operations for Trusted Boot by creating an + * instance of the structure 'auth_mod_t'. This instance must be called + * 'auth_mod' and must provide the functions to initialize the module and + * verify the authenticity of the images. + */ + +/* Objects (images and certificates) involved in the TBB process */ +enum { + AUTH_BL2_IMG_CERT, + AUTH_BL2_IMG, + AUTH_TRUSTED_KEY_CERT, + AUTH_BL30_KEY_CERT, + AUTH_BL30_IMG_CERT, + AUTH_BL30_IMG, + AUTH_BL31_KEY_CERT, + AUTH_BL31_IMG_CERT, + AUTH_BL31_IMG, + AUTH_BL32_KEY_CERT, + AUTH_BL32_IMG_CERT, + AUTH_BL32_IMG, + AUTH_BL33_KEY_CERT, + AUTH_BL33_IMG_CERT, + AUTH_BL33_IMG, + AUTH_NUM_OBJ +}; + +/* Authentication module structure */ +typedef struct auth_mod_s { + /* [mandatory] Module name. Printed to the log during initialization */ + const char *name; + + /* [mandatory] Initialize the authentication module */ + int (*init)(void); + + /* [mandatory] This function will be called to authenticate a new + * object loaded into memory. The obj_id corresponds to one of the + * values in the enumeration above */ + int (*verify)(unsigned int obj_id, uintptr_t obj_buf, size_t len); +} auth_mod_t; + +/* This variable must be instantiated by the authentication module */ +extern const auth_mod_t auth_mod; + +/* Public functions */ +void auth_init(void); +int auth_verify_obj(unsigned int obj_id, uintptr_t obj_buf, size_t len); + +#endif /* AUTH_H_ */ diff --git a/include/common/firmware_image_package.h b/include/common/firmware_image_package.h index f4554ec..8fb669e 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 69bb749..18b7eae 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -191,4 +191,9 @@ ******************************************************************************/ 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 0000000..269f3e7 --- /dev/null +++ b/include/stdlib/inttypes.h @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2001 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _INTTYPES_H_ +#define _INTTYPES_H_ + +#include +#include + +typedef struct { + intmax_t quot; /* Quotient. */ + intmax_t rem; /* Remainder. */ +} imaxdiv_t; + +__BEGIN_DECLS +#ifdef _XLOCALE_H_ +#include +#endif +intmax_t imaxabs(intmax_t) __pure2; +imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2; + +intmax_t strtoimax(const char *__restrict, char **__restrict, int); +uintmax_t strtoumax(const char *__restrict, char **__restrict, int); + +__END_DECLS + +#endif /* !_INTTYPES_H_ */ diff --git a/include/stdlib/machine/_inttypes.h b/include/stdlib/machine/_inttypes.h new file mode 100644 index 0000000..8dd07d6 --- /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 1b8429b..60e081b 100644 --- a/include/stdlib/stdio.h +++ b/include/stdlib/stdio.h @@ -65,6 +65,8 @@ 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 0000000..b1ac1bf --- /dev/null +++ b/include/stdlib/stdlib.h @@ -0,0 +1,313 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)stdlib.h 8.5 (Berkeley) 5/19/95 + * $FreeBSD$ + */ + +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + +#include +#include +#include + +#if __BSD_VISIBLE +#ifndef _RUNE_T_DECLARED +typedef __rune_t rune_t; +#define _RUNE_T_DECLARED +#endif +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +typedef struct { + int quot; /* quotient */ + int rem; /* remainder */ +} div_t; + +typedef struct { + long quot; + long rem; +} ldiv_t; + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +#define RAND_MAX 0x7ffffffd + +__BEGIN_DECLS +#ifdef _XLOCALE_H_ +#include +#endif +extern int __mb_cur_max; +extern int ___mb_cur_max(void); +#define MB_CUR_MAX (___mb_cur_max()) + +_Noreturn void abort(void); +int abs(int) __pure2; +int atexit(void (*)(void)); +double atof(const char *); +int atoi(const char *); +long atol(const char *); +void *bsearch(const void *, const void *, size_t, + size_t, int (*)(const void *, const void *)); +void *calloc(size_t, size_t) __malloc_like; +div_t div(int, int) __pure2; +_Noreturn void exit(int); +void free(void *); +char *getenv(const char *); +long labs(long) __pure2; +ldiv_t ldiv(long, long) __pure2; +void *malloc(size_t) __malloc_like; +int mblen(const char *, size_t); +void qsort(void *, size_t, size_t, + int (*)(const void *, const void *)); +int rand(void); +void *realloc(void *, size_t); +void srand(unsigned); +double strtod(const char *__restrict, char **__restrict); +float strtof(const char *__restrict, char **__restrict); +long strtol(const char *__restrict, char **__restrict, int); +long double + strtold(const char *__restrict, char **__restrict); +unsigned long + strtoul(const char *__restrict, char **__restrict, int); +int system(const char *); + +/* + * Functions added in C99 which we make conditionally available in the + * BSD^C89 namespace if the compiler supports `long long'. + * The #if test is more complicated than it ought to be because + * __BSD_VISIBLE implies __ISO_C_VISIBLE == 1999 *even if* `long long' + * is not supported in the compilation environment (which therefore means + * that it can't really be ISO C99). + * + * (The only other extension made by C99 in thie header is _Exit().) + */ +#if __ISO_C_VISIBLE >= 1999 +#ifdef __LONG_LONG_SUPPORTED +/* LONGLONG */ +typedef struct { + long long quot; + long long rem; +} lldiv_t; + +/* LONGLONG */ +long long + atoll(const char *); +/* LONGLONG */ +long long + llabs(long long) __pure2; +/* LONGLONG */ +lldiv_t lldiv(long long, long long) __pure2; +/* LONGLONG */ +long long + strtoll(const char *__restrict, char **__restrict, int); +/* LONGLONG */ +unsigned long long + strtoull(const char *__restrict, char **__restrict, int); +#endif /* __LONG_LONG_SUPPORTED */ + +_Noreturn void _Exit(int); +#endif /* __ISO_C_VISIBLE >= 1999 */ + +/* + * If we're in a mode greater than C99, expose C11 functions. + */ +#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L +void *aligned_alloc(size_t, size_t) __malloc_like; +int at_quick_exit(void (*)(void)); +_Noreturn void + quick_exit(int); +#endif /* __ISO_C_VISIBLE >= 2011 */ +/* + * Extensions made by POSIX relative to C. + */ +#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE +char *realpath(const char *__restrict, char *__restrict); +#endif +#if __POSIX_VISIBLE >= 199506 +int rand_r(unsigned *); /* (TSF) */ +#endif +#if __POSIX_VISIBLE >= 200112 +int posix_memalign(void **, size_t, size_t); /* (ADV) */ +int setenv(const char *, const char *, int); +int unsetenv(const char *); +#endif + +#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE +int getsubopt(char **, char *const *, char **); +#ifndef _MKDTEMP_DECLARED +char *mkdtemp(char *); +#define _MKDTEMP_DECLARED +#endif +#ifndef _MKSTEMP_DECLARED +int mkstemp(char *); +#define _MKSTEMP_DECLARED +#endif +#endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */ + +/* + * The only changes to the XSI namespace in revision 6 were the deletion + * of the ttyslot() and valloc() functions, which FreeBSD never declared + * in this header. For revision 7, ecvt(), fcvt(), and gcvt(), which + * FreeBSD also does not have, and mktemp(), are to be deleted. + */ +#if __XSI_VISIBLE +/* XXX XSI requires pollution from here. We'd rather not. */ +long a64l(const char *); +double drand48(void); +/* char *ecvt(double, int, int * __restrict, int * __restrict); */ +double erand48(unsigned short[3]); +/* char *fcvt(double, int, int * __restrict, int * __restrict); */ +/* char *gcvt(double, int, int * __restrict, int * __restrict); */ +int grantpt(int); +char *initstate(unsigned long /* XSI requires u_int */, char *, long); +long jrand48(unsigned short[3]); +char *l64a(long); +void lcong48(unsigned short[7]); +long lrand48(void); +#if !defined(_MKTEMP_DECLARED) && (__BSD_VISIBLE || __XSI_VISIBLE <= 600) +char *mktemp(char *); +#define _MKTEMP_DECLARED +#endif +long mrand48(void); +long nrand48(unsigned short[3]); +int posix_openpt(int); +char *ptsname(int); +int putenv(char *); +long random(void); +unsigned short + *seed48(unsigned short[3]); +#ifndef _SETKEY_DECLARED +int setkey(const char *); +#define _SETKEY_DECLARED +#endif +char *setstate(/* const */ char *); +void srand48(long); +void srandom(unsigned long); +int unlockpt(int); +#endif /* __XSI_VISIBLE */ + +#if __BSD_VISIBLE +extern const char *malloc_conf; +extern void (*malloc_message)(void *, const char *); + +/* + * The alloca() function can't be implemented in C, and on some + * platforms it can't be implemented at all as a callable function. + * The GNU C compiler provides a built-in alloca() which we can use; + * in all other cases, provide a prototype, mainly to pacify various + * incarnations of lint. On platforms where alloca() is not in libc, + * programs which use it will fail to link when compiled with non-GNU + * compilers. + */ +#if __GNUC__ >= 2 || defined(__INTEL_COMPILER) +#undef alloca /* some GNU bits try to get cute and define this on their own */ +#define alloca(sz) __builtin_alloca(sz) +#elif defined(lint) +void *alloca(size_t); +#endif + +void abort2(const char *, int, void **) __dead2; +__uint32_t + arc4random(void); +void arc4random_addrandom(unsigned char *, int); +void arc4random_buf(void *, size_t); +void arc4random_stir(void); +__uint32_t + arc4random_uniform(__uint32_t); +#ifdef __BLOCKS__ +int atexit_b(void (^)(void)); +void *bsearch_b(const void *, const void *, size_t, + size_t, int (^)(const void *, const void *)); +#endif +char *getbsize(int *, long *); + /* getcap(3) functions */ +char *cgetcap(char *, const char *, int); +int cgetclose(void); +int cgetent(char **, char **, const char *); +int cgetfirst(char **, char **); +int cgetmatch(const char *, const char *); +int cgetnext(char **, char **); +int cgetnum(char *, const char *, long *); +int cgetset(const char *); +int cgetstr(char *, const char *, char **); +int cgetustr(char *, const char *, char **); + +int daemon(int, int); +char *devname(__dev_t, __mode_t); +char *devname_r(__dev_t, __mode_t, char *, int); +char *fdevname(int); +char *fdevname_r(int, char *, int); +int getloadavg(double [], int); +const char * + getprogname(void); + +int heapsort(void *, size_t, size_t, int (*)(const void *, const void *)); +#ifdef __BLOCKS__ +int heapsort_b(void *, size_t, size_t, int (^)(const void *, const void *)); +void qsort_b(void *, size_t, size_t, + int (^)(const void *, const void *)); +#endif +int l64a_r(long, char *, int); +int mergesort(void *, size_t, size_t, int (*)(const void *, const void *)); +#ifdef __BLOCKS__ +int mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *)); +#endif +int mkostemp(char *, int); +int mkostemps(char *, int, int); +void qsort_r(void *, size_t, size_t, void *, + int (*)(void *, const void *, const void *)); +int radixsort(const unsigned char **, int, const unsigned char *, + unsigned); +void *reallocf(void *, size_t); +int rpmatch(const char *); +void setprogname(const char *); +int sradixsort(const unsigned char **, int, const unsigned char *, + unsigned); +void sranddev(void); +void srandomdev(void); +long long + strtonum(const char *, long long, long long, const char **); + +/* Deprecated interfaces, to be removed in FreeBSD 6.0. */ +__int64_t + strtoq(const char *, char **, int); +__uint64_t + strtouq(const char *, char **, int); + +extern char *suboptarg; /* getsubopt(3) external variable */ +#endif /* __BSD_VISIBLE */ +__END_DECLS + +#endif /* !_STDLIB_H_ */ diff --git a/include/stdlib/string.h b/include/stdlib/string.h index 00a5dcd..61e8102 100644 --- a/include/stdlib/string.h +++ b/include/stdlib/string.h @@ -59,6 +59,7 @@ 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 0000000..2210df0 --- /dev/null +++ b/include/stdlib/strings.h @@ -0,0 +1,71 @@ +/*- + * Copyright (c) 2002 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _STRINGS_H_ +#define _STRINGS_H_ + +#include +#include + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +__BEGIN_DECLS +#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 +int bcmp(const void *, const void *, size_t) __pure; /* LEGACY */ +void bcopy(const void *, void *, size_t); /* LEGACY */ +void bzero(void *, size_t); /* LEGACY */ +#endif +#if __BSD_VISIBLE +void explicit_bzero(void *, size_t); +#endif +#if __XSI_VISIBLE +int ffs(int) __pure2; +#endif +#if __BSD_VISIBLE +int ffsl(long) __pure2; +int ffsll(long long) __pure2; +int fls(int) __pure2; +int flsl(long) __pure2; +int flsll(long long) __pure2; +#endif +#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112 +char *index(const char *, int) __pure; /* LEGACY */ +char *rindex(const char *, int) __pure; /* LEGACY */ +#endif +int strcasecmp(const char *, const char *) __pure; +int strncasecmp(const char *, const char *, size_t) __pure; + +#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) +#include +#endif +__END_DECLS + +#endif /* _STRINGS_H_ */ diff --git a/include/stdlib/sys/_timespec.h b/include/stdlib/sys/_timespec.h new file mode 100644 index 0000000..d51559c --- /dev/null +++ b/include/stdlib/sys/_timespec.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)time.h 8.5 (Berkeley) 5/4/95 + * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp + * $FreeBSD$ + */ + +#ifndef _SYS__TIMESPEC_H_ +#define _SYS__TIMESPEC_H_ + +#include + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; + +#endif /* !_SYS__TIMESPEC_H_ */ diff --git a/include/stdlib/sys/timespec.h b/include/stdlib/sys/timespec.h new file mode 100644 index 0000000..2505cef --- /dev/null +++ b/include/stdlib/sys/timespec.h @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)time.h 8.5 (Berkeley) 5/4/95 + * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp + * $FreeBSD$ + */ + +#ifndef _SYS_TIMESPEC_H_ +#define _SYS_TIMESPEC_H_ + +#include +#include + +#if __BSD_VISIBLE +#define TIMEVAL_TO_TIMESPEC(tv, ts) \ + do { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ + } while (0) +#define TIMESPEC_TO_TIMEVAL(tv, ts) \ + do { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ + } while (0) + +#endif /* __BSD_VISIBLE */ + +/* + * Structure defined by POSIX.1b to be like a itimerval, but with + * timespecs. Used in the timer_*() system calls. + */ +struct itimerspec { + struct timespec it_interval; + struct timespec it_value; +}; + +#endif /* _SYS_TIMESPEC_H_ */ diff --git a/include/stdlib/sys/types.h b/include/stdlib/sys/types.h new file mode 100644 index 0000000..ae2ea33 --- /dev/null +++ b/include/stdlib/sys/types.h @@ -0,0 +1,245 @@ +/*- + * Copyright (c) 1982, 1986, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)types.h 8.6 (Berkeley) 2/19/95 + * $FreeBSD$ + */ + +#ifndef _SYS_TYPES_H_ +#define _SYS_TYPES_H_ + +#include + +/* Machine type dependent parameters. */ +#include + +#if __BSD_VISIBLE +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +#ifndef _KERNEL +typedef unsigned short ushort; /* Sys V compatibility */ +typedef unsigned int uint; /* Sys V compatibility */ +#endif +#endif + +/* + * XXX POSIX sized integrals that should appear only in . + */ +#include + +typedef __uint8_t u_int8_t; /* unsigned integrals (deprecated) */ +typedef __uint16_t u_int16_t; +typedef __uint32_t u_int32_t; +typedef __uint64_t u_int64_t; + +typedef __uint64_t u_quad_t; /* quads (deprecated) */ +typedef __int64_t quad_t; +typedef quad_t *qaddr_t; + +typedef char *caddr_t; /* core address */ +typedef const char *c_caddr_t; /* core address, pointer to const */ + +#ifndef _BLKSIZE_T_DECLARED +typedef __blksize_t blksize_t; +#define _BLKSIZE_T_DECLARED +#endif + +typedef __cpuwhich_t cpuwhich_t; +typedef __cpulevel_t cpulevel_t; +typedef __cpusetid_t cpusetid_t; + +#ifndef _BLKCNT_T_DECLARED +typedef __blkcnt_t blkcnt_t; +#define _BLKCNT_T_DECLARED +#endif + +#ifndef _CLOCK_T_DECLARED +typedef __clock_t clock_t; +#define _CLOCK_T_DECLARED +#endif + +#ifndef _CLOCKID_T_DECLARED +typedef __clockid_t clockid_t; +#define _CLOCKID_T_DECLARED +#endif + +typedef __critical_t critical_t; /* Critical section value */ +typedef __int64_t daddr_t; /* disk address */ + +#ifndef _DEV_T_DECLARED +typedef __dev_t dev_t; /* device number or struct cdev */ +#define _DEV_T_DECLARED +#endif + +#ifndef _FFLAGS_T_DECLARED +typedef __fflags_t fflags_t; /* file flags */ +#define _FFLAGS_T_DECLARED +#endif + +typedef __fixpt_t fixpt_t; /* fixed point number */ + +#ifndef _FSBLKCNT_T_DECLARED /* for statvfs() */ +typedef __fsblkcnt_t fsblkcnt_t; +typedef __fsfilcnt_t fsfilcnt_t; +#define _FSBLKCNT_T_DECLARED +#endif + +#ifndef _GID_T_DECLARED +typedef __gid_t gid_t; /* group id */ +#define _GID_T_DECLARED +#endif + +#ifndef _IN_ADDR_T_DECLARED +typedef __uint32_t in_addr_t; /* base type for internet address */ +#define _IN_ADDR_T_DECLARED +#endif + +#ifndef _IN_PORT_T_DECLARED +typedef __uint16_t in_port_t; +#define _IN_PORT_T_DECLARED +#endif + +#ifndef _ID_T_DECLARED +typedef __id_t id_t; /* can hold a uid_t or pid_t */ +#define _ID_T_DECLARED +#endif + +#ifndef _INO_T_DECLARED +typedef __ino_t ino_t; /* inode number */ +#define _INO_T_DECLARED +#endif + +#ifndef _KEY_T_DECLARED +typedef __key_t key_t; /* IPC key (for Sys V IPC) */ +#define _KEY_T_DECLARED +#endif + +#ifndef _LWPID_T_DECLARED +typedef __lwpid_t lwpid_t; /* Thread ID (a.k.a. LWP) */ +#define _LWPID_T_DECLARED +#endif + +#ifndef _MODE_T_DECLARED +typedef __mode_t mode_t; /* permissions */ +#define _MODE_T_DECLARED +#endif + +#ifndef _ACCMODE_T_DECLARED +typedef __accmode_t accmode_t; /* access permissions */ +#define _ACCMODE_T_DECLARED +#endif + +#ifndef _NLINK_T_DECLARED +typedef __nlink_t nlink_t; /* link count */ +#define _NLINK_T_DECLARED +#endif + +#ifndef _OFF_T_DECLARED +typedef __off_t off_t; /* file offset */ +#define _OFF_T_DECLARED +#endif + +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; /* process id */ +#define _PID_T_DECLARED +#endif + +typedef __register_t register_t; + +#ifndef _RLIM_T_DECLARED +typedef __rlim_t rlim_t; /* resource limit */ +#define _RLIM_T_DECLARED +#endif + +typedef __int64_t sbintime_t; + +typedef __segsz_t segsz_t; /* segment size (in pages) */ + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#ifndef _SSIZE_T_DECLARED +typedef __ssize_t ssize_t; +#define _SSIZE_T_DECLARED +#endif + +#ifndef _SUSECONDS_T_DECLARED +typedef __suseconds_t suseconds_t; /* microseconds (signed) */ +#define _SUSECONDS_T_DECLARED +#endif + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +#ifndef _TIMER_T_DECLARED +typedef __timer_t timer_t; +#define _TIMER_T_DECLARED +#endif + +#ifndef _MQD_T_DECLARED +typedef __mqd_t mqd_t; +#define _MQD_T_DECLARED +#endif + +typedef __u_register_t u_register_t; + +#ifndef _UID_T_DECLARED +typedef __uid_t uid_t; /* user id */ +#define _UID_T_DECLARED +#endif + +#ifndef _USECONDS_T_DECLARED +typedef __useconds_t useconds_t; /* microseconds (unsigned) */ +#define _USECONDS_T_DECLARED +#endif + +#ifndef _CAP_RIGHTS_T_DECLARED +#define _CAP_RIGHTS_T_DECLARED +struct cap_rights; + +typedef struct cap_rights cap_rights_t; +#endif + +typedef __vm_offset_t vm_offset_t; +typedef __vm_ooffset_t vm_ooffset_t; +typedef __vm_paddr_t vm_paddr_t; +typedef __vm_pindex_t vm_pindex_t; +typedef __vm_size_t vm_size_t; + +#endif /* !_SYS_TYPES_H_ */ diff --git a/include/stdlib/time.h b/include/stdlib/time.h new file mode 100644 index 0000000..08200cf --- /dev/null +++ b/include/stdlib/time.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)time.h 8.3 (Berkeley) 1/21/94 + */ + +/* + * $FreeBSD$ + */ + +#ifndef _TIME_H_ +#define _TIME_H_ + +#include +#include +#include + +#if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE +/* + * Frequency of the clock ticks reported by times(). Deprecated - use + * sysconf(_SC_CLK_TCK) instead. (Removed in 1003.1-2001.) + */ +#define CLK_TCK 128 +#endif + +/* Frequency of the clock ticks reported by clock(). */ +#define CLOCKS_PER_SEC 128 + +#ifndef _CLOCK_T_DECLARED +typedef __clock_t clock_t; +#define _CLOCK_T_DECLARED +#endif + +#ifndef _TIME_T_DECLARED +typedef __time_t time_t; +#define _TIME_T_DECLARED +#endif + +#ifndef _SIZE_T_DECLARED +typedef __size_t size_t; +#define _SIZE_T_DECLARED +#endif + +#if __POSIX_VISIBLE >= 199309 +/* + * New in POSIX 1003.1b-1993. + */ +#ifndef _CLOCKID_T_DECLARED +typedef __clockid_t clockid_t; +#define _CLOCKID_T_DECLARED +#endif + +#ifndef _TIMER_T_DECLARED +typedef __timer_t timer_t; +#define _TIMER_T_DECLARED +#endif + +#include +#endif /* __POSIX_VISIBLE >= 199309 */ + +#if __POSIX_VISIBLE >= 200112 +#ifndef _PID_T_DECLARED +typedef __pid_t pid_t; +#define _PID_T_DECLARED +#endif +#endif + +/* These macros are also in sys/time.h. */ +#if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 +#define CLOCK_REALTIME 0 +#ifdef __BSD_VISIBLE +#define CLOCK_VIRTUAL 1 +#define CLOCK_PROF 2 +#endif +#define CLOCK_MONOTONIC 4 +#define CLOCK_UPTIME 5 /* FreeBSD-specific. */ +#define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */ +#define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */ +#define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */ +#define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */ +#define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */ +#define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */ +#define CLOCK_SECOND 13 /* FreeBSD-specific. */ +#define CLOCK_THREAD_CPUTIME_ID 14 +#define CLOCK_PROCESS_CPUTIME_ID 15 +#endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */ + +#if !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 +#if __BSD_VISIBLE +#define TIMER_RELTIME 0x0 /* relative timer */ +#endif +#define TIMER_ABSTIME 0x1 /* absolute timer */ +#endif /* !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 */ + +struct tm { + int tm_sec; /* seconds after the minute [0-60] */ + int tm_min; /* minutes after the hour [0-59] */ + int tm_hour; /* hours since midnight [0-23] */ + int tm_mday; /* day of the month [1-31] */ + int tm_mon; /* months since January [0-11] */ + int tm_year; /* years since 1900 */ + int tm_wday; /* days since Sunday [0-6] */ + int tm_yday; /* days since January 1 [0-365] */ + int tm_isdst; /* Daylight Savings Time flag */ + long tm_gmtoff; /* offset from UTC in seconds */ + char *tm_zone; /* timezone abbreviation */ +}; + +#if __POSIX_VISIBLE +extern char *tzname[]; +#endif + +__BEGIN_DECLS +char *asctime(const struct tm *); +clock_t clock(void); +char *ctime(const time_t *); +double difftime(time_t, time_t); +/* XXX missing: getdate() */ +struct tm *gmtime(const time_t *); +struct tm *localtime(const time_t *); +time_t mktime(struct tm *); +size_t strftime(char *__restrict, size_t, const char *__restrict, + const struct tm *__restrict); +time_t time(time_t *); +#if __POSIX_VISIBLE >= 200112 +struct sigevent; +int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict); +int timer_delete(timer_t); +int timer_gettime(timer_t, struct itimerspec *); +int timer_getoverrun(timer_t); +int timer_settime(timer_t, int, const struct itimerspec *__restrict, + struct itimerspec *__restrict); +#endif +#if __POSIX_VISIBLE +void tzset(void); +#endif + +#if __POSIX_VISIBLE >= 199309 +int clock_getres(clockid_t, struct timespec *); +int clock_gettime(clockid_t, struct timespec *); +int clock_settime(clockid_t, const struct timespec *); +/* XXX missing: clock_nanosleep() */ +int nanosleep(const struct timespec *, struct timespec *); +#endif /* __POSIX_VISIBLE >= 199309 */ + +#if __POSIX_VISIBLE >= 200112 +int clock_getcpuclockid(pid_t, clockid_t *); +#endif + +#if __POSIX_VISIBLE >= 199506 +char *asctime_r(const struct tm *, char *); +char *ctime_r(const time_t *, char *); +struct tm *gmtime_r(const time_t *, struct tm *); +struct tm *localtime_r(const time_t *, struct tm *); +#endif + +#if __XSI_VISIBLE +char *strptime(const char *__restrict, const char *__restrict, + struct tm *__restrict); +#endif + +#if __BSD_VISIBLE +char *timezone(int, int); /* XXX XSI conflict */ +void tzsetwall(void); +time_t timelocal(struct tm * const); +time_t timegm(struct tm * const); +#endif /* __BSD_VISIBLE */ + +#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) +#include +#endif +__END_DECLS + +#endif /* !_TIME_H_ */ diff --git a/include/stdlib/xlocale/_strings.h b/include/stdlib/xlocale/_strings.h new file mode 100644 index 0000000..da1cff3 --- /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 0000000..6da49a4 --- /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 0000000..3e77591 --- /dev/null +++ b/lib/stdlib/exit.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +void exit(int v) +{ + ERROR("EXIT\n"); + panic(); +} diff --git a/lib/stdlib/sscanf.c b/lib/stdlib/sscanf.c new file mode 100644 index 0000000..e9f5c4a --- /dev/null +++ b/lib/stdlib/sscanf.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +/* + * TODO: This is not a real implementation of the sscanf() function. It just + * returns the number of expected arguments based on the number of '%' found + * in the format string. + */ +int +sscanf(const char *__restrict str, char const *__restrict fmt, ...) +{ + int ret = 0; + + while (*fmt != '\0') { + if (*fmt++ == '%') { + ret++; + } + } + + return ret; +} diff --git a/lib/stdlib/std.c b/lib/stdlib/std.c index 4608754..5f6ef75 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 1d26f2b..bb86e0f 100644 --- a/lib/stdlib/strcmp.c +++ b/lib/stdlib/strcmp.c @@ -36,6 +36,7 @@ */ #include +#include #include /* @@ -49,3 +50,17 @@ 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 5764b6a..364833f 100644 --- a/plat/fvp/bl2_fvp_setup.c +++ b/plat/fvp/bl2_fvp_setup.c @@ -175,6 +175,9 @@ /* 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 @@ * 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 b4a04f1..ec1fe58 100644 --- a/plat/fvp/fvp_io_storage.c +++ b/plat/fvp/fvp_io_storage.c @@ -77,6 +77,58 @@ .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 @@ (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 0000000..e7dcc01 --- /dev/null +++ b/plat/fvp/fvp_trusted_boot.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "fvp_def.h" +#include "fvp_private.h" + +/* + * Check the validity of the key + * + * 0 = success, Otherwise = error + */ +int plat_match_rotpk(const unsigned char *key_buf, unsigned int key_len) +{ + /* TODO: check against the ROT key stored in the platform */ + return 0; +} diff --git a/plat/fvp/include/platform_def.h b/plat/fvp/include/platform_def.h index b0460e0..326ba9d 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 0000000..38aca12 --- /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 892e43c..bcee328 100644 --- a/plat/fvp/platform.mk +++ b/plat/fvp/platform.mk @@ -89,3 +89,8 @@ 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 cd07702..1071d12 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 0000000..38aca12 --- /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 8e1a83d..8a85aec 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 0000000..e63d4b2 --- /dev/null +++ b/plat/juno/juno_trusted_boot.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "juno_def.h" +#include "juno_private.h" + +/* + * Check the validity of the key + * + * 0 = success, Otherwise = error + */ +int plat_match_rotpk(const unsigned char *key_buf, unsigned int key_len) +{ + /* TODO: check against the ROT key stored in the platform */ + return 0; +} diff --git a/plat/juno/plat_io_storage.c b/plat/juno/plat_io_storage.c index 83d7e43..b31865e 100644 --- a/plat/juno/plat_io_storage.c +++ b/plat/juno/plat_io_storage.c @@ -77,6 +77,58 @@ .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 @@ (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 158e3ac..8beaecf 100644 --- a/plat/juno/platform.mk +++ b/plat/juno/platform.mk @@ -90,6 +90,11 @@ 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 0000000..f1aa797 --- /dev/null +++ b/tools/cert_create/Makefile @@ -0,0 +1,92 @@ +# +# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# Neither the name of ARM nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific +# prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +PROJECT := cert_create +PLAT := none +V := 0 +DEBUG := 0 +BINARY := ${PROJECT} + +OBJECTS := src/cert.o \ + src/ext.o \ + src/key.o \ + src/main.o \ + src/tbb_cert.o \ + src/tbb_ext.o \ + src/tbb_key.o \ + src/sha.o + +CFLAGS := -Wall -std=c99 + +# Check the platform +ifeq (${PLAT},none) + $(error Error: No platform defined. Use PLAT=.) +endif + +ifeq (${DEBUG},1) + CFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40 +else + CFLAGS += -O2 -DLOG_LEVEL=20 +endif +ifeq (${V},0) + Q := @ +else + Q := +endif + +# Make soft links and include from local directory otherwise wrong headers +# could get pulled in from firmware tree. +INC_DIR := -I ./include -I ../../plat/${PLAT}/include +LIB_DIR := +LIB := -lssl -lcrypto + +CC := gcc +RM := rm -rf + +.PHONY: all clean + +all: clean ${BINARY} + +${BINARY}: ${OBJECTS} Makefile + @echo " LD $@" + @echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \ + const char platform_msg[] = "${PLAT}";' | \ + ${CC} -c ${CFLAGS} -xc - -o src/build_msg.o + ${Q}${CC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@ + +%.o: %.c + @echo " CC $<" + ${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@ + +clean: + ${Q}${RM} -f src/build_msg.o ${OBJECTS} + +realclean: clean + ${Q}${RM} -f ${BINARY} diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h new file mode 100644 index 0000000..48a4146 --- /dev/null +++ b/tools/cert_create/include/cert.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CERT_H_ +#define CERT_H_ + +#include +#include +#include "key.h" + +/* + * This structure contains information related to the generation of the + * certificates. All these fields must be known and specified at build time + * except for the file name, which is picked up from the command line at + * run time. + * + * One instance of this structure must be created for each of the certificates + * present in the chain of trust. + * + * If the issuer points to this same instance, the generated certificate will + * be self-signed. + */ +typedef struct cert_s cert_t; +struct cert_s { + int id; /* Unique identifier */ + + const char *fn; /* Filename to save the certificate */ + const char *bin; /* Image associated to this certificate */ + + const char *cn; /* Subject CN (Company Name) */ + + X509 *x; /* X509 certificate container */ + key_t *key; /* Key to be signed */ + + cert_t *issuer; /* Issuer certificate */ +}; + +int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value); + +int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk); + +#endif /* CERT_H_ */ diff --git a/tools/cert_create/include/debug.h b/tools/cert_create/include/debug.h new file mode 100644 index 0000000..dd0510a --- /dev/null +++ b/tools/cert_create/include/debug.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include + +/* The log output macros print output to the console. These macros produce + * compiled log output only if the LOG_LEVEL defined in the makefile (or the + * make command line) is greater or equal than the level required for that + * type of log output. + * The format expected is the same as for printf(). For example: + * INFO("Info %s.\n", "message") -> INFO: Info message. + * WARN("Warning %s.\n", "message") -> WARNING: Warning message. + */ + +#define LOG_LEVEL_NONE 0 +#define LOG_LEVEL_ERROR 10 +#define LOG_LEVEL_NOTICE 20 +#define LOG_LEVEL_WARNING 30 +#define LOG_LEVEL_INFO 40 +#define LOG_LEVEL_VERBOSE 50 + + +#if LOG_LEVEL >= LOG_LEVEL_NOTICE +# define NOTICE(...) printf("NOTICE: " __VA_ARGS__) +#else +# define NOTICE(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_ERROR +# define ERROR(...) printf("ERROR: " __VA_ARGS__) +#else +# define ERROR(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_WARNING +# define WARN(...) printf("WARNING: " __VA_ARGS__) +#else +# define WARN(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_INFO +# define INFO(...) printf("INFO: " __VA_ARGS__) +#else +# define INFO(...) +#endif + +#if LOG_LEVEL >= LOG_LEVEL_VERBOSE +# define VERBOSE(...) printf("VERBOSE: " __VA_ARGS__) +#else +# define VERBOSE(...) +#endif + +#endif /* __DEBUG_H__ */ diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h new file mode 100644 index 0000000..d73f573 --- /dev/null +++ b/tools/cert_create/include/ext.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef EXT_H_ +#define EXT_H_ + +#include + +/* + * This structure contains the relevant information to create the extensions + * to be included in the certificates. This extensions will be used to + * establish the chain of trust. + */ +typedef struct ext_s { + const char *oid; /* OID of the extension */ + const char *sn; /* Short name */ + const char *ln; /* Long description */ + int type; /* OpenSSL ASN1 type of the extension data. + * Supported types are: + * - V_ASN1_INTEGER + * - V_ASN1_OCTET_STRING + */ + int alias; /* In case OpenSSL provides an standard + * extension of the same type, add the new + * extension as an alias of this one + */ + + X509V3_EXT_METHOD method; /* This field may be used to define a custom + * function to print the contents of the + * extension */ +} ext_t; + +enum { + EXT_NON_CRIT = 0, + EXT_CRIT = !EXT_NON_CRIT, +}; + +int ext_init(ext_t *tbb_ext); +X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len); +X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value); +X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k); + +#endif /* EXT_H_ */ diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h new file mode 100644 index 0000000..8819750 --- /dev/null +++ b/tools/cert_create/include/key.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef KEY_H_ +#define KEY_H_ + +#include + +#define RSA_KEY_BITS 2048 + +/* + * This structure contains the relevant information to create the keys + * required to sign the certificates. + * + * One instance of this structure must be created for each key, usually in an + * array fashion. The filename is obtained at run time from the command line + * parameters + */ +typedef struct key_s { + int id; /* Key id */ + const char *desc; /* Key description (debug purposes) */ + char *fn; /* Filename to load/store the key */ + EVP_PKEY *key; /* Key container */ +} key_t; + +int key_new(key_t *key); +int key_load(key_t *key); +int key_store(key_t *key); + +#endif /* KEY_H_ */ diff --git a/tools/cert_create/include/sha.h b/tools/cert_create/include/sha.h new file mode 100644 index 0000000..466d668 --- /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 0000000..4e48125 --- /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 0000000..155d3cb --- /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 0000000..cc927d1 --- /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 0000000..9705643 --- /dev/null +++ b/tools/cert_create/src/cert.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "cert.h" +#include "debug.h" +#include "key.h" +#include "platform_oid.h" +#include "sha.h" + +#define SERIAL_RAND_BITS 64 + +int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) +{ + BIGNUM *btmp; + int ret = 0; + if (b) + btmp = b; + else + btmp = BN_new(); + + if (!btmp) + return 0; + + if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0)) + goto error; + if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) + goto error; + + ret = 1; + +error: + + if (!b) + BN_free(btmp); + + return ret; +} + +int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value) +{ + X509_EXTENSION *ex; + X509V3_CTX ctx; + + /* No configuration database */ + X509V3_set_ctx_nodb(&ctx); + + /* Set issuer and subject certificates in the context */ + X509V3_set_ctx(&ctx, issuer, subject, NULL, NULL, 0); + ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value); + if (!ex) { + ERR_print_errors_fp(stdout); + return 0; + } + + X509_add_ext(subject, ex, -1); + X509_EXTENSION_free(ex); + + return 1; +} + + +int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) +{ + EVP_PKEY *pkey = cert->key->key; + EVP_PKEY *ikey = cert->issuer->key->key; + X509 *issuer = cert->issuer->x; + X509 *x = NULL; + X509_EXTENSION *ex = NULL; + X509_NAME *name = NULL; + ASN1_INTEGER *sno = NULL; + int i, num; + + /* Create the certificate structure */ + x = X509_new(); + if (!x) { + return 0; + } + + /* If we do not have a key, use the issuer key (the certificate will + * become self signed). This happens in content certificates. */ + if (!pkey) { + pkey = ikey; + } + + /* If we do not have an issuer certificate, use our own (the certificate + * will become self signed) */ + if (!issuer) { + issuer = x; + } + + /* x509.v3 */ + X509_set_version(x, 2); + + /* Random serial number */ + sno = ASN1_INTEGER_new(); + rand_serial(NULL, sno); + X509_set_serialNumber(x, sno); + ASN1_INTEGER_free(sno); + + X509_gmtime_adj(X509_get_notBefore(x), 0); + X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days); + X509_set_pubkey(x, pkey); + + /* Subject name */ + name = X509_get_subject_name(x); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)cert->cn, -1, -1, 0); + X509_set_subject_name(x, name); + + /* Issuer name */ + name = X509_get_issuer_name(x); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)cert->issuer->cn, -1, -1, 0); + X509_set_issuer_name(x, name); + + /* Add various extensions: standard extensions */ + cert_add_ext(issuer, x, NID_subject_key_identifier, "hash"); + cert_add_ext(issuer, x, NID_authority_key_identifier, "keyid:always"); + if (ca) { + cert_add_ext(issuer, x, NID_basic_constraints, "CA:TRUE"); + cert_add_ext(issuer, x, NID_key_usage, "keyCertSign"); + } else { + cert_add_ext(issuer, x, NID_basic_constraints, "CA:FALSE"); + } + + /* Add custom extensions */ + if (sk != NULL) { + num = sk_X509_EXTENSION_num(sk); + for (i = 0; i < num; i++) { + ex = sk_X509_EXTENSION_value(sk, i); + X509_add_ext(x, ex, -1); + } + } + + /* Sign the certificate with the issuer key */ + if (!X509_sign(x, ikey, EVP_sha1())) { + ERR_print_errors_fp(stdout); + return 0; + } + + cert->x = x; + return 1; +} diff --git a/tools/cert_create/src/ext.c b/tools/cert_create/src/ext.c new file mode 100644 index 0000000..31f84a8 --- /dev/null +++ b/tools/cert_create/src/ext.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include "ext.h" + +DECLARE_ASN1_ITEM(ASN1_INTEGER) +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING) + +/* + * This function adds the TBB extensions to the internal extension list + * maintained by OpenSSL so they can be used later. + * + * It also initializes the methods to print the contents of the extension. If an + * alias is specified in the TBB extension, we reuse the methods of the alias. + * Otherwise, only methods for V_ASN1_INTEGER and V_ASN1_OCTET_STRING are + * provided. Any other type will be printed as a raw ascii string. + * + * Return: 0 = success, Otherwise: error + */ +int ext_init(ext_t *tbb_ext) +{ + ext_t *ext; + X509V3_EXT_METHOD *m; + int i = 0, nid, ret; + + while ((ext = &tbb_ext[i++]) && ext->oid) { + nid = OBJ_create(ext->oid, ext->sn, ext->ln); + if (ext->alias) { + X509V3_EXT_add_alias(nid, ext->alias); + } else { + m = &ext->method; + memset(m, 0x0, sizeof(X509V3_EXT_METHOD)); + switch (ext->type) { + case V_ASN1_INTEGER: + m->it = ASN1_ITEM_ref(ASN1_INTEGER); + m->i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER; + m->s2i = (X509V3_EXT_S2I)s2i_ASN1_INTEGER; + break; + case V_ASN1_OCTET_STRING: + m->it = ASN1_ITEM_ref(ASN1_OCTET_STRING); + m->i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING; + m->s2i = (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING; + break; + default: + continue; + } + m->ext_nid = nid; + ret = X509V3_EXT_add(m); + if (!ret) { + ERR_print_errors_fp(stdout); + return 1; + } + } + } + return 0; +} + +/* + * Create a new extension + * + * Extension ::= SEQUENCE { + * id OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * value OCTET STRING } + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * data: extension data. This data will be encapsulated in an Octet String + * + * Return: Extension address, NULL if error + */ +static +X509_EXTENSION *ext_new(int nid, int crit, unsigned char *data, int len) +{ + X509_EXTENSION *ex; + ASN1_OCTET_STRING *ext_data; + + /* Octet string containing the extension data */ + ext_data = ASN1_OCTET_STRING_new(); + ASN1_OCTET_STRING_set(ext_data, data, len); + + /* Create the extension */ + ex = X509_EXTENSION_create_by_NID(NULL, nid, crit, ext_data); + + /* The extension makes a copy of the data, so we can free this object */ + ASN1_OCTET_STRING_free(ext_data); + + return ex; +} + +/* + * Creates a x509v3 extension containing a hash encapsulated in an ASN1 Octet + * String + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * buf: pointer to the buffer that contains the hash + * len: size of the hash in bytes + * + * Return: Extension address, NULL if error + */ +X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len) +{ + X509_EXTENSION *ex = NULL; + ASN1_OCTET_STRING *hash = NULL; + unsigned char *p = NULL; + int sz = -1; + + /* Encode Hash */ + hash = ASN1_OCTET_STRING_new(); + ASN1_OCTET_STRING_set(hash, buf, len); + sz = i2d_ASN1_OCTET_STRING(hash, NULL); + i2d_ASN1_OCTET_STRING(hash, &p); + + /* Create the extension */ + ex = ext_new(nid, crit, p, sz); + + /* Clean up */ + OPENSSL_free(p); + ASN1_OCTET_STRING_free(hash); + + return ex; +} + +/* + * Creates a x509v3 extension containing a nvcounter encapsulated in an ASN1 + * Integer + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * value: nvcounter value + * + * Return: Extension address, NULL if error + */ +X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value) +{ + X509_EXTENSION *ex = NULL; + ASN1_INTEGER *counter = NULL; + unsigned char *p = NULL; + int sz = -1; + + /* Encode counter */ + counter = ASN1_INTEGER_new(); + ASN1_INTEGER_set(counter, value); + sz = i2d_ASN1_INTEGER(counter, NULL); + i2d_ASN1_INTEGER(counter, &p); + + /* Create the extension */ + ex = ext_new(nid, crit, p, sz); + + /* Free objects */ + OPENSSL_free(p); + ASN1_INTEGER_free(counter); + + return ex; +} + +/* + * Creates a x509v3 extension containing a public key in DER format: + * + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + * + * Parameters: + * pex: OpenSSL extension pointer (output parameter) + * nid: extension identifier + * crit: extension critical (EXT_NON_CRIT, EXT_CRIT) + * k: key + * + * Return: Extension address, NULL if error + */ +X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k) +{ + X509_EXTENSION *ex = NULL; + unsigned char *p = NULL; + int sz = -1; + + /* Encode key */ + BIO *mem = BIO_new(BIO_s_mem()); + if (i2d_PUBKEY_bio(mem, k) <= 0) { + ERR_print_errors_fp(stderr); + return NULL; + } + p = (unsigned char *)OPENSSL_malloc(4096); + sz = BIO_read(mem, p, 4096); + + /* Create the extension */ + ex = ext_new(nid, crit, p, sz); + + /* Clean up */ + OPENSSL_free(p); + + return ex; +} diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c new file mode 100644 index 0000000..b5737d9 --- /dev/null +++ b/tools/cert_create/src/key.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "cert.h" +#include "debug.h" +#include "key.h" +#include "platform_oid.h" +#include "sha.h" + +#define MAX_FILENAME_LEN 1024 + +/* + * Create a new key + */ +int key_new(key_t *key) +{ + RSA *rsa = NULL; + EVP_PKEY *k = NULL; + + /* Create key pair container */ + k = EVP_PKEY_new(); + if (k == NULL) { + return 0; + } + + /* Generate a new RSA key */ + rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL); + if (EVP_PKEY_assign_RSA(k, rsa)) { + key->key = k; + return 1; + } else { + printf("Cannot assign RSA key\n"); + } + + if (k) + EVP_PKEY_free(k); + return 0; +} + +int key_load(key_t *key) +{ + FILE *fp = NULL; + EVP_PKEY *k = NULL; + + /* Create key pair container */ + k = EVP_PKEY_new(); + if (k == NULL) { + return 0; + } + + if (key->fn) { + /* Load key from file */ + fp = fopen(key->fn, "r"); + if (fp) { + k = PEM_read_PrivateKey(fp, &k, NULL, NULL); + fclose(fp); + if (k) { + key->key = k; + return 1; + } else { + ERROR("Cannot read key from %s\n", key->fn); + } + } else { + ERROR("Cannot open file %s\n", key->fn); + } + } else { + ERROR("Key filename not specified\n"); + } + + if (k) + EVP_PKEY_free(k); + + return 0; +} + +int key_store(key_t *key) +{ + FILE *fp = NULL; + + if (key->fn) { + fp = fopen(key->fn, "w"); + if (fp) { + PEM_write_PrivateKey(fp, key->key, + NULL, NULL, 0, NULL, NULL); + fclose(fp); + return 1; + } else { + ERROR("Cannot create file %s\n", key->fn); + } + } else { + ERROR("Key filename not specified\n"); + } + + return 0; +} diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c new file mode 100644 index 0000000..6df367a --- /dev/null +++ b/tools/cert_create/src/main.c @@ -0,0 +1,719 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "cert.h" +#include "debug.h" +#include "ext.h" +#include "key.h" +#include "platform_oid.h" +#include "sha.h" +#include "tbb_ext.h" +#include "tbb_cert.h" +#include "tbb_key.h" + +/* + * Helper macros to simplify the code. This macro assigns the return value of + * the 'fn' function to 'v' and exits if the value is NULL. + */ +#define CHECK_NULL(v, fn) \ + do { \ + v = fn; \ + if (v == NULL) { \ + ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \ + exit(1); \ + } \ + } while (0) + +/* + * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the + * NID is undefined. + */ +#define CHECK_OID(v, oid) \ + do { \ + v = OBJ_txt2nid(oid); \ + if (v == NID_undef) { \ + ERROR("Cannot find TBB extension %s\n", oid); \ + exit(1); \ + } \ + } while (0) + +#define MAX_FILENAME_LEN 1024 +#define VAL_DAYS 7300 +#define ID_TO_BIT_MASK(id) (1 << id) +#define NVCOUNTER_VALUE 0 + +/* Files */ +enum { + /* Image file names (inputs) */ + BL2_ID = 0, + BL30_ID, + BL31_ID, + BL32_ID, + BL33_ID, + /* Certificate file names (outputs) */ + BL2_CERT_ID, + TRUSTED_KEY_CERT_ID, + BL30_KEY_CERT_ID, + BL30_CERT_ID, + BL31_KEY_CERT_ID, + BL31_CERT_ID, + BL32_KEY_CERT_ID, + BL32_CERT_ID, + BL33_KEY_CERT_ID, + BL33_CERT_ID, + /* Key file names (input/output) */ + ROT_KEY_ID, + TRUSTED_WORLD_KEY_ID, + NON_TRUSTED_WORLD_KEY_ID, + BL30_KEY_ID, + BL31_KEY_ID, + BL32_KEY_ID, + BL33_KEY_ID, + NUM_OPTS +}; + +/* Global options */ +static int new_keys; +static int save_keys; +static int print_cert; +static int bl30_present; +static int bl32_present; + +/* We are not checking nvcounters in TF. Include them in the certificates but + * the value will be set to 0 */ +static int tf_nvcounter; +static int non_tf_nvcounter; + +/* Info messages created in the Makefile */ +extern const char build_msg[]; +extern const char platform_msg[]; + + +static char *strdup(const char *str) +{ + int n = strlen(str) + 1; + char *dup = malloc(n); + if (dup) { + strcpy(dup, str); + } + return dup; +} + +/* Command line options */ +static const struct option long_opt[] = { + /* Binary images */ + {"bl2", required_argument, 0, BL2_ID}, + {"bl30", required_argument, 0, BL30_ID}, + {"bl31", required_argument, 0, BL31_ID}, + {"bl32", required_argument, 0, BL32_ID}, + {"bl33", required_argument, 0, BL33_ID}, + /* Certificate files */ + {"bl2-cert", required_argument, 0, BL2_CERT_ID}, + {"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID}, + {"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID}, + {"bl30-cert", required_argument, 0, BL30_CERT_ID}, + {"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID}, + {"bl31-cert", required_argument, 0, BL31_CERT_ID}, + {"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID}, + {"bl32-cert", required_argument, 0, BL32_CERT_ID}, + {"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID}, + {"bl33-cert", required_argument, 0, BL33_CERT_ID}, + /* Private key files */ + {"rot-key", required_argument, 0, ROT_KEY_ID}, + {"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID}, + {"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID}, + {"bl30-key", required_argument, 0, BL30_KEY_ID}, + {"bl31-key", required_argument, 0, BL31_KEY_ID}, + {"bl32-key", required_argument, 0, BL32_KEY_ID}, + {"bl33-key", required_argument, 0, BL33_KEY_ID}, + /* Common options */ + {"help", no_argument, 0, 'h'}, + {"save-keys", no_argument, 0, 'k'}, + {"new-chain", no_argument, 0, 'n'}, + {"print-cert", no_argument, 0, 'p'}, + {0, 0, 0, 0} +}; + +static void print_help(const char *cmd) +{ + int i = 0; + printf("\n\n"); + printf("The certificate generation tool loads the binary images and\n" + "optionally the RSA keys, and outputs the key and content\n" + "certificates properly signed to implement the chain of trust.\n" + "If keys are provided, they must be in PEM format.\n" + "Certificates are generated in DER format.\n"); + printf("\n"); + printf("Usage:\n\n"); + printf(" %s [-hknp] \\\n", cmd); + for (i = 0; i < NUM_OPTS; i++) { + printf(" --%s \\\n", long_opt[i].name); + } + printf("\n"); + printf("-h Print help and exit\n"); + printf("-k Save key pairs into files. Filenames must be provided\n"); + printf("-n Generate new key pairs if no key files are provided\n"); + printf("-p Print the certificates in the standard output\n"); + printf("\n"); + + exit(0); +} + +static void check_cmd_params(void) +{ + /* BL2, BL31 and BL33 are mandatory */ + if (certs[BL2_CERT].bin == NULL) { + ERROR("BL2 image not specified\n"); + exit(1); + } + + if (certs[BL31_CERT].bin == NULL) { + ERROR("BL31 image not specified\n"); + exit(1); + } + + if (certs[BL33_CERT].bin == NULL) { + ERROR("BL33 image not specified\n"); + exit(1); + } + + /* BL30 and BL32 are optional */ + if (certs[BL30_CERT].bin != NULL) { + bl30_present = 1; + } + + if (certs[BL32_CERT].bin != NULL) { + bl32_present = 1; + } + + /* TODO: Certificate filenames */ + + /* Filenames to store keys must be specified */ + if (save_keys || !new_keys) { + if (keys[ROT_KEY].fn == NULL) { + ERROR("ROT key not specified\n"); + exit(1); + } + + if (keys[TRUSTED_WORLD_KEY].fn == NULL) { + ERROR("Trusted World key not specified\n"); + exit(1); + } + + if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) { + ERROR("Non-trusted World key not specified\n"); + exit(1); + } + + if (keys[BL31_KEY].fn == NULL) { + ERROR("BL31 key not specified\n"); + exit(1); + } + + if (keys[BL33_KEY].fn == NULL) { + ERROR("BL33 key not specified\n"); + exit(1); + } + + if (bl30_present && (keys[BL30_KEY].fn == NULL)) { + ERROR("BL30 key not specified\n"); + exit(1); + } + + if (bl32_present && (keys[BL32_KEY].fn == NULL)) { + ERROR("BL32 key not specified\n"); + exit(1); + } + } +} + +int main(int argc, char *argv[]) +{ + STACK_OF(X509_EXTENSION) * sk = NULL; + X509_EXTENSION *hash_ext = NULL; + X509_EXTENSION *nvctr_ext = NULL; + X509_EXTENSION *trusted_key_ext = NULL; + X509_EXTENSION *non_trusted_key_ext = NULL; + FILE *file = NULL; + int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid; + int c, opt_idx = 0; + unsigned char md[SHA256_DIGEST_LENGTH]; + + NOTICE("CoT Generation Tool: %s\n", build_msg); + NOTICE("Target platform: %s\n", platform_msg); + + while (1) { + /* getopt_long stores the option index here. */ + c = getopt_long(argc, argv, "hknp", long_opt, &opt_idx); + + /* Detect the end of the options. */ + if (c == -1) { + break; + } + + switch (c) { + case 'h': + print_help(argv[0]); + break; + case 'k': + save_keys = 1; + break; + case 'n': + new_keys = 1; + break; + case 'p': + print_cert = 1; + break; + case BL2_ID: + certs[BL2_CERT].bin = strdup(optarg); + break; + case BL30_ID: + certs[BL30_CERT].bin = strdup(optarg); + break; + case BL31_ID: + certs[BL31_CERT].bin = strdup(optarg); + break; + case BL32_ID: + certs[BL32_CERT].bin = strdup(optarg); + break; + case BL33_ID: + certs[BL33_CERT].bin = strdup(optarg); + break; + case BL2_CERT_ID: + certs[BL2_CERT].fn = strdup(optarg); + break; + case TRUSTED_KEY_CERT_ID: + certs[TRUSTED_KEY_CERT].fn = strdup(optarg); + break; + case BL30_KEY_CERT_ID: + certs[BL30_KEY_CERT].fn = strdup(optarg); + break; + case BL30_CERT_ID: + certs[BL30_CERT].fn = strdup(optarg); + break; + case BL31_KEY_CERT_ID: + certs[BL31_KEY_CERT].fn = strdup(optarg); + break; + case BL31_CERT_ID: + certs[BL31_CERT].fn = strdup(optarg); + break; + case BL32_KEY_CERT_ID: + certs[BL32_KEY_CERT].fn = strdup(optarg); + break; + case BL32_CERT_ID: + certs[BL32_CERT].fn = strdup(optarg); + break; + case BL33_KEY_CERT_ID: + certs[BL33_KEY_CERT].fn = strdup(optarg); + break; + case BL33_CERT_ID: + certs[BL33_CERT].fn = strdup(optarg); + break; + case ROT_KEY_ID: + keys[ROT_KEY].fn = strdup(optarg); + break; + case TRUSTED_WORLD_KEY_ID: + keys[TRUSTED_WORLD_KEY].fn = strdup(optarg); + break; + case NON_TRUSTED_WORLD_KEY_ID: + keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg); + break; + case BL30_KEY_ID: + keys[BL30_KEY].fn = strdup(optarg); + break; + case BL31_KEY_ID: + keys[BL31_KEY].fn = strdup(optarg); + break; + case BL32_KEY_ID: + keys[BL32_KEY].fn = strdup(optarg); + break; + case BL33_KEY_ID: + keys[BL33_KEY].fn = strdup(optarg); + break; + case '?': + default: + printf("%s\n", optarg); + exit(1); + } + } + + /* Set the value of the NVCounters */ + tf_nvcounter = NVCOUNTER_VALUE; + non_tf_nvcounter = NVCOUNTER_VALUE; + + /* Check command line arguments */ + check_cmd_params(); + + /* Register the new types and OIDs for the extensions */ + if (ext_init(tbb_ext) != 0) { + ERROR("Cannot initialize TBB extensions\n"); + exit(1); + } + + /* Get non-volatile counters NIDs */ + CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID); + CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID); + + /* Load private keys from files (or generate new ones) */ + if (new_keys) { + for (i = 0 ; i < NUM_KEYS ; i++) { + if (!key_new(&keys[i])) { + ERROR("Error creating %s\n", keys[i].desc); + exit(1); + } + } + } else { + for (i = 0 ; i < NUM_KEYS ; i++) { + if (!key_load(&keys[i])) { + ERROR("Error loading %s\n", keys[i].desc); + exit(1); + } + } + } + + /* ********************************************************************* + * BL2 certificate (Trusted Boot Firmware certificate): + * - Self-signed with OEM ROT private key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - BL2 hash + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + + /* Add the NVCounter as a critical extension */ + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + /* Add hash of BL2 as an extension */ + if (!sha_file(certs[BL2_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL2_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + /* Create certificate. Signed with ROT key */ + if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL2_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * Trusted Key certificate: + * - Self-signed with OEM ROT private key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - TrustedWorldPK + * - NonTrustedWorldPK + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, TZ_WORLD_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[TRUSTED_WORLD_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + CHECK_OID(pk_nid, NTZ_WORLD_PK_OID); + CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[NON_TRUSTED_WORLD_KEY].key)); + sk_X509_EXTENSION_push(sk, non_trusted_key_ext); + if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL30 Key certificate (Trusted SCP Firmware Key certificate): + * - Self-signed with Trusted World key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - SCPFirmwareContentCertPK + **********************************************************************/ + if (bl30_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL30_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL30 certificate (SCP Firmware Content certificate): + * - Signed with Trusted World Key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - SCPFirmwareHash + **********************************************************************/ + if (bl30_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL30_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", + certs[BL30_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL30_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL30_CERT].cn); + exit(1); + } + + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL31 Key certificate (Trusted SoC Firmware Key certificate): + * - Self-signed with Trusted World key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - SoCFirmwareContentCertPK + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL31_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL31 certificate (SOC Firmware Content certificate): + * - Signed with Trusted World Key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - BL31 hash + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL31_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL31_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL31_CERT].cn); + exit(1); + } + + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL32 Key certificate (Trusted OS Firmware Key certificate): + * - Self-signed with Trusted World key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - TrustedOSFirmwareContentCertPK + **********************************************************************/ + if (bl32_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID); + CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL32_KEY].key)); + sk_X509_EXTENSION_push(sk, trusted_key_ext); + if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL32 certificate (TrustedOS Firmware Content certificate): + * - Signed with Trusted World Key + * - Extensions: + * - TrustedFirmwareNVCounter (TODO) + * - BL32 hash + **********************************************************************/ + if (bl32_present) { + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT, + tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL32_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", + certs[BL32_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL32_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL32_CERT].cn); + exit(1); + } + + sk_X509_EXTENSION_free(sk); + } + + /* ********************************************************************* + * BL33 Key certificate (Non Trusted Firmware Key certificate): + * - Self-signed with Non Trusted World key + * - Extensions: + * - NonTrustedFirmwareNVCounter (TODO) + * - NonTrustedFirmwareContentCertPK + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT, + non_tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID); + CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT, + keys[BL33_KEY].key)); + sk_X509_EXTENSION_push(sk, non_trusted_key_ext); + if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* ********************************************************************* + * BL33 certificate (Non-Trusted World Content certificate): + * - Signed with Non-Trusted World Key + * - Extensions: + * - NonTrustedFirmwareNVCounter (TODO) + * - BL33 hash + **********************************************************************/ + CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); + CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT, + non_tf_nvcounter)); + sk_X509_EXTENSION_push(sk, nvctr_ext); + + if (!sha_file(certs[BL33_CERT].bin, md)) { + ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin); + exit(1); + } + CHECK_OID(hash_nid, BL33_HASH_OID); + CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md, + SHA256_DIGEST_LENGTH)); + sk_X509_EXTENSION_push(sk, hash_ext); + + if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) { + ERROR("Cannot create %s\n", certs[BL33_CERT].cn); + exit(1); + } + sk_X509_EXTENSION_free(sk); + + /* Print the certificates */ + if (print_cert) { + for (i = 0 ; i < NUM_CERTIFICATES ; i++) { + if (!certs[i].x) { + continue; + } + printf("\n\n=====================================\n\n"); + X509_print_fp(stdout, certs[i].x); + } + } + + /* Save created certificates to files */ + for (i = 0 ; i < NUM_CERTIFICATES ; i++) { + if (certs[i].x && certs[i].fn) { + file = fopen(certs[i].fn, "w"); + if (file != NULL) { + i2d_X509_fp(file, certs[i].x); + fclose(file); + } else { + ERROR("Cannot create file %s\n", certs[i].fn); + } + } + } + + /* Save keys */ + if (save_keys) { + for (i = 0 ; i < NUM_KEYS ; i++) { + if (!key_store(&keys[i])) { + ERROR("Cannot save %s\n", keys[i].desc); + } + } + } + + X509_EXTENSION_free(hash_ext); + X509_EXTENSION_free(nvctr_ext); + X509_EXTENSION_free(trusted_key_ext); + X509_EXTENSION_free(non_trusted_key_ext); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + CRYPTO_cleanup_all_ex_data(); + + return 0; +} diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c new file mode 100644 index 0000000..57026b5 --- /dev/null +++ b/tools/cert_create/src/sha.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "debug.h" + +#define BUFFER_SIZE 256 + +int sha_file(const char *filename, unsigned char *md) +{ + FILE *inFile; + SHA256_CTX shaContext; + int bytes; + unsigned char data[BUFFER_SIZE]; + + if ((filename == NULL) || (md == NULL)) { + ERROR("%s(): NULL argument\n", __FUNCTION__); + return 0; + } + + inFile = fopen(filename, "rb"); + if (inFile == NULL) { + ERROR("Cannot read %s\n", filename); + return 0; + } + + SHA256_Init(&shaContext); + while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { + SHA256_Update(&shaContext, data, bytes); + } + SHA256_Final(md, &shaContext); + + fclose(inFile); + return 1; +} diff --git a/tools/cert_create/src/tbb_cert.c b/tools/cert_create/src/tbb_cert.c new file mode 100644 index 0000000..8dfda60 --- /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 0000000..0022611 --- /dev/null +++ b/tools/cert_create/src/tbb_ext.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "ext.h" +#include "platform_oid.h" + +ext_t tbb_ext[] = { + { + .oid = TZ_FW_NVCOUNTER_OID, + .sn = "TrustedNvCounter", + .ln = "Non-volatile trusted counter", + .type = V_ASN1_INTEGER + }, + { + .oid = NTZ_FW_NVCOUNTER_OID, + .sn = "NonTrustedNvCounter", + .ln = "Non-volatile non-trusted counter", + .type = V_ASN1_INTEGER + }, + { + .oid = BL2_HASH_OID, + .sn = "TrustedBootFirmwareHash", + .ln = "Trusted Boot Firmware (BL2) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = TZ_WORLD_PK_OID, + .sn = "TrustedWorldPublicKey", + .ln = "Trusted World Public Key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = NTZ_WORLD_PK_OID, + .sn = "NonTrustedWorldPublicKey", + .ln = "Non-Trusted World Public Key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL31_CONTENT_CERT_PK_OID, + .sn = "SoCFirmwareContentCertPK", + .ln = "SoC Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL31_HASH_OID, + .sn = "APROMPatchHash", + .ln = "AP ROM patch hash", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL30_CONTENT_CERT_PK_OID, + .sn = "SCPFirmwareContentCertPK", + .ln = "SCP Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL30_HASH_OID, + .sn = "SCPFirmwareHash", + .ln = "SCP Firmware (BL30) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL32_CONTENT_CERT_PK_OID, + .sn = "TrustedOSFirmwareContentCertPK", + .ln = "Trusted OS Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL32_HASH_OID, + .sn = "TrustedOSHash", + .ln = "Trusted OS (BL32) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL33_CONTENT_CERT_PK_OID, + .sn = "NonTrustedFirmwareContentCertPK", + .ln = "Non-Trusted Firmware content certificate public key", + .type = V_ASN1_OCTET_STRING + }, + { + .oid = BL33_HASH_OID, + .sn = "NonTrustedWorldBootloaderHash", + .ln = "Non-Trusted World (BL33) hash (SHA256)", + .type = V_ASN1_OCTET_STRING + }, + { 0, 0, 0, 0 } +}; diff --git a/tools/cert_create/src/tbb_key.c b/tools/cert_create/src/tbb_key.c new file mode 100644 index 0000000..140aeda --- /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 c940c5b..c6869f9 100644 --- a/tools/fip_create/fip_create.c +++ b/tools/fip_create/fip_create.c @@ -65,6 +65,30 @@ "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 ef321cd..3258335 100644 --- a/tools/fip_create/fip_create.h +++ b/tools/fip_create/fip_create.h @@ -34,7 +34,7 @@ #include #include -#define MAX_FILES 10 +#define MAX_FILES 20 /* TODO: Update this number as required */ #define TOC_HEADER_SERIAL_NUMBER 0x12345678