Nyx: emuMMC Manage window, Tools UI, and misc updates
- Add gui_emu_tools: emuMMC Manage window with correct positioning (LV_PROTECT_PARENT + re-parent to win) - Tools: single SD button (tap = SD partition manager, 3s hold = eMMC) - Remove emuSD from Nyx UI (tabs, UMS, partition manager); keep bootloader emusd - Shorten Create emuMMC description text by one character - Storage/build/config and dependency updates Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <bdk.h>
|
||||
|
||||
#include "hos.h"
|
||||
#include <storage/boot_storage.h>
|
||||
#include "../config.h"
|
||||
|
||||
u8 *cal0_buf = NULL;
|
||||
@@ -208,7 +209,7 @@ static void _hos_eks_get()
|
||||
|
||||
// Decrypt EKS blob.
|
||||
hos_eks_mbr_t *eks = (hos_eks_mbr_t *)(mbr + 0x80);
|
||||
se_aes_crypt_ecb(14, DECRYPT, eks, eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, DECRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Check if valid and for this unit.
|
||||
if (eks->magic == HOS_EKS_MAGIC && eks->lot0 == FUSE(FUSE_OPT_LOT_CODE_0))
|
||||
@@ -254,7 +255,7 @@ static void _hos_eks_save()
|
||||
|
||||
// Get keys.
|
||||
u8 *keys = (u8 *)zalloc(SZ_8K);
|
||||
se_aes_ctx_get_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
|
||||
se_get_aes_keys(keys + SZ_4K, keys, SE_KEY_128_SIZE);
|
||||
|
||||
// Set magic and personalized info.
|
||||
h_cfg.eks->magic = HOS_EKS_MAGIC;
|
||||
@@ -269,7 +270,7 @@ static void _hos_eks_save()
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = malloc(sizeof(hos_eks_mbr_t));
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
@@ -304,7 +305,7 @@ void hos_eks_clear(u32 mkey)
|
||||
// Encrypt EKS blob.
|
||||
u8 *eks = malloc(sizeof(hos_eks_mbr_t));
|
||||
memcpy(eks, h_cfg.eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, eks, sizeof(hos_eks_mbr_t));
|
||||
se_aes_crypt_ecb(14, ENCRYPT, eks, sizeof(hos_eks_mbr_t), eks, sizeof(hos_eks_mbr_t));
|
||||
|
||||
// Write EKS blob to SD.
|
||||
memcpy(mbr + 0x80, eks, sizeof(hos_eks_mbr_t));
|
||||
@@ -381,7 +382,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt)
|
||||
*/
|
||||
|
||||
// Use custom TSEC Hovi Keygen firmware.
|
||||
tsec_ctxt->fw = sd_file_read("bootloader/sys/thk.bin", NULL);
|
||||
tsec_ctxt->fw = boot_storage_file_read("bootloader/sys/thk.bin", NULL);
|
||||
if (!tsec_ctxt->fw)
|
||||
{
|
||||
EPRINTF("\nFailed to load thk.bin");
|
||||
@@ -423,7 +424,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt)
|
||||
}
|
||||
|
||||
// Decrypt eks and set keyslots.
|
||||
se_aes_crypt_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0]);
|
||||
se_aes_unwrap_key(15, 14, tsec_keys.tmp);
|
||||
|
||||
// Derive device keys.
|
||||
@@ -447,7 +448,7 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt)
|
||||
se_aes_key_set(13, tsec_keys.tsec_root, SE_KEY_128_SIZE);
|
||||
|
||||
// Decrypt eks and set keyslots.
|
||||
se_aes_crypt_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tmp, eks_keyseeds[0]);
|
||||
se_aes_unwrap_key(15, 14, tsec_keys.tmp);
|
||||
|
||||
// Derive device keys.
|
||||
@@ -469,30 +470,30 @@ int hos_keygen(pkg1_eks_t *eks, u32 mkey, tsec_ctxt_t *tsec_ctxt)
|
||||
se_aes_key_set(13, tsec_keys.tsec, SE_KEY_128_SIZE);
|
||||
|
||||
// Derive eks keys from TSEC+SBK.
|
||||
se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[0], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[0]);
|
||||
se_aes_unwrap_key(15, 14, tsec_keys.tsec);
|
||||
se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[mkey], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, eks_keyseeds[mkey]);
|
||||
se_aes_unwrap_key(13, 14, tsec_keys.tsec);
|
||||
|
||||
/*
|
||||
// Verify eks CMAC.
|
||||
u8 cmac[SE_KEY_128_SIZE];
|
||||
se_aes_unwrap_key(11, 13, cmac_keyseed);
|
||||
se_aes_hash_cmac(cmac, SE_KEY_128_SIZE, 11, (void *)eks->ctr, sizeof(eks->ctr) + sizeof(eks->keys));
|
||||
se_aes_cmac(cmac, SE_KEY_128_SIZE, 11, (void *)eks->ctr, sizeof(eks->ctr) + sizeof(eks->keys));
|
||||
if (!memcmp(eks->cmac, cmac, SE_KEY_128_SIZE))
|
||||
return 0;
|
||||
*/
|
||||
|
||||
se_aes_crypt_ecb(13, DECRYPT, tsec_keys.tsec, cmac_keyseed, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(13, DECRYPT, tsec_keys.tsec, cmac_keyseed);
|
||||
se_aes_unwrap_key(11, 13, cmac_keyseed);
|
||||
|
||||
// Decrypt eks and set keyslots.
|
||||
se_aes_crypt_ctr(13, &eks->keys, &eks->keys, sizeof(eks_keys_t), eks->ctr);
|
||||
se_aes_crypt_ctr(13, &eks->keys, sizeof(eks_keys_t), &eks->keys, sizeof(eks_keys_t), eks->ctr);
|
||||
se_aes_key_set(11, eks->keys.package1_key, SE_KEY_128_SIZE);
|
||||
se_aes_key_set(12, eks->keys.master_kekseed, SE_KEY_128_SIZE);
|
||||
se_aes_key_set(13, eks->keys.master_kekseed, SE_KEY_128_SIZE);
|
||||
|
||||
se_aes_crypt_ecb(12, DECRYPT, tsec_keys.tsec, master_keyseed_retail, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(12, DECRYPT, tsec_keys.tsec, master_keyseed_retail);
|
||||
|
||||
switch (mkey)
|
||||
{
|
||||
@@ -531,11 +532,12 @@ static void _hos_validate_mkey()
|
||||
do
|
||||
{
|
||||
mkey_idx--;
|
||||
se_aes_crypt_ecb(7, DECRYPT, tmp_mkey, mkey_vectors[mkey_idx], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(7, DECRYPT, tmp_mkey, SE_KEY_128_SIZE, mkey_vectors[mkey_idx], SE_KEY_128_SIZE);
|
||||
for (u32 idx = 0; idx < mkey_idx; idx++)
|
||||
{
|
||||
se_aes_key_clear(2);
|
||||
se_aes_key_set(2, tmp_mkey, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(2, DECRYPT, tmp_mkey, mkey_vectors[mkey_idx - 1 - idx], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(2, DECRYPT, tmp_mkey, SE_KEY_128_SIZE, mkey_vectors[mkey_idx - 1 - idx], SE_KEY_128_SIZE);
|
||||
}
|
||||
|
||||
if (!memcmp(tmp_mkey, "\x00\x00\x00\x00\x00\x00\x00\x00", 8))
|
||||
@@ -592,17 +594,19 @@ int hos_bis_keygen()
|
||||
do
|
||||
{
|
||||
mkey_idx--;
|
||||
se_aes_crypt_ecb(7, DECRYPT, tmp_mkey, mkey_vectors[mkey_idx], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(7, DECRYPT, tmp_mkey, SE_KEY_128_SIZE, mkey_vectors[mkey_idx], SE_KEY_128_SIZE);
|
||||
for (u32 idx = 0; idx < mkey_idx; idx++)
|
||||
{
|
||||
se_aes_key_clear(2);
|
||||
se_aes_key_set(2, tmp_mkey, SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(2, DECRYPT, tmp_mkey, mkey_vectors[mkey_idx - 1 - idx], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(2, DECRYPT, tmp_mkey, SE_KEY_128_SIZE, mkey_vectors[mkey_idx - 1 - idx], SE_KEY_128_SIZE);
|
||||
}
|
||||
} while (memcmp(tmp_mkey, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0 && (mkey_idx - 1));
|
||||
|
||||
// Derive new device key.
|
||||
se_aes_key_clear(1);
|
||||
se_aes_unwrap_key(1, 10, new_console_keyseed[keygen_rev]); // Uses Device key 4x.
|
||||
se_aes_crypt_ecb(10, DECRYPT, tmp_mkey, new_console_keyseed[keygen_rev], SE_KEY_128_SIZE); // Uses Device key 4x.
|
||||
se_aes_crypt_ecb(10, DECRYPT, tmp_mkey, SE_KEY_128_SIZE, new_console_keyseed[keygen_rev], SE_KEY_128_SIZE); // Uses Device key 4x.
|
||||
se_aes_unwrap_key(1, 2, new_console_kekseed[keygen_rev]); // Uses Master Key 0.
|
||||
se_aes_unwrap_key(1, 1, tmp_mkey);
|
||||
|
||||
@@ -610,27 +614,29 @@ int hos_bis_keygen()
|
||||
}
|
||||
|
||||
// Generate generic key.
|
||||
se_aes_key_clear(2);
|
||||
se_aes_unwrap_key(2, console_key_slot, gen_keyseed_retail);
|
||||
|
||||
// Clear bis keys storage.
|
||||
memset(bis_keys, 0, SE_KEY_128_SIZE * 6);
|
||||
|
||||
// Generate BIS 0 Keys.
|
||||
se_aes_crypt_ecb(2, DECRYPT, bis_keys + (0 * SE_KEY_128_SIZE), bis_keyseed[0], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(2, DECRYPT, bis_keys + (1 * SE_KEY_128_SIZE), bis_keyseed[1], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(2, DECRYPT, bis_keys + (0 * SE_KEY_128_SIZE), bis_keyseed[0]);
|
||||
se_aes_crypt_block_ecb(2, DECRYPT, bis_keys + (1 * SE_KEY_128_SIZE), bis_keyseed[1]);
|
||||
|
||||
// Generate generic kek.
|
||||
se_aes_key_clear(2);
|
||||
se_aes_unwrap_key(2, console_key_slot, gen_kekseed);
|
||||
se_aes_unwrap_key(2, 2, bis_kekseed);
|
||||
se_aes_unwrap_key(2, 2, gen_keyseed);
|
||||
|
||||
// Generate BIS 1 Keys.
|
||||
se_aes_crypt_ecb(2, DECRYPT, bis_keys + (2 * SE_KEY_128_SIZE), bis_keyseed[2], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(2, DECRYPT, bis_keys + (3 * SE_KEY_128_SIZE), bis_keyseed[3], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(2, DECRYPT, bis_keys + (2 * SE_KEY_128_SIZE), bis_keyseed[2]);
|
||||
se_aes_crypt_block_ecb(2, DECRYPT, bis_keys + (3 * SE_KEY_128_SIZE), bis_keyseed[3]);
|
||||
|
||||
// Generate BIS 2/3 Keys.
|
||||
se_aes_crypt_ecb(2, DECRYPT, bis_keys + (4 * SE_KEY_128_SIZE), bis_keyseed[4], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_ecb(2, DECRYPT, bis_keys + (5 * SE_KEY_128_SIZE), bis_keyseed[5], SE_KEY_128_SIZE);
|
||||
se_aes_crypt_block_ecb(2, DECRYPT, bis_keys + (4 * SE_KEY_128_SIZE), bis_keyseed[4]);
|
||||
se_aes_crypt_block_ecb(2, DECRYPT, bis_keys + (5 * SE_KEY_128_SIZE), bis_keyseed[5]);
|
||||
|
||||
// Validate key because HOS_MKEY_VER_MAX.
|
||||
if (!h_cfg.t210b01)
|
||||
@@ -682,7 +688,7 @@ int hos_dump_cal0()
|
||||
LIST_INIT(gpt);
|
||||
emmc_gpt_parse(&gpt);
|
||||
emmc_part_t *cal0_part = emmc_part_find(&gpt, "PRODINFO"); // check if null
|
||||
nx_emmc_bis_init(cal0_part, false, 0);
|
||||
nx_emmc_bis_init(cal0_part, false, NULL, 0);
|
||||
nx_emmc_bis_read(0, 0x40, cal0_buf);
|
||||
nx_emmc_bis_end();
|
||||
emmc_gpt_free(&gpt);
|
||||
@@ -707,7 +713,7 @@ int hos_dump_cal0()
|
||||
}
|
||||
|
||||
u32 hash[8];
|
||||
se_sha_hash_256_oneshot(hash, (u8 *)&cal0->cfg_id1, cal0->body_size);
|
||||
se_calc_sha256_oneshot(hash, (u8 *)&cal0->cfg_id1, cal0->body_size);
|
||||
if (memcmp(hash, cal0->body_sha256, 0x20))
|
||||
return 3;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user