diff --git a/bootloader/frontend/fe_tools.c b/bootloader/frontend/fe_tools.c index a17623d..d0dadc2 100644 --- a/bootloader/frontend/fe_tools.c +++ b/bootloader/frontend/fe_tools.c @@ -270,8 +270,6 @@ void _toggle_autorcm(bool enable) sdmmc_storage_t storage; sdmmc_t sdmmc; - u8 randomXor = 0; - gfx_clear_partial_grey(0x1B, 0, 1256); gfx_con_setpos(0, 0); @@ -285,28 +283,25 @@ void _toggle_autorcm(bool enable) sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0); int i, sect = 0; - u8 corr_mod_byte0; - if ((fuse_read_odm(4) & 3) != 3) - corr_mod_byte0 = 0xF7; - else - corr_mod_byte0 = 0x37; + u8 corr_mod0, mod1; + // Get the correct RSA modulus byte masks. + nx_emmc_get_autorcm_masks(&corr_mod0, &mod1); + + // Iterate BCTs. for (i = 0; i < 4; i++) { sect = (0x200 + (0x4000 * i)) / NX_EMMC_BLOCKSIZE; sdmmc_storage_read(&storage, sect, 1, tempbuf); - if (enable) - { - do - { - randomXor = get_tmr_us() & 0xFF; // Bricmii style of bricking. - } while (!randomXor); // Avoid the lottery. + // Check if 2nd byte of modulus is correct. + if (tempbuf[0x11] != mod1) + continue; - tempbuf[0x10] ^= randomXor; - } + if (enable) + tempbuf[0x10] = 0; else - tempbuf[0x10] = corr_mod_byte0; + tempbuf[0x10] = corr_mod0; sdmmc_storage_write(&storage, sect, 1, tempbuf); } @@ -354,20 +349,18 @@ void menu_autorcm() return; } + u8 mod0, mod1; + // Get the correct RSA modulus byte masks. + nx_emmc_get_autorcm_masks(&mod0, &mod1); + u8 *tempbuf = (u8 *)malloc(0x200); sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0); sdmmc_storage_read(&storage, 0x200 / NX_EMMC_BLOCKSIZE, 1, tempbuf); - if ((fuse_read_odm(4) & 3) != 3) - { - if (tempbuf[0x10] != 0xF7) + // Check if 2nd byte of modulus is correct. + if (tempbuf[0x11] == mod1) + if (tempbuf[0x10] != mod0) disabled = false; - } - else - { - if (tempbuf[0x10] != 0x37) - disabled = false; - } free(tempbuf); sdmmc_storage_end(&storage); diff --git a/bootloader/hos/secmon_exo.c b/bootloader/hos/secmon_exo.c index 38183bf..0ccc088 100644 --- a/bootloader/hos/secmon_exo.c +++ b/bootloader/hos/secmon_exo.c @@ -314,20 +314,23 @@ void config_exosphere(launch_ctxt_t *ctxt, u32 warmboot_base, bool exo_new) sdmmc_storage_set_mmc_partition(&emmc_storage, EMMC_BOOT0); u32 sector; + u8 mod0, mod1; + + // Get the correct RSA modulus byte masks. + nx_emmc_get_autorcm_masks(&mod0, &mod1); + + // Iterate BCTs. for (u32 i = 0; i < 4; i++) { sector = 1 + (32 * i); // 0x4000 bct + 0x200 offset. sdmmc_storage_read(&emmc_storage, sector, 1, rsa_mod); // Check if 2nd byte of modulus is correct. - if (rsa_mod[0x11] != 0x86) + if (rsa_mod[0x11] != mod1) continue; // Patch AutoRCM out. - if ((fuse_read_odm(4) & 3) != 3) - rsa_mod[0x10] = 0xF7; - else - rsa_mod[0x10] = 0x37; + rsa_mod[0x10] = mod0; break; } diff --git a/bootloader/main.c b/bootloader/main.c index 87094d1..ab877e7 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -1134,25 +1134,25 @@ static void _patched_rcm_protection() sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0); u32 sector; - u8 corr_mod_byte0; - if ((fuse_read_odm(4) & 3) != 3) - corr_mod_byte0 = 0xF7; - else - corr_mod_byte0 = 0x37; + u8 corr_mod0, mod1; + // Get the correct RSA modulus byte masks. + nx_emmc_get_autorcm_masks(&corr_mod0, &mod1); + + // Iterate BCTs. for (u32 i = 0; i < 4; i++) { sector = 1 + (32 * i); // 0x4000 bct + 0x200 offset. sdmmc_storage_read(&storage, sector, 1, buf); // Check if 2nd byte of modulus is correct. - if (buf[0x11] != 0x86) + if (buf[0x11] != mod1) continue; // If AutoRCM is enabled, disable it. - if (buf[0x10] != corr_mod_byte0) + if (buf[0x10] != corr_mod0) { - buf[0x10] = corr_mod_byte0; + buf[0x10] = corr_mod0; sdmmc_storage_write(&storage, sector, 1, buf); } diff --git a/bootloader/storage/nx_emmc.c b/bootloader/storage/nx_emmc.c index be7aa4b..ae3fd7c 100644 --- a/bootloader/storage/nx_emmc.c +++ b/bootloader/storage/nx_emmc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 naehrwert + * Copyright (c) 2019-2020 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -19,6 +20,7 @@ #include "nx_emmc.h" #include "emummc.h" #include +#include #include #include @@ -66,6 +68,7 @@ emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name) LIST_FOREACH_ENTRY(emmc_part_t, part, gpt, link) if (!strcmp(part->name, name)) return part; + return NULL; } @@ -74,6 +77,7 @@ int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_of // The last LBA is inclusive. if (part->lba_start + sector_off > part->lba_end) return 0; + return emummc_storage_read(storage, part->lba_start + sector_off, num_sectors, buf); } @@ -82,5 +86,20 @@ int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_o // The last LBA is inclusive. if (part->lba_start + sector_off > part->lba_end) return 0; + return sdmmc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf); } + +void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1) +{ + if (fuse_read_hw_state() == FUSE_NX_HW_STATE_PROD) + { + *mod0 = 0xF7; + *mod1 = 0x86; + } + else + { + *mod0 = 0x37; + *mod1 = 0x84; + } +} diff --git a/bootloader/storage/nx_emmc.h b/bootloader/storage/nx_emmc.h index 5db6a1f..f89f526 100644 --- a/bootloader/storage/nx_emmc.h +++ b/bootloader/storage/nx_emmc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 naehrwert + * Copyright (c) 2019-2020 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -43,7 +44,9 @@ extern FATFS emmc_fs; void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage); void nx_emmc_gpt_free(link_t *gpt); emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name); -int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); -int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); +int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); +int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); + +void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1); #endif diff --git a/nyx/nyx_gui/frontend/gui_tools.c b/nyx/nyx_gui/frontend/gui_tools.c index 7bf696b..caac525 100644 --- a/nyx/nyx_gui/frontend/gui_tools.c +++ b/nyx/nyx_gui/frontend/gui_tools.c @@ -70,7 +70,7 @@ static lv_obj_t *_create_container(lv_obj_t *parent) bool get_autorcm_status(bool change) { - u8 corr_mod_byte0; + u8 corr_mod0, mod1; sdmmc_storage_t storage; sdmmc_t sdmmc; bool enabled = false; @@ -84,41 +84,37 @@ bool get_autorcm_status(bool change) sdmmc_storage_set_mmc_partition(&storage, EMMC_BOOT0); sdmmc_storage_read(&storage, 0x200 / NX_EMMC_BLOCKSIZE, 1, tempbuf); - if ((fuse_read_odm(4) & 3) != 3) - corr_mod_byte0 = 0xF7; - else - corr_mod_byte0 = 0x37; + // Get the correct RSA modulus byte masks. + nx_emmc_get_autorcm_masks(&corr_mod0, &mod1); - if (tempbuf[0x10] != corr_mod_byte0) + // Check if 2nd byte of modulus is correct. + if (tempbuf[0x11] != mod1) + goto out; + + if (tempbuf[0x10] != corr_mod0) enabled = true; // Change autorcm status if requested. if (change) { int i, sect = 0; - u8 randomXor = 0; + // Iterate BCTs. for (i = 0; i < 4; i++) { sect = (0x200 + (0x4000 * i)) / NX_EMMC_BLOCKSIZE; sdmmc_storage_read(&storage, sect, 1, tempbuf); if (!enabled) - { - do - { - randomXor = get_tmr_us() & 0xFF; // Bricmii style of bricking. - } while (!randomXor); // Avoid the lottery. - - tempbuf[0x10] ^= randomXor; - } + tempbuf[0x10] = 0; else - tempbuf[0x10] = corr_mod_byte0; + tempbuf[0x10] = corr_mod0; sdmmc_storage_write(&storage, sect, 1, tempbuf); } enabled = !(enabled); } +out: free(tempbuf); sdmmc_storage_end(&storage); diff --git a/nyx/nyx_gui/storage/nx_emmc.c b/nyx/nyx_gui/storage/nx_emmc.c index fa36e59..2a945f3 100644 --- a/nyx/nyx_gui/storage/nx_emmc.c +++ b/nyx/nyx_gui/storage/nx_emmc.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 naehrwert + * Copyright (c) 2019-2020 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -16,9 +17,10 @@ #include -#include #include "nx_emmc.h" #include +#include +#include #include sdmmc_t emmc_sdmmc; @@ -83,3 +85,17 @@ int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_o return 0; return sdmmc_storage_write(storage, part->lba_start + sector_off, num_sectors, buf); } + +void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1) +{ + if (fuse_read_hw_state() == FUSE_NX_HW_STATE_PROD) + { + *mod0 = 0xF7; + *mod1 = 0x86; + } + else + { + *mod0 = 0x37; + *mod1 = 0x84; + } +} diff --git a/nyx/nyx_gui/storage/nx_emmc.h b/nyx/nyx_gui/storage/nx_emmc.h index 5db6a1f..f89f526 100644 --- a/nyx/nyx_gui/storage/nx_emmc.h +++ b/nyx/nyx_gui/storage/nx_emmc.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018 naehrwert + * Copyright (c) 2019-2020 CTCaer * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -43,7 +44,9 @@ extern FATFS emmc_fs; void nx_emmc_gpt_parse(link_t *gpt, sdmmc_storage_t *storage); void nx_emmc_gpt_free(link_t *gpt); emmc_part_t *nx_emmc_part_find(link_t *gpt, const char *name); -int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); -int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); +int nx_emmc_part_read(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); +int nx_emmc_part_write(sdmmc_storage_t *storage, emmc_part_t *part, u32 sector_off, u32 num_sectors, void *buf); + +void nx_emmc_get_autorcm_masks(u8 *mod0, u8 *mod1); #endif