From: Ion Agorria <[email protected]> Commonize the BCT patching process across all supported Tegra SoC generations. Refactor the function to handle core logic only, allowing it to be used in other execution pathways.
Signed-off-by: Ion Agorria <[email protected]> Signed-off-by: Svyatoslav Ryhel <[email protected]> --- arch/arm/mach-tegra/Kconfig | 7 +- arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/{tegra20 => }/bct.c | 63 +++++++++--------- arch/arm/mach-tegra/bct.h | 44 +++++++++++++ arch/arm/mach-tegra/tegra124/Makefile | 1 - arch/arm/mach-tegra/tegra124/bct.c | 86 ------------------------- arch/arm/mach-tegra/tegra124/bct.h | 24 +------ arch/arm/mach-tegra/tegra20/Makefile | 1 - arch/arm/mach-tegra/tegra20/bct.h | 22 ++----- arch/arm/mach-tegra/tegra30/Makefile | 1 - arch/arm/mach-tegra/tegra30/bct.c | 84 ------------------------ arch/arm/mach-tegra/tegra30/bct.h | 22 ++----- 12 files changed, 95 insertions(+), 261 deletions(-) rename arch/arm/mach-tegra/{tegra20 => }/bct.c (54%) create mode 100644 arch/arm/mach-tegra/bct.h delete mode 100644 arch/arm/mach-tegra/tegra124/bct.c delete mode 100644 arch/arm/mach-tegra/tegra30/bct.c diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 32cdfebfc01..ec4993788f1 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -21,6 +21,11 @@ config TEGRA_CRYPTO select AES select TEGRA_AES +config TEGRA_BCT + bool "Tegra BCT operations" + depends on TEGRA20 || TEGRA30 || TEGRA124 + select TEGRA_CRYPTO + config TEGRA_GP_PADCTRL bool @@ -267,7 +272,7 @@ config CMD_ENTERRCM config CMD_EBTUPDATE bool "Enable 'ebtupdate' command" depends on TEGRA20 || TEGRA30 || TEGRA124 - select TEGRA_CRYPTO + select TEGRA_BCT help Updating u-boot from within u-boot in rather complex or even impossible on production devices. To make it easier procedure of diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 2f0341bc02a..63fd95d7208 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_TEGRA_GPU) += gpu.o obj-$(CONFIG_TEGRA_IVC) += ivc.o ifndef CONFIG_XPL_BUILD obj-$(CONFIG_ARMV7_PSCI) += psci.o +obj-$(CONFIG_TEGRA_BCT) += bct.o endif obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o obj-y += pmc.o diff --git a/arch/arm/mach-tegra/tegra20/bct.c b/arch/arm/mach-tegra/bct.c similarity index 54% rename from arch/arm/mach-tegra/tegra20/bct.c rename to arch/arm/mach-tegra/bct.c index 0270cf592c1..a4647d854a7 100644 --- a/arch/arm/mach-tegra/tegra20/bct.c +++ b/arch/arm/mach-tegra/bct.c @@ -13,72 +13,67 @@ #include "bct.h" #include "uboot_aes.h" -/* - * @param bct boot config table start in RAM - * @param ect bootloader start in RAM - * @param ebt_size bootloader file size in bytes - * Return: 0, or 1 if failed - */ -static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) +int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) { - struct nvboot_config_table *bct_tbl = NULL; - u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; - u8 *bct_hash = bct; + struct nvboot_config_table *bct_tbl = (struct nvboot_config_table *)bct; bool encrypted; int ret; - bct += BCT_HASH; + bct += UBCT_LENGTH; ebt_size = roundup(ebt_size, EBT_ALIGNMENT); - encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE; - - if (encrypted) { - ret = decrypt_data_block(bct, bct, BCT_LENGTH); - if (ret) - return 1; - - ret = encrypt_data_block(ebt, ebt, ebt_size); - if (ret) - return 1; - } - - ret = sign_data_block(ebt, ebt_size, ebt_hash); + ret = sign_data_block(ebt, ebt_size, (u8 *)bct_tbl->bootloader[0].crypto_hash); if (ret) return 1; - bct_tbl = (struct nvboot_config_table *)bct; - - memcpy((u8 *)&bct_tbl->bootloader[0].crypto_hash, - ebt_hash, NVBOOT_CMAC_AES_HASH_LENGTH * 4); bct_tbl->bootloader[0].entry_point = CONFIG_SPL_TEXT_BASE; bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE; bct_tbl->bootloader[0].length = ebt_size; + encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE; if (encrypted) { - ret = encrypt_data_block(bct, bct, BCT_LENGTH); + ret = encrypt_data_block(bct, bct, SBCT_LENGTH); if (ret) return 1; } - ret = sign_data_block(bct, BCT_LENGTH, bct_hash); + ret = sign_data_block(bct, SBCT_LENGTH, (u8 *)bct_tbl->crypto_hash); if (ret) return 1; return 0; + } +#ifdef CONFIG_CMD_EBTUPDATE static int do_ebtupdate(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - u32 bct_addr = hextoul(argv[1], NULL); - u32 ebt_addr = hextoul(argv[2], NULL); + u8 *bct = (u8 *)hextoul(argv[1], NULL); + u8 *ebt = (u8 *)hextoul(argv[2], NULL); u32 ebt_size = hextoul(argv[3], NULL); + bool encrypted; + int ret; + + ebt_size = roundup(ebt_size, EBT_ALIGNMENT); + encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE; + + if (encrypted) { + ret = decrypt_data_block(bct, bct, SBCT_LENGTH); + if (ret) + return 1; + + ret = encrypt_data_block(ebt, ebt, ebt_size); + if (ret) + return 1; + } - return bct_patch((u8 *)bct_addr, (u8 *)ebt_addr, ebt_size); + return bct_patch(bct, ebt, ebt_size); } U_BOOT_CMD(ebtupdate, 4, 0, do_ebtupdate, - "update bootloader on re-crypted Tegra20 devices", + "update bootloader on re-crypted Tegra devices", "" ); +#endif diff --git a/arch/arm/mach-tegra/bct.h b/arch/arm/mach-tegra/bct.h new file mode 100644 index 00000000000..76756cba8ed --- /dev/null +++ b/arch/arm/mach-tegra/bct.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _BCT_H_ +#define _BCT_H_ + +#define EBT_ALIGNMENT 0x10 + +/* + * Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) + */ +#define NVBOOT_CMAC_AES_HASH_LENGTH 4 + +/* + * Defines the RSA modulus length in 32 bit words used for PKC secure boot. + */ +#define NVBOOT_SE_RSA_MODULUS_LENGTH 64 + +/* + * Defines the maximum number of bootloader descriptions in the BCT. + */ +#define NVBOOT_MAX_BOOTLOADERS 4 + +#ifdef CONFIG_TEGRA20 +#include "tegra20/bct.h" +#elif CONFIG_TEGRA30 +#include "tegra30/bct.h" +#elif CONFIG_TEGRA124 +#include "tegra124/bct.h" +#endif + +#define BCT_LENGTH (UBCT_LENGTH + SBCT_LENGTH) + +/* + * Updates the hash of bootloader entry and the BCT itself + * It will encrypt BCT in place if the device requires it + * + * @param bct boot config table start in RAM + * @param ebt bootloader start in RAM + * @param ebt_size bootloader file size in bytes + * Return: 0, or 1 if failed + */ +int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size); + +#endif /* _BCT_H_ */ diff --git a/arch/arm/mach-tegra/tegra124/Makefile b/arch/arm/mach-tegra/tegra124/Makefile index 7b93db89c0f..dee790015a3 100644 --- a/arch/arm/mach-tegra/tegra124/Makefile +++ b/arch/arm/mach-tegra/tegra124/Makefile @@ -6,7 +6,6 @@ # obj-$(CONFIG_XPL_BUILD) += cpu.o -obj-$(CONFIG_$(XPL_)CMD_EBTUPDATE) += bct.o obj-y += clock.o obj-y += pmc.o diff --git a/arch/arm/mach-tegra/tegra124/bct.c b/arch/arm/mach-tegra/tegra124/bct.c deleted file mode 100644 index 676b68dc5de..00000000000 --- a/arch/arm/mach-tegra/tegra124/bct.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2022, Ramin <[email protected]> - * Copyright (c) 2022, Svyatoslav Ryhel <[email protected]> - */ - -#include <command.h> -#include <log.h> -#include <vsprintf.h> -#include <linux/string.h> -#include <asm/arch-tegra/crypto.h> -#include <asm/arch-tegra/fuse.h> -#include "bct.h" -#include "uboot_aes.h" - -/* - * @param bct boot config table start in RAM - * @param ect bootloader start in RAM - * @param ebt_size bootloader file size in bytes - * Return: 0, or 1 if failed - */ -static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) -{ - struct nvboot_config_table *bct_tbl = NULL; - u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; - u8 bct_hash[AES128_KEY_LENGTH] = { 0 }; - u8 *sbct = bct + UBCT_LENGTH; - bool encrypted; - int ret; - - ebt_size = roundup(ebt_size, EBT_ALIGNMENT); - - encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE; - - if (encrypted) { - ret = decrypt_data_block(sbct, sbct, SBCT_LENGTH); - if (ret) - return 1; - - ret = encrypt_data_block(ebt, ebt, ebt_size); - if (ret) - return 1; - } - - ret = sign_data_block(ebt, ebt_size, ebt_hash); - if (ret) - return 1; - - bct_tbl = (struct nvboot_config_table *)bct; - - memcpy((u8 *)&bct_tbl->bootloader[0].crypto_hash, - ebt_hash, NVBOOT_CMAC_AES_HASH_LENGTH * 4); - bct_tbl->bootloader[0].entry_point = CONFIG_SPL_TEXT_BASE; - bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE; - bct_tbl->bootloader[0].length = ebt_size; - - if (encrypted) { - ret = encrypt_data_block(sbct, sbct, SBCT_LENGTH); - if (ret) - return 1; - } - - ret = sign_data_block(sbct, SBCT_LENGTH, bct_hash); - if (ret) - return 1; - - memcpy((u8 *)&bct_tbl->crypto_hash, bct_hash, - NVBOOT_CMAC_AES_HASH_LENGTH * 4); - - return 0; -} - -static int do_ebtupdate(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - u32 bct_addr = hextoul(argv[1], NULL); - u32 ebt_addr = hextoul(argv[2], NULL); - u32 ebt_size = hextoul(argv[3], NULL); - - return bct_patch((u8 *)bct_addr, (u8 *)ebt_addr, ebt_size); -} - -U_BOOT_CMD(ebtupdate, 4, 0, do_ebtupdate, - "update bootloader on re-crypted Tegra124 devices", - "" -); diff --git a/arch/arm/mach-tegra/tegra124/bct.h b/arch/arm/mach-tegra/tegra124/bct.h index eb0f712d595..f7d65621c0a 100644 --- a/arch/arm/mach-tegra/tegra124/bct.h +++ b/arch/arm/mach-tegra/tegra124/bct.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _BCT_H_ -#define _BCT_H_ +#ifndef _TEGRA124_BCT_H_ +#define _TEGRA124_BCT_H_ /* * Defines the BCT parametres for T124 @@ -9,24 +9,6 @@ #define UBCT_LENGTH 0x6b0 /* bytes */ #define SBCT_LENGTH 0x1950 /* bytes */ -#define BCT_HASH 0x10 -#define EBT_ALIGNMENT 0x10 - -/* - * Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) - */ -#define NVBOOT_CMAC_AES_HASH_LENGTH 4 - -/* - * Defines the RSA modulus length in 32 bit words used for PKC secure boot. - */ -#define NVBOOT_SE_RSA_MODULUS_LENGTH 64 - -/* - * Defines the maximum number of bootloader descriptions in the BCT. - */ -#define NVBOOT_MAX_BOOTLOADERS 4 - struct nv_bootloader_info { u32 version; u32 start_blk; @@ -52,4 +34,4 @@ struct nvboot_config_table { u32 sbct_unused2; }; -#endif /* _BCT_H_ */ +#endif /* _TEGRA124_BCT_H_ */ diff --git a/arch/arm/mach-tegra/tegra20/Makefile b/arch/arm/mach-tegra/tegra20/Makefile index a3ea759d764..fad4b1bc07d 100644 --- a/arch/arm/mach-tegra/tegra20/Makefile +++ b/arch/arm/mach-tegra/tegra20/Makefile @@ -3,7 +3,6 @@ # (C) Copyright 2010,2011 Nvidia Corporation. obj-$(CONFIG_XPL_BUILD) += cpu.o -obj-$(CONFIG_$(PHASE_)CMD_EBTUPDATE) += bct.o # The AVP is ARMv4T architecture so we must use special compiler # flags for any startup files it might use. diff --git a/arch/arm/mach-tegra/tegra20/bct.h b/arch/arm/mach-tegra/tegra20/bct.h index 4b78aef7cfd..a9feba42bf6 100644 --- a/arch/arm/mach-tegra/tegra20/bct.h +++ b/arch/arm/mach-tegra/tegra20/bct.h @@ -1,24 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _BCT_H_ -#define _BCT_H_ +#ifndef _TEGRA20_BCT_H_ +#define _TEGRA20_BCT_H_ /* * Defines the BCT parametres for T20 */ -#define BCT_LENGTH 0xFE0 -#define BCT_HASH 0x10 -#define EBT_ALIGNMENT 0x10 - -/* - * Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) - */ -#define NVBOOT_CMAC_AES_HASH_LENGTH 4 - -/* - * Defines the maximum number of bootloader descriptions in the BCT. - */ -#define NVBOOT_MAX_BOOTLOADERS 4 +#define UBCT_LENGTH 0x10 +#define SBCT_LENGTH 0xFE0 struct nv_bootloader_info { u32 version; @@ -32,6 +21,7 @@ struct nv_bootloader_info { }; struct nvboot_config_table { + u32 crypto_hash[NVBOOT_CMAC_AES_HASH_LENGTH]; u32 unused0[4]; u32 boot_data_version; u32 unused1[668]; @@ -39,4 +29,4 @@ struct nvboot_config_table { u32 unused2[508]; }; -#endif /* _BCT_H_ */ +#endif /* _TEGRA20_BCT_H_ */ diff --git a/arch/arm/mach-tegra/tegra30/Makefile b/arch/arm/mach-tegra/tegra30/Makefile index d6351734ec0..d983800a89c 100644 --- a/arch/arm/mach-tegra/tegra30/Makefile +++ b/arch/arm/mach-tegra/tegra30/Makefile @@ -3,6 +3,5 @@ # Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. obj-$(CONFIG_XPL_BUILD) += cpu.o -obj-$(CONFIG_$(PHASE_)CMD_EBTUPDATE) += bct.o obj-y += clock.o diff --git a/arch/arm/mach-tegra/tegra30/bct.c b/arch/arm/mach-tegra/tegra30/bct.c deleted file mode 100644 index de668214517..00000000000 --- a/arch/arm/mach-tegra/tegra30/bct.c +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 2022, Ramin <[email protected]> - * Copyright (c) 2022, Svyatoslav Ryhel <[email protected]> - */ - -#include <command.h> -#include <log.h> -#include <vsprintf.h> -#include <linux/string.h> -#include <asm/arch-tegra/crypto.h> -#include <asm/arch-tegra/fuse.h> -#include "bct.h" -#include "uboot_aes.h" - -/* - * @param bct boot config table start in RAM - * @param ect bootloader start in RAM - * @param ebt_size bootloader file size in bytes - * Return: 0, or 1 if failed - */ -static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) -{ - struct nvboot_config_table *bct_tbl = NULL; - u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; - u8 *bct_hash = bct; - bool encrypted; - int ret; - - bct += BCT_HASH; - - ebt_size = roundup(ebt_size, EBT_ALIGNMENT); - - encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE; - - if (encrypted) { - ret = decrypt_data_block(bct, bct, BCT_LENGTH); - if (ret) - return 1; - - ret = encrypt_data_block(ebt, ebt, ebt_size); - if (ret) - return 1; - } - - ret = sign_data_block(ebt, ebt_size, ebt_hash); - if (ret) - return 1; - - bct_tbl = (struct nvboot_config_table *)bct; - - memcpy((u8 *)&bct_tbl->bootloader[0].crypto_hash, - ebt_hash, NVBOOT_CMAC_AES_HASH_LENGTH * 4); - bct_tbl->bootloader[0].entry_point = CONFIG_SPL_TEXT_BASE; - bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE; - bct_tbl->bootloader[0].length = ebt_size; - - if (encrypted) { - ret = encrypt_data_block(bct, bct, BCT_LENGTH); - if (ret) - return 1; - } - - ret = sign_data_block(bct, BCT_LENGTH, bct_hash); - if (ret) - return 1; - - return 0; -} - -static int do_ebtupdate(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - u32 bct_addr = hextoul(argv[1], NULL); - u32 ebt_addr = hextoul(argv[2], NULL); - u32 ebt_size = hextoul(argv[3], NULL); - - return bct_patch((u8 *)bct_addr, (u8 *)ebt_addr, ebt_size); -} - -U_BOOT_CMD(ebtupdate, 4, 0, do_ebtupdate, - "update bootloader on re-crypted Tegra30 devices", - "" -); diff --git a/arch/arm/mach-tegra/tegra30/bct.h b/arch/arm/mach-tegra/tegra30/bct.h index 9797384da32..8420615ce62 100644 --- a/arch/arm/mach-tegra/tegra30/bct.h +++ b/arch/arm/mach-tegra/tegra30/bct.h @@ -1,24 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _BCT_H_ -#define _BCT_H_ +#ifndef _TEGRA30_BCT_H_ +#define _TEGRA30_BCT_H_ /* * Defines the BCT parametres for T30 */ -#define BCT_LENGTH 0x17E0 -#define BCT_HASH 0x10 -#define EBT_ALIGNMENT 0x10 - -/* - * Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) - */ -#define NVBOOT_CMAC_AES_HASH_LENGTH 4 - -/* - * Defines the maximum number of bootloader descriptions in the BCT. - */ -#define NVBOOT_MAX_BOOTLOADERS 4 +#define UBCT_LENGTH 0x10 +#define SBCT_LENGTH 0x17E0 struct nv_bootloader_info { u32 version; @@ -32,6 +21,7 @@ struct nv_bootloader_info { }; struct nvboot_config_table { + u32 crypto_hash[NVBOOT_CMAC_AES_HASH_LENGTH]; u32 unused0[4]; u32 boot_data_version; u32 unused1[972]; @@ -39,4 +29,4 @@ struct nvboot_config_table { u32 unused2[508]; }; -#endif /* _BCT_H_ */ +#endif /* _TEGRA30_BCT_H_ */ -- 2.53.0
