1
0
Fork 0
mirror of https://github.com/DarkMatterCore/nxdumptool.git synced 2024-11-26 12:12:02 +00:00

Check the key generation value from the eticket device key.

This commit is contained in:
Pablo Curiel 2020-07-07 08:58:17 -04:00
parent 11e9d6612a
commit 0c34ef84ac
3 changed files with 14 additions and 16 deletions

View file

@ -69,7 +69,8 @@ typedef struct {
u8 key_area_key_system_source[0x10]; ///< Seed for kaek 2. Retrieved from the .rodata section in the FS sysmodule. u8 key_area_key_system_source[0x10]; ///< Seed for kaek 2. Retrieved from the .rodata section in the FS sysmodule.
///< Needed to decrypt the titlekey block from a ticket. Retrieved from the Lockpick_RCM keys file. ///< Needed to decrypt the titlekey block from a ticket. Retrieved from the Lockpick_RCM keys file.
u8 eticket_rsa_kek[0x10]; ///< eTicket RSA kek. u8 eticket_rsa_kek[0x10]; ///< eTicket RSA kek (generic).
u8 eticket_rsa_kek_personalized[0x10]; ///< eTicket RSA kek (console-specific).
u8 titlekeks[0x20][0x10]; ///< Titlekey encryption keys. u8 titlekeks[0x20][0x10]; ///< Titlekey encryption keys.
///< Needed to reencrypt the NCA key area for tik-less NSP dumps. Retrieved from the Lockpick_RCM keys file. ///< Needed to reencrypt the NCA key area for tik-less NSP dumps. Retrieved from the Lockpick_RCM keys file.
@ -226,9 +227,9 @@ const u8 *keysGetKeyAreaEncryptionKeySource(u8 kaek_index)
return ptr; return ptr;
} }
const u8 *keysGetEticketRsaKek(void) const u8 *keysGetEticketRsaKek(bool personalized)
{ {
return (const u8*)(g_ncaKeyset.eticket_rsa_kek); return (const u8*)(personalized ? g_ncaKeyset.eticket_rsa_kek_personalized : g_ncaKeyset.eticket_rsa_kek);
} }
const u8 *keysGetTitlekek(u8 key_generation) const u8 *keysGetTitlekek(u8 key_generation)
@ -719,7 +720,7 @@ static bool keysReadKeysFromFile(void)
FILE *keys_file = NULL; FILE *keys_file = NULL;
char *key = NULL, *value = NULL; char *key = NULL, *value = NULL;
char test_name[0x40] = {0}; char test_name[0x40] = {0};
bool parse_fail = false, common_eticket_rsa_kek = false, personalized_eticket_rsa_kek = false; bool parse_fail = false;
keys_file = fopen(KEYS_FILE_PATH, "rb"); keys_file = fopen(KEYS_FILE_PATH, "rb");
if (!keys_file) if (!keys_file)
@ -736,24 +737,21 @@ static bool keysReadKeysFromFile(void)
/* Ignore malformed lines. */ /* Ignore malformed lines. */
if (ret != 0 || !key || !value) continue; if (ret != 0 || !key || !value) continue;
if (!common_eticket_rsa_kek && !personalized_eticket_rsa_kek && !strcasecmp(key, "eticket_rsa_kek")) if (strlen(key) == 15 && !strcasecmp(key, "eticket_rsa_kek"))
{ {
if ((parse_fail = !keysParseHexKey(g_ncaKeyset.eticket_rsa_kek, key, value, sizeof(g_ncaKeyset.eticket_rsa_kek)))) break; if ((parse_fail = !keysParseHexKey(g_ncaKeyset.eticket_rsa_kek, key, value, sizeof(g_ncaKeyset.eticket_rsa_kek)))) break;
common_eticket_rsa_kek = true;
key_count++; key_count++;
} else } else
if (!personalized_eticket_rsa_kek && !strcasecmp(key, "eticket_rsa_kek_personalized")) if (strlen(key) == 28 && !strcasecmp(key, "eticket_rsa_kek_personalized"))
{ {
/* Use the personalized eTicket RSA kek if available. */
/* This only appears on consoles that use the new PRODINFO key generation scheme. */ /* This only appears on consoles that use the new PRODINFO key generation scheme. */
if ((parse_fail = !keysParseHexKey(g_ncaKeyset.eticket_rsa_kek, key, value, sizeof(g_ncaKeyset.eticket_rsa_kek)))) break; if ((parse_fail = !keysParseHexKey(g_ncaKeyset.eticket_rsa_kek_personalized, key, value, sizeof(g_ncaKeyset.eticket_rsa_kek_personalized)))) break;
personalized_eticket_rsa_kek = true;
key_count++; key_count++;
} else { } else {
for(u32 i = 0; i < 0x20; i++) for(u32 i = 0; i < 0x20; i++)
{ {
snprintf(test_name, sizeof(test_name), "titlekek_%02x", i); snprintf(test_name, sizeof(test_name), "titlekek_%02x", i);
if (!strcasecmp(key, test_name)) if (strlen(key) == 11 && !strcasecmp(key, test_name))
{ {
if ((parse_fail = !keysParseHexKey(g_ncaKeyset.titlekeks[i], key, value, sizeof(g_ncaKeyset.titlekeks[i])))) break; if ((parse_fail = !keysParseHexKey(g_ncaKeyset.titlekeks[i], key, value, sizeof(g_ncaKeyset.titlekeks[i])))) break;
key_count++; key_count++;
@ -761,7 +759,7 @@ static bool keysReadKeysFromFile(void)
} }
snprintf(test_name, sizeof(test_name), "key_area_key_application_%02x", i); snprintf(test_name, sizeof(test_name), "key_area_key_application_%02x", i);
if (!strcasecmp(key, test_name)) if (strlen(key) == 27 && !strcasecmp(key, test_name))
{ {
if ((parse_fail = !keysParseHexKey(g_ncaKeyset.key_area_keys[i][0], key, value, sizeof(g_ncaKeyset.key_area_keys[i][0])))) break; if ((parse_fail = !keysParseHexKey(g_ncaKeyset.key_area_keys[i][0], key, value, sizeof(g_ncaKeyset.key_area_keys[i][0])))) break;
key_count++; key_count++;
@ -769,7 +767,7 @@ static bool keysReadKeysFromFile(void)
} }
snprintf(test_name, sizeof(test_name), "key_area_key_ocean_%02x", i); snprintf(test_name, sizeof(test_name), "key_area_key_ocean_%02x", i);
if (!strcasecmp(key, test_name)) if (strlen(key) == 21 && !strcasecmp(key, test_name))
{ {
if ((parse_fail = !keysParseHexKey(g_ncaKeyset.key_area_keys[i][1], key, value, sizeof(g_ncaKeyset.key_area_keys[i][1])))) break; if ((parse_fail = !keysParseHexKey(g_ncaKeyset.key_area_keys[i][1], key, value, sizeof(g_ncaKeyset.key_area_keys[i][1])))) break;
key_count++; key_count++;
@ -777,7 +775,7 @@ static bool keysReadKeysFromFile(void)
} }
snprintf(test_name, sizeof(test_name), "key_area_key_system_%02x", i); snprintf(test_name, sizeof(test_name), "key_area_key_system_%02x", i);
if (!strcasecmp(key, test_name)) if (strlen(key) == 22 && !strcasecmp(key, test_name))
{ {
if ((parse_fail = !keysParseHexKey(g_ncaKeyset.key_area_keys[i][2], key, value, sizeof(g_ncaKeyset.key_area_keys[i][2])))) break; if ((parse_fail = !keysParseHexKey(g_ncaKeyset.key_area_keys[i][2], key, value, sizeof(g_ncaKeyset.key_area_keys[i][2])))) break;
key_count++; key_count++;

View file

@ -29,7 +29,7 @@ bool keysLoadNcaKeyset(void);
const u8 *keysGetNcaHeaderKey(void); const u8 *keysGetNcaHeaderKey(void);
const u8 *keysGetKeyAreaEncryptionKeySource(u8 kaek_index); const u8 *keysGetKeyAreaEncryptionKeySource(u8 kaek_index);
const u8 *keysGetEticketRsaKek(void); const u8 *keysGetEticketRsaKek(bool personalized);
const u8 *keysGetTitlekek(u8 key_generation); const u8 *keysGetTitlekek(u8 key_generation);
const u8 *keysGetKeyAreaEncryptionKey(u8 key_generation, u8 kaek_index); const u8 *keysGetKeyAreaEncryptionKey(u8 key_generation, u8 kaek_index);

View file

@ -542,7 +542,7 @@ static bool tikRetrieveEticketDeviceKey(void)
/* Decrypt eTicket RSA key. */ /* Decrypt eTicket RSA key. */
eticket_devkey = (tikEticketDeviceKeyData*)g_eTicketDeviceKey.key; eticket_devkey = (tikEticketDeviceKeyData*)g_eTicketDeviceKey.key;
aes128CtrContextCreate(&eticket_aes_ctx, keysGetEticketRsaKek(), eticket_devkey->ctr); aes128CtrContextCreate(&eticket_aes_ctx, keysGetEticketRsaKek(g_eTicketDeviceKey.generation > 0), eticket_devkey->ctr);
aes128CtrCrypt(&eticket_aes_ctx, &(eticket_devkey->exponent), &(eticket_devkey->exponent), sizeof(tikEticketDeviceKeyData) - 0x10); aes128CtrCrypt(&eticket_aes_ctx, &(eticket_devkey->exponent), &(eticket_devkey->exponent), sizeof(tikEticketDeviceKeyData) - 0x10);
/* Public exponent value must be 0x10001. */ /* Public exponent value must be 0x10001. */