From 3121a5bf08cd81d3a99719feb2cab3b60767afd5 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 1 Jun 2020 17:14:12 -0700 Subject: [PATCH] pki: implement mariko key derivation --- extkeys.c | 7 +++++++ pki.c | 16 ++++++++++++++++ settings.h | 1 + 3 files changed, 24 insertions(+) diff --git a/extkeys.c b/extkeys.c index 0d227fe..db7c2f2 100644 --- a/extkeys.c +++ b/extkeys.c @@ -364,6 +364,13 @@ void extkeys_initialize_settings(hactool_settings_t *settings, FILE *f) { break; } + snprintf(test_name, sizeof(test_name), "mariko_master_kek_source_%02"PRIx32, i); + if (strcmp(key, test_name) == 0) { + parse_hex_key(keyset->mariko_master_kek_sources[i], value, sizeof(keyset->mariko_master_kek_sources[i])); + matched_key = 1; + break; + } + snprintf(test_name, sizeof(test_name), "package1_mac_key_%02"PRIx32, i); if (strcmp(key, test_name) == 0) { parse_hex_key(keyset->package1_mac_keys[i], value, sizeof(keyset->package1_mac_keys[i])); diff --git a/pki.c b/pki.c index ae0b506..7ddab66 100644 --- a/pki.c +++ b/pki.c @@ -386,6 +386,18 @@ void pki_derive_keys(nca_keyset_t *keyset) { aes_decrypt(tsec_root_ctx, keyset->master_keks[i], keyset->master_kek_sources[i], 0x10); free_aes_ctx(tsec_root_ctx); } + /* Derive master keks with mariko keydata -- these are always preferred to other sources. */ + for (unsigned int i = 0; i < 0x20; i++) { + if (memcmp(keyset->mariko_kek, zeroes, 0x10) == 0) { + continue; + } + if (memcmp(keyset->mariko_master_kek_sources[i], zeroes, 0x10) == 0) { + continue; + } + aes_ctx_t *mariko_kek_ctx = new_aes_ctx(keyset->mariko_kek, 0x10, AES_MODE_ECB); + aes_decrypt(mariko_kek_ctx, keyset->master_keks[i], keyset->mariko_master_kek_sources[i], 0x10); + free_aes_ctx(mariko_kek_ctx); + } for (unsigned int i = 0; i < 0x20; i++) { /* Then we derive master keys. */ if (memcmp(keyset->master_key_source, zeroes, 0x10) == 0) { @@ -514,6 +526,10 @@ void pki_print_keys(nca_keyset_t *keyset) { PRINT_KEY_WITH_NAME_IDX(keyset->mariko_aes_class_keys[i], mariko_aes_class_key, i); } printf("\n"); + for (unsigned int i = 0x0; i < 0x20; i++) { + PRINT_KEY_WITH_NAME_IDX(keyset->mariko_master_kek_sources[i], mariko_master_kek_source, i); + } + printf("\n"); for (unsigned int i = 0x0; i < 0x20; i++) { PRINT_KEY_WITH_NAME_IDX(keyset->master_keks[i], master_kek, i); } diff --git a/settings.h b/settings.h index 202f89a..2fa7ce6 100644 --- a/settings.h +++ b/settings.h @@ -34,6 +34,7 @@ typedef struct { unsigned char tsec_auth_signatures[0x20][0x10]; /* Auth signatures, seeds for tsec root key/package1 mac kek/package1 key on 6.2.0+. */ unsigned char tsec_root_keys[0x20][0x10]; /* Key for master kek decryption, from TSEC firmware on 6.2.0+. */ unsigned char master_kek_sources[0x20][0x10]; /* Seeds for firmware master keks. */ + unsigned char mariko_master_kek_sources[0x20][0x10]; /* Seeds for firmware master keks (Mariko). */ unsigned char master_keks[0x20][0x10]; /* Firmware master keks, stored in keyblob prior to 6.2.0. */ unsigned char master_key_source[0x10]; /* Seed for master key derivation. */ unsigned char master_keys[0x20][0x10]; /* Firmware master keys. */