]>
Commit | Line | Data |
---|---|---|
327ff8e0 RK |
1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* | |
3 | * Copyright (c) 2022, Ramin <raminterex@yahoo.com> | |
4 | * Copyright (c) 2022, Svyatoslav Ryhel <clamor95@gmail.com> | |
5 | */ | |
6 | ||
d678a59d | 7 | #include <common.h> |
327ff8e0 RK |
8 | #include <command.h> |
9 | #include <log.h> | |
10 | #include <asm/arch-tegra/crypto.h> | |
11 | #include "bct.h" | |
12 | #include "uboot_aes.h" | |
13 | ||
f2cf7feb SR |
14 | /* Device with "sbk burned: false" will expose zero key */ |
15 | const u8 nosbk[AES128_KEY_LENGTH] = { 0 }; | |
16 | ||
327ff8e0 RK |
17 | /* |
18 | * @param bct boot config table start in RAM | |
19 | * @param ect bootloader start in RAM | |
20 | * @param ebt_size bootloader file size in bytes | |
21 | * Return: 0, or 1 if failed | |
22 | */ | |
23 | static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) | |
24 | { | |
25 | struct nvboot_config_table *bct_tbl = NULL; | |
26 | u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; | |
27 | u8 sbk[AES128_KEY_LENGTH] = { 0 }; | |
28 | u8 *bct_hash = bct; | |
f2cf7feb | 29 | bool encrypted; |
327ff8e0 RK |
30 | int ret; |
31 | ||
32 | bct += BCT_HASH; | |
33 | ||
f2cf7feb SR |
34 | ebt_size = roundup(ebt_size, EBT_ALIGNMENT); |
35 | ||
327ff8e0 RK |
36 | memcpy(sbk, (u8 *)(bct + BCT_LENGTH), |
37 | NVBOOT_CMAC_AES_HASH_LENGTH * 4); | |
38 | ||
f2cf7feb | 39 | encrypted = memcmp(&sbk, &nosbk, AES128_KEY_LENGTH); |
327ff8e0 | 40 | |
f2cf7feb SR |
41 | if (encrypted) { |
42 | ret = decrypt_data_block(bct, BCT_LENGTH, sbk); | |
43 | if (ret) | |
44 | return 1; | |
327ff8e0 | 45 | |
f2cf7feb SR |
46 | ret = encrypt_data_block(ebt, ebt_size, sbk); |
47 | if (ret) | |
48 | return 1; | |
49 | } | |
327ff8e0 RK |
50 | |
51 | ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk); | |
52 | if (ret) | |
53 | return 1; | |
54 | ||
55 | bct_tbl = (struct nvboot_config_table *)bct; | |
56 | ||
57 | memcpy((u8 *)&bct_tbl->bootloader[0].crypto_hash, | |
58 | ebt_hash, NVBOOT_CMAC_AES_HASH_LENGTH * 4); | |
59 | bct_tbl->bootloader[0].entry_point = CONFIG_SPL_TEXT_BASE; | |
60 | bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE; | |
61 | bct_tbl->bootloader[0].length = ebt_size; | |
62 | ||
f2cf7feb SR |
63 | if (encrypted) { |
64 | ret = encrypt_data_block(bct, BCT_LENGTH, sbk); | |
65 | if (ret) | |
66 | return 1; | |
67 | } | |
327ff8e0 RK |
68 | |
69 | ret = sign_enc_data_block(bct, BCT_LENGTH, bct_hash, sbk); | |
70 | if (ret) | |
71 | return 1; | |
72 | ||
73 | return 0; | |
74 | } | |
75 | ||
76 | static int do_ebtupdate(struct cmd_tbl *cmdtp, int flag, int argc, | |
77 | char *const argv[]) | |
78 | { | |
79 | u32 bct_addr = hextoul(argv[1], NULL); | |
80 | u32 ebt_addr = hextoul(argv[2], NULL); | |
81 | u32 ebt_size = hextoul(argv[3], NULL); | |
82 | ||
83 | return bct_patch((u8 *)bct_addr, (u8 *)ebt_addr, ebt_size); | |
84 | } | |
85 | ||
86 | U_BOOT_CMD(ebtupdate, 4, 0, do_ebtupdate, | |
87 | "update bootloader on re-crypted Tegra30 devices", | |
88 | "" | |
89 | ); |