mirror of
https://github.com/shchmue/Lockpick_RCM.git
synced 2024-12-22 20:15:29 +00:00
keys: Add helper func for eticket rsa kek
This commit is contained in:
parent
514343db9b
commit
54412f5a9d
|
@ -73,7 +73,7 @@ static ALWAYS_INLINE u32 _read_be_u32(const void *buffer, u32 offset) {
|
||||||
static int _key_exists(const void *data) { return memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 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(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 _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);
|
static void _generate_kek(u32 ks, const void *key_source, const void *master_key, const void *kek_seed, const void *key_seed);
|
||||||
static void _generate_specific_aes_key(u32 ks, key_derivation_ctx_t *keys, void *out_key, const void *key_source, u32 key_generation);
|
static void _generate_specific_aes_key(u32 ks, key_derivation_ctx_t *keys, void *out_key, const void *key_source, u32 key_generation);
|
||||||
static void _get_device_key(u32 ks, key_derivation_ctx_t *keys, void *out_device_key, u32 revision);
|
static void _get_device_key(u32 ks, key_derivation_ctx_t *keys, void *out_device_key, u32 revision);
|
||||||
// titlekey functions
|
// titlekey functions
|
||||||
|
@ -226,6 +226,14 @@ static void _derive_non_unique_keys(key_derivation_ctx_t *keys, bool is_dev) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _derive_eticket_rsa_kek(key_derivation_ctx_t *keys, u32 ks, void *out_rsa_kek, const void *master_key, const void *kek_source) {
|
||||||
|
u8 kek_seed[AES_128_KEY_SIZE];
|
||||||
|
for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
|
||||||
|
kek_seed[i] = aes_kek_generation_source[i] ^ aes_seal_key_mask_import_es_device_key[i];
|
||||||
|
_generate_kek(ks, eticket_rsa_kekek_source, master_key, kek_seed, NULL);
|
||||||
|
se_aes_crypt_block_ecb(ks, DECRYPT, out_rsa_kek, kek_source);
|
||||||
|
}
|
||||||
|
|
||||||
static void _derive_misc_keys(key_derivation_ctx_t *keys, bool is_dev) {
|
static void _derive_misc_keys(key_derivation_ctx_t *keys, bool is_dev) {
|
||||||
if (_key_exists(keys->device_key) || (_key_exists(keys->master_key[0]) && _key_exists(keys->device_key_4x))) {
|
if (_key_exists(keys->device_key) || (_key_exists(keys->master_key[0]) && _key_exists(keys->device_key_4x))) {
|
||||||
_get_device_key(8, keys, keys->temp_key, 0);
|
_get_device_key(8, keys, keys->temp_key, 0);
|
||||||
|
@ -234,10 +242,7 @@ static void _derive_misc_keys(key_derivation_ctx_t *keys, bool is_dev) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_key_exists(keys->master_key[0])) {
|
if (_key_exists(keys->master_key[0])) {
|
||||||
for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
|
_derive_eticket_rsa_kek(keys, 8, keys->eticket_rsa_kek, keys->master_key[0], is_dev ? eticket_rsa_kek_source_dev : eticket_rsa_kek_source);
|
||||||
keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_seal_key_mask_import_es_device_key[i];
|
|
||||||
_generate_kek(8, eticket_rsa_kekek_source, keys->master_key[0], keys->temp_key, NULL);
|
|
||||||
se_aes_crypt_block_ecb(8, DECRYPT, keys->eticket_rsa_kek, is_dev ? eticket_rsa_kek_source_dev : eticket_rsa_kek_source);
|
|
||||||
|
|
||||||
for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
|
for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
|
||||||
keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_seal_key_mask_decrypt_device_unique_data[i];
|
keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_seal_key_mask_decrypt_device_unique_data[i];
|
||||||
|
@ -440,7 +445,7 @@ static bool _derive_sd_seed(key_derivation_ctx_t *keys) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *titlekey_buffer) {
|
static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *titlekey_buffer, bool is_dev) {
|
||||||
if (!_key_exists(keys->eticket_rsa_kek)) {
|
if (!_key_exists(keys->eticket_rsa_kek)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -482,12 +487,8 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
|
||||||
|
|
||||||
if (keypair_generation) {
|
if (keypair_generation) {
|
||||||
keypair_generation--;
|
keypair_generation--;
|
||||||
for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
|
_get_device_key(7, keys, keys->temp_key, keypair_generation);
|
||||||
keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_seal_key_mask_import_es_device_key[i];
|
_derive_eticket_rsa_kek(keys, 7, keys->eticket_rsa_kek_personalized, keys->temp_key, is_dev ? eticket_rsa_kek_source_dev : eticket_rsa_kek_source);
|
||||||
u32 temp_device_key[AES_128_KEY_SIZE / 4] = {0};
|
|
||||||
_get_device_key(7, keys, temp_device_key, keypair_generation);
|
|
||||||
_generate_kek(7, eticket_rsa_kekek_source, temp_device_key, keys->temp_key, NULL);
|
|
||||||
se_aes_crypt_block_ecb(7, DECRYPT, keys->eticket_rsa_kek_personalized, eticket_rsa_kek_source);
|
|
||||||
memcpy(keys->temp_key, keys->eticket_rsa_kek_personalized, sizeof(keys->temp_key));
|
memcpy(keys->temp_key, keys->eticket_rsa_kek_personalized, sizeof(keys->temp_key));
|
||||||
} else {
|
} else {
|
||||||
memcpy(keys->temp_key, keys->eticket_rsa_kek, sizeof(keys->temp_key));
|
memcpy(keys->temp_key, keys->eticket_rsa_kek, sizeof(keys->temp_key));
|
||||||
|
@ -498,10 +499,8 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
|
||||||
|
|
||||||
// Check public exponent is 65537 big endian
|
// Check public exponent is 65537 big endian
|
||||||
if (_read_be_u32(rsa_keypair.public_exponent, 0) != 65537) {
|
if (_read_be_u32(rsa_keypair.public_exponent, 0) != 65537) {
|
||||||
for (u32 i = 0; i < AES_128_KEY_SIZE; i++)
|
// try legacy kek source
|
||||||
keys->temp_key[i] = aes_kek_generation_source[i] ^ aes_seal_key_mask_import_es_device_key[i];
|
_derive_eticket_rsa_kek(keys, 7, keys->temp_key, keys->master_key[0], eticket_rsa_kek_source_legacy);
|
||||||
_generate_kek(8, eticket_rsa_kekek_source, keys->master_key[0], keys->temp_key, NULL);
|
|
||||||
se_aes_crypt_block_ecb(8, DECRYPT, keys->temp_key, eticket_rsa_kek_source_legacy);
|
|
||||||
|
|
||||||
se_aes_key_set(6, keys->temp_key, sizeof(keys->temp_key));
|
se_aes_key_set(6, keys->temp_key, sizeof(keys->temp_key));
|
||||||
se_aes_crypt_ctr(6, &rsa_keypair, sizeof(rsa_keypair), eticket_device_key, sizeof(rsa_keypair), eticket_iv);
|
se_aes_crypt_ctr(6, &rsa_keypair, sizeof(rsa_keypair), eticket_device_key, sizeof(rsa_keypair), eticket_iv);
|
||||||
|
@ -530,7 +529,7 @@ static bool _derive_titlekeys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _derive_emmc_keys(key_derivation_ctx_t *keys, titlekey_buffer_t *titlekey_buffer) {
|
static bool _derive_emmc_keys(key_derivation_ctx_t *keys, titlekey_buffer_t *titlekey_buffer, bool is_dev) {
|
||||||
// Set BIS keys.
|
// Set BIS keys.
|
||||||
// PRODINFO/PRODINFOF
|
// PRODINFO/PRODINFOF
|
||||||
se_aes_key_set(0, keys->bis_key[0] + 0x00, AES_128_KEY_SIZE);
|
se_aes_key_set(0, keys->bis_key[0] + 0x00, AES_128_KEY_SIZE);
|
||||||
|
@ -571,7 +570,7 @@ static bool _derive_emmc_keys(key_derivation_ctx_t *keys, titlekey_buffer_t *tit
|
||||||
EPRINTF("Unable to get SD seed.");
|
EPRINTF("Unable to get SD seed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool res = _derive_titlekeys(keys, titlekey_buffer);
|
bool res = _derive_titlekeys(keys, titlekey_buffer, is_dev);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
EPRINTF("Unable to derive titlekeys.");
|
EPRINTF("Unable to derive titlekeys.");
|
||||||
}
|
}
|
||||||
|
@ -882,7 +881,7 @@ static void _derive_keys() {
|
||||||
if (!emmc_storage.initialized) {
|
if (!emmc_storage.initialized) {
|
||||||
EPRINTF("eMMC not initialized.\nSkipping SD seed and titlekeys.");
|
EPRINTF("eMMC not initialized.\nSkipping SD seed and titlekeys.");
|
||||||
} else if (_key_exists(keys->bis_key[2])) {
|
} else if (_key_exists(keys->bis_key[2])) {
|
||||||
_derive_emmc_keys(keys, titlekey_buffer);
|
_derive_emmc_keys(keys, titlekey_buffer, is_dev);
|
||||||
} else {
|
} else {
|
||||||
EPRINTF("Missing needed BIS keys.\nSkipping SD seed and titlekeys.");
|
EPRINTF("Missing needed BIS keys.\nSkipping SD seed and titlekeys.");
|
||||||
}
|
}
|
||||||
|
@ -963,7 +962,7 @@ static void _save_key_family(const char *name, const void *data, u32 start_key,
|
||||||
free(temp_name);
|
free(temp_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed) {
|
static void _generate_kek(u32 ks, const void *key_source, const void *master_key, const void *kek_seed, const void *key_seed) {
|
||||||
if (!_key_exists(key_source) || !_key_exists(master_key) || !_key_exists(kek_seed))
|
if (!_key_exists(key_source) || !_key_exists(master_key) || !_key_exists(kek_seed))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue