From a71d98d78b48b0e2e328218bcddfef581bfbcdd5 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 25 Nov 2018 17:11:21 -0800 Subject: [PATCH] exosphere: Implement optional 6.2.0+ keygen --- exosphere/src/exocfg.c | 2 +- exosphere/src/exocfg.h | 2 +- exosphere/src/package2.c | 60 ++++++++++++++++++++++++++++++++++------ exosphere/src/se.h | 5 ++++ 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/exosphere/src/exocfg.c b/exosphere/src/exocfg.c index 4fbe8996e..10bc3ae64 100644 --- a/exosphere/src/exocfg.c +++ b/exosphere/src/exocfg.c @@ -60,7 +60,7 @@ unsigned int exosphere_get_target_firmware(void) { return g_exosphere_cfg.target_firmware; } -unsigned int exosphere_get_should_perform_620_keygen(void) { +unsigned int exosphere_should_perform_620_keygen(void) { if (!g_has_loaded_config) { generic_panic(); } diff --git a/exosphere/src/exocfg.h b/exosphere/src/exocfg.h index 2a1dc810d..286825965 100644 --- a/exosphere/src/exocfg.h +++ b/exosphere/src/exocfg.h @@ -59,7 +59,7 @@ typedef struct { unsigned int exosphere_load_config(void); unsigned int exosphere_get_target_firmware(void); -unsigned int exosphere_get_should_perform_620_keygen(void); +unsigned int exosphere_should_perform_620_keygen(void); static inline unsigned int exosphere_get_target_firmware_for_init(void) { const unsigned int magic = MAILBOX_EXOSPHERE_CONFIG_PHYS.magic; diff --git a/exosphere/src/package2.c b/exosphere/src/package2.c index 94fa821d5..c6ef81dc2 100644 --- a/exosphere/src/package2.c +++ b/exosphere/src/package2.c @@ -38,21 +38,48 @@ extern void *__start_cold_addr; extern size_t __bin_size; static const uint8_t new_device_key_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = { - {0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */ - {0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */ - {0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4} /* 6.x New Device Key Source. */ + {0x8B, 0x4E, 0x1C, 0x22, 0x42, 0x07, 0xC8, 0x73, 0x56, 0x94, 0x08, 0x8B, 0xCC, 0x47, 0x0F, 0x5D}, /* 4.x New Device Key Source. */ + {0x6C, 0xEF, 0xC6, 0x27, 0x8B, 0xEC, 0x8A, 0x91, 0x99, 0xAB, 0x24, 0xAC, 0x4F, 0x1C, 0x8F, 0x1C}, /* 5.x New Device Key Source. */ + {0x70, 0x08, 0x1B, 0x97, 0x44, 0x64, 0xF8, 0x91, 0x54, 0x9D, 0xC6, 0x84, 0x8F, 0x1A, 0xB2, 0xE4}, /* 6.x New Device Key Source. */ + {0x8E, 0x09, 0x1F, 0x7A, 0xBB, 0xCA, 0x6A, 0xFB, 0xB8, 0x9B, 0xD5, 0xC1, 0x25, 0x9C, 0xA9, 0x17} /* 6.2.0 New Device Key Source. */ }; static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = { - {0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.x New Device Keygen Source. */ - {0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E}, /* 5.x New Device Keygen Source. */ - {0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF} /* 6.x New Device Keygen Source. */ + {0x88, 0x62, 0x34, 0x6E, 0xFA, 0xF7, 0xD8, 0x3F, 0xE1, 0x30, 0x39, 0x50, 0xF0, 0xB7, 0x5D, 0x5D}, /* 4.x New Device Keygen Source. */ + {0x06, 0x1E, 0x7B, 0xE9, 0x6D, 0x47, 0x8C, 0x77, 0xC5, 0xC8, 0xE7, 0x94, 0x9A, 0xA8, 0x5F, 0x2E}, /* 5.x New Device Keygen Source. */ + {0x99, 0xFA, 0x98, 0xBD, 0x15, 0x1C, 0x72, 0xFD, 0x7D, 0x9A, 0xD5, 0x41, 0x00, 0xFD, 0xB2, 0xEF}, /* 6.x New Device Keygen Source. */ + {0x81, 0x3C, 0x6C, 0xBF, 0x5D, 0x21, 0xDE, 0x77, 0x20, 0xD9, 0x6C, 0xE3, 0x22, 0x06, 0xAE, 0xBB} /* 6.2.0 New Device Keygen Source. */ }; static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = { - {0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34}, /* 4.x New Device Keygen Source. */ - {0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8}, /* 5.x New Device Keygen Source. */ - {0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5} /* 6.x New Device Keygen Source. */ + {0xD6, 0xBD, 0x9F, 0xC6, 0x18, 0x09, 0xE1, 0x96, 0x20, 0x39, 0x60, 0xD2, 0x89, 0x83, 0x31, 0x34}, /* 4.x New Device Keygen Source. */ + {0x59, 0x2D, 0x20, 0x69, 0x33, 0xB5, 0x17, 0xBA, 0xCF, 0xB1, 0x4E, 0xFD, 0xE4, 0xC2, 0x7B, 0xA8}, /* 5.x New Device Keygen Source. */ + {0xF6, 0xD8, 0x59, 0x63, 0x8F, 0x47, 0xCB, 0x4A, 0xD8, 0x74, 0x05, 0x7F, 0x88, 0x92, 0x33, 0xA5}, /* 6.x New Device Keygen Source. */ + {0x20, 0xAB, 0xF2, 0x0F, 0x05, 0xE3, 0xDE, 0x2E, 0xA1, 0xFB, 0x37, 0x5E, 0x8B, 0x22, 0x1A, 0x38} /* 6.2.0 New Device Keygen Source. */ +}; + +static const uint8_t new_master_kek_sources[1][0x10] = { + {0x37, 0x4B, 0x77, 0x29, 0x59, 0xB4, 0x04, 0x30, 0x81, 0xF6, 0xE5, 0x8C, 0x6D, 0x36, 0x17, 0x9A}, /* 6.2.0 Master Kek Source. */ +}; + +static const uint8_t keyblob_key_seed_00[0x10] = { + 0xDF, 0x20, 0x6F, 0x59, 0x44, 0x54, 0xEF, 0xDC, 0x70, 0x74, 0x48, 0x3B, 0x0D, 0xED, 0x9F, 0xD3 +}; + +static const uint8_t devicekey_seed[0x10] = { + 0x4F, 0x02, 0x5F, 0x0E, 0xB6, 0x6D, 0x11, 0x0E, 0xDC, 0x32, 0x7D, 0x41, 0x86, 0xC2, 0xF4, 0x78 +}; + +static const uint8_t devicekey_4x_seed[0x10] = { + 0x0C, 0x91, 0x09, 0xDB, 0x93, 0x93, 0x07, 0x81, 0x07, 0x3C, 0xC4, 0x16, 0x22, 0x7C, 0x6C, 0x28 +}; + +static const uint8_t masterkey_seed[0x10] = { + 0xD8, 0xA2, 0x41, 0x0A, 0xC6, 0xC5, 0x90, 0x01, 0xC6, 0x1D, 0x6A, 0x26, 0x7C, 0x51, 0x3F, 0x3C +}; + +static const uint8_t devicekek_4x_seed[0x10] = { + 0x2D, 0xC1, 0xF4, 0x8D, 0xF3, 0x5B, 0x69, 0x33, 0x42, 0x10, 0xAC, 0x65, 0xDA, 0x90, 0x46, 0x66 }; static void derive_new_device_keys(unsigned int keygen_keyslot) { @@ -105,6 +132,20 @@ static void setup_se(void) { for (unsigned int i = 0; i < KEYSLOT_RSA_MAX; i++) { set_rsa_keyslot_flags(i, 0x41); } + + if (exosphere_get_target_firmware() >= EXOSPHERE_TARGET_FIRMWARE_620 && exosphere_should_perform_620_keygen()) { + /* Start by generating device keys. */ + se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_6XTSECKEY, work_buffer, 0x10, keyblob_key_seed_00, 0x10); + decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_6XSBK, work_buffer, 0x10); + decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XNEWCONSOLEKEYGENKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_4x_seed, 0x10); + decrypt_data_into_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, KEYSLOT_SWITCH_4XOLDDEVICEKEY, devicekey_seed, 0x10); + + /* Next, generate the master kek, and from there master key/device kek. We use different keyslots than Nintendo, here. */ + decrypt_data_into_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, new_master_kek_sources[0], 0x10); + decrypt_data_into_keyslot(KEYSLOT_SWITCH_MASTERKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, masterkey_seed, 0x10); + decrypt_data_into_keyslot(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, KEYSLOT_SWITCH_6XTSECROOTKEY, devicekek_4x_seed, 0x10); + clear_aes_keyslot(KEYSLOT_SWITCH_6XTSECROOTKEY); + } /* Detect Master Key revision. */ mkey_detect_revision(); @@ -120,6 +161,7 @@ static void setup_se(void) { break; case EXOSPHERE_TARGET_FIRMWARE_500: case EXOSPHERE_TARGET_FIRMWARE_600: + case EXOSPHERE_TARGET_FIRMWARE_620: derive_new_device_keys(KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY); break; } diff --git a/exosphere/src/se.h b/exosphere/src/se.h index 54768d620..61c8973fa 100644 --- a/exosphere/src/se.h +++ b/exosphere/src/se.h @@ -43,6 +43,11 @@ /* This keyslot was added in 5.0.0. */ #define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA +/* This keyslot was added in 6.00. */ +#define KEYSLOT_SWITCH_6XTSECKEY 0xC +#define KEYSLOT_SWITCH_6XTSECROOTKEY 0xD +#define KEYSLOT_SWITCH_6XSBK 0xE + #define KEYSLOT_AES_MAX 0x10 #define KEYSLOT_RSA_MAX 0x2