diff --git a/source/keys/key_sources.inl b/source/keys/key_sources.inl
index 5cb7f08..e5fddea 100644
--- a/source/keys/key_sources.inl
+++ b/source/keys/key_sources.inl
@@ -14,8 +14,7 @@
* along with this program. If not, see .
*/
-static u8 zeros[0x10] = {0};
-
+// Sha256 hash of the null string.
static u8 null_hash[0x20] = {
0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24,
0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55};
diff --git a/source/keys/keys.c b/source/keys/keys.c
index a33a260..6ac19c4 100644
--- a/source/keys/keys.c
+++ b/source/keys/keys.c
@@ -71,7 +71,7 @@ static ALWAYS_INLINE u32 _read_be_u32(const void *buffer, u32 offset) {
}
// key functions
-static int _key_exists(const void *data) { return memcmp(data, zeros, 0x10) != 0; };
+static int _key_exists(const void *data) { return memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0; };
static void _save_key(const char *name, const void *data, u32 len, char *outbuf);
static void _save_key_family(const char *name, const void *data, u32 start_key, u32 num_keys, u32 len, char *outbuf);
static void _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed);
@@ -94,6 +94,114 @@ static ALWAYS_INLINE u32 _get_tsec_fw_size(tsec_key_data_t *key_data) {
return key_data->blob0_size + sizeof(tsec_key_data_t) + key_data->blob1_size + key_data->blob2_size + key_data->blob3_size + key_data->blob4_size;
}
+#define RELOC_META_OFF 0x7C
+
+static bool _handle_sept(void *tsec_fw, u32 tsec_size, u32 kb, void *out_key) {
+ sd_mount();
+ if (!f_stat("sd:/sept/payload.bak", NULL)) {
+ if (f_unlink("sd:/sept/payload.bin"))
+ gfx_printf("%kNote: no payload.bin already in /sept\n", colors[(color_idx++) % 6]);
+ f_rename("sd:/sept/payload.bak", "sd:/sept/payload.bin");
+ }
+
+ if (!h_cfg.sept_run) {
+ // bundle lp0 fw for sept instead of loading it from SD as hekate does
+ sdram_lp0_save_params(sdram_get_params_patched());
+
+ FIL fp;
+ if (f_stat("sd:/sept", NULL)) {
+ EPRINTF("On firmware 7.x+ but Sept missing.\nSkipping new key derivation...");
+ return true;
+ }
+ // backup post-reboot payload
+ if (!f_stat("sd:/sept/payload.bin", NULL)) {
+ if (f_rename("sd:/sept/payload.bin", "sd:/sept/payload.bak")) {
+ EPRINTF("Unable to backup payload.bin.");
+ return false;
+ }
+ }
+ // write self to payload.bin to run again when sept finishes
+ volatile reloc_meta_t *relocator = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
+ u32 payload_size = relocator->end - IPL_LOAD_ADDR;
+ if (f_open(&fp, "sd:/sept/payload.bin", FA_CREATE_NEW | FA_WRITE)) {
+ EPRINTF("Unable to open /sept/payload.bin to write.");
+ return false;
+ }
+ gfx_printf("%kWrite self to /sept/payload.bin...", colors[(color_idx++) % 6]);
+ if (f_write(&fp, (u8 *)IPL_LOAD_ADDR, payload_size, NULL)) {
+ EPRINTF("Unable to write self to /sept/payload.bin.");
+ f_close(&fp);
+ return false;
+ }
+ gfx_printf(" done");
+ f_close(&fp);
+ gfx_printf("%k\nFirmware 7.x or higher detected.\n\n", colors[(color_idx++) % 6]);
+ gfx_printf("%kRenamed /sept/payload.bin", colors[(color_idx++) % 6]);
+ gfx_printf("\n to /sept/payload.bak\n\n");
+ gfx_printf("%kCopied self to /sept/payload.bin\n", colors[(color_idx++) % 6]);
+ sdmmc_storage_end(&emmc_storage);
+ if (!reboot_to_sept((u8 *)tsec_fw, tsec_size, kb)) {
+ return false;
+ }
+ } else {
+ se_aes_key_read(se_key_acc_ctrl_get(12) == 0x6A ? 13 : 12, out_key, AES_128_KEY_SIZE);
+ }
+
+ return true;
+}
+
+static bool _handle_tsec(tsec_ctxt_t *tsec_ctxt, u32 kb, void *out_master_key, void *out_tsec_keys, u32 out_tsec_keys_size) {
+ tsec_ctxt->fw = _find_tsec_fw(tsec_ctxt->pkg1);
+ if (!tsec_ctxt->fw) {
+ EPRINTF("Unable to locate TSEC firmware.");
+ return false;
+ }
+
+ minerva_periodic_training();
+
+ tsec_ctxt->size = _get_tsec_fw_size((tsec_key_data_t *)(tsec_ctxt->fw + TSEC_KEY_DATA_OFFSET));
+ if (tsec_ctxt->size > PKG1_MAX_SIZE) {
+ EPRINTF("Unexpected TSEC firmware size.");
+ return false;
+ }
+
+ if (kb >= KB_FIRMWARE_VERSION_700 && !h_cfg.t210b01) {
+ if (!_handle_sept(tsec_ctxt->fw, tsec_ctxt->size, kb, out_master_key)) {
+ return false;
+ }
+ }
+
+ if (kb == KB_FIRMWARE_VERSION_620) {
+ u8 *tsec_paged = (u8 *)page_alloc(3);
+ memcpy(tsec_paged, tsec_ctxt->fw, tsec_ctxt->size);
+ tsec_ctxt->fw = tsec_paged;
+ }
+
+ int res = 0;
+ u32 retries = 0;
+
+ mc_disable_ahb_redirect();
+
+ while (tsec_query(out_tsec_keys, kb, tsec_ctxt) < 0) {
+ memset(out_tsec_keys, 0, out_tsec_keys_size);
+ retries++;
+ if (retries > 15) {
+ res = -1;
+ break;
+ }
+ }
+
+ mc_enable_ahb_redirect();
+
+ if (res < 0) {
+ EPRINTFARGS("ERROR %x dumping TSEC.\n", res);
+ return false;
+ }
+
+ TPRINTFARGS("%kTSEC key(s)... ", colors[(color_idx++) % 6]);
+ return true;
+}
+
static bool _get_titlekeys_from_save(u32 buf_size, const u8 *save_mac_key, titlekey_buffer_t *titlekey_buffer, rsa_keypair_t *rsa_keypair) {
FIL fp;
u64 br = buf_size;
@@ -221,33 +329,32 @@ static bool _get_titlekeys_from_save(u32 buf_size, const u8 *save_mac_key, title
return true;
}
-#define RELOC_META_OFF 0x7C
-
void dump_keys() {
- u8 temp_key[0x10],
- bis_key[4][0x20] = {0},
- device_key[0x10] = {0},
- device_key_4x[0x10] = {0},
- sd_seed[0x10] = {0},
+ u8 temp_key[AES_128_KEY_SIZE],
+ bis_key[4][AES_128_KEY_SIZE * 2] = {0},
+ device_key[AES_128_KEY_SIZE] = {0},
+ device_key_4x[AES_128_KEY_SIZE] = {0},
+ sd_seed[AES_128_KEY_SIZE] = {0},
// FS-related keys
- header_key[0x20] = {0},
- save_mac_key[0x10] = {0},
+ header_key[AES_128_KEY_SIZE * 2] = {0},
+ save_mac_key[AES_128_KEY_SIZE] = {0},
// other sysmodule keys
- eticket_rsa_kek[0x10] = {0},
- eticket_rsa_kek_personalized[0x10] = {0},
- ssl_rsa_kek[0x10] = {0},
+ eticket_rsa_kek[AES_128_KEY_SIZE] = {0},
+ eticket_rsa_kek_personalized[AES_128_KEY_SIZE] = {0},
+ ssl_rsa_kek[AES_128_KEY_SIZE] = {0},
// keyblob-derived families
- keyblob_key[KB_FIRMWARE_VERSION_600+1][0x10] = {0},
- keyblob_mac_key[KB_FIRMWARE_VERSION_600+1][0x10] = {0},
- package1_key[KB_FIRMWARE_VERSION_600+1][0x10] = {0},
+ keyblob_key[KB_FIRMWARE_VERSION_600 + 1][AES_128_KEY_SIZE] = {0},
+ keyblob_mac_key[KB_FIRMWARE_VERSION_600 + 1][AES_128_KEY_SIZE] = {0},
+ package1_key[KB_FIRMWARE_VERSION_600 + 1][AES_128_KEY_SIZE] = {0},
// master key-derived families
- key_area_key[3][KB_FIRMWARE_VERSION_MAX+1][0x10] = {0},
- master_kek[KB_FIRMWARE_VERSION_MAX+1][0x10] = {0},
- master_key[KB_FIRMWARE_VERSION_MAX+1][0x10] = {0},
- package2_key[KB_FIRMWARE_VERSION_MAX+1][0x10] = {0},
- titlekek[KB_FIRMWARE_VERSION_MAX+1][0x10] = {0};
+ key_area_key[3][KB_FIRMWARE_VERSION_MAX + 1][AES_128_KEY_SIZE] = {0},
+ master_kek[KB_FIRMWARE_VERSION_MAX + 1][AES_128_KEY_SIZE] = {0},
+ master_key[KB_FIRMWARE_VERSION_MAX + 1][AES_128_KEY_SIZE] = {0},
+ package2_key[KB_FIRMWARE_VERSION_MAX + 1][AES_128_KEY_SIZE] = {0},
+ titlekek[KB_FIRMWARE_VERSION_MAX + 1][AES_128_KEY_SIZE] = {0},
+ tsec_keys[AES_128_KEY_SIZE * 2] = {0};
- keyblob_t keyblob[KB_FIRMWARE_VERSION_600+1] = {0};
+ keyblob_t keyblob[KB_FIRMWARE_VERSION_600 + 1] = {0};
sd_mount();
@@ -264,9 +371,7 @@ void dump_keys() {
start_time = get_tmr_us();
u32 begin_time = get_tmr_us();
- u32 retries = 0;
- tsec_ctxt_t tsec_ctxt;
sdmmc_t sdmmc;
if (emummc_storage_init_mmc(&emmc_storage, &sdmmc)) {
@@ -291,113 +396,25 @@ void dump_keys() {
goto out_wait;
}
- tsec_ctxt.fw = _find_tsec_fw(pkg1);
- if (!tsec_ctxt.fw) {
- EPRINTF("Unable to locate TSEC firmware.");
- goto out_wait;
- }
-
- minerva_periodic_training();
-
- tsec_ctxt.pkg1 = pkg1;
- tsec_ctxt.size = _get_tsec_fw_size((tsec_key_data_t *)(tsec_ctxt.fw + TSEC_KEY_DATA_OFFSET));
- if (tsec_ctxt.size > PKG1_MAX_SIZE) {
- EPRINTF("Unexpected TSEC firmware size.");
- goto out_wait;
- }
-
u32 derivable_key_count = pkg1_id->kb >= KB_FIRMWARE_VERSION_620 ? pkg1_id->kb + 1 : 6;
- if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700) {
- sd_mount();
- if (!f_stat("sd:/sept/payload.bak", NULL)) {
- if (f_unlink("sd:/sept/payload.bin"))
- gfx_printf("%kNote: no payload.bin already in /sept\n", colors[(color_idx++) % 6]);
- f_rename("sd:/sept/payload.bak", "sd:/sept/payload.bin");
- }
-
- if (!h_cfg.sept_run) {
- // bundle lp0 fw for sept instead of loading it from SD as hekate does
- sdram_lp0_save_params(sdram_get_params_patched());
-
- FIL fp;
- if (f_stat("sd:/sept", NULL)) {
- EPRINTF("On firmware 7.x+ but Sept missing.\nSkipping new key derivation...");
- goto get_tsec;
- }
- // backup post-reboot payload
- if (!f_stat("sd:/sept/payload.bin", NULL)) {
- if (f_rename("sd:/sept/payload.bin", "sd:/sept/payload.bak")) {
- EPRINTF("Unable to backup payload.bin.");
- goto out_wait;
- }
- }
- // write self to payload.bin to run again when sept finishes
- volatile reloc_meta_t *relocator = (reloc_meta_t *)(IPL_LOAD_ADDR + RELOC_META_OFF);
- u32 payload_size = relocator->end - IPL_LOAD_ADDR;
- if (f_open(&fp, "sd:/sept/payload.bin", FA_CREATE_NEW | FA_WRITE)) {
- EPRINTF("Unable to open /sept/payload.bin to write.");
- goto out_wait;
- }
- gfx_printf("%kWrite self to /sept/payload.bin...", colors[(color_idx++) % 6]);
- if (f_write(&fp, (u8 *)IPL_LOAD_ADDR, payload_size, NULL)) {
- EPRINTF("Unable to write self to /sept/payload.bin.");
- f_close(&fp);
- goto out_wait;
- }
- gfx_printf(" done");
- f_close(&fp);
- gfx_printf("%k\nFirmware 7.x or higher detected.\n\n", colors[(color_idx++) % 6]);
- gfx_printf("%kRenamed /sept/payload.bin", colors[(color_idx++) % 6]);
- gfx_printf("\n to /sept/payload.bak\n\n");
- gfx_printf("%kCopied self to /sept/payload.bin\n", colors[(color_idx++) % 6]);
- sdmmc_storage_end(&emmc_storage);
- if (!reboot_to_sept((u8 *)tsec_ctxt.fw, tsec_ctxt.size, pkg1_id->kb))
- goto out_wait;
- } else {
- se_aes_key_read(se_key_acc_ctrl_get(12) == 0x6A ? 13 : 12, master_key[KB_FIRMWARE_VERSION_MAX], 0x10);
- }
- }
-
-get_tsec: ;
- u8 tsec_keys[0x10 * 2] = {0};
-
- if (pkg1_id->kb == KB_FIRMWARE_VERSION_620) {
- u8 *tsec_paged = (u8 *)page_alloc(3);
- memcpy(tsec_paged, (void *)tsec_ctxt.fw, tsec_ctxt.size);
- tsec_ctxt.fw = tsec_paged;
- }
-
- int res = 0;
-
- mc_disable_ahb_redirect();
-
- while (tsec_query(tsec_keys, pkg1_id->kb, &tsec_ctxt) < 0) {
- memset(tsec_keys, 0x00, 0x20);
- retries++;
- if (retries > 15) {
- res = -1;
- break;
+ if (!h_cfg.t210b01) {
+ tsec_ctxt_t tsec_ctxt;
+ tsec_ctxt.pkg1 = pkg1;
+ if (!_handle_tsec(&tsec_ctxt, pkg1_id->kb, master_key[KB_FIRMWARE_VERSION_MAX], tsec_keys, sizeof(tsec_keys))) {
+ free(pkg1);
+ goto out_wait;
}
}
free(pkg1);
- mc_enable_ahb_redirect();
-
- if (res < 0) {
- EPRINTFARGS("ERROR %x dumping TSEC.\n", res);
- goto out_wait;
- }
-
- TPRINTFARGS("%kTSEC key(s)... ", colors[(color_idx++) % 6]);
-
// Master key derivation
// on firmware 6.2.0 only, tsec_query delivers the tsec_root_key
- if (pkg1_id->kb == KB_FIRMWARE_VERSION_620 && _key_exists(tsec_keys + 0x10)) {
- se_aes_key_set(8, tsec_keys + 0x10, 0x10); // mkek6 = unwrap(mkeks6, tsecroot)
+ if (pkg1_id->kb == KB_FIRMWARE_VERSION_620 && _key_exists(tsec_keys + AES_128_KEY_SIZE)) {
+ se_aes_key_set(8, tsec_keys + AES_128_KEY_SIZE, AES_128_KEY_SIZE); // mkek6 = unwrap(mkeks6, tsecroot)
se_aes_crypt_block_ecb(8, 0, master_kek[6], master_kek_sources[0]);
- se_aes_key_set(8, master_kek[6], 0x10); // mkey = unwrap(mkek, mks)
+ se_aes_key_set(8, master_kek[6], AES_128_KEY_SIZE); // mkey = unwrap(mkek, mks)
se_aes_crypt_block_ecb(8, 0, master_key[6], master_key_source);
}
@@ -405,10 +422,10 @@ get_tsec: ;
// derive all lower master keys in case keyblobs are bad
if (_key_exists(master_key[pkg1_id->kb])) {
for (u32 i = pkg1_id->kb; i > 0; i--) {
- se_aes_key_set(8, master_key[i], 0x10);
+ se_aes_key_set(8, master_key[i], AES_128_KEY_SIZE);
se_aes_crypt_block_ecb(8, 0, master_key[i-1], master_key_vectors[i]);
}
- se_aes_key_set(8, master_key[0], 0x10);
+ se_aes_key_set(8, master_key[0], AES_128_KEY_SIZE);
se_aes_crypt_block_ecb(8, 0, temp_key, master_key_vectors[0]);
if (_key_exists(temp_key)) {
EPRINTFARGS("Unable to derive master key. kb = %d.\n Put current sept files on SD and retry.", pkg1_id->kb);
@@ -418,16 +435,16 @@ get_tsec: ;
// handle sept version differences
for (u32 kb = KB_FIRMWARE_VERSION_MAX; kb >= KB_FIRMWARE_VERSION_620; kb--) {
for (u32 i = kb; i > 0; i--) {
- se_aes_key_set(8, master_key[i], 0x10);
+ se_aes_key_set(8, master_key[i], AES_128_KEY_SIZE);
se_aes_crypt_block_ecb(8, 0, master_key[i-1], master_key_vectors[i]);
}
- se_aes_key_set(8, master_key[0], 0x10);
+ se_aes_key_set(8, master_key[0], AES_128_KEY_SIZE);
se_aes_crypt_block_ecb(8, 0, temp_key, master_key_vectors[0]);
if (!_key_exists(temp_key)) {
break;
}
- memcpy(master_key[kb-1], master_key[kb], 0x10);
- memset(master_key[kb], 0, 0x10);
+ memcpy(master_key[kb-1], master_key[kb], AES_128_KEY_SIZE);
+ memset(master_key[kb], 0, AES_128_KEY_SIZE);
}
if (_key_exists(temp_key)) {
EPRINTF("Unable to derive master keys via sept.");
@@ -438,14 +455,14 @@ get_tsec: ;
u8 *keyblob_block = (u8 *)calloc(KB_FIRMWARE_VERSION_600 + 1, NX_EMMC_BLOCKSIZE);
encrypted_keyblob_t *current_keyblob = (encrypted_keyblob_t *)keyblob_block;
- u8 keyblob_mac[0x10] = {0};
+ u8 keyblob_mac[AES_128_KEY_SIZE] = {0};
u32 sbk[4] = {FUSE(FUSE_PRIVATE_KEY0), FUSE(FUSE_PRIVATE_KEY1),
FUSE(FUSE_PRIVATE_KEY2), FUSE(FUSE_PRIVATE_KEY3)};
se_aes_key_set(8, tsec_keys, sizeof(tsec_keys) / 2);
se_aes_key_set(9, sbk, sizeof(sbk));
if (!emummc_storage_read(&emmc_storage, KEYBLOB_OFFSET / NX_EMMC_BLOCKSIZE, KB_FIRMWARE_VERSION_600 + 1, keyblob_block)) {
- EPRINTF("Unable to read keyblob.");
+ EPRINTF("Unable to read keyblobs.");
}
for (u32 i = 0; i <= KB_FIRMWARE_VERSION_600; i++, current_keyblob++) {
@@ -492,8 +509,8 @@ get_tsec: ;
if (key_generation) {
_get_device_key(8, temp_key, key_generation, device_key_4x, master_key[0]);
} else
- memcpy(temp_key, device_key, 0x10);
- se_aes_key_set(8, temp_key, 0x10);
+ memcpy(temp_key, device_key, AES_128_KEY_SIZE);
+ se_aes_key_set(8, temp_key, AES_128_KEY_SIZE);
se_aes_unwrap_key(8, 8, retail_specific_aes_key_source); // kek = unwrap(rsaks, devkey)
se_aes_crypt_block_ecb(8, 0, bis_key[0] + 0x00, bis_key_source[0] + 0x00); // bkey = unwrap(bkeys, kek)
se_aes_crypt_block_ecb(8, 0, bis_key[0] + 0x10, bis_key_source[0] + 0x10);
@@ -529,7 +546,7 @@ get_tsec: ;
_generate_kek(8, key_area_key_sources[j], master_key[i], aes_kek_generation_source, NULL);
se_aes_crypt_block_ecb(8, 0, key_area_key[j][i], aes_key_generation_source);
}
- se_aes_key_set(8, master_key[i], 0x10);
+ se_aes_key_set(8, master_key[i], AES_128_KEY_SIZE);
se_aes_crypt_block_ecb(8, 0, package2_key[i], package2_key_source);
se_aes_crypt_block_ecb(8, 0, titlekek[i], titlekek_source);
}
@@ -546,12 +563,12 @@ get_tsec: ;
// derive eticket_rsa_kek and ssl_rsa_kek
if (_key_exists(master_key[0])) {
- for (u32 i = 0; i < 0x10; i++)
+ for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i];
_generate_kek(7, eticket_rsa_kekek_source, master_key[0], temp_key, NULL);
se_aes_crypt_block_ecb(7, 0, eticket_rsa_kek, eticket_rsa_kek_source);
- for (u32 i = 0; i < 0x10; i++)
+ for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i];
_generate_kek(7, ssl_rsa_kek_source_x, master_key[0], temp_key, NULL);
se_aes_crypt_block_ecb(7, 0, ssl_rsa_kek, ssl_rsa_kek_source_y);
@@ -559,18 +576,18 @@ get_tsec: ;
// Set BIS keys.
// PRODINFO/PRODINFOF
- se_aes_key_set(0, bis_key[0] + 0x00, 0x10);
- se_aes_key_set(1, bis_key[0] + 0x10, 0x10);
+ se_aes_key_set(0, bis_key[0] + 0x00, AES_128_KEY_SIZE);
+ se_aes_key_set(1, bis_key[0] + 0x10, AES_128_KEY_SIZE);
// SAFE
- se_aes_key_set(2, bis_key[1] + 0x00, 0x10);
- se_aes_key_set(3, bis_key[1] + 0x10, 0x10);
+ se_aes_key_set(2, bis_key[1] + 0x00, AES_128_KEY_SIZE);
+ se_aes_key_set(3, bis_key[1] + 0x10, AES_128_KEY_SIZE);
// SYSTEM/USER
- se_aes_key_set(4, bis_key[2] + 0x00, 0x10);
- se_aes_key_set(5, bis_key[2] + 0x10, 0x10);
+ se_aes_key_set(4, bis_key[2] + 0x00, AES_128_KEY_SIZE);
+ se_aes_key_set(5, bis_key[2] + 0x10, AES_128_KEY_SIZE);
// Set header key for NCA decryption.
- se_aes_key_set(8, header_key + 0x00, 0x10);
- se_aes_key_set(9, header_key + 0x10, 0x10);
+ se_aes_key_set(8, header_key + 0x00, AES_128_KEY_SIZE);
+ se_aes_key_set(9, header_key + 0x10, AES_128_KEY_SIZE);
if (!emummc_storage_set_mmc_partition(&emmc_storage, EMMC_GPP)) {
EPRINTF("Unable to set partition.");
@@ -605,7 +622,7 @@ get_tsec: ;
goto get_titlekeys;
}
// get sd seed verification vector
- if (f_read(&fp, temp_key, 0x10, &read_bytes) || read_bytes != 0x10) {
+ if (f_read(&fp, temp_key, AES_128_KEY_SIZE, &read_bytes) || read_bytes != AES_128_KEY_SIZE) {
EPRINTF("Unable to read SD seed vector. Skipping.");
f_close(&fp);
goto get_titlekeys;
@@ -660,9 +677,9 @@ get_titlekeys:
if (keypair_generation) {
keypair_generation--;
- for (u32 i = 0; i < 0x10; i++)
+ for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i];
- u8 temp_device_key[0x10] = {0};
+ u8 temp_device_key[AES_128_KEY_SIZE] = {0};
_get_device_key(7, temp_device_key, keypair_generation, device_key_4x, master_key[0]);
_generate_kek(7, eticket_rsa_kekek_source, temp_device_key, temp_key, NULL);
se_aes_crypt_block_ecb(7, 0, eticket_rsa_kek_personalized, eticket_rsa_kek_source);
@@ -748,10 +765,10 @@ key_output: ;
SAVE_KEY(package2_key_source);
SAVE_KEY(per_console_key_source);
SAVE_KEY(retail_specific_aes_key_source);
- for (u32 i = 0; i < 0x10; i++)
+ for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_03[i];
SAVE_KEY_VAR(rsa_oaep_kek_generation_source, temp_key);
- for (u32 i = 0; i < 0x10; i++)
+ for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
temp_key[i] = aes_kek_generation_source[i] ^ aes_kek_seed_01[i];
SAVE_KEY_VAR(rsa_private_kek_generation_source, temp_key);
SAVE_KEY(save_mac_kek_source);
@@ -770,9 +787,9 @@ key_output: ;
SAVE_KEY(ssl_rsa_kek_source_y);
SAVE_KEY_FAMILY(titlekek, 0);
SAVE_KEY(titlekek_source);
- _save_key("tsec_key", tsec_keys, 0x10, text_buffer);
+ _save_key("tsec_key", tsec_keys, AES_128_KEY_SIZE, text_buffer);
if (pkg1_id->kb == KB_FIRMWARE_VERSION_620)
- _save_key("tsec_root_key", tsec_keys + 0x10, 0x10, text_buffer);
+ _save_key("tsec_root_key", tsec_keys + AES_128_KEY_SIZE, AES_128_KEY_SIZE, text_buffer);
end_time = get_tmr_us();
gfx_printf("\n%k Found %d keys.\n\n", colors[(color_idx++) % 6], _key_count);
@@ -797,10 +814,10 @@ key_output: ;
titlekey_text_buffer_t *titlekey_text = (titlekey_text_buffer_t *)text_buffer;
for (u32 i = 0; i < _titlekey_count; i++) {
- for (u32 j = 0; j < 0x10; j++)
+ for (u32 j = 0; j < AES_128_KEY_SIZE; j++)
sprintf(&titlekey_text[i].rights_id[j * 2], "%02x", titlekey_buffer->rights_ids[i][j]);
sprintf(titlekey_text[i].equals, " = ");
- for (u32 j = 0; j < 0x10; j++)
+ for (u32 j = 0; j < AES_128_KEY_SIZE; j++)
sprintf(&titlekey_text[i].titlekey[j * 2], "%02x", titlekey_buffer->titlekeys[i][j]);
sprintf(titlekey_text[i].newline, "\n");
}
@@ -847,7 +864,7 @@ static void _generate_kek(u32 ks, const void *key_source, void *master_key, cons
if (!_key_exists(key_source) || !_key_exists(master_key) || !_key_exists(kek_seed))
return;
- se_aes_key_set(ks, master_key, 0x10);
+ se_aes_key_set(ks, master_key, AES_128_KEY_SIZE);
se_aes_unwrap_key(ks, ks, kek_seed);
se_aes_unwrap_key(ks, ks, key_source);
if (key_seed && _key_exists(key_seed))
@@ -856,28 +873,28 @@ static void _generate_kek(u32 ks, const void *key_source, void *master_key, cons
static void _get_device_key(u32 ks, void *out_device_key, u32 revision, const void *device_key, const void *master_key) {
if (revision < KB_FIRMWARE_VERSION_400)
- memcpy(out_device_key, device_key, 0x10);
+ memcpy(out_device_key, device_key, AES_128_KEY_SIZE);
revision -= KB_FIRMWARE_VERSION_400;
- u8 temp_key[0x10] = {0};
- se_aes_key_set(ks, device_key, 0x10);
- se_aes_crypt_ecb(ks, 0, temp_key, 0x10, device_master_key_source_sources[revision], 0x10);
- se_aes_key_set(ks, master_key, 0x10);
+ u8 temp_key[AES_128_KEY_SIZE] = {0};
+ se_aes_key_set(ks, device_key, AES_128_KEY_SIZE);
+ se_aes_crypt_ecb(ks, 0, temp_key, AES_128_KEY_SIZE, device_master_key_source_sources[revision], AES_128_KEY_SIZE);
+ se_aes_key_set(ks, master_key, AES_128_KEY_SIZE);
se_aes_unwrap_key(ks, ks, device_master_kek_sources[revision]);
- se_aes_crypt_ecb(ks, 0, out_device_key, 0x10, temp_key, 0x10);
+ se_aes_crypt_ecb(ks, 0, out_device_key, AES_128_KEY_SIZE, temp_key, AES_128_KEY_SIZE);
}
static bool _test_key_pair(const void *public_exponent, const void *private_exponent, const void *modulus) {
- u8 plaintext[0x100] = {0}, ciphertext[0x100] = {0}, work[0x100] = {0};
+ u8 plaintext[RSA_2048_KEY_SIZE] = {0}, ciphertext[RSA_2048_KEY_SIZE] = {0}, work[RSA_2048_KEY_SIZE] = {0};
// 0xCAFEBABE
plaintext[0xfc] = 0xca; plaintext[0xfd] = 0xfe; plaintext[0xfe] = 0xba; plaintext[0xff] = 0xbe;
- se_rsa_key_set(0, modulus, 0x100, private_exponent, 0x100);
- se_rsa_exp_mod(0, ciphertext, 0x100, plaintext, 0x100);
+ se_rsa_key_set(0, modulus, RSA_2048_KEY_SIZE, private_exponent, RSA_2048_KEY_SIZE);
+ se_rsa_exp_mod(0, ciphertext, RSA_2048_KEY_SIZE, plaintext, RSA_2048_KEY_SIZE);
- se_rsa_key_set(0, modulus, 0x100, public_exponent, 4);
- se_rsa_exp_mod(0, work, 0x100, ciphertext, 0x100);
+ se_rsa_key_set(0, modulus, RSA_2048_KEY_SIZE, public_exponent, 4);
+ se_rsa_exp_mod(0, work, RSA_2048_KEY_SIZE, ciphertext, RSA_2048_KEY_SIZE);
- return !memcmp(plaintext, work, 0x100);
+ return !memcmp(plaintext, work, RSA_2048_KEY_SIZE);
}
diff --git a/source/keys/keys.h b/source/keys/keys.h
index ae6ead4..4e5d3ba 100644
--- a/source/keys/keys.h
+++ b/source/keys/keys.h
@@ -19,13 +19,16 @@
#include
+#define AES_128_KEY_SIZE 16
+#define RSA_2048_KEY_SIZE 256
+
// only tickets of type Rsa2048Sha256 are expected
typedef struct {
u32 signature_type; // always 0x10004
- u8 signature[0x100];
+ u8 signature[RSA_2048_KEY_SIZE];
u8 sig_padding[0x3C];
char issuer[0x40];
- u8 titlekey_block[0x100];
+ u8 titlekey_block[RSA_2048_KEY_SIZE];
u8 format_version;
u8 titlekey_type;
u16 ticket_version;
@@ -59,8 +62,8 @@ typedef struct {
} titlekey_buffer_t;
typedef struct {
- u8 private_exponent[0x100];
- u8 modulus[0x100];
+ u8 private_exponent[RSA_2048_KEY_SIZE];
+ u8 modulus[RSA_2048_KEY_SIZE];
u8 public_exponent[4];
u8 reserved[0x14];
u64 device_id;
@@ -68,9 +71,9 @@ typedef struct {
} rsa_keypair_t;
typedef struct {
- u8 master_kek[0x10];
+ u8 master_kek[AES_128_KEY_SIZE];
u8 data[0x70];
- u8 package1_key[0x10];
+ u8 package1_key[AES_128_KEY_SIZE];
} keyblob_t;
typedef struct {