Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
CTCaer
GitHub Repository: CTCaer/hekate
Path: blob/master/bootloader/hos/hos.c
1476 views
1
/*
2
* Copyright (c) 2018 naehrwert
3
* Copyright (c) 2018 st4rk
4
* Copyright (c) 2018 Ced2911
5
* Copyright (c) 2018-2025 CTCaer
6
* Copyright (c) 2018 balika011
7
*
8
* This program is free software; you can redistribute it and/or modify it
9
* under the terms and conditions of the GNU General Public License,
10
* version 2, as published by the Free Software Foundation.
11
*
12
* This program is distributed in the hope it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15
* more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
*/
20
21
#include <string.h>
22
23
#include <bdk.h>
24
25
#include "hos.h"
26
#include "hos_config.h"
27
#include "secmon_exo.h"
28
#include "../frontend/fe_tools.h"
29
#include "../config.h"
30
#include "../storage/emummc.h"
31
32
extern hekate_config h_cfg;
33
34
//#define DPRINTF(...) gfx_printf(__VA_ARGS__)
35
#define DPRINTF(...)
36
37
#define EHPRINTFARGS(text, args...) \
38
({ gfx_con.mute = false; \
39
gfx_printf("%k"text"%k\n", TXT_CLR_ERROR, args, TXT_CLR_DEFAULT); })
40
41
#define PKG2_LOAD_ADDR 0xA9800000
42
43
#define SECMON_BCT_CFG_ADDR 0x4003D000
44
#define SECMON6_BCT_CFG_ADDR 0x4003F800
45
46
// Secmon mailbox.
47
#define SECMON_MAILBOX_ADDR 0x40002E00
48
#define SECMON7_MAILBOX_ADDR 0x40000000
49
#define SECMON_STATE_OFFSET 0xF8
50
51
typedef enum
52
{
53
SECMON_STATE_NOT_READY = 0,
54
55
PKG1_STATE_NOT_READY = 0,
56
PKG1_STATE_BCT_COPIED = 1,
57
PKG1_STATE_DRAM_READY = 2,
58
PKG1_STATE_PKG2_READY_OLD = 3,
59
PKG1_STATE_PKG2_READY = 4
60
} pkg1_states_t;
61
62
typedef struct _secmon_mailbox_t
63
{
64
// < 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM and pkg2 ready, 3: Continue boot.
65
// >= 4.0.0 Signals - 0: Not ready, 1: BCT ready, 2: DRAM ready, 4: pkg2 ready and continue boot.
66
u32 in;
67
// Non-zero: Secmon ready.
68
u32 out;
69
} secmon_mailbox_t;
70
71
typedef struct _tsec_keys_t
72
{
73
u8 tsec[SE_KEY_128_SIZE];
74
u8 tsec_root[SE_KEY_128_SIZE];
75
u8 tmp[SE_KEY_128_SIZE];
76
} tsec_keys_t;
77
78
typedef struct _kb_keys_t
79
{
80
u8 master_kekseed[SE_KEY_128_SIZE];
81
u8 random_data[0x70];
82
u8 package1_key[SE_KEY_128_SIZE];
83
} kb_keys_t;
84
85
typedef struct _kb_t
86
{
87
u8 cmac[SE_KEY_128_SIZE];
88
u8 ctr[SE_AES_IV_SIZE];
89
kb_keys_t keys;
90
u8 padding[0x150];
91
} kb_t;
92
93
static const u8 keyblob_keyseeds[HOS_KB_VERSION_600 - HOS_KB_VERSION_100 + 1][SE_KEY_128_SIZE] = {
94
{ 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 }, // 1.0.0.
95
{ 0x0C, 0x25, 0x61, 0x5D, 0x68, 0x4C, 0xEB, 0x42, 0x1C, 0x23, 0x79, 0xEA, 0x82, 0x25, 0x12, 0xAC }, // 3.0.0.
96
{ 0x33, 0x76, 0x85, 0xEE, 0x88, 0x4A, 0xAE, 0x0A, 0xC2, 0x8A, 0xFD, 0x7D, 0x63, 0xC0, 0x43, 0x3B }, // 3.0.1.
97
{ 0x2D, 0x1F, 0x48, 0x80, 0xED, 0xEC, 0xED, 0x3E, 0x3C, 0xF2, 0x48, 0xB5, 0x65, 0x7D, 0xF7, 0xBE }, // 4.0.0.
98
{ 0xBB, 0x5A, 0x01, 0xF9, 0x88, 0xAF, 0xF5, 0xFC, 0x6C, 0xFF, 0x07, 0x9E, 0x13, 0x3C, 0x39, 0x80 }, // 5.0.0.
99
{ 0xD8, 0xCC, 0xE1, 0x26, 0x6A, 0x35, 0x3F, 0xCC, 0x20, 0xF3, 0x2D, 0x3B, 0x51, 0x7D, 0xE9, 0xC0 } // 6.0.0.
100
};
101
102
static const u8 cmac_keyseed[SE_KEY_128_SIZE] =
103
{ 0x59, 0xC7, 0xFB, 0x6F, 0xBE, 0x9B, 0xBE, 0x87, 0x65, 0x6B, 0x15, 0xC0, 0x53, 0x73, 0x36, 0xA5 };
104
105
static const u8 master_keyseed_retail[SE_KEY_128_SIZE] =
106
{ 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C };
107
108
static const u8 master_keyseed_4xx[SE_KEY_128_SIZE] =
109
{ 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 };
110
111
static const u8 master_kekseed_620[SE_KEY_128_SIZE] =
112
{ 0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A };
113
114
//!TODO: Update on tsec/mkey changes.
115
static const u8 master_kekseed_t210_tsec_v4[HOS_KB_VERSION_MAX - HOS_KB_VERSION_810 + 1][SE_KEY_128_SIZE] = {
116
{ 0xDE, 0xDC, 0xE3, 0x39, 0x30, 0x88, 0x16, 0xF8, 0xAE, 0x97, 0xAD, 0xEC, 0x64, 0x2D, 0x41, 0x41 }, // 8.1.0.
117
{ 0x1A, 0xEC, 0x11, 0x82, 0x2B, 0x32, 0x38, 0x7A, 0x2B, 0xED, 0xBA, 0x01, 0x47, 0x7E, 0x3B, 0x67 }, // 9.0.0.
118
{ 0x30, 0x3F, 0x02, 0x7E, 0xD8, 0x38, 0xEC, 0xD7, 0x93, 0x25, 0x34, 0xB5, 0x30, 0xEB, 0xCA, 0x7A }, // 9.1.0.
119
{ 0x84, 0x67, 0xB6, 0x7F, 0x13, 0x11, 0xAE, 0xE6, 0x58, 0x9B, 0x19, 0xAF, 0x13, 0x6C, 0x80, 0x7A }, // 12.1.0.
120
{ 0x68, 0x3B, 0xCA, 0x54, 0xB8, 0x6F, 0x92, 0x48, 0xC3, 0x05, 0x76, 0x87, 0x88, 0x70, 0x79, 0x23 }, // 13.0.0.
121
{ 0xF0, 0x13, 0x37, 0x9A, 0xD5, 0x63, 0x51, 0xC3, 0xB4, 0x96, 0x35, 0xBC, 0x9C, 0xE8, 0x76, 0x81 }, // 14.0.0.
122
{ 0x6E, 0x77, 0x86, 0xAC, 0x83, 0x0A, 0x8D, 0x3E, 0x7D, 0xB7, 0x66, 0xA0, 0x22, 0xB7, 0x6E, 0x67 }, // 15.0.0.
123
{ 0x99, 0x22, 0x09, 0x57, 0xA7, 0xF9, 0x5E, 0x94, 0xFE, 0x78, 0x7F, 0x41, 0xD6, 0xE7, 0x56, 0xE6 }, // 16.0.0.
124
{ 0x71, 0xB9, 0xA6, 0xC0, 0xFF, 0x97, 0x6B, 0x0C, 0xB4, 0x40, 0xB9, 0xD5, 0x81, 0x5D, 0x81, 0x90 }, // 17.0.0.
125
{ 0x00, 0x04, 0x5D, 0xF0, 0x4D, 0xCD, 0x14, 0xA3, 0x1C, 0xBF, 0xDE, 0x48, 0x55, 0xBA, 0x35, 0xC1 }, // 18.0.0.
126
{ 0xD7, 0x63, 0x74, 0x46, 0x4E, 0xBA, 0x78, 0x0A, 0x7C, 0x9D, 0xB3, 0xE8, 0x7A, 0x3D, 0x71, 0xE3 }, // 19.0.0.
127
{ 0xA1, 0x7D, 0x34, 0xDB, 0x2D, 0x9D, 0xDA, 0xE5, 0xF8, 0x15, 0x63, 0x4C, 0x8F, 0xE7, 0x6C, 0xD8 }, // 20.0.0.
128
};
129
130
//!TODO: Update on mkey changes.
131
static const u8 master_kekseed_t210b01[HOS_KB_VERSION_MAX - HOS_KB_VERSION_600 + 1][SE_KEY_128_SIZE] = {
132
{ 0x77, 0x60, 0x5A, 0xD2, 0xEE, 0x6E, 0xF8, 0x3C, 0x3F, 0x72, 0xE2, 0x59, 0x9D, 0xAC, 0x5E, 0x56 }, // 6.0.0.
133
{ 0x1E, 0x80, 0xB8, 0x17, 0x3E, 0xC0, 0x60, 0xAA, 0x11, 0xBE, 0x1A, 0x4A, 0xA6, 0x6F, 0xE4, 0xAE }, // 6.2.0.
134
{ 0x94, 0x08, 0x67, 0xBD, 0x0A, 0x00, 0x38, 0x84, 0x11, 0xD3, 0x1A, 0xDB, 0xDD, 0x8D, 0xF1, 0x8A }, // 7.0.0.
135
{ 0x5C, 0x24, 0xE3, 0xB8, 0xB4, 0xF7, 0x00, 0xC2, 0x3C, 0xFD, 0x0A, 0xCE, 0x13, 0xC3, 0xDC, 0x23 }, // 8.1.0.
136
{ 0x86, 0x69, 0xF0, 0x09, 0x87, 0xC8, 0x05, 0xAE, 0xB5, 0x7B, 0x48, 0x74, 0xDE, 0x62, 0xA6, 0x13 }, // 9.0.0.
137
{ 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82 }, // 9.1.0.
138
{ 0xE5, 0x41, 0xAC, 0xEC, 0xD1, 0xA7, 0xD1, 0xAB, 0xED, 0x03, 0x77, 0xF1, 0x27, 0xCA, 0xF8, 0xF1 }, // 12.1.0.
139
{ 0x52, 0x71, 0x9B, 0xDF, 0xA7, 0x8B, 0x61, 0xD8, 0xD5, 0x85, 0x11, 0xE4, 0x8E, 0x4F, 0x74, 0xC6 }, // 13.0.0.
140
{ 0xD2, 0x68, 0xC6, 0x53, 0x9D, 0x94, 0xF9, 0xA8, 0xA5, 0xA8, 0xA7, 0xC8, 0x8F, 0x53, 0x4B, 0x7A }, // 14.0.0.
141
{ 0xEC, 0x61, 0xBC, 0x82, 0x1E, 0x0F, 0x5A, 0xC3, 0x2B, 0x64, 0x3F, 0x9D, 0xD6, 0x19, 0x22, 0x2D }, // 15.0.0.
142
{ 0xA5, 0xEC, 0x16, 0x39, 0x1A, 0x30, 0x16, 0x08, 0x2E, 0xCF, 0x09, 0x6F, 0x5E, 0x7C, 0xEE, 0xA9 }, // 16.0.0.
143
{ 0x8D, 0xEE, 0x9E, 0x11, 0x36, 0x3A, 0x9B, 0x0A, 0x6A, 0xC7, 0xBB, 0xE9, 0xD1, 0x03, 0xF7, 0x80 }, // 17.0.0.
144
{ 0x4F, 0x41, 0x3C, 0x3B, 0xFB, 0x6A, 0x01, 0x2A, 0x68, 0x9F, 0x83, 0xE9, 0x53, 0xBD, 0x16, 0xD2 }, // 18.0.0.
145
{ 0x31, 0xBE, 0x25, 0xFB, 0xDB, 0xB4, 0xEE, 0x49, 0x5C, 0x77, 0x05, 0xC2, 0x36, 0x9F, 0x34, 0x80 }, // 19.0.0.
146
{ 0x1A, 0x31, 0x62, 0x87, 0xA8, 0x09, 0xCA, 0xF8, 0x69, 0x15, 0x45, 0xC2, 0x6B, 0xAA, 0x5A, 0x8A }, // 20.0.0.
147
};
148
149
static const u8 console_keyseed[SE_KEY_128_SIZE] =
150
{ 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 };
151
152
static const u8 console_keyseed_4xx[SE_KEY_128_SIZE] =
153
{ 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 };
154
155
const u8 package2_keyseed[SE_KEY_128_SIZE] =
156
{ 0xFB, 0x8B, 0x6A, 0x9C, 0x79, 0x00, 0xC8, 0x49, 0xEF, 0xD2, 0x4D, 0x85, 0x4D, 0x30, 0xA0, 0xC7 };
157
158
static void _hos_crit_error(const char *text)
159
{
160
gfx_con.mute = false;
161
gfx_printf("%k%s%k\n", TXT_CLR_ERROR, text, TXT_CLR_DEFAULT);
162
}
163
164
static void _se_lock(bool lock_se)
165
{
166
if (lock_se)
167
{
168
// Disable aes key read.
169
for (u32 i = 0; i < 16; i++)
170
se_key_acc_ctrl(i, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
171
172
// Disable RSA key read.
173
for (u32 i = 0; i < 2; i++)
174
se_rsa_acc_ctrl(i, SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG);
175
176
SE(SE_TZRAM_SECURITY_REG) = 0; // Make SE TZRAM secure only.
177
SE(SE_CRYPTO_SECURITY_PERKEY_REG) = 0; // Make all AES keys access secure only.
178
SE(SE_RSA_SECURITY_PERKEY_REG) = 0; // Make all RSA keys access secure only.
179
SE(SE_SE_SECURITY_REG) &= ~SE_PERKEY_SETTING; // Make access lock regs secure only.
180
}
181
182
memset((void *)IPATCH_BASE, 0, 14 * sizeof(u32));
183
SB(SB_CSR) = SB_CSR_PIROM_DISABLE;
184
185
// This is useful for documenting the bits in the SE config registers, so we can keep it around.
186
/*gfx_printf("SE(SE_SE_SECURITY_REG) = %08X\n", SE(SE_SE_SECURITY_REG));
187
gfx_printf("SE(0x4) = %08X\n", SE(0x4));
188
gfx_printf("SE(SE_CRYPTO_SECURITY_PERKEY_REG) = %08X\n", SE(SE_CRYPTO_SECURITY_PERKEY_REG));
189
gfx_printf("SE(SE_RSA_SECURITY_PERKEY_REG) = %08X\n", SE(SE_RSA_SECURITY_PERKEY_REG));
190
for (u32 i = 0; i < 16; i++)
191
gfx_printf("%02X ", SE(SE_CRYPTO_KEYTABLE_ACCESS_REG + i * 4) & 0xFF);
192
gfx_putc('\n');
193
for (u32 i = 0; i < 2; i++)
194
gfx_printf("%02X ", SE(SE_RSA_KEYTABLE_ACCESS_REG + i * 4) & 0xFF);
195
gfx_putc('\n');
196
gfx_hexdump(SE_BASE, (void *)SE_BASE, 0x400);*/
197
}
198
199
static bool _hos_eks_rw_try(u8 *buf, bool write)
200
{
201
for (u32 i = 0; i < 3; i++)
202
{
203
if (!write)
204
{
205
if (sdmmc_storage_read(&sd_storage, 0, 1, buf))
206
return true;
207
}
208
else
209
{
210
if (sdmmc_storage_write(&sd_storage, 0, 1, buf))
211
return true;
212
}
213
}
214
215
return false;
216
}
217
218
static void _hos_eks_get()
219
{
220
// Check if Erista based unit.
221
if (h_cfg.t210b01)
222
return;
223
224
// Check if EKS already found and parsed.
225
if (!h_cfg.eks)
226
{
227
// Read EKS blob.
228
u8 *mbr = zalloc(SD_BLOCKSIZE);
229
if (!_hos_eks_rw_try(mbr, false))
230
goto out;
231
232
// Decrypt EKS blob.
233
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x80);
234
se_aes_crypt_ecb(14, DECRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
235
236
// Check if valid and for this unit.
237
if (eks->magic == HOS_EKS_MAGIC && eks->lot0 == FUSE(FUSE_OPT_LOT_CODE_0))
238
{
239
h_cfg.eks = eks;
240
return;
241
}
242
243
out:
244
free(mbr);
245
}
246
}
247
248
static void _hos_eks_save()
249
{
250
// Check if Erista based unit.
251
if (h_cfg.t210b01)
252
return;
253
254
// EKS save. Only for 7.0.0 and up.
255
bool new_eks = false;
256
if (!h_cfg.eks)
257
{
258
h_cfg.eks = zalloc(SD_BLOCKSIZE);
259
new_eks = true;
260
}
261
262
// If matching blob doesn't exist, create it.
263
if (h_cfg.eks->enabled != HOS_EKS_TSEC_VER)
264
{
265
// Read EKS blob.
266
u8 *mbr = zalloc(SD_BLOCKSIZE);
267
if (!_hos_eks_rw_try(mbr, false))
268
{
269
if (new_eks)
270
{
271
free(h_cfg.eks);
272
h_cfg.eks = NULL;
273
}
274
275
goto out;
276
}
277
278
// Get keys.
279
u8 *keys = (u8 *)zalloc(SZ_8K);
280
se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
281
282
// Set magic and personalized info.
283
h_cfg.eks->magic = HOS_EKS_MAGIC;
284
h_cfg.eks->enabled = HOS_EKS_TSEC_VER;
285
h_cfg.eks->lot0 = FUSE(FUSE_OPT_LOT_CODE_0);
286
287
// Copy new keys.
288
memcpy(h_cfg.eks->tsec, keys + 12 * SE_KEY_128_SIZE, SE_KEY_128_SIZE);
289
memcpy(h_cfg.eks->troot, keys + 13 * SE_KEY_128_SIZE, SE_KEY_128_SIZE);
290
memcpy(h_cfg.eks->troot_dev, keys + 11 * SE_KEY_128_SIZE, SE_KEY_128_SIZE);
291
292
// Encrypt EKS blob.
293
u8 *eks = zalloc(SD_BLOCKSIZE);
294
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
295
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
296
297
// Write EKS blob to SD.
298
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
299
_hos_eks_rw_try(mbr, true);
300
301
free(eks);
302
free(keys);
303
out:
304
free(mbr);
305
}
306
}
307
308
static void _hos_eks_clear(u32 kb)
309
{
310
// Check if Erista based unit.
311
if (h_cfg.t210b01)
312
return;
313
314
if (h_cfg.eks && kb >= HOS_KB_VERSION_700)
315
{
316
// Check if current Master key is enabled.
317
if (h_cfg.eks->enabled)
318
{
319
// Read EKS blob.
320
u8 *mbr = zalloc(SD_BLOCKSIZE);
321
if (!_hos_eks_rw_try(mbr, false))
322
goto out;
323
324
// Disable current Master key version.
325
h_cfg.eks->enabled = 0;
326
327
// Encrypt EKS blob.
328
u8 *eks = zalloc(SD_BLOCKSIZE);
329
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
330
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
331
332
// Write EKS blob to SD.
333
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
334
_hos_eks_rw_try(mbr, true);
335
336
free(eks);
337
out:
338
free(mbr);
339
}
340
}
341
}
342
343
static int _hos_keygen(void *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, bool stock, bool is_exo)
344
{
345
static bool sbk_is_set = true;
346
347
u32 retries = 0;
348
bool use_tsec = false;
349
tsec_keys_t tsec_keys;
350
kb_t *kb_data = (kb_t *)keyblob;
351
352
if (kb > HOS_KB_VERSION_MAX)
353
return 0;
354
355
// Do Mariko keygen.
356
if (h_cfg.t210b01)
357
{
358
// Use SBK as Device key 4x unsealer and KEK for mkey in T210B01 units.
359
se_aes_unwrap_key(10, 14, console_keyseed_4xx);
360
361
// Derive master key.
362
se_aes_unwrap_key(7, 12, master_kekseed_t210b01[kb - HOS_KB_VERSION_600]);
363
se_aes_unwrap_key(7, 7, master_keyseed_retail);
364
365
// Derive latest pkg2 key.
366
se_aes_unwrap_key(8, 7, package2_keyseed);
367
368
return 1;
369
}
370
371
// Do Erista keygen.
372
373
// Check if SBK is wiped and try to restore it from fuses.
374
if (!sbk_is_set)
375
{
376
if (fuse_set_sbk())
377
sbk_is_set = true;
378
else
379
return 1; // Continue with current SE keys.
380
}
381
382
// Use HOS EKS if it exists.
383
_hos_eks_get();
384
385
// Use tsec keygen for old firmware or if EKS keys does not exist for newer.
386
if (kb <= HOS_KB_VERSION_620 || !h_cfg.eks || (h_cfg.eks->enabled != HOS_EKS_TSEC_VER))
387
use_tsec = true;
388
389
if (kb <= HOS_KB_VERSION_600)
390
{
391
tsec_ctxt->size = 0xF00;
392
tsec_ctxt->type = TSEC_FW_TYPE_OLD;
393
}
394
else if (kb == HOS_KB_VERSION_620)
395
{
396
tsec_ctxt->size = 0x2900;
397
tsec_ctxt->type = TSEC_FW_TYPE_EMU;
398
399
// Prepare smmu tsec page for 6.2.0.
400
u8 *tsec_paged = (u8 *)smmu_page_zalloc(3);
401
memcpy(tsec_paged, (void *)tsec_ctxt->fw, tsec_ctxt->size);
402
tsec_ctxt->fw = tsec_paged;
403
}
404
else if (use_tsec) // 7.0.0+
405
{
406
/*
407
* 7.0.0/8.1.0 tsec fw are 0x3000/0x3300.
408
* Unused here because of THK.
409
*/
410
411
// Use custom TSEC Hovi Keygen firmware.
412
tsec_ctxt->fw = sd_file_read("bootloader/sys/thk.bin", NULL);
413
if (!tsec_ctxt->fw)
414
{
415
_hos_crit_error("Failed to load thk.bin");
416
return 0;
417
}
418
419
tsec_ctxt->size = 0x1F00;
420
tsec_ctxt->type = TSEC_FW_TYPE_NEW;
421
}
422
else if (h_cfg.eks)
423
{
424
// EKS found. Set TSEC keys.
425
se_aes_key_set(12, h_cfg.eks->tsec, SE_KEY_128_SIZE);
426
se_aes_key_set(13, h_cfg.eks->troot, SE_KEY_128_SIZE);
427
se_aes_key_set(11, h_cfg.eks->troot_dev, SE_KEY_128_SIZE);
428
}
429
430
// Get TSEC key.
431
while (use_tsec && tsec_query(&tsec_keys, tsec_ctxt) < 0)
432
{
433
memset(&tsec_keys, 0x00, 0x20);
434
retries++;
435
436
// We rely on racing conditions, make sure we cover even the unluckiest cases.
437
if (retries > 15)
438
{
439
_hos_crit_error("Failed to get TSEC keys.");
440
return 0;
441
}
442
}
443
444
if (kb >= HOS_KB_VERSION_700)
445
{
446
// For 7.0.0 and up, save EKS slot if it doesn't exist.
447
if (use_tsec)
448
{
449
_hos_eks_save();
450
free(tsec_ctxt->fw);
451
}
452
453
// Use 8.1.0 for 7.0.0 otherwise the proper one.
454
u32 mkey_idx = 0;
455
if (kb >= HOS_KB_VERSION_810)
456
mkey_idx = kb - HOS_KB_VERSION_810;
457
458
if (!is_exo)
459
{
460
// Derive Package2 key in secmon compatible way.
461
se_aes_unwrap_key(7, 13, master_kekseed_t210_tsec_v4[mkey_idx]);
462
se_aes_unwrap_key(7, 7, master_keyseed_retail);
463
se_aes_unwrap_key(8, 7, package2_keyseed);
464
}
465
else
466
{
467
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tmp, keyblob_keyseeds[0]);
468
se_aes_unwrap_key(15, 14, tsec_keys.tmp);
469
470
// Derive device keys.
471
se_aes_unwrap_key(10, 15, console_keyseed_4xx);
472
se_aes_unwrap_key(15, 15, console_keyseed);
473
474
// Derive master kek.
475
se_aes_unwrap_key(13, 13, master_kekseed_t210_tsec_v4[mkey_idx]);
476
477
// Derive device master key and master key.
478
se_aes_unwrap_key(12, 13, master_keyseed_4xx);
479
se_aes_unwrap_key(13, 13, master_keyseed_retail);
480
481
// Package2 key.
482
se_aes_unwrap_key(8, 13, package2_keyseed);
483
}
484
}
485
else if (kb == HOS_KB_VERSION_620)
486
{
487
// Set TSEC key.
488
se_aes_key_set(12, tsec_keys.tsec, SE_KEY_128_SIZE);
489
// Set TSEC root key.
490
se_aes_key_set(13, tsec_keys.tsec_root, SE_KEY_128_SIZE);
491
492
if (!is_exo)
493
{
494
// Derive Package2 key in secmon compatible way.
495
se_aes_key_set(8, tsec_keys.tsec_root, SE_KEY_128_SIZE);
496
se_aes_unwrap_key(8, 8, master_kekseed_620);
497
se_aes_unwrap_key(8, 8, master_keyseed_retail);
498
se_aes_unwrap_key(8, 8, package2_keyseed);
499
}
500
else
501
{
502
// Decrypt keyblob and set keyslots for Exosphere 2.
503
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tmp, keyblob_keyseeds[0]);
504
se_aes_unwrap_key(15, 14, tsec_keys.tmp);
505
506
// Derive device keys.
507
se_aes_unwrap_key(10, 15, console_keyseed_4xx);
508
se_aes_unwrap_key(15, 15, console_keyseed);
509
510
// Derive master kek.
511
se_aes_unwrap_key(13, 13, master_kekseed_620);
512
513
// Derive device master key and master key.
514
se_aes_unwrap_key(12, 13, master_keyseed_4xx);
515
se_aes_unwrap_key(13, 13, master_keyseed_retail);
516
517
// Package2 key.
518
se_aes_unwrap_key(8, 13, package2_keyseed);
519
}
520
}
521
else
522
{
523
se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
524
se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
525
526
// Set TSEC key.
527
se_aes_key_set(13, tsec_keys.tsec, SE_KEY_128_SIZE);
528
529
// Derive keyblob keys from TSEC+SBK.
530
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, keyblob_keyseeds[0]);
531
se_aes_unwrap_key(15, 14, tsec_keys.tsec);
532
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, keyblob_keyseeds[kb]);
533
se_aes_unwrap_key(13, 14, tsec_keys.tsec);
534
535
// Clear SBK.
536
//se_aes_key_clear(14);
537
538
/*
539
// Verify keyblob CMAC.
540
u8 cmac[SE_KEY_128_SIZE];
541
se_aes_unwrap_key(11, 13, cmac_keyseed);
542
se_aes_cmac(cmac, SE_KEY_128_SIZE, 11, (void *)kb_data->ctr, sizeof(kb_data->ctr) + sizeof(kb_data->keys));
543
if (!memcmp(kb_data->cmac, cmac, SE_KEY_128_SIZE))
544
return 0;
545
*/
546
547
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, cmac_keyseed);
548
se_aes_unwrap_key(11, 13, cmac_keyseed);
549
550
// Decrypt keyblob and set keyslots.
551
se_aes_crypt_ctr(13, &kb_data->keys, sizeof(kb_keys_t), &kb_data->keys, sizeof(kb_keys_t), kb_data->ctr);
552
se_aes_key_set(11, kb_data->keys.package1_key, SE_KEY_128_SIZE);
553
se_aes_key_set(12, kb_data->keys.master_kekseed, SE_KEY_128_SIZE);
554
se_aes_key_set(13, kb_data->keys.master_kekseed, SE_KEY_128_SIZE);
555
556
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tsec, master_keyseed_retail);
557
558
if (!is_exo)
559
{
560
switch (kb)
561
{
562
case HOS_KB_VERSION_100:
563
case HOS_KB_VERSION_300:
564
case HOS_KB_VERSION_301:
565
se_aes_unwrap_key(13, 15, console_keyseed);
566
se_aes_unwrap_key(12, 12, master_keyseed_retail);
567
break;
568
case HOS_KB_VERSION_400:
569
se_aes_unwrap_key(13, 15, console_keyseed_4xx);
570
se_aes_unwrap_key(15, 15, console_keyseed);
571
se_aes_unwrap_key(14, 12, master_keyseed_4xx);
572
se_aes_unwrap_key(12, 12, master_keyseed_retail);
573
sbk_is_set = false;
574
break;
575
case HOS_KB_VERSION_500:
576
case HOS_KB_VERSION_600:
577
se_aes_unwrap_key(10, 15, console_keyseed_4xx);
578
se_aes_unwrap_key(15, 15, console_keyseed);
579
se_aes_unwrap_key(14, 12, master_keyseed_4xx);
580
se_aes_unwrap_key(12, 12, master_keyseed_retail);
581
sbk_is_set = false;
582
break;
583
}
584
}
585
else // Exosphere 2.
586
{
587
se_aes_unwrap_key(10, 15, console_keyseed_4xx);
588
se_aes_unwrap_key(15, 15, console_keyseed);
589
se_aes_unwrap_key(13, 12, master_keyseed_retail);
590
se_aes_unwrap_key(12, 12, master_keyseed_4xx);
591
}
592
593
// Package2 key.
594
se_key_acc_ctrl(8, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG);
595
se_aes_unwrap_key(8, !is_exo ? 12 : 13, package2_keyseed);
596
}
597
598
return 1;
599
}
600
601
static int _read_emmc_pkg1(launch_ctxt_t *ctxt)
602
{
603
const u32 pk1_offset = h_cfg.t210b01 ? sizeof(bl_hdr_t210b01_t) : 0; // Skip T210B01 OEM header.
604
u32 bootloader_offset = PKG1_BOOTLOADER_MAIN_OFFSET;
605
ctxt->pkg1 = (void *)malloc(PKG1_BOOTLOADER_SIZE);
606
607
try_load:
608
// Read package1.
609
emummc_storage_set_mmc_partition(EMMC_BOOT0);
610
emummc_storage_read(bootloader_offset / EMMC_BLOCKSIZE, PKG1_BOOTLOADER_SIZE / EMMC_BLOCKSIZE, ctxt->pkg1);
611
612
ctxt->pkg1_id = pkg1_identify(ctxt->pkg1 + pk1_offset);
613
if (!ctxt->pkg1_id)
614
{
615
// Check if wrong pkg1 was flashed.
616
bool wrong_pkg1;
617
618
const u32 pkg1_erista_check = ((bl_hdr_t210b01_t *)ctxt->pkg1)->entrypoint;
619
const u32 pkg1_mariko_check = *(u32 *)(ctxt->pkg1 + sizeof(pk1_hdr_t) * 2);
620
621
if (!h_cfg.t210b01) // For Erista check if start is 0 and entrypoint matches Mariko.
622
wrong_pkg1 = *(u32 *)ctxt->pkg1 == 0 && pkg1_erista_check == PKG1_MARIKO_ON_ERISTA_MAGIC;
623
else // For Mariko check if start is not 0 and build id. It works for 8.0.0 Erista pkg1 and up.
624
wrong_pkg1 = *(u32 *)ctxt->pkg1 != 0 && pkg1_mariko_check == PKG1_ERISTA_ON_MARIKO_MAGIC;
625
626
if (wrong_pkg1)
627
{
628
_hos_crit_error("Wrong pkg1 flashed:");
629
EPRINTFARGS("%s pkg1 on %s!",
630
!h_cfg.t210b01 ? "Mariko" : "Erista", !h_cfg.t210b01 ? "Erista" : "Mariko");
631
}
632
else
633
{
634
_hos_crit_error("Unknown pkg1 version.");
635
EPRINTFARGS("HOS version not supported!%s",
636
(emu_cfg.enabled && !h_cfg.emummc_force_disable) ? "\nOr emuMMC corrupt!" : "");
637
}
638
639
// Try backup bootloader.
640
if (bootloader_offset != PKG1_BOOTLOADER_BACKUP_OFFSET)
641
{
642
EPRINTF("\nTrying backup bootloader...");
643
bootloader_offset = PKG1_BOOTLOADER_BACKUP_OFFSET;
644
goto try_load;
645
}
646
647
return 0;
648
}
649
gfx_printf("Identified pkg1 and mkey %d\n\n", ctxt->pkg1_id->kb);
650
651
// Read the correct keyblob for older HOS versions.
652
if (ctxt->pkg1_id->kb <= HOS_KB_VERSION_600)
653
{
654
ctxt->keyblob = (u8 *)zalloc(EMMC_BLOCKSIZE);
655
emummc_storage_read(PKG1_HOS_KEYBLOBS_OFFSET / EMMC_BLOCKSIZE + ctxt->pkg1_id->kb, 1, ctxt->keyblob);
656
}
657
658
return 1;
659
}
660
661
static u8 *_read_emmc_pkg2(launch_ctxt_t *ctxt)
662
{
663
u8 *bctBuf = NULL;
664
665
emummc_storage_set_mmc_partition(EMMC_GPP);
666
667
// Parse eMMC GPT.
668
LIST_INIT(gpt);
669
emmc_gpt_parse(&gpt);
670
DPRINTF("Parsed GPT\n");
671
// Find package2 partition.
672
emmc_part_t *pkg2_part = emmc_part_find(&gpt, "BCPKG2-1-Normal-Main");
673
if (!pkg2_part)
674
goto out;
675
676
// Read in package2 header and get package2 real size.
677
static const u32 BCT_SIZE = SZ_16K;
678
bctBuf = (u8 *)malloc(BCT_SIZE);
679
emmc_part_read(pkg2_part, BCT_SIZE / EMMC_BLOCKSIZE, 1, bctBuf);
680
u32 *hdr = (u32 *)(bctBuf + 0x100);
681
u32 pkg2_size = hdr[0] ^ hdr[2] ^ hdr[3];
682
DPRINTF("pkg2 size on emmc is %08X\n", pkg2_size);
683
684
// Read in Boot Config.
685
emmc_part_read(pkg2_part, 0, BCT_SIZE / EMMC_BLOCKSIZE, bctBuf);
686
687
// Read in package2.
688
u32 pkg2_size_aligned = ALIGN(pkg2_size, EMMC_BLOCKSIZE);
689
DPRINTF("pkg2 size aligned is %08X\n", pkg2_size_aligned);
690
ctxt->pkg2 = malloc(pkg2_size_aligned);
691
ctxt->pkg2_size = pkg2_size;
692
emmc_part_read(pkg2_part, BCT_SIZE / EMMC_BLOCKSIZE,
693
pkg2_size_aligned / EMMC_BLOCKSIZE, ctxt->pkg2);
694
out:
695
emmc_gpt_free(&gpt);
696
697
return bctBuf;
698
}
699
700
static void _free_launch_components(launch_ctxt_t *ctxt)
701
{
702
// Free the malloc'ed guaranteed addresses.
703
free(ctxt->pkg3);
704
free(ctxt->keyblob);
705
free(ctxt->pkg1);
706
free(ctxt->pkg2);
707
free(ctxt->warmboot);
708
free(ctxt->kip1_patches);
709
}
710
711
static bool _get_fs_exfat_compatible(link_t *info, u32 *hos_revision)
712
{
713
u32 fs_ids_cnt;
714
u32 sha_buf[32 / sizeof(u32)];
715
kip1_id_t *kip_ids;
716
717
LIST_FOREACH_ENTRY(pkg2_kip1_info_t, ki, info, link)
718
{
719
if (strcmp((char *)ki->kip1->name, "FS"))
720
continue;
721
722
if (!se_calc_sha256_oneshot(sha_buf, ki->kip1, ki->size))
723
break;
724
725
pkg2_get_ids(&kip_ids, &fs_ids_cnt);
726
727
for (int fs_idx = fs_ids_cnt - 1; fs_idx >= 0; fs_idx--)
728
{
729
if (!memcmp(sha_buf, kip_ids[fs_idx].hash, 8))
730
{
731
// HOS Api special handling.
732
if ((fs_idx & ~1) == 16) // Check if it's 5.1.0.
733
*hos_revision = 1;
734
else if ((fs_idx & ~1) == 34) // Check if it's 10.2.0.
735
*hos_revision = 2;
736
737
// Check if FAT32-only.
738
if (!(fs_idx & 1))
739
return false;
740
741
// FS is FAT32 + exFAT.
742
break;
743
}
744
}
745
746
break;
747
}
748
749
// FAT32 + exFAT or unknown FS version.
750
return true;
751
}
752
753
void hos_launch(ini_sec_t *cfg)
754
{
755
u8 kb;
756
u32 secmon_base;
757
u32 warmboot_base;
758
bool is_exo = false;
759
launch_ctxt_t ctxt = {0};
760
tsec_ctxt_t tsec_ctxt = {0};
761
762
minerva_change_freq(FREQ_1600);
763
sdram_src_pllc(true);
764
list_init(&ctxt.kip1_list);
765
766
ctxt.cfg = cfg;
767
768
if (!gfx_con.mute)
769
gfx_clear_grey(0x1B);
770
gfx_con_setpos(0, 0);
771
772
gfx_puts("Initializing...\n\n");
773
774
// Initialize eMMC/emuMMC.
775
int res = emummc_storage_init_mmc();
776
if (res)
777
{
778
_hos_crit_error(res == 2 ? "Failed to init eMMC." : "Failed to init emuMMC.");
779
780
goto error;
781
}
782
783
// Check if SD Card is GPT.
784
if (sd_is_gpt())
785
{
786
_hos_crit_error("SD has GPT only! Run Fix Hybrid MBR!");
787
goto error;
788
}
789
790
// Try to parse config if present.
791
if (!parse_boot_config(&ctxt))
792
{
793
_hos_crit_error("Wrong ini cfg or missing/corrupt files!");
794
goto error;
795
}
796
797
// Read package1 and the correct keyblob.
798
if (!_read_emmc_pkg1(&ctxt))
799
{
800
// Check if stock is enabled and device can boot in OFW.
801
if (ctxt.stock && (h_cfg.t210b01 || !tools_autorcm_enabled()))
802
{
803
sdram_src_pllc(false);
804
emmc_end();
805
806
WPRINTF("\nRebooting to OFW in 5s...");
807
msleep(5000);
808
809
power_set_state(REBOOT_BYPASS_FUSES);
810
}
811
goto error;
812
}
813
814
kb = ctxt.pkg1_id->kb;
815
816
bool emummc_enabled = emu_cfg.enabled && !h_cfg.emummc_force_disable;
817
818
// Enable emummc patching.
819
if (emummc_enabled)
820
{
821
if (ctxt.stock)
822
{
823
_hos_crit_error("Stock emuMMC is not supported yet!");
824
goto error;
825
}
826
827
ctxt.patch_krn_proc_id = true; // Set kernel process id patching in case of no pkg3.
828
config_kip1patch(&ctxt, "emummc");
829
}
830
else if (!emu_cfg.enabled && ctxt.emummc_forced)
831
{
832
_hos_crit_error("emuMMC is forced but not enabled!");
833
goto error;
834
}
835
836
// If Auto NOGC is enabled, check if burnt fuses lower than installed HOS fuses and apply NOGC patch.
837
// For emuMMC, unconditionally enable NOGC when burnt fuses are higher than installed HOS fuses.
838
// Disable Auto NOGC in stock to prevent black screen (fatal error). Use kip1patch=nogc to force it.
839
if (!ctxt.stock)
840
{
841
u32 fuses = fuse_read_odm(7);
842
if ((h_cfg.autonogc && // Prevent GC fuse burning (sysMMC and emuMMC).
843
(
844
(!(fuses & ~0xF) && (ctxt.pkg1_id->fuses >= 5)) || // LAFW v2, 4.0.0+
845
(!(fuses & ~0x3FF) && (ctxt.pkg1_id->fuses >= 11)) || // LAFW v3, 9.0.0+
846
(!(fuses & ~0x1FFF) && (ctxt.pkg1_id->fuses >= 14)) || // LAFW v4, 11.0.0+
847
// Detection broken! Use kip1patch=nogc // LAFW v5, 12.0.0+
848
(!(fuses & ~0x3FFF) && (ctxt.pkg1_id->fuses >= 15)) // LAFW v5, 12.0.2+
849
)
850
)
851
|| ((emummc_enabled) && // Force NOGC if already burnt (only emuMMC).
852
(
853
((fuses & BIT(10)) && (ctxt.pkg1_id->fuses <= 10)) || // HOS 9.0.0+ fuses burnt.
854
((fuses & BIT(13)) && (ctxt.pkg1_id->fuses <= 13)) || // HOS 11.0.0+ fuses burnt.
855
// Detection broken! Use kip1patch=nogc // HOS 12.0.0+
856
((fuses & BIT(14)) && (ctxt.pkg1_id->fuses <= 14)) // HOS 12.0.2+ fuses burnt.
857
)
858
))
859
config_kip1patch(&ctxt, "nogc");
860
}
861
862
gfx_printf("Loaded config and pkg1\n%s mode\n", ctxt.stock ? "Stock" : "CFW");
863
864
// Check if secmon is exosphere.
865
if (ctxt.secmon)
866
is_exo = !memcmp((void *)((u8 *)ctxt.secmon + ctxt.secmon_size - 4), "LENY", 4);
867
868
// Get secmon and warmboot bases.
869
const pkg1_id_t *pk1_latest = pkg1_get_latest();
870
secmon_base = is_exo ? pk1_latest->secmon_base : ctxt.pkg1_id->secmon_base;
871
warmboot_base = is_exo ? pk1_latest->warmboot_base : ctxt.pkg1_id->warmboot_base;
872
873
// Set package1 and tsec fw offsets.
874
tsec_ctxt.fw = (u8 *)ctxt.pkg1 + ctxt.pkg1_id->tsec_off;
875
tsec_ctxt.pkg1 = ctxt.pkg1;
876
tsec_ctxt.pkg11_off = ctxt.pkg1_id->pkg11_off;
877
878
// Generate keys.
879
if (!_hos_keygen(ctxt.keyblob, kb, &tsec_ctxt, ctxt.stock, is_exo))
880
goto error;
881
gfx_puts("Generated keys\n");
882
883
// Decrypt and unpack package1 if we require parts of it.
884
if (!ctxt.warmboot || !ctxt.secmon)
885
{
886
// Decrypt PK1 or PK11.
887
if (kb <= HOS_KB_VERSION_600 || h_cfg.t210b01)
888
{
889
if (!pkg1_decrypt(ctxt.pkg1_id, ctxt.pkg1))
890
{
891
_hos_crit_error("Pkg1 decryption failed!");
892
893
// Check if T210B01 BEK is missing or wrong.
894
if (h_cfg.t210b01)
895
{
896
u32 bek_vector[4] = {0};
897
se_aes_crypt_ecb(13, ENCRYPT, bek_vector, SE_KEY_128_SIZE, bek_vector, SE_KEY_128_SIZE);
898
if (bek_vector[0] == 0x59C14895) // Encrypted zeroes first 32bits.
899
EPRINTF("Pkg1 corrupt?");
900
else
901
EPRINTF("BEK is missing!");
902
}
903
goto error;
904
}
905
}
906
907
// Unpack PK11.
908
if (h_cfg.t210b01 || (kb <= HOS_KB_VERSION_620 && !emummc_enabled))
909
{
910
// Skip T210B01 OEM header.
911
u32 pk1_offset = 0;
912
if (h_cfg.t210b01)
913
pk1_offset = sizeof(bl_hdr_t210b01_t);
914
915
pkg1_unpack((void *)warmboot_base, &ctxt.warmboot_size,
916
!is_exo ? (void *)ctxt.pkg1_id->secmon_base : NULL, NULL,
917
ctxt.pkg1_id, ctxt.pkg1 + pk1_offset);
918
919
gfx_puts("Decrypted & unpacked pkg1\n");
920
}
921
else
922
{
923
_hos_crit_error("No mandatory pkg1 files provided!");
924
goto error;
925
}
926
}
927
928
// Configure and manage Warmboot binary.
929
if (!pkg1_warmboot_config(&ctxt, warmboot_base, ctxt.pkg1_id->fuses, kb))
930
{
931
// Can only happen on T210B01.
932
_hos_crit_error("\nFailed to match warmboot with fuses!\nIf you continue, sleep wont work!");
933
934
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
935
display_backlight_brightness(h_cfg.backlight, 1000);
936
937
if (!(btn_wait() & BTN_POWER))
938
goto error;
939
}
940
941
// Replace 'warmboot.bin' if requested.
942
if (ctxt.warmboot)
943
memcpy((void *)warmboot_base, ctxt.warmboot, ctxt.warmboot_size);
944
else if (!h_cfg.t210b01)
945
{
946
// Patch warmboot on T210 to allow downgrading.
947
if (kb >= HOS_KB_VERSION_700)
948
{
949
_hos_crit_error("No warmboot provided!");
950
goto error;
951
}
952
953
pkg1_warmboot_patch((void *)&ctxt);
954
}
955
956
// Replace 'SecureMonitor' if requested or patch Pkg2 checks if needed.
957
if (ctxt.secmon)
958
memcpy((void *)secmon_base, ctxt.secmon, ctxt.secmon_size);
959
else
960
pkg1_secmon_patch((void *)&ctxt, secmon_base, h_cfg.t210b01);
961
962
gfx_puts("Loaded warmboot and secmon\n");
963
964
// Read package2.
965
u8 *bootConfigBuf = _read_emmc_pkg2(&ctxt);
966
if (!bootConfigBuf)
967
{
968
_hos_crit_error("Pkg2 read failed!");
969
goto error;
970
}
971
972
gfx_puts("Read pkg2\n");
973
974
// Decrypt package2 and parse KIP1 blobs in INI1 section.
975
pkg2_hdr_t *pkg2_hdr = pkg2_decrypt(ctxt.pkg2, kb, is_exo);
976
if (!pkg2_hdr)
977
{
978
_hos_crit_error("Pkg2 decryption failed!\npkg1/pkg2 mismatch or old hekate!");
979
980
// Clear EKS slot, in case something went wrong with tsec keygen.
981
_hos_eks_clear(kb);
982
goto error;
983
}
984
985
LIST_INIT(kip1_info);
986
if (!pkg2_parse_kips(&kip1_info, pkg2_hdr, &ctxt.new_pkg2))
987
{
988
_hos_crit_error("INI1 parsing failed!");
989
goto error;
990
}
991
992
gfx_puts("Parsed ini1\n");
993
994
// Use the kernel included in package2 in case we didn't load one already.
995
if (!ctxt.kernel)
996
{
997
ctxt.kernel = pkg2_hdr->data;
998
ctxt.kernel_size = pkg2_hdr->sec_size[PKG2_SEC_KERNEL];
999
1000
if (!ctxt.stock && (ctxt.svcperm || ctxt.debugmode || ctxt.patch_krn_proc_id))
1001
{
1002
// Hash only Kernel when it embeds INI1.
1003
u8 kernel_hash[0x20];
1004
if (!ctxt.new_pkg2)
1005
se_calc_sha256_oneshot(kernel_hash, ctxt.kernel, ctxt.kernel_size);
1006
else
1007
se_calc_sha256_oneshot(kernel_hash, ctxt.kernel + PKG2_NEWKERN_START,
1008
pkg2_newkern_ini1_start - PKG2_NEWKERN_START);
1009
1010
ctxt.pkg2_kernel_id = pkg2_identify(kernel_hash);
1011
if (!ctxt.pkg2_kernel_id)
1012
{
1013
_hos_crit_error("Failed to identify kernel!");
1014
1015
goto error;
1016
}
1017
1018
// In case a kernel patch option is set; allows to disable SVC verification or/and enable debug mode.
1019
const kernel_patch_t *kernel_patchset = ctxt.pkg2_kernel_id->kernel_patchset;
1020
if (kernel_patchset != NULL)
1021
{
1022
gfx_printf("%kPatching kernel%k\n", TXT_CLR_ORANGE, TXT_CLR_DEFAULT);
1023
u32 *temp;
1024
for (u32 i = 0; kernel_patchset[i].id != 0xFFFFFFFF; i++)
1025
{
1026
if ((ctxt.svcperm && kernel_patchset[i].id == SVC_VERIFY_DS)
1027
|| (ctxt.debugmode && kernel_patchset[i].id == DEBUG_MODE_EN && !(ctxt.patch_krn_proc_id && ctxt.secmon))
1028
|| (ctxt.patch_krn_proc_id && kernel_patchset[i].id == ATM_GEN_PATCH))
1029
*(vu32 *)(ctxt.kernel + kernel_patchset[i].off) = kernel_patchset[i].val;
1030
else if (ctxt.patch_krn_proc_id && kernel_patchset[i].id == ATM_ARR_PATCH)
1031
{
1032
temp = (u32 *)kernel_patchset[i].ptr;
1033
for (u32 j = 0; j < kernel_patchset[i].val; j++)
1034
*(vu32 *)(ctxt.kernel + kernel_patchset[i].off + (j << 2)) = temp[j];
1035
}
1036
else if (kernel_patchset[i].id < SVC_VERIFY_DS)
1037
*(vu32 *)(ctxt.kernel + kernel_patchset[i].off) = kernel_patchset[i].val;
1038
}
1039
}
1040
}
1041
}
1042
1043
// Merge extra KIP1s into loaded ones.
1044
LIST_FOREACH_ENTRY(merge_kip_t, mki, &ctxt.kip1_list, link)
1045
pkg2_merge_kip(&kip1_info, (pkg2_kip1_t *)mki->kip1);
1046
1047
// Check if FS is compatible with exFAT and if 5.1.0.
1048
if (!ctxt.stock && (sd_fs.fs_type == FS_EXFAT || kb == HOS_KB_VERSION_500 || ctxt.pkg1_id->fuses == 13))
1049
{
1050
bool exfat_compat = _get_fs_exfat_compatible(&kip1_info, &ctxt.exo_ctx.hos_revision);
1051
1052
if (sd_fs.fs_type == FS_EXFAT && !exfat_compat)
1053
{
1054
_hos_crit_error("SD Card is exFAT but installed HOS driver\nonly supports FAT32!");
1055
1056
goto error;
1057
}
1058
}
1059
1060
// Patch kip1s in memory if needed.
1061
const char *failed_patch = pkg2_patch_kips(&kip1_info, ctxt.kip1_patches);
1062
if (failed_patch != NULL)
1063
{
1064
EHPRINTFARGS("Failed to apply '%s'!", failed_patch);
1065
1066
bool emmc_patch_failed = !strcmp(failed_patch, "emummc");
1067
if (!emmc_patch_failed)
1068
{
1069
gfx_puts("\nPress POWER to continue.\nPress VOL to go to the menu.\n");
1070
display_backlight_brightness(h_cfg.backlight, 1000);
1071
}
1072
1073
if (emmc_patch_failed || !(btn_wait() & BTN_POWER))
1074
goto error; // MUST stop here, because if user requests 'nogc' but it's not applied, their GC controller gets updated!
1075
}
1076
1077
// Rebuild and encrypt package2.
1078
pkg2_build_encrypt((void *)PKG2_LOAD_ADDR, &ctxt, &kip1_info, is_exo);
1079
1080
// Configure Exosphere if secmon is replaced.
1081
if (is_exo)
1082
config_exosphere(&ctxt, warmboot_base);
1083
1084
// Unmount SD card and eMMC.
1085
sd_end();
1086
emmc_end();
1087
1088
// Close AHB aperture. Important when stock old secmon is used.
1089
mc_disable_ahb_redirect();
1090
1091
gfx_printf("Rebuilt & loaded pkg2\n\n%kBooting...%k\n", TXT_CLR_GREENISH, TXT_CLR_DEFAULT);
1092
1093
// Clear pkg1/pkg2 keys.
1094
se_aes_key_clear(8);
1095
se_aes_key_clear(11);
1096
1097
// Clear derived master key in case of Erista and 7.0.0+
1098
se_aes_key_clear(9);
1099
1100
// Set secmon mailbox pkg2 ready state.
1101
u32 pkg1_state_pkg2_ready = PKG1_STATE_PKG2_READY;
1102
1103
// Finalize per firmware key access. Skip access control if Exosphere 2.
1104
switch (kb | (is_exo << 7))
1105
{
1106
case HOS_KB_VERSION_100:
1107
case HOS_KB_VERSION_300:
1108
case HOS_KB_VERSION_301:
1109
se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_LOCK_FLAG);
1110
se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_LOCK_FLAG);
1111
pkg1_state_pkg2_ready = PKG1_STATE_PKG2_READY_OLD;
1112
break;
1113
case HOS_KB_VERSION_400:
1114
case HOS_KB_VERSION_500:
1115
case HOS_KB_VERSION_600:
1116
se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_LOCK_FLAG);
1117
se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_LOCK_FLAG);
1118
break;
1119
}
1120
1121
// Clear BCT area for retail units and copy it over if dev unit.
1122
if (kb <= HOS_KB_VERSION_500 && !is_exo)
1123
{
1124
memset((void *)SECMON_BCT_CFG_ADDR, 0, SZ_4K + SZ_8K);
1125
if (fuse_read_hw_state() == FUSE_NX_HW_STATE_DEV)
1126
memcpy((void *)SECMON_BCT_CFG_ADDR, bootConfigBuf, SZ_4K);
1127
}
1128
else
1129
{
1130
memset((void *)SECMON6_BCT_CFG_ADDR, 0, SZ_2K);
1131
if (fuse_read_hw_state() == FUSE_NX_HW_STATE_DEV)
1132
memcpy((void *)SECMON6_BCT_CFG_ADDR, bootConfigBuf, SZ_2K);
1133
}
1134
1135
// Finalize MC carveout.
1136
if (kb <= HOS_KB_VERSION_301 && !is_exo)
1137
mc_config_carveout();
1138
1139
// Lock SE before starting 'SecureMonitor' if < 6.2.0, otherwise lock bootrom and ipatches.
1140
_se_lock(kb <= HOS_KB_VERSION_600 && !is_exo);
1141
1142
// Reset sysctr0 counters. Mandatory for 6.2.0 and up.
1143
for (u32 i = 0; i < SYSCTR0_COUNTERS; i++)
1144
SYSCTR0(SYSCTR0_COUNTERS_BASE + i * sizeof(u32)) = 0;
1145
1146
// NX Bootloader locks LP0 Carveout secure scratch registers.
1147
//pmc_scratch_lock(PMC_SEC_LOCK_LP0_PARAMS);
1148
1149
// Set secmon mailbox address and clear it.
1150
volatile secmon_mailbox_t *secmon_mailbox;
1151
if (kb >= HOS_KB_VERSION_700 || is_exo)
1152
{
1153
memset((void *)SECMON7_MAILBOX_ADDR, 0, 0x200);
1154
secmon_mailbox = (secmon_mailbox_t *)(SECMON7_MAILBOX_ADDR + SECMON_STATE_OFFSET);
1155
}
1156
else
1157
{
1158
if (kb <= HOS_KB_VERSION_301)
1159
memset((void *)SECMON_MAILBOX_ADDR, 0, 0x200);
1160
secmon_mailbox = (secmon_mailbox_t *)(SECMON_MAILBOX_ADDR + SECMON_STATE_OFFSET);
1161
}
1162
1163
// Start directly from PKG2 ready signal and reset outgoing value.
1164
secmon_mailbox->in = pkg1_state_pkg2_ready;
1165
secmon_mailbox->out = SECMON_STATE_NOT_READY;
1166
1167
// Disable display. This must be executed before secmon to provide support for all fw versions.
1168
display_end();
1169
clock_disable_host1x();
1170
1171
// Override uCID if set.
1172
EMC(EMC_SCRATCH0) = ctxt.ucid;
1173
1174
// Hold USBD, USB2, AHBDMA and APBDMA in reset for SoC state validation on sleep.
1175
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_USBD);
1176
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_AHBDMA) | BIT(CLK_H_APBDMA) | BIT(CLK_H_USB2);
1177
1178
// Reset arbiter.
1179
hw_config_arbiter(true);
1180
1181
// Scale down RAM OC if enabled.
1182
sdram_src_pllc(false);
1183
minerva_prep_boot_freq();
1184
1185
// Flush cache and disable MMU.
1186
bpmp_mmu_disable();
1187
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
1188
1189
// Launch secmon.
1190
ccplex_boot_cpu0(secmon_base, true);
1191
1192
// Halt ourselves in wait-event state.
1193
while (true)
1194
bpmp_halt();
1195
1196
error:
1197
_free_launch_components(&ctxt);
1198
sdram_src_pllc(false);
1199
emmc_end();
1200
1201
EPRINTF("\nFailed to launch HOS!");
1202
}
1203
1204