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);