mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-26 04:02:11 +00:00
Check the key generation value from the eticket device key.
This commit is contained in:
parent
11e9d6612a
commit
0c34ef84ac
3 changed files with 14 additions and 16 deletions
|
@ -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++;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
Loading…
Reference in a new issue