aboutsummaryrefslogtreecommitdiffstats
path: root/plat/arm/board/common
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2021-02-16 21:01:22 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-16 21:01:22 +0000
commitefb2826bb8160e2d8e0fcec85133a7468484f9fd (patch)
tree37a21c69306801ee7cdda5167a30896c8740155b /plat/arm/board/common
parentb00a71fc312c9781fa6f404dccfb55b062b2ccac (diff)
parentfaa476c0caaa598afa5a6109d17102db5fe35ec6 (diff)
downloadplatform_external_arm-trusted-firmware-master.tar.gz
platform_external_arm-trusted-firmware-master.tar.bz2
platform_external_arm-trusted-firmware-master.zip
Original change: https://android-review.googlesource.com/c/platform/external/arm-trusted-firmware/+/1589611 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I3a25534ceed4f8e188510641080d8b8ed49b8f62
Diffstat (limited to 'plat/arm/board/common')
-rw-r--r--plat/arm/board/common/board_arm_trusted_boot.c260
-rw-r--r--plat/arm/board/common/board_common.mk105
-rw-r--r--plat/arm/board/common/protpk/README14
-rw-r--r--plat/arm/board/common/protpk/arm_dev_protpk.S18
-rw-r--r--plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin1
-rw-r--r--plat/arm/board/common/protpk/arm_protprivk_rsa.pem27
-rw-r--r--plat/arm/board/common/rotpk/arm_dev_rotpk.S26
7 files changed, 299 insertions, 152 deletions
diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c
index c71e932a0..66cc3e949 100644
--- a/plat/arm/board/common/board_arm_trusted_boot.c
+++ b/plat/arm/board/common/board_arm_trusted_boot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,136 +8,180 @@
#include <stdint.h>
#include <string.h>
+#include <common/debug.h>
+#include <drivers/arm/cryptocell/cc_rotpk.h>
+#include <drivers/delay_timer.h>
#include <lib/cassert.h>
+#include <lib/fconf/fconf.h>
+#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/fconf_nv_cntr_getter.h>
+#include <plat/common/common_def.h>
#include <plat/common/platform.h>
-#include <tools_share/tbbr_oid.h>
#include <platform_def.h>
-/* SHA256 algorithm */
-#define SHA256_BYTES 32
-
-/* ROTPK locations */
-#define ARM_ROTPK_REGS_ID 1
-#define ARM_ROTPK_DEVEL_RSA_ID 2
-#define ARM_ROTPK_DEVEL_ECDSA_ID 3
-
-static const unsigned char rotpk_hash_hdr[] = \
- "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \
- "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20";
-static const unsigned int rotpk_hash_hdr_len = sizeof(rotpk_hash_hdr) - 1;
-static unsigned char rotpk_hash_der[sizeof(rotpk_hash_hdr) - 1 + SHA256_BYTES];
+#if defined(ARM_COT_tbbr)
+#include <tools_share/tbbr_oid.h>
+#elif defined(ARM_COT_dualroot)
+#include <tools_share/dualroot_oid.h>
+#endif
-/* Use the cryptocell variants if Cryptocell is present */
#if !ARM_CRYPTOCELL_INTEG
#if !ARM_ROTPK_LOCATION_ID
#error "ARM_ROTPK_LOCATION_ID not defined"
#endif
+#endif
+
+#if COT_DESC_IN_DTB && defined(IMAGE_BL2)
+uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS];
+#else
+uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = {
+ TFW_NVCTR_BASE,
+ NTFW_CTR_BASE
+};
+#endif
+
/* Weak definition may be overridden in specific platform */
#pragma weak plat_get_nv_ctr
#pragma weak plat_set_nv_ctr
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] = \
- "\xB0\xF3\x82\x09\x12\x97\xD8\x3A" \
- "\x37\x7A\x72\x47\x1B\xEC\x32\x73" \
- "\xE9\x92\x32\xE2\x49\x59\xF6\x5E" \
- "\x8B\x4A\x4A\x46\xD8\x22\x9A\xDA";
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
-static const unsigned char arm_devel_rotpk_hash[] = \
- "\x2E\x40\xBF\x6E\xF9\x12\xBB\x98" \
- "\x31\x71\x09\x0E\x1E\x15\x3D\x0B" \
- "\xFD\xD1\xCC\x69\x4A\x98\xEB\x8B" \
- "\xA0\xB0\x20\x86\x4E\x6C\x07\x17";
+extern unsigned char arm_rotpk_header[], arm_rotpk_hash_end[];
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID) || ARM_CRYPTOCELL_INTEG
+static unsigned char rotpk_hash_der[ARM_ROTPK_HEADER_LEN + ARM_ROTPK_HASH_LEN];
#endif
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm AlgorithmIdentifier,
- * digest OCTET STRING
- * }
+ * Return the ROTPK hash stored in dedicated registers.
*/
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+int arm_get_rotpk_info_regs(void **key_ptr, unsigned int *key_len,
unsigned int *flags)
{
uint8_t *dst;
+ uint32_t *src, tmp;
+ unsigned int words, i;
assert(key_ptr != NULL);
assert(key_len != NULL);
assert(flags != NULL);
/* Copy the DER header */
- memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
- dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len];
-#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
- || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
- memcpy(dst, arm_devel_rotpk_hash, SHA256_BYTES);
-#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
- uint32_t *src, tmp;
- unsigned int words, i;
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = (uint8_t *)&rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
- /*
- * Append the hash from Trusted Root-Key Storage registers. The hash has
- * not been written linearly into the registers, so we have to do a bit
- * of byte swapping:
- *
- * 0x00 0x04 0x08 0x0C 0x10 0x14 0x18 0x1C
- * +---------------------------------------------------------------+
- * | Reg0 | Reg1 | Reg2 | Reg3 | Reg4 | Reg5 | Reg6 | Reg7 |
- * +---------------------------------------------------------------+
- * | ... ... | | ... ... |
- * | +--------------------+ | +-------+
- * | | | |
- * +----------------------------+ +----------------------------+
- * | | | |
- * +-------+ | +--------------------+ |
- * | | | |
- * v v v v
- * +---------------------------------------------------------------+
- * | | |
- * +---------------------------------------------------------------+
- * 0 15 16 31
- *
- * Additionally, we have to access the registers in 32-bit words
- */
- words = SHA256_BYTES >> 3;
+ words = ARM_ROTPK_HASH_LEN >> 2;
- /* Swap bytes 0-15 (first four registers) */
src = (uint32_t *)TZ_PUB_KEY_HASH_BASE;
for (i = 0 ; i < words ; i++) {
tmp = src[words - 1 - i];
/* Words are read in little endian */
- *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 8) & 0xFF);
*dst++ = (uint8_t)(tmp & 0xFF);
- }
-
- /* Swap bytes 16-31 (last four registers) */
- src = (uint32_t *)(TZ_PUB_KEY_HASH_BASE + SHA256_BYTES / 2);
- for (i = 0 ; i < words ; i++) {
- tmp = src[words - 1 - i];
- *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
- *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
*dst++ = (uint8_t)((tmp >> 8) & 0xFF);
- *dst++ = (uint8_t)(tmp & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 16) & 0xFF);
+ *dst++ = (uint8_t)((tmp >> 24) & 0xFF);
}
-#endif /* (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) \
- || (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID) */
*key_ptr = (void *)rotpk_hash_der;
*key_len = (unsigned int)sizeof(rotpk_hash_der);
*flags = ROTPK_IS_HASH;
return 0;
}
+#endif
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+/*
+ * Return development ROTPK hash generated from ROT_KEY.
+ */
+int arm_get_rotpk_info_dev(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = arm_rotpk_header;
+ *key_len = arm_rotpk_hash_end - arm_rotpk_header;
+ *flags = ROTPK_IS_HASH;
+ return 0;
+}
+#endif
+
+#if ARM_CRYPTOCELL_INTEG
+/*
+ * Return ROTPK hash from CryptoCell.
+ */
+int arm_get_rotpk_info_cc(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ unsigned char *dst;
+
+ assert(key_ptr != NULL);
+ assert(key_len != NULL);
+ assert(flags != NULL);
+
+ /* Copy the DER header */
+ memcpy(rotpk_hash_der, arm_rotpk_header, ARM_ROTPK_HEADER_LEN);
+ dst = &rotpk_hash_der[ARM_ROTPK_HEADER_LEN];
+ *key_ptr = rotpk_hash_der;
+ *key_len = sizeof(rotpk_hash_der);
+ return cc_get_rotpk_hash(dst, ARM_ROTPK_HASH_LEN, flags);
+}
+#endif
+
+/*
+ * Wrapper function for most Arm platforms to get ROTPK hash.
+ */
+static int get_rotpk_info(void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+#if ARM_CRYPTOCELL_INTEG
+ return arm_get_rotpk_info_cc(key_ptr, key_len, flags);
+#else
+
+#if (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_RSA_ID) || \
+ (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_DEVEL_ECDSA_ID)
+ return arm_get_rotpk_info_dev(key_ptr, key_len, flags);
+#elif (ARM_ROTPK_LOCATION_ID == ARM_ROTPK_REGS_ID)
+ return arm_get_rotpk_info_regs(key_ptr, key_len, flags);
+#else
+ return 1;
+#endif
+#endif /* ARM_CRYPTOCELL_INTEG */
+}
+
+#if defined(ARM_COT_tbbr)
+
+int arm_get_rotpk_info(void *cookie __unused, void **key_ptr,
+ unsigned int *key_len, unsigned int *flags)
+{
+ return get_rotpk_info(key_ptr, key_len, flags);
+}
+
+#elif defined(ARM_COT_dualroot)
+
+int arm_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ /*
+ * Return the right root of trust key hash based on the cookie value:
+ * - NULL means the primary ROTPK.
+ * - Otherwise, interpret cookie as the OID of the certificate
+ * extension containing the key.
+ */
+ if (cookie == NULL) {
+ return get_rotpk_info(key_ptr, key_len, flags);
+ } else if (strcmp(cookie, PROT_PK_OID) == 0) {
+ extern unsigned char arm_protpk_hash[];
+ extern unsigned char arm_protpk_hash_end[];
+ *key_ptr = arm_protpk_hash;
+ *key_len = arm_protpk_hash_end - arm_protpk_hash;
+ *flags = ROTPK_IS_HASH;
+ return 0;
+ } else {
+ /* Invalid key ID. */
+ return 1;
+ }
+}
+#endif
/*
* Return the non-volatile counter value stored in the platform. The cookie
@@ -155,9 +199,11 @@ int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
oid = (const char *)cookie;
if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
- nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
+ nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ TRUSTED_NV_CTR_ID);
} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
- nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
+ nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr,
+ NON_TRUSTED_NV_CTR_ID);
} else {
return 1;
}
@@ -179,37 +225,3 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 1;
}
-#else /* ARM_CRYPTOCELL_INTEG */
-
-#include <drivers/arm/cryptocell/cc_rotpk.h>
-
-/*
- * Return the ROTPK hash in the following ASN.1 structure in DER format:
- *
- * AlgorithmIdentifier ::= SEQUENCE {
- * algorithm OBJECT IDENTIFIER,
- * parameters ANY DEFINED BY algorithm OPTIONAL
- * }
- *
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm AlgorithmIdentifier,
- * digest OCTET STRING
- * }
- */
-int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
- unsigned int *flags)
-{
- unsigned char *dst;
-
- assert(key_ptr != NULL);
- assert(key_len != NULL);
- assert(flags != NULL);
-
- /* Copy the DER header */
- memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len);
- dst = &rotpk_hash_der[rotpk_hash_hdr_len];
- *key_ptr = rotpk_hash_der;
- *key_len = sizeof(rotpk_hash_der);
- return cc_get_rotpk_hash(dst, SHA256_BYTES, flags);
-}
-#endif /* ARM_CRYPTOCELL_INTEG */
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index b98dfd48b..6db0c0031 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,31 +12,80 @@ BL1_SOURCES += drivers/cfi/v2m/v2m_flash.c
BL2_SOURCES += drivers/cfi/v2m/v2m_flash.c
ifneq (${TRUSTED_BOARD_BOOT},0)
- ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
- # ROTPK hash location
- ifeq (${ARM_ROTPK_LOCATION}, regs)
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
- else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
- KEY_ALG := rsa
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
- else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
- KEY_ALG := ecdsa
- ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
- else
- $(error "Unsupported ARM_ROTPK_LOCATION value")
- endif
- $(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
-
- # Certificate NV-Counters. Use values corresponding to tied off values in
- # ARM development platforms
- TFW_NVCTR_VAL ?= 31
- NTFW_NVCTR_VAL ?= 223
- else
- # Certificate NV-Counters when CryptoCell is integrated. For development
- # platforms we set the counter to first valid value.
- TFW_NVCTR_VAL ?= 0
- NTFW_NVCTR_VAL ?= 0
- endif
- BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
- BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
+ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
+# ROTPK hash location
+ifeq (${ARM_ROTPK_LOCATION}, regs)
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_REGS_ID
+else ifeq (${ARM_ROTPK_LOCATION}, devel_rsa)
+ CRYPTO_ALG=rsa
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_RSA_ID
+ ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else ifeq (${ARM_ROTPK_LOCATION}, devel_ecdsa)
+ CRYPTO_ALG=ec
+ ARM_ROTPK_LOCATION_ID = ARM_ROTPK_DEVEL_ECDSA_ID
+ ARM_ROTPK_HASH = plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin
+$(eval $(call add_define_val,ARM_ROTPK_HASH,'"$(ARM_ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl2/arm_dev_rotpk.o : $(ARM_ROTPK_HASH)
+$(warning Development keys support for FVP is deprecated. Use `regs` \
+option instead)
+else
+ $(error "Unsupported ARM_ROTPK_LOCATION value")
+endif
+
+$(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
+
+# Force generation of the new hash if ROT_KEY is specified
+ifdef ROT_KEY
+ HASH_PREREQUISITES = $(ROT_KEY) FORCE
+else
+ HASH_PREREQUISITES = $(ROT_KEY)
+endif
+
+$(ARM_ROTPK_HASH) : $(HASH_PREREQUISITES)
+ifndef ROT_KEY
+ $(error Cannot generate hash: no ROT_KEY defined)
+endif
+ openssl ${CRYPTO_ALG} -in $< -pubout -outform DER | openssl dgst \
+ -sha256 -binary > $@
+
+# Certificate NV-Counters. Use values corresponding to tied off values in
+# ARM development platforms
+TFW_NVCTR_VAL ?= 31
+NTFW_NVCTR_VAL ?= 223
+else
+# Certificate NV-Counters when CryptoCell is integrated. For development
+# platforms we set the counter to first valid value.
+TFW_NVCTR_VAL ?= 0
+NTFW_NVCTR_VAL ?= 0
+endif
+BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \
+ plat/arm/board/common/rotpk/arm_dev_rotpk.S
+BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c \
+ plat/arm/board/common/rotpk/arm_dev_rotpk.S
+
+# Allows platform code to provide implementation variants depending on the
+# selected chain of trust.
+$(eval $(call add_define,ARM_COT_${COT}))
+
+ifeq (${COT},dualroot)
+# Platform Root of Trust key files.
+ARM_PROT_KEY := plat/arm/board/common/protpk/arm_protprivk_rsa.pem
+ARM_PROTPK_HASH := plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
+
+# Provide the private key to cert_create tool. It needs it to sign the images.
+PROT_KEY := ${ARM_PROT_KEY}
+
+$(eval $(call add_define_val,ARM_PROTPK_HASH,'"$(ARM_PROTPK_HASH)"'))
+
+BL1_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S
+BL2_SOURCES += plat/arm/board/common/protpk/arm_dev_protpk.S
+
+$(BUILD_PLAT)/bl1/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+$(BUILD_PLAT)/bl2/arm_dev_protpk.o: $(ARM_PROTPK_HASH)
+endif
+
endif
diff --git a/plat/arm/board/common/protpk/README b/plat/arm/board/common/protpk/README
new file mode 100644
index 000000000..3aca180d2
--- /dev/null
+++ b/plat/arm/board/common/protpk/README
@@ -0,0 +1,14 @@
+This directory contains some development keys to be used as the platform
+root-of-trust key.
+
+* arm_protprivk_rsa.pem is a 2K RSA private key in PEM format. It has been
+ generated using the openssl command line tool:
+
+ openssl genrsa 2048 > arm_protprivk_rsa.pem
+
+* arm_protpk_rsa_sha256.bin is the SHA-256 hash of the DER-encoded public key
+ associated with the above private key. It has been generated using the openssl
+ command line tool:
+
+ openssl rsa -in arm_protprivk_rsa.pem -pubout -outform DER | \
+ openssl dgst -sha256 -binary > arm_protpk_rsa_sha256.bin
diff --git a/plat/arm/board/common/protpk/arm_dev_protpk.S b/plat/arm/board/common/protpk/arm_dev_protpk.S
new file mode 100644
index 000000000..2688cbbb1
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_dev_protpk.S
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global arm_protpk_hash
+ .global arm_protpk_hash_end
+
+ .section .rodata.arm_protpk_hash, "a"
+
+arm_protpk_hash:
+ /* DER header. */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* Key hash. */
+ .incbin ARM_PROTPK_HASH
+arm_protpk_hash_end:
diff --git a/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
new file mode 100644
index 000000000..587da6605
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protpk_rsa_sha256.bin
@@ -0,0 +1 @@
+œó6{W*…`Ÿtíve×·§è£ €¾PžÆK{9 \ No newline at end of file
diff --git a/plat/arm/board/common/protpk/arm_protprivk_rsa.pem b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem
new file mode 100644
index 000000000..eeaad9e28
--- /dev/null
+++ b/plat/arm/board/common/protpk/arm_protprivk_rsa.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAzR0h/Z4Up17wfuRlYrUWseGDmlGKpl1PflGiYbyVmI7PwTTp
+y/T77EiljGp52suLWntHsc0lee50pW16DU2c5bVfmyofau3GjJ1Yqw5XFAahr6eM
+/0mkN8utrevvcRT9CP07D+zdhb/WlRUAnedqr/AUHU8BXS+Bxe8P0Z0Z7+DKjYZp
+thzXxsjKM02BFFzNwyVrlyBFDkW/53A4M+dpmuWDjAGCJH88W/u0LdmLcii11IzD
+/Ofz8Jxc/ZhqL+9FFK4qU+AJp8yXAnACSB46DlNltJrode0y5tmPhtS37ZF7EFb8
+UZWwZVgtuQyuyz9RYUS6jtiGuq6s8GlRwjTe7wIDAQABAoIBAFoWIYeyln+sQxR4
+W88umfkmgxaUGcFX2kIwuJEUst9+WeERzF24C62LeqphWYOvQlVLMAH3iC41fSXr
+H2AYZoC9WHBd386nAD1iHj+C3Nv+zaTIgjTdszKOUonAxjl0bm40SmyELAdCaoyv
+3MV9jm4Xk74LpR24b9bvWJNH3MxttH9hiYS+n0IzeTXDfO8GrNvHh92zx+jo8yMm
+Khhu+TDC9jA2pHpJcF/0EXxYMhwYiQT16nnHb+xMgS4JpalQhvVK01s4VYGHRoFk
+K6xh4TIS336LDLyalrGsPlfNfEdx+DimShDIfBUx9Jp3Pp11TUQUz4rhIHB9WdfG
+b6bV4wECgYEA+cgPS2TQ7XQ1RJq1S7OGePtBXvnoH226KwGS6Fey8838tLxbblim
+MU+EOYs3O66V6U2YpzmIakXo8030k8thY+jKbZl3l0m/hMuPOG66hfE5i7dYsiP4
+atok5wFiNeNYYjHMEayzk53MhG8EOh36msAO7ohKmenONUBA7pk6yTkCgYEA0jhk
+HPshwi+wKkx+JLTnuoEgx40tkRgSF2xBqKssMTasaQmX8qG+w9CEs0R8nZCI70Vc
+tXSFcidjdkHUVE2WsygIFuS1tbsAnpaxtn3E6rjie30X/Z280+TV0HjR0EMETmwl
+ShC5lZ0oP3LpEZfjbR5qs2kFW4MOxA7tjQVaMWcCgYEA5ZbVMBifzdMl70RA5i9C
+qEtSQAl3KgRCvar5rKSHsX+iC0Kiy9+iCusq/3WONEZ6NvMDIJpKYFyYDaOW7o5f
+m2TrRChu+1lnN5mfsGBfBCTBH0JMvZlAin6ussLb0eqBX+ijyY8zlLjTttsQSJcr
+tThZwTj3UVfOGbZQuL+RgEkCgYBXO3U3nXI9vUIx2zoBC1yZRNoQVGITMlTXiWGZ
+lyYoadKTZ5q44Sti4BUguounaoGYIEU/OtHhM70PJnPwY53kS/lHXrKUbbvtEwU9
+f+UFraC1s4wP/rOLjgq3jlsqO5T+4dt7Z4NLNUKtSYazeT6zWgrW1f6WIcUv0C38
+9bqegwKBgFCK3Oa5ibL5sPaPQ/1UfdeW4JVuu6A4JhHS7r+cVLsmcrvE1Qv7Wcvw
+B5aqXeqLu2dtIN8/f++3tzccs9LXKY/fh72D4TVjfrqOSSZoGTH9l4U5NXbqWM3I
+skkAYb2bMST/d1qSyYesgXVNAlaQHRh3vEz8x853nJ3v9OFj8/rW
+-----END RSA PRIVATE KEY-----
diff --git a/plat/arm/board/common/rotpk/arm_dev_rotpk.S b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
new file mode 100644
index 000000000..80f2192e4
--- /dev/null
+++ b/plat/arm/board/common/rotpk/arm_dev_rotpk.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "plat/arm/common/arm_def.h"
+
+ .global arm_rotpk_header
+ .global arm_rotpk_header_end
+ .section .rodata.arm_rotpk_hash, "a"
+
+arm_rotpk_header:
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+arm_rotpk_header_len:
+
+#ifdef ARM_ROTPK_HASH
+ .global arm_rotpk_hash_end
+ .incbin ARM_ROTPK_HASH
+arm_rotpk_hash_end:
+#endif
+
+.if ARM_ROTPK_HEADER_LEN != arm_rotpk_header_len - arm_rotpk_header
+.error "Invalid ROTPK header length."
+.endif