diff --git a/README.md b/README.md index 3a91a4b..dc31a7f 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,8 @@ Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute. Open source and free packages used: - FatFs R0.13a, Copyright (C) 2017, ChaN - bcl-1.2.0, Copyright (C) 2003-2006, Marcus Geelnard - - Atmosphère (SE sha256, prc id kernel patches), Copyright (C) 2018, Atmosphère-NX + - Atmosphère (Exosphere types/panic, prc id kernel patches), + Copyright (C) 2018-2019, Atmosphère-NX - elfload, Copyright (C) 2014 Owen Shepherd, Copyright (C) 2018 M4xw ___ diff --git a/bootloader/hos/hos.c b/bootloader/hos/hos.c index 5f86ea3..fe8cb93 100644 --- a/bootloader/hos/hos.c +++ b/bootloader/hos/hos.c @@ -114,11 +114,11 @@ static void _se_lock(bool lock_se) if (lock_se) { for (u32 i = 0; i < 16; i++) - se_key_acc_ctrl(i, 0x15); + se_key_acc_ctrl(i, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); for (u32 i = 0; i < 2; i++) - se_rsa_acc_ctrl(i, 1); - SE(0x4) = 0; // Make this reg secure only. + se_rsa_acc_ctrl(i, SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG); + SE(SE_TZRAM_SECURITY_0) = 0; // Make SE TZRAM secure only. SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) = 0; // Make all key access regs secure only. SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) = 0; // Make all RSA access regs secure only. SE(SE_SECURITY_0) &= 0xFFFFFFFB; // Make access lock regs secure only. @@ -264,8 +264,8 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt) } else { - se_key_acc_ctrl(13, 0x15); - se_key_acc_ctrl(14, 0x15); + se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); + se_key_acc_ctrl(14, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); // Set TSEC key. se_aes_key_set(13, tmp, 0x10); @@ -320,7 +320,7 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt, launch_ctxt_t *hos_ctxt) } // Package2 key. - se_key_acc_ctrl(8, 0x15); + se_key_acc_ctrl(8, SE_KEY_TBL_DIS_KEYREAD_FLAG | SE_KEY_TBL_DIS_OIVREAD_FLAG | SE_KEY_TBL_DIS_UIVREAD_FLAG); se_aes_unwrap_key(8, 12, package2_keyseed); } @@ -660,16 +660,16 @@ int hos_launch(ini_sec_t *cfg) PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0xE3; // Warmboot 3.0.0 PA address id. else if (ctxt.pkg1_id->kb == KB_FIRMWARE_VERSION_301) PMC(APBDEV_PMC_SECURE_SCRATCH32) = 0x104; // Warmboot 3.0.1/.2 PA address id. - se_key_acc_ctrl(12, 0xFF); - se_key_acc_ctrl(13, 0xFF); + se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG); + se_key_acc_ctrl(13, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG); bootStateDramPkg2 = 2; bootStatePkg2Continue = 3; break; case KB_FIRMWARE_VERSION_400: case KB_FIRMWARE_VERSION_500: case KB_FIRMWARE_VERSION_600: - se_key_acc_ctrl(12, 0xFF); - se_key_acc_ctrl(15, 0xFF); + se_key_acc_ctrl(12, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG); + se_key_acc_ctrl(15, SE_KEY_TBL_DIS_KEY_ACCESS_FLAG | SE_KEY_TBL_DIS_KEY_LOCK_FLAG); default: bootStateDramPkg2 = 2; bootStatePkg2Continue = 4; diff --git a/bootloader/main.c b/bootloader/main.c index bf64a86..504dbbf 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -1100,8 +1100,8 @@ void about() " Copyright (c) 2018, ChaN\n\n" " - bcl-1.2.0,\n" " Copyright (c) 2003-2006, Marcus Geelnard\n\n" - " - Atmosphere (SE sha256, prc id patches),\n" - " Copyright (c) 2018, Atmosphere-NX\n\n" + " - Atmosphere (Exo st/types, prc id patches),\n" + " Copyright (c) 2018-2019, Atmosphere-NX\n\n" " - elfload,\n" " Copyright (c) 2014, Owen Shepherd\n" " Copyright (c) 2018, M4xw\n" diff --git a/bootloader/sec/se.c b/bootloader/sec/se.c index e20eddf..8d27510 100644 --- a/bootloader/sec/se.c +++ b/bootloader/sec/se.c @@ -1,7 +1,6 @@ /* * Copyright (c) 2018 naehrwert * Copyright (c) 2018 CTCaer - * Copyright (c) 2018 Atmosphère-NX * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -66,8 +65,8 @@ static int _se_wait() while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET))) ; if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) || - SE(SE_STATUS_0) & 3 || - SE(SE_ERR_STATUS_0) != 0) + SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN || + SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR) return 0; return 1; } @@ -93,12 +92,12 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0); SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET); - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op); int res = _se_wait(); - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); if (src) free(ll_src); @@ -121,7 +120,7 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr memcpy(block, src, src_size); int res = _se_execute(op, block, 0x10, block, 0x10); memcpy(dst, block, dst_size); - + free(block); return res; } @@ -135,17 +134,19 @@ static void _se_aes_ctr_set(void *ctr) void se_rsa_acc_ctrl(u32 rs, u32 flags) { - if (flags & 0x7F) - SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = (((flags >> 4) & 4) | (flags & 3)) ^ 7; - if (flags & 0x80) + if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG) + SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = + ((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | + ((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG); + if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG) SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs); } void se_key_acc_ctrl(u32 ks, u32 flags) { - if (flags & 0x7F) + if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags; - if (flags & 0x80) + if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG) SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks); } @@ -280,15 +281,15 @@ int se_calc_sha256(void *dst, const void *src, u32 src_size) int res; // Setup config for SHA256, size = BITS(src_size). SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); - SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_ENABLE; - SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3); - SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 1) = 0; - SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 2) = 0; - SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 3) = 0; - SE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3); - SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 1) = 0; - SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 2) = 0; - SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 3) = 0; + SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_INIT_HASH; + SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(src_size << 3); + SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(src_size << 3); + SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0; // Trigger the operation. res = _se_execute(OP_START, NULL, 0, src, src_size); diff --git a/bootloader/sec/se_t210.h b/bootloader/sec/se_t210.h index 72ceb24..3b610bc 100644 --- a/bootloader/sec/se_t210.h +++ b/bootloader/sec/se_t210.h @@ -36,6 +36,8 @@ #define SE_SECURITY_0 0x000 #define SE_KEY_SCHED_READ_SHIFT 3 +#define SE_TZRAM_SECURITY_0 0x004 + #define SE_CONFIG_REG_OFFSET 0x014 #define SE_CONFIG_ENC_ALG_SHIFT 12 #define SE_CONFIG_DEC_ALG_SHIFT 8 @@ -211,7 +213,10 @@ #define SE_INT_ERROR(x) (x << SE_INT_ERROR_SHIFT) #define SE_STATUS_0 0x800 +#define SE_STATUS_0_STATE_WAIT_IN 3 + #define SE_ERR_STATUS_0 0x804 +#define SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR 0 #define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330 #define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0 @@ -232,11 +237,17 @@ #define SE_SPARE_0_REG_OFFSET 0x80c #define SE_SHA_CONFIG_REG_OFFSET 0x200 -#define SHA_DISABLE 0 -#define SHA_ENABLE 1 +#define SHA_CONTINUE 0 +#define SHA_INIT_HASH 1 -#define SE_SHA_MSG_LENGTH_REG_OFFSET 0x204 -#define SE_SHA_MSG_LEFT_REG_OFFSET 0x214 +#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204 +#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208 +#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C +#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210 +#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214 +#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218 +#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C +#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220 #define SE_HASH_RESULT_REG_COUNT 16 #define SE_HASH_RESULT_REG_OFFSET 0x030 @@ -255,13 +266,24 @@ TEGRA_SE_RNG_DT_SIZE) #define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16 -#define TEGRA_SE_RSA512_DIGEST_SIZE 64 +#define TEGRA_SE_RSA512_DIGEST_SIZE 64 #define TEGRA_SE_RSA1024_DIGEST_SIZE 128 #define TEGRA_SE_RSA1536_DIGEST_SIZE 192 #define TEGRA_SE_RSA2048_DIGEST_SIZE 256 #define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280 +#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 + #define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284 +#define SE_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0) +#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1) +#define SE_KEY_TBL_DIS_OIVREAD_FLAG (1 << 2) +#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG (1 << 3) +#define SE_KEY_TBL_DIS_UIVREAD_FLAG (1 << 4) +#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG (1 << 5) +#define SE_KEY_TBL_DIS_KEYUSE_FLAG (1 << 6) +#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F + #define SE_KEY_READ_DISABLE_SHIFT 0 #define SE_KEY_UPDATE_DISABLE_SHIFT 1 @@ -313,7 +335,16 @@ #define TEGRA_SE_RSA_KEYSLOT_COUNT 2 #define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C +#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 + #define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410 +#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0) +#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1) +#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG) +#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG (1 << 2) +#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT (1 << 2) +#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7 +#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F #define SE_RSA_KEYTABLE_ADDR 0x420 #define SE_RSA_KEYTABLE_DATA 0x424 diff --git a/nyx/nyx_gui/frontend/fe_emmc_tools.c b/nyx/nyx_gui/frontend/fe_emmc_tools.c index da268dc..117a750 100644 --- a/nyx/nyx_gui/frontend/fe_emmc_tools.c +++ b/nyx/nyx_gui/frontend/fe_emmc_tools.c @@ -250,8 +250,8 @@ static int _dump_emmc_verify(emmc_tool_gui_t *gui, sdmmc_storage_t *storage, u32 return 1; } - se_calc_sha256(hashEm, bufEm, num << 9); - se_calc_sha256(hashSd, bufSd, num << 9); + se_calc_sha256(hashEm, NULL, bufEm, num << 9, 0, SHA_INIT_HASH, true); + se_calc_sha256(hashSd, NULL, bufSd, num << 9, 0, SHA_INIT_HASH, true); res = memcmp(hashEm, hashSd, 0x10); if (res) diff --git a/nyx/nyx_gui/frontend/fe_emummc_tools.c b/nyx/nyx_gui/frontend/fe_emummc_tools.c index a3af6d4..a9d4e41 100644 --- a/nyx/nyx_gui/frontend/fe_emummc_tools.c +++ b/nyx/nyx_gui/frontend/fe_emummc_tools.c @@ -38,7 +38,6 @@ #define NUM_SECTORS_PER_ITER 8192 // 4MB Cache. #define OUT_FILENAME_SZ 128 -#define SHA256_SZ 0x20 #define MBR_1ST_PART_TYPE_OFF 0x1C2 diff --git a/nyx/nyx_gui/frontend/gui.c b/nyx/nyx_gui/frontend/gui.c index 1cbdd7a..8fbe09a 100644 --- a/nyx/nyx_gui/frontend/gui.c +++ b/nyx/nyx_gui/frontend/gui.c @@ -714,8 +714,8 @@ static void _create_tab_about(lv_theme_t * th, lv_obj_t * parent) " Copyright (c) 2018, ChaN\n\n" " - bcl-1.2.0,\n" " Copyright (c) 2003-2006, Marcus Geelnard\n\n" - " - Atmosphere (SE sha256, process id patches),\n" - " Copyright (c) 2018, Atmosphere-NX\n\n" + " - Atmosphere (Exosphere types/panic, proc id patches),\n" + " Copyright (c) 2018-2019, Atmosphere-NX\n\n" " - elfload,\n" " Copyright (c) 2014, Owen Shepherd\n" " Copyright (c) 2018, M4xw\n\n" diff --git a/nyx/nyx_gui/hos/hos.c b/nyx/nyx_gui/hos/hos.c index 2526e6c..d173625 100644 --- a/nyx/nyx_gui/hos/hos.c +++ b/nyx/nyx_gui/hos/hos.c @@ -150,9 +150,6 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) } else { - se_key_acc_ctrl(13, 0x15); - se_key_acc_ctrl(14, 0x15); - // Set TSEC key. se_aes_key_set(13, tmp, 0x10); @@ -206,7 +203,6 @@ int keygen(u8 *keyblob, u32 kb, tsec_ctxt_t *tsec_ctxt) } // Package2 key. - se_key_acc_ctrl(8, 0x15); se_aes_unwrap_key(8, 12, package2_keyseed); } diff --git a/nyx/nyx_gui/sec/se.c b/nyx/nyx_gui/sec/se.c index e20eddf..36cc35f 100644 --- a/nyx/nyx_gui/sec/se.c +++ b/nyx/nyx_gui/sec/se.c @@ -1,7 +1,6 @@ /* * Copyright (c) 2018 naehrwert * Copyright (c) 2018 CTCaer - * Copyright (c) 2018 Atmosphère-NX * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -66,15 +65,17 @@ static int _se_wait() while (!(SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_OP_DONE(INT_SET))) ; if (SE(SE_INT_STATUS_REG_OFFSET) & SE_INT_ERROR(INT_SET) || - SE(SE_STATUS_0) & 3 || - SE(SE_ERR_STATUS_0) != 0) + SE(SE_STATUS_0) & SE_STATUS_0_STATE_WAIT_IN || + SE(SE_ERR_STATUS_0) != SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR) return 0; return 1; } -static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size) +se_ll_t *ll_dst, *ll_src; +static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src_size, bool is_oneshot) { - se_ll_t *ll_dst = NULL, *ll_src = NULL; + ll_dst = NULL; + ll_src = NULL; if (dst) { @@ -93,17 +94,42 @@ static int _se_execute(u32 op, void *dst, u32 dst_size, const void *src, u32 src SE(SE_ERR_STATUS_0) = SE(SE_ERR_STATUS_0); SE(SE_INT_STATUS_REG_OFFSET) = SE(SE_INT_STATUS_REG_OFFSET); - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); SE(SE_OPERATION_REG_OFFSET) = SE_OPERATION(op); + + int res = 1; + if (is_oneshot) + { + res = _se_wait(); + + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); + + if (src) + free(ll_src); + if (dst) + free(ll_dst); + } + + return res; +} + +static int _se_execute_finalize() +{ int res = _se_wait(); - bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY); + bpmp_mmu_maintenance(BPMP_MMU_MAINT_CLN_INV_WAY, false); - if (src) + if (ll_src) + { free(ll_src); - if (dst) + ll_src = NULL; + } + if (ll_dst) + { free(ll_dst); + ll_dst = NULL; + } return res; } @@ -119,9 +145,9 @@ static int _se_execute_one_block(u32 op, void *dst, u32 dst_size, const void *sr SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; memcpy(block, src, src_size); - int res = _se_execute(op, block, 0x10, block, 0x10); + int res = _se_execute(op, block, 0x10, block, 0x10, true); memcpy(dst, block, dst_size); - + free(block); return res; } @@ -135,17 +161,19 @@ static void _se_aes_ctr_set(void *ctr) void se_rsa_acc_ctrl(u32 rs, u32 flags) { - if (flags & 0x7F) - SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = (((flags >> 4) & 4) | (flags & 3)) ^ 7; - if (flags & 0x80) + if (flags & SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG) + SE(SE_RSA_KEYTABLE_ACCESS_REG_OFFSET + 4 * rs) = + ((flags >> SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT) & SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG) | + ((flags & SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG) ^ SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG); + if (flags & SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG) SE(SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET) &= ~(1 << rs); } void se_key_acc_ctrl(u32 ks, u32 flags) { - if (flags & 0x7F) + if (flags & SE_KEY_TBL_DIS_KEY_ACCESS_FLAG) SE(SE_KEY_TABLE_ACCESS_REG_OFFSET + 4 * ks) = ~flags; - if (flags & 0x80) + if (flags & SE_KEY_TBL_DIS_KEY_LOCK_FLAG) SE(SE_KEY_TABLE_ACCESS_LOCK_OFFSET) &= ~(1 << ks); } @@ -175,7 +203,7 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input) SE(SE_BLOCK_COUNT_REG_OFFSET) = 0; SE(SE_CRYPTO_KEYTABLE_DST_REG_OFFSET) = SE_CRYPTO_KEYTABLE_DST_KEY_INDEX(ks_dst); - return _se_execute(OP_START, NULL, 0, input, 0x10); + return _se_execute(OP_START, NULL, 0, input, 0x10, true); } int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size) @@ -191,7 +219,7 @@ int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, SE(SE_CRYPTO_REG_OFFSET) = SE_CRYPTO_KEY_INDEX(ks) | SE_CRYPTO_CORE_SEL(CORE_DECRYPT); } SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; - return _se_execute(OP_START, dst, dst_size, src, src_size); + return _se_execute(OP_START, dst, dst_size, src, src_size, true); } int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src) @@ -213,7 +241,7 @@ int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_s if (src_size_aligned) { SE(SE_BLOCK_COUNT_REG_OFFSET) = (src_size >> 4) - 1; - if (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned)) + if (!_se_execute(OP_START, dst, dst_size, src, src_size_aligned, true)) return 0; } @@ -274,30 +302,84 @@ int se_aes_xts_crypt(u32 ks1, u32 ks2, u32 enc, u64 sec, void *dst, void *src, u return 1; } -// se_calc_sha256() was derived from Atmosphère's se_calculate_sha256. -int se_calc_sha256(void *dst, const void *src, u32 src_size) +int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot) { int res; - // Setup config for SHA256, size = BITS(src_size). + u32 *hash32 = (u32 *)hash; + + if (src_size > 0xFFFFFF || (u32)hash % 4 || !hash) // Max 16MB - 1 chunks and aligned x4 hash buffer. + return 0; + + // Setup config for SHA256. SE(SE_CONFIG_REG_OFFSET) = SE_CONFIG_ENC_MODE(MODE_SHA256) | SE_CONFIG_ENC_ALG(ALG_SHA) | SE_CONFIG_DST(DST_HASHREG); - SE(SE_SHA_CONFIG_REG_OFFSET) = SHA_ENABLE; - SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3); - SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 1) = 0; - SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 2) = 0; - SE(SE_SHA_MSG_LENGTH_REG_OFFSET + 4 * 3) = 0; - SE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3); - SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 1) = 0; - SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 2) = 0; - SE(SE_SHA_MSG_LEFT_REG_OFFSET + 4 * 3) = 0; + SE(SE_SHA_CONFIG_REG_OFFSET) = sha_cfg; + + // Set total size to current buffer size if empty. + if (!total_size) + total_size = src_size; + + // Set total size: BITS(src_size), up to 2 EB. + SE(SE_SHA_MSG_LENGTH_0_REG_OFFSET) = (u32)(total_size << 3); + SE(SE_SHA_MSG_LENGTH_1_REG_OFFSET) = (u32)(total_size >> 29); + SE(SE_SHA_MSG_LENGTH_2_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LENGTH_3_REG_OFFSET) = 0; + + // Set size left to hash. + SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = (u32)(total_size << 3); + SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = (u32)(total_size >> 29); + SE(SE_SHA_MSG_LEFT_2_REG_OFFSET) = 0; + SE(SE_SHA_MSG_LEFT_3_REG_OFFSET) = 0; + + // If we hash in chunks, copy over the intermediate. + if (sha_cfg == SHA_CONTINUE) + { + if (!msg_left) + return 0; + + // Restore message left to process. + SE(SE_SHA_MSG_LEFT_0_REG_OFFSET) = msg_left[0]; + SE(SE_SHA_MSG_LEFT_1_REG_OFFSET) = msg_left[1]; + + // Restore hash reg. + for (u32 i = 0; i < 8; i++) + SE(SE_HASH_RESULT_REG_OFFSET + (i << 2)) = byte_swap_32(hash32[i]); + } // Trigger the operation. - res = _se_execute(OP_START, NULL, 0, src, src_size); + res = _se_execute(OP_START, NULL, 0, src, src_size, is_oneshot); - // Copy output hash. - u32 *dst32 = (u32 *)dst; - for (u32 i = 0; i < 8; i++) - dst32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); + if (is_oneshot) + { + // Backup message left. + if (msg_left) + { + msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET); + msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET); + } + + // Copy output hash. + for (u32 i = 0; i < 8; i++) + hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); + } return res; } +int se_calc_sha256_finalize(void *hash, u32 *msg_left) +{ + u32 *hash32 = (u32 *)hash; + int res = _se_execute_finalize(); + + // Backup message left. + if (msg_left) + { + msg_left[0] = SE(SE_SHA_MSG_LEFT_0_REG_OFFSET); + msg_left[1] = SE(SE_SHA_MSG_LEFT_1_REG_OFFSET); + } + + // Copy output hash. + for (u32 i = 0; i < 8; i++) + hash32[i] = byte_swap_32(SE(SE_HASH_RESULT_REG_OFFSET + (i << 2))); + + return res; +} diff --git a/nyx/nyx_gui/sec/se.h b/nyx/nyx_gui/sec/se.h index bd70b28..8ff74c1 100644 --- a/nyx/nyx_gui/sec/se.h +++ b/nyx/nyx_gui/sec/se.h @@ -27,6 +27,7 @@ int se_aes_unwrap_key(u32 ks_dst, u32 ks_src, const void *input); int se_aes_crypt_ecb(u32 ks, u32 enc, void *dst, u32 dst_size, const void *src, u32 src_size); int se_aes_crypt_block_ecb(u32 ks, u32 enc, void *dst, const void *src); int se_aes_crypt_ctr(u32 ks, void *dst, u32 dst_size, const void *src, u32 src_size, void *ctr); -int se_calc_sha256(void *dst, const void *src, u32 src_size); +int se_calc_sha256(void *hash, u32 *msg_left, const void *src, u32 src_size, u64 total_size, u32 sha_cfg, bool is_oneshot); +int se_calc_sha256_finalize(void *hash, u32 *msg_left); #endif diff --git a/nyx/nyx_gui/sec/se_t210.h b/nyx/nyx_gui/sec/se_t210.h index 72ceb24..3b610bc 100644 --- a/nyx/nyx_gui/sec/se_t210.h +++ b/nyx/nyx_gui/sec/se_t210.h @@ -36,6 +36,8 @@ #define SE_SECURITY_0 0x000 #define SE_KEY_SCHED_READ_SHIFT 3 +#define SE_TZRAM_SECURITY_0 0x004 + #define SE_CONFIG_REG_OFFSET 0x014 #define SE_CONFIG_ENC_ALG_SHIFT 12 #define SE_CONFIG_DEC_ALG_SHIFT 8 @@ -211,7 +213,10 @@ #define SE_INT_ERROR(x) (x << SE_INT_ERROR_SHIFT) #define SE_STATUS_0 0x800 +#define SE_STATUS_0_STATE_WAIT_IN 3 + #define SE_ERR_STATUS_0 0x804 +#define SE_ERR_STATUS_0_SE_NS_ACCESS_CLEAR 0 #define SE_CRYPTO_KEYTABLE_DST_REG_OFFSET 0X330 #define SE_CRYPTO_KEYTABLE_DST_WORD_QUAD_SHIFT 0 @@ -232,11 +237,17 @@ #define SE_SPARE_0_REG_OFFSET 0x80c #define SE_SHA_CONFIG_REG_OFFSET 0x200 -#define SHA_DISABLE 0 -#define SHA_ENABLE 1 +#define SHA_CONTINUE 0 +#define SHA_INIT_HASH 1 -#define SE_SHA_MSG_LENGTH_REG_OFFSET 0x204 -#define SE_SHA_MSG_LEFT_REG_OFFSET 0x214 +#define SE_SHA_MSG_LENGTH_0_REG_OFFSET 0x204 +#define SE_SHA_MSG_LENGTH_1_REG_OFFSET 0x208 +#define SE_SHA_MSG_LENGTH_2_REG_OFFSET 0x20C +#define SE_SHA_MSG_LENGTH_3_REG_OFFSET 0x210 +#define SE_SHA_MSG_LEFT_0_REG_OFFSET 0x214 +#define SE_SHA_MSG_LEFT_1_REG_OFFSET 0x218 +#define SE_SHA_MSG_LEFT_2_REG_OFFSET 0x21C +#define SE_SHA_MSG_LEFT_3_REG_OFFSET 0x220 #define SE_HASH_RESULT_REG_COUNT 16 #define SE_HASH_RESULT_REG_OFFSET 0x030 @@ -255,13 +266,24 @@ TEGRA_SE_RNG_DT_SIZE) #define TEGRA_SE_AES_CMAC_DIGEST_SIZE 16 -#define TEGRA_SE_RSA512_DIGEST_SIZE 64 +#define TEGRA_SE_RSA512_DIGEST_SIZE 64 #define TEGRA_SE_RSA1024_DIGEST_SIZE 128 #define TEGRA_SE_RSA1536_DIGEST_SIZE 192 #define TEGRA_SE_RSA2048_DIGEST_SIZE 256 #define SE_KEY_TABLE_ACCESS_LOCK_OFFSET 0x280 +#define SE_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 + #define SE_KEY_TABLE_ACCESS_REG_OFFSET 0x284 +#define SE_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0) +#define SE_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1) +#define SE_KEY_TBL_DIS_OIVREAD_FLAG (1 << 2) +#define SE_KEY_TBL_DIS_OIVUPDATE_FLAG (1 << 3) +#define SE_KEY_TBL_DIS_UIVREAD_FLAG (1 << 4) +#define SE_KEY_TBL_DIS_UIVUPDATE_FLAG (1 << 5) +#define SE_KEY_TBL_DIS_KEYUSE_FLAG (1 << 6) +#define SE_KEY_TBL_DIS_KEY_ACCESS_FLAG 0x7F + #define SE_KEY_READ_DISABLE_SHIFT 0 #define SE_KEY_UPDATE_DISABLE_SHIFT 1 @@ -313,7 +335,16 @@ #define TEGRA_SE_RSA_KEYSLOT_COUNT 2 #define SE_RSA_KEYTABLE_ACCESS_LOCK_OFFSET 0x40C +#define SE_RSA_KEY_TBL_DIS_KEY_LOCK_FLAG 0x80 + #define SE_RSA_KEYTABLE_ACCESS_REG_OFFSET 0x410 +#define SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG (1 << 0) +#define SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG (1 << 1) +#define SE_RSA_KEY_TBL_DIS_KEY_READ_UPDATE_FLAG (SE_RSA_KEY_TBL_DIS_KEYREAD_FLAG | SE_RSA_KEY_TBL_DIS_KEYUPDATE_FLAG) +#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG (1 << 2) +#define SE_RSA_KEY_TBL_DIS_KEYUSE_FLAG_SHIFT (1 << 2) +#define SE_RSA_KEY_TBL_DIS_KEY_ALL_COMMON_FLAG 7 +#define SE_RSA_KEY_TBL_DIS_KEY_ALL_FLAG 0x7F #define SE_RSA_KEYTABLE_ADDR 0x420 #define SE_RSA_KEYTABLE_DATA 0x424