Add support for key derivation.

Passing in --sbk=, --tseckey= with -t keygen and an input BOOT0
BIS partition will now derive all keys derivable iwth the sources
in the loaded keyset, and print them to output.
This commit is contained in:
Michael Scire 2018-04-26 00:10:14 -06:00
parent 41e6695e6e
commit 2159f4396f
8 changed files with 623 additions and 5 deletions

13
aes.c
View file

@ -48,6 +48,19 @@ void aes_setiv(aes_ctx_t *ctx, const void *iv, size_t l) {
} }
} }
/* Calculate CMAC. */
void aes_calculate_cmac(void *dst, void *src, size_t size, const void *key) {
mbedtls_cipher_context_t m_ctx;
mbedtls_cipher_init(&m_ctx);
if (mbedtls_cipher_setup(&m_ctx, mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB))
|| mbedtls_cipher_cmac_starts(&m_ctx, key, 0x80)
|| mbedtls_cipher_cmac_update(&m_ctx, src, size)
|| mbedtls_cipher_cmac_finish(&m_ctx, dst)) {
FATAL_ERROR("Failed to calculate CMAC!");
}
}
/* Encrypt with context. */ /* Encrypt with context. */
void aes_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l) { void aes_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l) {
size_t out_len = 0; size_t out_len = 0;

3
aes.h
View file

@ -2,6 +2,7 @@
#define HACTOOL_AES_H #define HACTOOL_AES_H
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#include "mbedtls/cmac.h"
/* Enumerations. */ /* Enumerations. */
typedef enum { typedef enum {
@ -30,6 +31,8 @@ void aes_setiv(aes_ctx_t *ctx, const void *iv, size_t l);
void aes_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l); void aes_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l);
void aes_decrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l); void aes_decrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l);
void aes_calculate_cmac(void *dst, void *src, size_t size, const void *key);
void aes_xts_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l, size_t sector, size_t sector_size); void aes_xts_encrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l, size_t sector, size_t sector_size);
void aes_xts_decrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l, size_t sector, size_t sector_size); void aes_xts_decrypt(aes_ctx_t *ctx, void *dst, const void *src, size_t l, size_t sector, size_t sector_size);

View file

@ -209,6 +209,9 @@ void extkeys_initialize_keyset(nca_keyset_t *keyset, FILE *f) {
} else if (strcmp(key, "header_key") == 0) { } else if (strcmp(key, "header_key") == 0) {
parse_hex_key(keyset->header_key, value, sizeof(keyset->header_key)); parse_hex_key(keyset->header_key, value, sizeof(keyset->header_key));
matched_key = 1; matched_key = 1;
} else if (strcmp(key, "encrypted_header_key") == 0) {
parse_hex_key(keyset->encrypted_header_key, value, sizeof(keyset->encrypted_header_key));
matched_key = 1;
} else if (strcmp(key, "package2_key_source") == 0) { } else if (strcmp(key, "package2_key_source") == 0) {
parse_hex_key(keyset->package2_key_source, value, sizeof(keyset->package2_key_source)); parse_hex_key(keyset->package2_key_source, value, sizeof(keyset->package2_key_source));
matched_key = 1; matched_key = 1;
@ -221,10 +224,57 @@ void extkeys_initialize_keyset(nca_keyset_t *keyset, FILE *f) {
} else if (strcmp(key, "sd_card_save_key_source") == 0) { } else if (strcmp(key, "sd_card_save_key_source") == 0) {
parse_hex_key(keyset->sd_card_key_sources[0], value, sizeof(keyset->sd_card_key_sources[0])); parse_hex_key(keyset->sd_card_key_sources[0], value, sizeof(keyset->sd_card_key_sources[0]));
matched_key = 1; matched_key = 1;
} else if (strcmp(key, "master_key_source") == 0) {
parse_hex_key(keyset->master_key_source, value, sizeof(keyset->master_key_source));
matched_key = 1;
} else if (strcmp(key, "keyblob_mac_key_source") == 0) {
parse_hex_key(keyset->keyblob_mac_key_source, value, sizeof(keyset->keyblob_mac_key_source));
matched_key = 1;
} else if (strcmp(key, "secure_boot_key") == 0) {
parse_hex_key(keyset->secure_boot_key, value, sizeof(keyset->secure_boot_key));
matched_key = 1;
} else if (strcmp(key, "tsec_key") == 0) {
parse_hex_key(keyset->tsec_key, value, sizeof(keyset->tsec_key));
matched_key = 1;
} else { } else {
char test_name[0x100]; char test_name[0x100];
memset(test_name, 0, sizeof(100)); memset(test_name, 0, sizeof(100));
for (unsigned int i = 0; i < 0x20 && !matched_key; i++) { for (unsigned int i = 0; i < 0x20 && !matched_key; i++) {
snprintf(test_name, sizeof(test_name), "keyblob_key_source_%02"PRIx32, i);
if (strcmp(key, test_name) == 0) {
parse_hex_key(keyset->keyblob_key_sources[i], value, sizeof(keyset->keyblob_key_sources[i]));
matched_key = 1;
break;
}
snprintf(test_name, sizeof(test_name), "keyblob_key_%02"PRIx32, i);
if (strcmp(key, test_name) == 0) {
parse_hex_key(keyset->keyblob_keys[i], value, sizeof(keyset->keyblob_keys[i]));
matched_key = 1;
break;
}
snprintf(test_name, sizeof(test_name), "keyblob_mac_key_%02"PRIx32, i);
if (strcmp(key, test_name) == 0) {
parse_hex_key(keyset->keyblob_mac_keys[i], value, sizeof(keyset->keyblob_mac_keys[i]));
matched_key = 1;
break;
}
snprintf(test_name, sizeof(test_name), "encrypted_keyblob_%02"PRIx32, i);
if (strcmp(key, test_name) == 0) {
parse_hex_key(keyset->encrypted_keyblobs[i], value, sizeof(keyset->encrypted_keyblobs[i]));
matched_key = 1;
break;
}
snprintf(test_name, sizeof(test_name), "keyblob_%02"PRIx32, i);
if (strcmp(key, test_name) == 0) {
parse_hex_key(keyset->keyblobs[i], value, sizeof(keyset->keyblobs[i]));
matched_key = 1;
break;
}
snprintf(test_name, sizeof(test_name), "master_key_%02"PRIx32, i); snprintf(test_name, sizeof(test_name), "master_key_%02"PRIx32, i);
if (strcmp(key, test_name) == 0) { if (strcmp(key, test_name) == 0) {
parse_hex_key(keyset->master_keys[i], value, sizeof(keyset->master_keys[i])); parse_hex_key(keyset->master_keys[i], value, sizeof(keyset->master_keys[i]));

42
main.c
View file

@ -31,7 +31,7 @@ static void usage(void) {
" -y, --verify Verify hashes and signatures.\n" " -y, --verify Verify hashes and signatures.\n"
" -d, --dev Decrypt with development keys instead of retail.\n" " -d, --dev Decrypt with development keys instead of retail.\n"
" -k, --keyset Load keys from an external file.\n" " -k, --keyset Load keys from an external file.\n"
" -t, --intype=type Specify input file type [nca, xci, pfs0, romfs, hfs0, npdm, pk11, pk21, ini1, kip1]\n" " -t, --intype=type Specify input file type [nca, xci, pfs0, romfs, hfs0, npdm, pk11, pk21, ini1, kip1, keygen]\n"
" --titlekey=key Set title key for Rights ID crypto titles.\n" " --titlekey=key Set title key for Rights ID crypto titles.\n"
" --contentkey=key Set raw key for NCA body decryption.\n" " --contentkey=key Set raw key for NCA body decryption.\n"
"NCA options:\n" "NCA options:\n"
@ -86,6 +86,9 @@ static void usage(void) {
"NAX0 options:\n" "NAX0 options:\n"
" --sdseed=seed Set console unique seed for SD card NAX0 encryption.\n" " --sdseed=seed Set console unique seed for SD card NAX0 encryption.\n"
" --sdpath=path Set relative path for NAX0 key derivation (ex: /registered/000000FF/cafebabecafebabecafebabecafebabe.nca).\n" " --sdpath=path Set relative path for NAX0 key derivation (ex: /registered/000000FF/cafebabecafebabecafebabecafebabe.nca).\n"
"Key Derivation options:\n"
" --sbk=key Set console unique Secure Boot Key for key derivation.\n"
" --tseckey=key Set console unique TSEC Key for key derivation.\n"
"\n", __TIME__, __DATE__, prog_name); "\n", __TIME__, __DATE__, prog_name);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -158,6 +161,8 @@ int main(int argc, char **argv) {
{"onlyupdated", 0, NULL, 31}, {"onlyupdated", 0, NULL, 31},
{"sdseed", 1, NULL, 32}, {"sdseed", 1, NULL, 32},
{"sdpath", 1, NULL, 33}, {"sdpath", 1, NULL, 33},
{"sbk", 1, NULL, 34},
{"tseckey", 1, NULL, 35},
{NULL, 0, NULL, 0}, {NULL, 0, NULL, 0},
}; };
@ -209,6 +214,8 @@ int main(int argc, char **argv) {
nca_ctx.tool_ctx->file_type = FILETYPE_KIP1; nca_ctx.tool_ctx->file_type = FILETYPE_KIP1;
} else if (!strcmp(optarg, "nax0") || !strcmp(optarg, "nax")) { } else if (!strcmp(optarg, "nax0") || !strcmp(optarg, "nax")) {
nca_ctx.tool_ctx->file_type = FILETYPE_NAX0; nca_ctx.tool_ctx->file_type = FILETYPE_NAX0;
} else if (!strcmp(optarg, "keygen") || !strcmp(optarg, "keys") || !strcmp(optarg, "boot0") || !strcmp(optarg, "boot")) {
nca_ctx.tool_ctx->file_type = FILETYPE_BOOT0;
} }
break; break;
case 0: filepath_set(&nca_ctx.tool_ctx->settings.section_paths[0], optarg); break; case 0: filepath_set(&nca_ctx.tool_ctx->settings.section_paths[0], optarg); break;
@ -340,6 +347,12 @@ int main(int argc, char **argv) {
case 33: case 33:
filepath_set(&tool_ctx.settings.nax0_sd_path, optarg); filepath_set(&tool_ctx.settings.nax0_sd_path, optarg);
break; break;
case 34:
parse_hex_key(nca_ctx.tool_ctx->settings.keygen_sbk, optarg, 16);
break;
case 35:
parse_hex_key(nca_ctx.tool_ctx->settings.keygen_tsec, optarg, 16);
break;
default: default:
usage(); usage();
return EXIT_FAILURE; return EXIT_FAILURE;
@ -589,6 +602,33 @@ int main(int argc, char **argv) {
xci_process(&xci_ctx); xci_process(&xci_ctx);
break; break;
} }
case FILETYPE_BOOT0: {
nca_keyset_t new_keyset;
memcpy(&new_keyset, &tool_ctx.settings.keyset, sizeof(new_keyset));
for (unsigned int i = 0; i < 0x10; i++) {
if (tool_ctx.settings.keygen_sbk[i] != 0) {
memcpy(new_keyset.secure_boot_key, tool_ctx.settings.keygen_sbk, 0x10);
}
}
for (unsigned int i = 0; i < 0x10; i++) {
if (tool_ctx.settings.keygen_tsec[i] != 0) {
memcpy(new_keyset.tsec_key, tool_ctx.settings.keygen_tsec, 0x10);
}
}
for (unsigned int i = 0; i < 0x20; i++) {
fseek(tool_ctx.file, 0x180000 + 0x200 * i, SEEK_SET);
if (fread(&new_keyset.encrypted_keyblobs[i], sizeof(new_keyset.encrypted_keyblobs[i]), 1, tool_ctx.file) != 1) {
fprintf(stderr, "Error: Failed to read encrypted_keyblob_%02x from boot0!\n", i);
return EXIT_FAILURE;
}
}
printf("Deriving keys...\n");
pki_derive_keys(&new_keyset);
printf("--\n");
printf("All derivable keys (using loaded sources):\n\n");
pki_print_keys(&new_keyset);
break;
}
default: { default: {
fprintf(stderr, "Unknown File Type!\n\n"); fprintf(stderr, "Unknown File Type!\n\n");
usage(); usage();

View file

@ -1783,7 +1783,7 @@
* Requires: MBEDTLS_AES_C or MBEDTLS_DES_C * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
* *
*/ */
//#define MBEDTLS_CMAC_C #define MBEDTLS_CMAC_C
/** /**
* \def MBEDTLS_CTR_DRBG_C * \def MBEDTLS_CTR_DRBG_C

497
pki.c
View file

@ -4,6 +4,180 @@
#include "pki.h" #include "pki.h"
const nca_keyset_t nca_keys_retail = { const nca_keyset_t nca_keys_retail = {
ZEROES_KEY, /* Secure Boot Key (CONSOLE UNIQUE) */
ZEROES_KEY, /* TSEC Key (CONSOLE UNIQUE) */
{
ZEROES_KEY, /* Keyblob Key 00 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 01 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 02 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 03 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 04 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 05 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 06 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 07 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 08 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 09 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 10 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 11 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 12 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 13 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 14 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 15 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 16 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 17 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 18 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 19 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 20 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 21 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 22 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 23 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 24 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 25 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 26 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 27 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 28 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 29 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 30 (CONSOLE UNIQUE) */
ZEROES_KEY /* Keyblob Key 31 (CONSOLE UNIQUE) */
},
{
ZEROES_KEY, /* Keyblob Mac Key 00 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 01 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 02 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 03 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 04 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 05 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 06 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 07 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 08 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 09 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 10 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 11 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 12 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 13 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 14 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 15 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 16 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 17 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 18 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 19 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 20 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 21 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 22 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 23 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 24 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 25 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 26 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 27 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 28 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 29 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 30 (CONSOLE UNIQUE) */
ZEROES_KEY /* Keyblob Mac Key 31 (CONSOLE UNIQUE) */
},
{
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 00 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 01 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 02 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 03 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 04 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 05 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 06 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 07 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 08 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 09 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 10 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 11 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 12 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 13 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 14 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 15 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 16 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 17 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 18 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 19 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 20 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 21 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 22 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 23 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 24 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 25 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 26 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 27 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 28 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 29 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 30 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB /* Encrypted Keyblob 31 (CONSOLE UNIQUE) */
},
{
ZEROES_KEYBLOB, /* Keyblob 00 */
ZEROES_KEYBLOB, /* Keyblob 01 */
ZEROES_KEYBLOB, /* Keyblob 02 */
ZEROES_KEYBLOB, /* Keyblob 03 */
ZEROES_KEYBLOB, /* Keyblob 04 */
ZEROES_KEYBLOB, /* Keyblob 05 */
ZEROES_KEYBLOB, /* Keyblob 06 */
ZEROES_KEYBLOB, /* Keyblob 07 */
ZEROES_KEYBLOB, /* Keyblob 08 */
ZEROES_KEYBLOB, /* Keyblob 09 */
ZEROES_KEYBLOB, /* Keyblob 10 */
ZEROES_KEYBLOB, /* Keyblob 11 */
ZEROES_KEYBLOB, /* Keyblob 12 */
ZEROES_KEYBLOB, /* Keyblob 13 */
ZEROES_KEYBLOB, /* Keyblob 14 */
ZEROES_KEYBLOB, /* Keyblob 15 */
ZEROES_KEYBLOB, /* Keyblob 16 */
ZEROES_KEYBLOB, /* Keyblob 17 */
ZEROES_KEYBLOB, /* Keyblob 18 */
ZEROES_KEYBLOB, /* Keyblob 19 */
ZEROES_KEYBLOB, /* Keyblob 20 */
ZEROES_KEYBLOB, /* Keyblob 21 */
ZEROES_KEYBLOB, /* Keyblob 22 */
ZEROES_KEYBLOB, /* Keyblob 23 */
ZEROES_KEYBLOB, /* Keyblob 24 */
ZEROES_KEYBLOB, /* Keyblob 25 */
ZEROES_KEYBLOB, /* Keyblob 26 */
ZEROES_KEYBLOB, /* Keyblob 27 */
ZEROES_KEYBLOB, /* Keyblob 28 */
ZEROES_KEYBLOB, /* Keyblob 29 */
ZEROES_KEYBLOB, /* Keyblob 30 */
ZEROES_KEYBLOB /* Keyblob 31 */
},
{
ZEROES_KEY, /* Keyblob Key Source 00 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 01 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 02 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 03 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 04 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 05 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 06 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 07 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 08 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 09 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 10 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 11 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 12 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 13 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 14 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 15 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 16 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 17 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 18 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 19 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 20 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 21 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 22 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 23 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 24 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 25 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 26 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 27 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 28 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 29 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 30 (CONSOLE UNIQUE) */
ZEROES_KEY /* Keyblob Key Source 31 (CONSOLE UNIQUE) */
},
ZEROES_KEY, /* Keyblob Mac Key Source */
ZEROES_KEY, /* Master Key Source */
{ {
ZEROES_KEY, /* Master Key 00 */ ZEROES_KEY, /* Master Key 00 */
ZEROES_KEY, /* Master Key 01 */ ZEROES_KEY, /* Master Key 01 */
@ -250,6 +424,180 @@ const nca_keyset_t nca_keys_retail = {
}; };
const nca_keyset_t nca_keys_dev = { const nca_keyset_t nca_keys_dev = {
ZEROES_KEY, /* Secure Boot Key (CONSOLE UNIQUE) */
ZEROES_KEY, /* TSEC Key (CONSOLE UNIQUE) */
{
ZEROES_KEY, /* Keyblob Key 00 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 01 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 02 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 03 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 04 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 05 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 06 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 07 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 08 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 09 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 10 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 11 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 12 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 13 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 14 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 15 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 16 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 17 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 18 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 19 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 20 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 21 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 22 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 23 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 24 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 25 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 26 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 27 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 28 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 29 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key 30 (CONSOLE UNIQUE) */
ZEROES_KEY /* Keyblob Key 31 (CONSOLE UNIQUE) */
},
{
ZEROES_KEY, /* Keyblob Mac Key 00 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 01 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 02 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 03 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 04 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 05 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 06 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 07 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 08 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 09 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 10 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 11 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 12 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 13 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 14 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 15 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 16 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 17 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 18 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 19 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 20 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 21 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 22 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 23 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 24 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 25 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 26 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 27 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 28 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 29 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Mac Key 30 (CONSOLE UNIQUE) */
ZEROES_KEY /* Keyblob Mac Key 31 (CONSOLE UNIQUE) */
},
{
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 00 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 01 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 02 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 03 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 04 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 05 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 06 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 07 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 08 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 09 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 10 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 11 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 12 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 13 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 14 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 15 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 16 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 17 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 18 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 19 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 20 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 21 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 22 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 23 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 24 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 25 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 26 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 27 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 28 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 29 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB, /* Encrypted Keyblob 30 (CONSOLE UNIQUE) */
ZEROES_ENC_KEYBLOB /* Encrypted Keyblob 31 (CONSOLE UNIQUE) */
},
{
ZEROES_KEYBLOB, /* Keyblob 00 */
ZEROES_KEYBLOB, /* Keyblob 01 */
ZEROES_KEYBLOB, /* Keyblob 02 */
ZEROES_KEYBLOB, /* Keyblob 03 */
ZEROES_KEYBLOB, /* Keyblob 04 */
ZEROES_KEYBLOB, /* Keyblob 05 */
ZEROES_KEYBLOB, /* Keyblob 06 */
ZEROES_KEYBLOB, /* Keyblob 07 */
ZEROES_KEYBLOB, /* Keyblob 08 */
ZEROES_KEYBLOB, /* Keyblob 09 */
ZEROES_KEYBLOB, /* Keyblob 10 */
ZEROES_KEYBLOB, /* Keyblob 11 */
ZEROES_KEYBLOB, /* Keyblob 12 */
ZEROES_KEYBLOB, /* Keyblob 13 */
ZEROES_KEYBLOB, /* Keyblob 14 */
ZEROES_KEYBLOB, /* Keyblob 15 */
ZEROES_KEYBLOB, /* Keyblob 16 */
ZEROES_KEYBLOB, /* Keyblob 17 */
ZEROES_KEYBLOB, /* Keyblob 18 */
ZEROES_KEYBLOB, /* Keyblob 19 */
ZEROES_KEYBLOB, /* Keyblob 20 */
ZEROES_KEYBLOB, /* Keyblob 21 */
ZEROES_KEYBLOB, /* Keyblob 22 */
ZEROES_KEYBLOB, /* Keyblob 23 */
ZEROES_KEYBLOB, /* Keyblob 24 */
ZEROES_KEYBLOB, /* Keyblob 25 */
ZEROES_KEYBLOB, /* Keyblob 26 */
ZEROES_KEYBLOB, /* Keyblob 27 */
ZEROES_KEYBLOB, /* Keyblob 28 */
ZEROES_KEYBLOB, /* Keyblob 29 */
ZEROES_KEYBLOB, /* Keyblob 30 */
ZEROES_KEYBLOB /* Keyblob 31 */
},
{
ZEROES_KEY, /* Keyblob Key Source 00 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 01 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 02 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 03 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 04 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 05 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 06 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 07 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 08 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 09 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 10 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 11 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 12 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 13 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 14 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 15 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 16 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 17 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 18 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 19 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 20 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 21 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 22 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 23 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 24 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 25 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 26 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 27 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 28 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 29 (CONSOLE UNIQUE) */
ZEROES_KEY, /* Keyblob Key Source 30 (CONSOLE UNIQUE) */
ZEROES_KEY /* Keyblob Key Source 31 (CONSOLE UNIQUE) */
},
ZEROES_KEY, /* Keyblob Mac Key Source */
ZEROES_KEY, /* Master Key Source */
{ {
ZEROES_KEY, /* Master Key 00 */ ZEROES_KEY, /* Master Key 00 */
ZEROES_KEY, /* Master Key 01 */ ZEROES_KEY, /* Master Key 01 */
@ -518,8 +866,72 @@ void generate_kek(unsigned char *dst, const unsigned char *src, const unsigned c
void pki_derive_keys(nca_keyset_t *keyset) { void pki_derive_keys(nca_keyset_t *keyset) {
unsigned char zeroes[0x100]; unsigned char zeroes[0x100];
unsigned char cmac[0x10];
memset(zeroes, 0, 0x100); memset(zeroes, 0, 0x100);
memset(cmac, 0, 0x10);
/* Derive keys as necessary. */ /* Derive keys as necessary. */
for (unsigned int i = 0; i < 0x20; i++) {
/* Start by deriving keyblob keys. */
if (memcmp(&keyset->secure_boot_key, zeroes, 0x10) == 0) {
continue;
}
if (memcmp(&keyset->tsec_key, zeroes, 0x10) == 0) {
continue;
}
if (memcmp(&keyset->keyblob_key_sources[i], zeroes, 0x10) == 0) {
continue;
}
aes_ctx_t *sbk_ctx = new_aes_ctx(keyset->secure_boot_key, 0x10, AES_MODE_ECB);
aes_ctx_t *tsec_ctx = new_aes_ctx(keyset->tsec_key, 0x10, AES_MODE_ECB);
aes_decrypt(tsec_ctx, &keyset->keyblob_keys[i], &keyset->keyblob_key_sources[i], 0x10);
aes_decrypt(sbk_ctx, &keyset->keyblob_keys[i], &keyset->keyblob_keys[i], 0x10);
free_aes_ctx(tsec_ctx);
free_aes_ctx(sbk_ctx);
if (memcmp(keyset->keyblob_mac_key_source, zeroes, 0x10) == 0) {
continue;
}
aes_ctx_t *mac_gen_ctx = new_aes_ctx(&keyset->keyblob_keys[i], 0x10, AES_MODE_ECB);
aes_decrypt(sbk_ctx, &keyset->keyblob_mac_keys[i], keyset->keyblob_mac_key_source, 0x10);
free_aes_ctx(mac_gen_ctx);
}
for (unsigned int i = 0; i < 0x20; i++) {
/* Then we decrypt keyblobs. */
if (memcmp(&keyset->keyblob_keys[i], zeroes, 0x10) == 0) {
continue;
}
if (memcmp(&keyset->keyblob_mac_keys[i], zeroes, 0x10) == 0) {
continue;
}
if (memcmp(&keyset->encrypted_keyblobs[i], zeroes, 0xB0) == 0) {
continue;
}
aes_calculate_cmac(cmac, &keyset->encrypted_keyblobs[i][0x10], 0xA0, keyset->keyblob_mac_keys[i]);
if (memcmp(cmac, &keyset->encrypted_keyblobs[i][0], 0x10) != 0) {
fprintf(stderr, "[ WARN ] Keyblob MAC %02x is invalid. Are SBK/TSEC key correct?\n", i);
continue;
}
aes_ctx_t *keyblob_ctx = new_aes_ctx(&keyset->keyblob_keys[i], 0x10, AES_MODE_CTR);
aes_setiv(keyblob_ctx, &keyset->encrypted_keyblobs[i][0x10], 0x10);
aes_decrypt(keyblob_ctx, &keyset->keyblobs[i], &keyset->encrypted_keyblobs[i][0x20], sizeof(keyset->keyblobs[i]));
free_aes_ctx(keyblob_ctx);
/* Package1 key is at the end of the keyblob. */
memcpy(&keyset->package1_keys[i], &keyset->keyblobs[i][0x80], 0x10);
}
for (unsigned int i = 0; i < 0x20; i++) {
/* Then we derive master keys. */
if (memcmp(keyset->master_key_source, zeroes, 0x10) == 0) {
continue;
}
/* We only need the first key in the blob. */
if (memcmp(keyset->keyblobs[i], zeroes, 0x10) == 0) {
continue;
}
/* Derive Master Keys. */
aes_ctx_t *master_gen_ctx = new_aes_ctx(&keyset->keyblobs[i], 0x10, AES_MODE_ECB);
aes_decrypt(master_gen_ctx, &keyset->master_keys[i], keyset->master_key_source, 0x10);
free_aes_ctx(master_gen_ctx);
}
for (unsigned int i = 0; i < 0x20; i++) { for (unsigned int i = 0; i < 0x20; i++) {
if (memcmp(&keyset->master_keys[i], zeroes, 0x10) == 0) { if (memcmp(&keyset->master_keys[i], zeroes, 0x10) == 0) {
continue; continue;
@ -577,6 +989,91 @@ void pki_derive_keys(nca_keyset_t *keyset) {
} }
void pki_print_keys(nca_keyset_t *keyset) {
unsigned char zeroes[0x100] = {0};
#define PRINT_KEY_WITH_NAME(ky, kn) do { if (memcmp(ky, zeroes, sizeof(ky)) != 0) { printf("%-32s= ", #kn); for (unsigned int k_i = 0; k_i < sizeof(ky); k_i++) { printf("%02X", ky[k_i]); } printf("\n"); } } while (0)
#define PRINT_KEY_WITH_NAME_IDX(ky, kn, idx) do { if (memcmp(ky, zeroes, sizeof(ky)) != 0) { char KEY_NAME[32]; snprintf(KEY_NAME, sizeof(KEY_NAME), "%s_%02"PRIx32, #kn, idx); printf("%-32s= ", KEY_NAME); for (unsigned int k_i = 0; k_i < sizeof(ky); k_i++) { printf("%02X", ky[k_i]); } printf("\n"); } } while (0)
PRINT_KEY_WITH_NAME(keyset->secure_boot_key, secure_boot_key);
PRINT_KEY_WITH_NAME(keyset->tsec_key, tsec_key);
printf("\n");
PRINT_KEY_WITH_NAME(keyset->keyblob_mac_key_source, keyblob_mac_key_source);
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->keyblob_key_sources[i], keyblob_key_source, i);
}
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->keyblob_keys[i], keyblob_key, i);
}
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->keyblob_mac_keys[i], keyblob_mac_key, i);
}
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->encrypted_keyblobs[i], encrypted_keyblob, i);
}
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->keyblobs[i], keyblob, i);
}
printf("\n");
PRINT_KEY_WITH_NAME(keyset->master_key_source, master_key_source);
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->master_keys[i], master_key, i);
}
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->package1_keys[i], package1_key, i);
}
printf("\n");
PRINT_KEY_WITH_NAME(keyset->package2_key_source, package2_key_source);
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->package2_keys[i], package2_key, i);
}
printf("\n");
PRINT_KEY_WITH_NAME(keyset->aes_kek_generation_source, aes_kek_generation_source);
PRINT_KEY_WITH_NAME(keyset->aes_key_generation_source, aes_kek_generation_source);
PRINT_KEY_WITH_NAME(keyset->titlekek_source, titlekek_source);
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->titlekeks[i], titlekek, i);
}
printf("\n");
PRINT_KEY_WITH_NAME(keyset->key_area_key_application_source, key_area_key_application_source);
PRINT_KEY_WITH_NAME(keyset->key_area_key_ocean_source, key_area_key_ocean_source);
PRINT_KEY_WITH_NAME(keyset->key_area_key_system_source, key_area_key_system_source);
PRINT_KEY_WITH_NAME(keyset->sd_card_kek_source, sd_card_kek_source);
PRINT_KEY_WITH_NAME(keyset->sd_card_key_sources[0], sd_card_save_key_source);
PRINT_KEY_WITH_NAME(keyset->sd_card_key_sources[1], sd_card_nca_key_source);
printf("\n");
PRINT_KEY_WITH_NAME(keyset->encrypted_header_key, encrypted_header_key);
PRINT_KEY_WITH_NAME(keyset->header_key, header_key);
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->key_area_keys[i][0], key_area_key_application, i);
}
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->key_area_keys[i][1], key_area_key_ocean, i);
}
printf("\n");
for (unsigned int i = 0; i < 0x20; i++) {
PRINT_KEY_WITH_NAME_IDX(keyset->key_area_keys[i][2], key_area_key_system, i);
}
printf("\n");
/*
unsigned char titlekeks[0x20][0x10];
unsigned char key_area_keys[0x20][3][0x10];
*/
#undef PRINT_KEY_WITH_NAME
#undef PRINT_KEY
}
void pki_initialize_keyset(nca_keyset_t *keyset, keyset_variant_t variant) { void pki_initialize_keyset(nca_keyset_t *keyset, keyset_variant_t variant) {
switch (variant) { switch (variant) {
case KEYSET_DEV: case KEYSET_DEV:

3
pki.h
View file

@ -6,9 +6,12 @@
#define ZEROES_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} #define ZEROES_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
#define ZEROES_XTS_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} #define ZEROES_XTS_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
#define ZEROES_KEYBLOB {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
#define ZEROES_ENC_KEYBLOB {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
#define ZEROES_KAEKS {ZEROES_KEY, ZEROES_KEY, ZEROES_KEY} #define ZEROES_KAEKS {ZEROES_KEY, ZEROES_KEY, ZEROES_KEY}
void pki_derive_keys(nca_keyset_t *keyset); void pki_derive_keys(nca_keyset_t *keyset);
void pki_print_keys(nca_keyset_t *keyset);
void pki_initialize_keyset(nca_keyset_t *keyset, keyset_variant_t variant); void pki_initialize_keyset(nca_keyset_t *keyset, keyset_variant_t variant);
#endif #endif

View file

@ -16,6 +16,15 @@ typedef enum {
} hactool_basefile_t; } hactool_basefile_t;
typedef struct { typedef struct {
unsigned char secure_boot_key[0x10]; /* Secure boot key for use in key derivation. NOTE: CONSOLE UNIQUE. */
unsigned char tsec_key[0x10]; /* TSEC key for use in key derivation. NOTE: CONSOLE UNIQUE. */
unsigned char keyblob_keys[0x20][0x10]; /* Actual keys used to decrypt keyblobs. NOTE: CONSOLE UNIQUE.*/
unsigned char keyblob_mac_keys[0x20][0x10]; /* Keys used to validate keyblobs. NOTE: CONSOLE UNIQUE. */
unsigned char encrypted_keyblobs[0x20][0xB0]; /* Actual encrypted keyblobs (EKS). NOTE: CONSOLE UNIQUE. */
unsigned char keyblobs[0x20][0xB0]; /* Actual decrypted keyblobs (EKS). */
unsigned char keyblob_key_sources[0x20][0x10]; /* Seeds for keyblob keys. */
unsigned char keyblob_mac_key_source[0x10]; /* Seed for keyblob MAC key derivation. */
unsigned char master_key_source[0x10]; /* Seed for master key derivation. */
unsigned char master_keys[0x20][0x10]; /* Firmware master keys. */ unsigned char master_keys[0x20][0x10]; /* Firmware master keys. */
unsigned char package1_keys[0x20][0x10]; /* Package1 keys. */ unsigned char package1_keys[0x20][0x10]; /* Package1 keys. */
unsigned char package2_keys[0x20][0x10]; /* Package2 keys. */ unsigned char package2_keys[0x20][0x10]; /* Package2 keys. */
@ -53,6 +62,8 @@ typedef struct {
unsigned char contentkey[0x10]; unsigned char contentkey[0x10];
int has_sdseed; int has_sdseed;
unsigned char sdseed[0x10]; unsigned char sdseed[0x10];
unsigned char keygen_sbk[0x10];
unsigned char keygen_tsec[0x10];
filepath_t section_paths[4]; filepath_t section_paths[4];
filepath_t section_dir_paths[4]; filepath_t section_dir_paths[4];
override_filepath_t exefs_path; override_filepath_t exefs_path;
@ -87,7 +98,8 @@ enum hactool_file_type
FILETYPE_PACKAGE2, FILETYPE_PACKAGE2,
FILETYPE_INI1, FILETYPE_INI1,
FILETYPE_KIP1, FILETYPE_KIP1,
FILETYPE_NAX0 FILETYPE_NAX0,
FILETYPE_BOOT0
}; };
#define ACTION_INFO (1<<0) #define ACTION_INFO (1<<0)