RSS: Align SIC tools to specification
As it uses a non-standard AES counter mode to decrypt
Change-Id: Ic274c2084ba3405d123717fc9e674c8c69751ace
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/docs/platform/arm/rss/readme.rst b/docs/platform/arm/rss/readme.rst
index 3ca5639..5d0f373 100644
--- a/docs/platform/arm/rss/readme.rst
+++ b/docs/platform/arm/rss/readme.rst
@@ -110,8 +110,8 @@
fiptool create \
--align 8192 --rss-bl2 bl2_signed.bin \
- --align 8192 --rss-ns tfm_ns.bin \
- --align 8192 --rss-s tfm_s.bin \
+ --align 8192 --rss-ns tfm_ns_encrypted.bin \
+ --align 8192 --rss-s tfm_s_encrypted.bin \
--align 8192 --rss-sic-tables-ns tfm_ns_sic_tables_signed.bin \
--align 8192 --rss-sic-tables-s tfm_s_sic_tables_signed.bin \
--align 8192 --rss-scp-bl1 <signed Host SCP BL1 image> \
diff --git a/platform/ext/target/arm/rss/common/bl2/create_xip_tables.py b/platform/ext/target/arm/rss/common/bl2/create_xip_tables.py
index 192cc6d..ceabb7f 100644
--- a/platform/ext/target/arm/rss/common/bl2/create_xip_tables.py
+++ b/platform/ext/target/arm/rss/common/bl2/create_xip_tables.py
@@ -1,5 +1,5 @@
#-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -14,6 +14,7 @@
import secrets
sic_page_size = 1024
+sic_line_size = 16
def struct_pack(objects, pad_to=0):
defstring = "<"
@@ -40,8 +41,6 @@
with open(args.input_image, "rb") as in_file:
image = in_file.read()
-# TODO derive a key from the main key based on the security counter / fw
-# version, as we do for BL2. This requires tweaks to crypto in BL2 first.
if args.encrypt_key_file is not None:
with open(args.encrypt_key, "rb") as in_file:
encrypt_key = in_file.read()
@@ -55,12 +54,16 @@
fw_version_bytes = int(args.image_version, 0).to_bytes(4, 'little')
nonce_bytes = secrets.token_bytes(8)
-# Provided the image starts at the beginning of the DR, we can start the line
-# index at 0.
-counter_val = struct_pack([nonce_bytes, fw_version_bytes], pad_to=16)
-
-cipher = Cipher(algorithms.AES(encrypt_key), modes.CTR(counter_val))
-enc_image = cipher.encryptor().update(image)
+# The SIC uses a non-standard counter construction, so we need to do this
+# manually
+enc_image = []
+line_idx = 0
+for chunk in chunk_bytes(image, sic_line_size):
+ counter_val = struct_pack([line_idx.to_bytes(4, 'little'), fw_version_bytes, nonce_bytes[4:], nonce_bytes[:4]], pad_to=16)
+ line_idx += 1
+ cipher = Cipher(algorithms.AES(encrypt_key), modes.CTR(counter_val))
+ enc_image.append(cipher.encryptor().update(chunk))
+enc_image = reduce(add, enc_image, b"")
htr = reduce(add, map(lambda x:hashlib.sha256(x).digest(), chunk_bytes(enc_image, sic_page_size)), b"")
diff --git a/platform/ext/target/arm/rss/common/bl2/sic_boot.c b/platform/ext/target/arm/rss/common/bl2/sic_boot.c
index be0d786..0968372 100644
--- a/platform/ext/target/arm/rss/common/bl2/sic_boot.c
+++ b/platform/ext/target/arm/rss/common/bl2/sic_boot.c
@@ -13,6 +13,7 @@
#include "tfm_plat_otp.h"
#include "host_flash_atu.h"
#include "plat_def_fip_uuid.h"
+#include "rss_kmu_slot_ids.h"
#include <string.h>
@@ -57,14 +58,15 @@
int sic_boot_post_load(uint32_t image_id, uint32_t image_load_offset)
{
enum sic_error_t sic_err;
+ enum kmu_error_t kmu_err;
struct rss_xip_htr_table *table;
- uint32_t key[8];
enum tfm_plat_err_t plat_err;
size_t sic_page_size;
- enum tfm_otp_element_id_t decrypt_key_otp_id;
+ enum rss_kmu_slot_id_t decrypt_key_slot;
uint32_t decrypt_region;
uint32_t xip_region_base_addr;
- uint32_t xip_region_size;
+ size_t xip_region_size;
+ size_t max_region_size;
uint64_t fip_offsets[2];
bool fip_found[2];
uint64_t fip_offset;
@@ -105,11 +107,11 @@
return 1;
}
- decrypt_key_otp_id = PLAT_OTP_ID_KEY_NON_SECURE_ENCRYPTION;
+ decrypt_key_slot = RSS_KMU_SLOT_NON_SECURE_ENCRYPTION_KEY;
atu_region = RSS_ATU_NS_IMAGE_XIP_REGION;
decrypt_region = RSS_SIC_NS_IMAGE_DECRYPT_REGION;
xip_region_base_addr = RSS_RUNTIME_NS_XIP_BASE_S;
- xip_region_size = NS_CODE_SIZE;
+ max_region_size = NS_CODE_SIZE;
image_uuid = UUID_RSS_FIRMWARE_NS;
image_offset = &ns_image_offset;
@@ -127,11 +129,11 @@
return 1;
}
- decrypt_key_otp_id = PLAT_OTP_ID_KEY_SECURE_ENCRYPTION;
+ decrypt_key_slot = RSS_KMU_SLOT_SECURE_ENCRYPTION_KEY;
atu_region = RSS_ATU_S_IMAGE_XIP_REGION;
decrypt_region = RSS_SIC_S_IMAGE_DECRYPT_REGION;
xip_region_base_addr = RSS_RUNTIME_S_XIP_BASE_S;
- xip_region_size = S_CODE_SIZE;
+ max_region_size = S_CODE_SIZE;
image_uuid = UUID_RSS_FIRMWARE_S;
image_offset = &s_image_offset;
@@ -148,7 +150,8 @@
atu_region,
xip_region_base_addr,
image_uuid,
- image_offset);
+ image_offset,
+ &xip_region_size);
if (rc) {
return rc;
}
@@ -162,6 +165,9 @@
return 1;
}
+ if (xip_region_size > max_region_size) {
+ return 1;
+ }
sic_err = sic_auth_table_set(&SIC_DEV_S, (uint32_t*)(table->htr),
table->htr_size, (xip_region_base_addr
@@ -171,23 +177,20 @@
return 1;
}
- plat_err = tfm_plat_otp_read(decrypt_key_otp_id, sizeof(key), (uint8_t*)key);
- if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return 1;
- }
-
sic_err = sic_decrypt_region_enable(&SIC_DEV_S,
decrypt_region, xip_region_base_addr,
xip_region_size,
- image_load_offset, table->nonce,
- key);
+ table->fw_revision, table->nonce,
+ NULL);
if (sic_err != SIC_ERROR_NONE) {
- memset(key, 0, sizeof(key));
return 1;
}
-
- memset(key, 0, sizeof(key));
+ kmu_err = kmu_export_key(&KMU_DEV_S, decrypt_key_slot);
+ if (kmu_err != KMU_ERROR_NONE) {
+ while(1){}
+ return 1;
+ }
return 0;
}
diff --git a/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.c b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.c
index b4f8dbc..0fdc026 100644
--- a/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.c
+++ b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.c
@@ -74,7 +74,8 @@
uint32_t slot,
uintptr_t logical_address,
uuid_t image_uuid,
- uint32_t *logical_address_offset)
+ uint32_t *logical_address_offset,
+ size_t *slot_size)
{
enum atu_error_t err;
int rc;
@@ -116,7 +117,12 @@
return rc;
}
- *logical_address_offset = alignment_offset;
+ if (logical_address_offset != NULL) {
+ *logical_address_offset = alignment_offset;
+ }
+ if (slot_size != NULL) {
+ *slot_size = atu_slot_size;
+ }
return 0;
}
@@ -232,7 +238,7 @@
rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[0],
RSS_ATU_REGION_INPUT_IMAGE_SLOT_0,
HOST_FLASH0_IMAGE0_BASE_S, image_uuid,
- &offsets[0]);
+ &offsets[0], NULL);
if (rc == 0) {
fip_mapped[0] = true;
}
@@ -240,7 +246,7 @@
rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[1],
RSS_ATU_REGION_INPUT_IMAGE_SLOT_1,
HOST_FLASH0_IMAGE1_BASE_S, image_uuid,
- &offsets[1]);
+ &offsets[1], NULL);
if (rc == 0) {
fip_mapped[1] = true;
}
@@ -256,7 +262,7 @@
rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[0],
RSS_ATU_REGION_INPUT_IMAGE_SLOT_1,
HOST_FLASH0_IMAGE1_BASE_S,
- image_uuid, &offsets[1]);
+ image_uuid, &offsets[1], NULL);
if (rc) {
return rc;
}
@@ -264,7 +270,7 @@
rc = host_flash_atu_setup_image_input_slots_from_fip(fip_offsets[1],
RSS_ATU_REGION_INPUT_IMAGE_SLOT_0,
HOST_FLASH0_IMAGE0_BASE_S,
- image_uuid, &offsets[0]);
+ image_uuid, &offsets[0], NULL);
if (rc) {
return rc;
}
diff --git a/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.h b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.h
index 62d65fe..7a11da0 100644
--- a/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.h
+++ b/platform/ext/target/arm/rss/common/fip_parser/host_flash_atu.h
@@ -56,13 +56,16 @@
* This is required because images may not be
* aligned to the ATU page size.
*
+ * \param[out] atu_slot_size The size of the mapped image.
+ *
* \return 0 on success, non-zero on failure.
*/
int host_flash_atu_setup_image_input_slots_from_fip(uint64_t fip_offset,
uint32_t slot,
uintptr_t logical_address,
uuid_t image_uuid,
- uint32_t *logical_address_offset);
+ uint32_t *logical_address_offset,
+ size_t *atu_slot_size);
/**
* \brief Setup the input and output slots for a
diff --git a/platform/ext/target/arm/rss/common/native_drivers/sic_drv.c b/platform/ext/target/arm/rss/common/native_drivers/sic_drv.c
index 69ab33d..4886da0 100644
--- a/platform/ext/target/arm/rss/common/native_drivers/sic_drv.c
+++ b/platform/ext/target/arm/rss/common/native_drivers/sic_drv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023 Arm Limited. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -470,11 +470,13 @@
}
/* The key is 4 words, plus another 4 if the 256-bit key bit is set in the
- * CCR
+ * CCR. If it is NULL, assume it is set in another way (e.g. by KMU export)
*/
- key_len = 4 + (((p_sic->ccr >> 3) & 0x1) * 4);
- for (idx = 0; idx < key_len; idx++) {
- p_sic->dr[region_idx].dkw[idx] = key[idx];
+ if (key != NULL) {
+ key_len = 4 + (((p_sic->ccr >> 3) & 0x1) * 4);
+ for (idx = 0; idx < key_len; idx++) {
+ p_sic->dr[region_idx].dkw[idx] = key[idx];
+ }
}
return SIC_ERROR_NONE;
diff --git a/platform/ext/target/arm/rss/kronos/flash_layout.h b/platform/ext/target/arm/rss/kronos/flash_layout.h
index 595a21b..a40de3a 100644
--- a/platform/ext/target/arm/rss/kronos/flash_layout.h
+++ b/platform/ext/target/arm/rss/kronos/flash_layout.h
@@ -53,13 +53,6 @@
#define HOST_IMAGE_HEADER_SIZE (0x2000)
-#ifdef RSS_XIP
-/* Each table contains a bit less that 8KiB of HTR and 2KiB of mcuboot headers.
- * The spare space in the 8KiB is used for decryption IVs.
- */
-#define FLASH_SIC_TABLE_SIZE (0x2800) /* 10KiB */
-#endif /* RSS_XIP */
-
/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */
#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x1000) /* 512 KiB */
/* Same as FLASH0_SIZE */
diff --git a/platform/ext/target/arm/rss/tc/flash_layout.h b/platform/ext/target/arm/rss/tc/flash_layout.h
index fcacb64..dcfaa0f 100644
--- a/platform/ext/target/arm/rss/tc/flash_layout.h
+++ b/platform/ext/target/arm/rss/tc/flash_layout.h
@@ -50,10 +50,10 @@
#define HOST_IMAGE_HEADER_SIZE (0x2000)
#ifdef RSS_XIP
-/* Each table contains a bit less that 8KiB of HTR and 2KiB of mcuboot headers.
+/* Each table contains a bit less that 12KiB of HTR and 2KiB of mcuboot headers.
* The spare space in the 8KiB is used for decryption IVs.
*/
-#define FLASH_SIC_TABLE_SIZE (0x2800) /* 10KiB */
+#define FLASH_SIC_TABLE_SIZE (0x3800) /* 10KiB */
#endif /* RSS_XIP */
/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */