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

Reply via email to