From a968d0be322784696c1726b1992650089a125b98 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 31 Dec 2020 23:29:00 -0800 Subject: [PATCH] fusee: fix support for mariko key derivation/package1 parsing --- fusee/fusee-secondary/src/fuse.c | 30 +++--- fusee/fusee-secondary/src/key_derivation.c | 13 +-- fusee/fusee-secondary/src/masterkey.c | 20 ++-- fusee/fusee-secondary/src/nxboot.c | 8 +- fusee/fusee-secondary/src/package1.c | 101 ++++++++++++++++++++- fusee/fusee-secondary/src/package1.h | 15 ++- fusee/fusee-secondary/src/se.c | 14 +++ fusee/fusee-secondary/src/se.h | 5 + 8 files changed, 165 insertions(+), 41 deletions(-) diff --git a/fusee/fusee-secondary/src/fuse.c b/fusee/fusee-secondary/src/fuse.c index a1de8fb14..9a64ce0be 100644 --- a/fusee/fusee-secondary/src/fuse.c +++ b/fusee/fusee-secondary/src/fuse.c @@ -305,21 +305,6 @@ void fuse_get_hardware_info(void *dst) { memcpy(dst, hw_info, 0x10); } - -/* Check if have a new ODM fuse format. */ -bool fuse_is_new_format(void) { - return ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2)); -} - -/* Get the DeviceUniqueKeyGeneration. */ -uint32_t fuse_get_device_unique_key_generation(void) { - if (fuse_is_new_format()) { - return (fuse_get_reserved_odm(2) & 0x1F); - } else { - return 0; - } -} - /* Get the SocType from the HardwareType. */ uint32_t fuse_get_soc_type(void) { switch (fuse_get_hardware_type()) { @@ -336,6 +321,21 @@ uint32_t fuse_get_soc_type(void) { } } +/* Check if have a new ODM fuse format. */ +bool fuse_is_new_format(void) { + return ((fuse_get_reserved_odm(4) & 0x800) && (fuse_get_reserved_odm(0) == 0x8E61ECAE) && (fuse_get_reserved_odm(1) == 0xF2BA3BB2)); +} + +/* Get the DeviceUniqueKeyGeneration. */ +uint32_t fuse_get_device_unique_key_generation(void) { + if (fuse_get_soc_type() != 0 || fuse_is_new_format()) { + return (fuse_get_reserved_odm(2) & 0x1F); + } else { + return 0; + } +} + + /* Get the Regulator type. */ uint32_t fuse_get_regulator(void) { if (fuse_get_soc_type() == 1) { diff --git a/fusee/fusee-secondary/src/key_derivation.c b/fusee/fusee-secondary/src/key_derivation.c index 42d96bc54..8996f2da8 100644 --- a/fusee/fusee-secondary/src/key_derivation.c +++ b/fusee/fusee-secondary/src/key_derivation.c @@ -61,13 +61,8 @@ static const uint8_t AL16 new_master_kek_seeds[MASTERKEY_REVISION_700_800 - MAST {0x9A, 0x3E, 0xA9, 0xAB, 0xFD, 0x56, 0x46, 0x1C, 0x9B, 0xF6, 0x48, 0x7F, 0x5C, 0xFA, 0x09, 0x5C}, /* MasterKek seed 07. */ }; -static const uint8_t AL16 master_kek_seeds_mariko[MASTERKEY_REVISION_910_CURRENT - MASTERKEY_REVISION_500_510][0x10] = { - {0x77, 0x60, 0x5A, 0xD2, 0xEE, 0x6E, 0xF8, 0x3C, 0x3F, 0x72, 0xE2, 0x59, 0x9D, 0xAC, 0x5E, 0x56}, /* Mariko MasterKek seed 05. */ - {0x1E, 0x80, 0xB8, 0x17, 0x3E, 0xC0, 0x60, 0xAA, 0x11, 0xBE, 0x1A, 0x4A, 0xA6, 0x6F, 0xE4, 0xAE}, /* Mariko MasterKek seed 06. */ - {0x94, 0x08, 0x67, 0xBD, 0x0A, 0x00, 0x38, 0x84, 0x11, 0xD3, 0x1A, 0xDB, 0xDD, 0x8D, 0xF1, 0x8A}, /* Mariko MasterKek seed 07. */ - {0x5C, 0x24, 0xE3, 0xB8, 0xB4, 0xF7, 0x00, 0xC2, 0x3C, 0xFD, 0x0A, 0xCE, 0x13, 0xC3, 0xDC, 0x23}, /* Mariko MasterKek seed 08. */ - {0x86, 0x69, 0xF0, 0x09, 0x87, 0xC8, 0x05, 0xAE, 0xB5, 0x7B, 0x48, 0x74, 0xDE, 0x62, 0xA6, 0x13}, /* Mariko MasterKek seed 09. */ - {0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82}, /* Mariko MasterKek seed 0A. */ +static const uint8_t AL16 master_kek_seed_mariko[0x10] = { /* TODO: Update on next change of keys. */ + 0x0E, 0x44, 0x0C, 0xED, 0xB4, 0x36, 0xC0, 0x3F, 0xAA, 0x1D, 0xAE, 0xBF, 0x62, 0xB1, 0x09, 0x82, /* Mariko MasterKek seed 0A. */ }; static nx_dec_keyblob_t AL16 g_dec_keyblobs[32]; @@ -227,7 +222,7 @@ int derive_nx_keydata_mariko(uint32_t target_firmware) { /* Derive the device and master keys. */ /* NOTE: Keyslots 7 and 10 are chosen here so we don't overwrite critical key material (KEK, BEK, SBK and SSK). */ decrypt_data_into_keyslot(0xA, 0xE, devicekey_4x_seed, 0x10); - decrypt_data_into_keyslot(0x7, 0xC, &master_kek_seeds_mariko[target_firmware - MASTERKEY_REVISION_600_610], 0x10); + decrypt_data_into_keyslot(0x7, 0xC, master_kek_seed_mariko, 0x10); decrypt_data_into_keyslot(0x7, 0x7, masterkey_seed, 0x10); /* Setup master key revision, derive older master keys for use. */ @@ -237,7 +232,7 @@ int derive_nx_keydata_mariko(uint32_t target_firmware) { static void generate_specific_aes_key(void *dst, const void *wrapped_key, bool should_mask, uint32_t target_firmware, uint32_t generation) { unsigned int keyslot = devkey_get_keyslot(generation); - if (fuse_get_bootrom_patch_version() < 0x7F) { + if (fuse_get_soc_type() == 0 && fuse_get_bootrom_patch_version() < 0x7F) { /* On dev units, use a fixed "all-zeroes" seed. */ /* Yes, this data really is all-zero in actual TrustZone .rodata. */ static const uint8_t AL16 dev_specific_aes_key_source[0x10] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/fusee/fusee-secondary/src/masterkey.c b/fusee/fusee-secondary/src/masterkey.c index 8040f8a07..94a1c8b4e 100644 --- a/fusee/fusee-secondary/src/masterkey.c +++ b/fusee/fusee-secondary/src/masterkey.c @@ -80,7 +80,7 @@ static const uint8_t new_device_keygen_sources[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x {0x86, 0x61, 0xB0, 0x16, 0xFA, 0x7A, 0x9A, 0xEA, 0xF6, 0xF5, 0xBE, 0x1A, 0x13, 0x5B, 0x6D, 0x9E}, /* 7.0.0 New Device Keygen Source. */ {0xA6, 0x81, 0x71, 0xE7, 0xB5, 0x23, 0x74, 0xB0, 0x39, 0x8C, 0xB7, 0xFF, 0xA0, 0x62, 0x9F, 0x8D}, /* 8.1.0 New Device Keygen Source. */ {0x03, 0xE7, 0xEB, 0x43, 0x1B, 0xCF, 0x5F, 0xB5, 0xED, 0xDC, 0x97, 0xAE, 0x21, 0x8D, 0x19, 0xED}, /* 9.0.0 New Device Keygen Source. */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 9.1.0 New Device Keygen Source to be added on next change-of-keys. */ + {0xCE, 0xFE, 0x41, 0x0F, 0x46, 0x9A, 0x30, 0xD6, 0xF2, 0xE9, 0x0C, 0x6B, 0xB7, 0x15, 0x91, 0x36}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */ }; static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS][0x10] = { @@ -91,7 +91,7 @@ static const uint8_t new_device_keygen_sources_dev[MASTERKEY_NUM_NEW_DEVICE_KEYS {0x60, 0xAE, 0x56, 0x68, 0x11, 0xE2, 0x0C, 0x99, 0xDE, 0x05, 0xAE, 0x68, 0x78, 0x85, 0x04, 0xAE}, /* 7.0.0 New Device Keygen Source. */ {0x94, 0xD6, 0xA8, 0xC0, 0x95, 0xAF, 0xD0, 0xA6, 0x27, 0x53, 0x5E, 0xE5, 0x8E, 0x70, 0x1F, 0x87}, /* 8.1.0 New Device Keygen Source. */ {0x61, 0x6A, 0x88, 0x21, 0xA3, 0x52, 0xB0, 0x19, 0x16, 0x25, 0xA4, 0xE3, 0x4C, 0x54, 0x02, 0x0F}, /* 9.0.0 New Device Keygen Source. */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* TODO: 9.1.0 New Device Keygen Source to be added on next change-of-keys. */ + {0x9D, 0xB1, 0xAE, 0xCB, 0xF6, 0xF6, 0xE3, 0xFE, 0xAB, 0x6F, 0xCB, 0xAF, 0x38, 0x03, 0xFC, 0x7B}, /* 9.1.0 New Device Keygen Source to be added on next change-of-keys. */ }; /* Determine the current SoC for Mariko specific code. */ @@ -158,7 +158,7 @@ unsigned int mkey_get_keyslot(unsigned int revision) { if (revision > g_mkey_revision) { generic_panic(); } - + if (revision == g_mkey_revision) { return (is_soc_mariko() ? KEYSLOT_SWITCH_MASTERKEY_MARIKO : KEYSLOT_SWITCH_MASTERKEY); } else { @@ -169,6 +169,8 @@ unsigned int mkey_get_keyslot(unsigned int revision) { } void derive_new_device_keys(bool is_retail, unsigned int keygen_keyslot, unsigned int target_firmware) { + const bool is_mariko = is_soc_mariko(); + uint8_t work_buffer[0x10]; for (unsigned int revision = 0; revision < MASTERKEY_NUM_NEW_DEVICE_KEYS; revision++) { const unsigned int relative_revision = revision + MASTERKEY_REVISION_400_410; @@ -178,13 +180,17 @@ void derive_new_device_keys(bool is_retail, unsigned int keygen_keyslot, unsigne if (relative_revision > mkey_get_revision()) { break; } else if (relative_revision == mkey_get_revision()) { - /* On 7.0.0, sept will have derived this key for us already. */ - if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0) { - decrypt_data_into_keyslot(KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10); + /* On 7.0.0 erista, sept will have derived this key for us already. */ + if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_7_0_0 || is_mariko) { + decrypt_data_into_keyslot(is_mariko ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY, KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10); } } else { se_aes_ecb_decrypt_block(KEYSLOT_SWITCH_TEMPKEY, work_buffer, 0x10, work_buffer, 0x10); set_old_devkey(relative_revision, work_buffer); + + if (revision == 0 && is_mariko) { + set_aes_keyslot(KEYSLOT_SWITCH_4XOLDDEVICEKEY, work_buffer, 0x10); + } } } } @@ -209,6 +215,6 @@ unsigned int devkey_get_keyslot(unsigned int revision) { set_aes_keyslot(KEYSLOT_SWITCH_TEMPKEY, g_old_devicekeys[revision - MASTERKEY_REVISION_400_410], 0x10); return KEYSLOT_SWITCH_TEMPKEY; } else { - return KEYSLOT_SWITCH_DEVICEKEY; + return is_soc_mariko() ? KEYSLOT_SWITCH_DEVICEKEY_MARIKO : KEYSLOT_SWITCH_DEVICEKEY; } } diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 4f7681c65..260d79454 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -907,9 +907,7 @@ uint32_t nxboot_main(void) { } /* Derive new device keys. */ - if (!is_mariko) { - derive_new_device_keys(fuse_get_hardware_state() != 0, KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, target_firmware); - } + derive_new_device_keys(fuse_get_hardware_state() != 0, KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY, target_firmware); /* Set the system partition's keys. */ if (fsdev_register_keys("system", target_firmware, BisPartition_UserSystem) != 0) { @@ -1001,7 +999,7 @@ uint32_t nxboot_main(void) { /* Copy the warmboot firmware and set the address in PMC if necessary. */ if (warmboot_fw && (warmboot_fw_size > 0)) { memcpy(warmboot_memaddr, warmboot_fw, warmboot_fw_size); - if (!is_mariko && (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0)) { + if (!is_mariko && (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_4_0_0)) { pmc->scratch1 = (uint32_t)warmboot_memaddr; } } @@ -1011,7 +1009,7 @@ uint32_t nxboot_main(void) { /* TODO */ } else { /* Set 3.0.0/3.0.1/3.0.2 warmboot security check. */ - if (MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware == ATMOSPHERE_TARGET_FIRMWARE_3_0_0) { + if (target_firmware == ATMOSPHERE_TARGET_FIRMWARE_3_0_0) { const package1loader_header_t *package1loader_header = (const package1loader_header_t *)package1loader; if (!strcmp(package1loader_header->build_timestamp, "20170519101410")) { pmc->secure_scratch32 = 0xE3; /* Warmboot 3.0.0 security check.*/ diff --git a/fusee/fusee-secondary/src/package1.c b/fusee/fusee-secondary/src/package1.c index 6b890d50e..80129ccd1 100644 --- a/fusee/fusee-secondary/src/package1.c +++ b/fusee/fusee-secondary/src/package1.c @@ -13,15 +13,43 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include #include #include +#include "../../../fusee/common/log.h" #include "package1.h" #include "bct.h" #include "se.h" +static const uint8_t custom_public_key[0x100] = { + 0x59, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, + 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0xFF, +}; + +static bool is_custom_public_key_erista(const void *bct) { + return memcmp((const uint8_t *)bct + 0x210, custom_public_key, sizeof(custom_public_key)) == 0; +} + +//static bool is_custom_public_key_mariko(const void *bct) { +// return memcmp((const uint8_t *)bct + 0x10, custom_public_key, sizeof(custom_public_key)) == 0; +//} + int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0) { nvboot_config_table *bct; /* Normal firmware BCT, primary. TODO: check? */ nv_bootloader_info *pk1l_info; /* TODO: check? */ @@ -50,6 +78,19 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1 free(bct); return -1; } + + /* If custom public key, use bct-2 instead of bct 0. */ + if (is_custom_public_key_erista(bct)) { + if (fseek(boot0, fpos + 0x4000 * 2, SEEK_SET) != 0) { + free(bct); + return -1; + } + if (fread(bct, sizeof(nvboot_config_table), 1, boot0) == 0) { + free(bct); + return -1; + } + } + if (bct->bootloader_used < 1 || pk1l_info->version < 1) { free(bct); errno = EILSEQ; @@ -91,7 +132,59 @@ int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1 } int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, FILE *boot0) { - /* TODO */ + /* TODO: Actually parse BOOT0 to locate package1ldr. */ + size_t fpos, pk1l_offset; + + fpos = ftell(boot0); + pk1l_offset = 0x100000; + + /* Read the OEM header. */ + pk11_mariko_oem_header_t oem_header; + if (fseek(boot0, fpos + pk1l_offset, SEEK_SET) != 0) { + return -1; + } + if (fread(&oem_header, sizeof(oem_header), 1, boot0) == 0) { + return -1; + } + + /* Sanity check the size. */ + if (oem_header.bl_size < 2 * sizeof(package1loader_header_t)) { + return -1; + } + + /* Set the size. */ + *package1loader_size = oem_header.bl_size; + + /* Allocate pk11. */ + (*package1loader) = memalign(0x10000, *package1loader_size); + + if (*package1loader == NULL) { + errno = ENOMEM; + return -1; + } + + /* Read pk11. */ + if (fread(*package1loader, *package1loader_size, 1, boot0) == 0) { + return -1; + } + + /* Copy the plaintext header. */ + package1loader_header_t dec_header; + memcpy(&dec_header, *package1loader, sizeof(dec_header)); + + /* Decrypt the binary. */ + const uint8_t __attribute__((aligned(16))) iv[16] = {0}; + se_aes_128_cbc_decrypt(KEYSLOT_SWITCH_BEK_MARIKO, *package1loader, *package1loader_size, *package1loader, *package1loader_size, iv); + + /* Validate the decryption. */ + if (memcmp(&dec_header, (const uint8_t *)*package1loader + sizeof(dec_header), sizeof(dec_header)) != 0) { + print(SCREEN_LOG_LEVEL_DEBUG, "Decrypted package1loader is invalid...\n"); + return -1; + } + + /* Copy out the first header. */ + memcpy(*package1loader, &dec_header, sizeof(dec_header)); + return 0; } @@ -106,7 +199,7 @@ bool package1_get_tsec_fw(void **tsec_fw, const void *package1loader, size_t pac return true; } } - + return false; } @@ -129,7 +222,7 @@ bool package1_decrypt(package1_header_t *package1, size_t package1_size, const u } void *package1_get_warmboot_fw(const package1_header_t *package1) { - /* + /* The layout of pk1 changes between versions. However, the secmon always starts by this erratum code: diff --git a/fusee/fusee-secondary/src/package1.h b/fusee/fusee-secondary/src/package1.h index 39da2f099..0557d5ddc 100644 --- a/fusee/fusee-secondary/src/package1.h +++ b/fusee/fusee-secondary/src/package1.h @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #ifndef FUSEE_PACKAGE1_H #define FUSEE_PACKAGE1_H @@ -44,6 +44,19 @@ typedef struct { uint8_t data[]; } package1_header_t; +typedef struct { + uint8_t aes_mac[0x10]; + uint8_t rsa_sig[0x100]; + uint8_t salt[0x20]; + uint8_t hash[0x20]; + uint32_t bl_version; + uint32_t bl_size; + uint32_t bl_load_addr; + uint32_t bl_entrypoint; + uint8_t _0x160[0x10]; + uint8_t data[]; +} pk11_mariko_oem_header_t; + int package1_read_and_parse_boot0_erista(void **package1loader, size_t *package1loader_size, nx_keyblob_t *keyblobs, uint32_t *revision, FILE *boot0); int package1_read_and_parse_boot0_mariko(void **package1loader, size_t *package1loader_size, FILE *boot0); diff --git a/fusee/fusee-secondary/src/se.c b/fusee/fusee-secondary/src/se.c index 86f416a02..73f0f845b 100644 --- a/fusee/fusee-secondary/src/se.c +++ b/fusee/fusee-secondary/src/se.c @@ -591,6 +591,20 @@ void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, co trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); } +void se_aes_128_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv) { + volatile tegra_se_t *se = se_get_regs(); + + if (keyslot >= KEYSLOT_AES_MAX || src_size < 0x10) { + generic_panic(); + } + + se->SE_CONFIG = (ALG_AES_DEC | DST_MEMORY) | (0x000 << 16); + se->SE_CRYPTO_CONFIG = (keyslot << 24) | 0x66; + set_aes_keyslot_iv(keyslot, iv, 0x10); + se->SE_CRYPTO_LAST_BLOCK = (src_size >> 4) - 1; + trigger_se_blocking_op(OP_START, dst, dst_size, src, src_size); +} + /* SHA256 Implementation. */ void se_calculate_sha256(void *dst, const void *src, size_t src_size) { volatile tegra_se_t *se = se_get_regs(); diff --git a/fusee/fusee-secondary/src/se.h b/fusee/fusee-secondary/src/se.h index d62174384..786ae1eb7 100644 --- a/fusee/fusee-secondary/src/se.h +++ b/fusee/fusee-secondary/src/se.h @@ -38,8 +38,12 @@ #define KEYSLOT_SWITCH_5XNEWDEVICEKEYGENKEY 0xA /* Mariko keyslots. */ +#define KEYSLOT_SWITCH_DEVICEKEY_MARIKO 0x6 #define KEYSLOT_SWITCH_MASTERKEY_MARIKO 0x7 +#define KEYSLOT_SWITCH_KEK_MARIKO 0xC +#define KEYSLOT_SWITCH_BEK_MARIKO 0xD + #define KEYSLOT_AES_MAX 0x10 #define KEYSLOT_RSA_MAX 0x2 @@ -194,6 +198,7 @@ void se_aes_256_ecb_encrypt_block(unsigned int keyslot, void *dst, size_t dst_si void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *ctr, size_t ctr_size); void se_aes_ecb_decrypt_block(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size); void se_aes_256_cbc_encrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv); +void se_aes_128_cbc_decrypt(unsigned int keyslot, void *dst, size_t dst_size, const void *src, size_t src_size, const void *iv); /* Hash API */ void se_calculate_sha256(void *dst, const void *src, size_t src_size);