From 37a15ca8ff07b1be00b699ae90eeffb3c8c09452 Mon Sep 17 00:00:00 2001 From: Kostas Missos Date: Tue, 26 Jun 2018 19:07:34 +0300 Subject: [PATCH] Make Backup verifying faster by using SE's SHA256 --- ipl/main.c | 25 +++++++++++++++++-------- ipl/se.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/ipl/main.c b/ipl/main.c index 9462266..8f78394 100755 --- a/ipl/main.c +++ b/ipl/main.c @@ -688,13 +688,15 @@ void power_off() i2c_send_byte(I2C_5, 0x3C, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); } -//TODO: Make it faster!! int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char* outFilename, emmc_part_t *part) { FIL fp; u32 prevPct = 200; int res = 0; + u8 hashEm[0x20]; + u8 hashSd[0x20]; + if (f_open(&fp, outFilename, FA_READ) == FR_OK) { u32 totalSectorsVer = (u32)(f_size(&fp) >> 9); @@ -735,11 +737,18 @@ int dump_emmc_verify(sdmmc_storage_t *storage, u32 lba_curr, char* outFilename, f_close(&fp); return 1; } - //TODO: Replace with the config check 2. - if (1) + //TODO: Replace 2 with config variable + switch (2) + { + case 1: res = memcmp32sparse((u32 *)bufEm, (u32 *)bufSd, num << 9); - else - res = memcmp((u32 *)bufEm, (u32 *)bufSd, num << 9); + break; + case 2: + se_calc_sha256(&hashEm, bufEm, num << 9); + se_calc_sha256(&hashSd, bufSd, num << 9); + res = memcmp(hashEm, hashSd, 0x20); + break; + } if(res) { EPRINTFARGS("\nSD card and eMMC data (@LBA %08X),\ndo not match!\n\nVerification failed..\n", num, lba_curr); @@ -1037,7 +1046,7 @@ int dump_emmc_part(char *sd_path, sdmmc_storage_t *storage, emmc_part_t *part) f_close(&fp); //TODO: Replace with the config check. - if (0) + if (1) { // Verify last part or single file backup. if (dump_emmc_verify(storage, lbaStartPart, outFilename, part)) @@ -1176,7 +1185,7 @@ static void dump_emmc_selected(dumpType_t dumpType) gfx_putc(&gfx_con, '\n'); gfx_printf(&gfx_con, "Time taken: %d seconds.\n", get_tmr_s() - timer); sdmmc_storage_end(&storage); - if (res && 0) //TODO: Replace with the config check. + if (res && 1) //TODO: Replace with the config check. gfx_printf(&gfx_con, "\n%kFinished and verified!%k\nPress any key...\n",0xFF96FF00, 0xFFCCCCCC); else if (res) gfx_printf(&gfx_con, "\nFinished! Press any key...\n"); @@ -1694,7 +1703,7 @@ ment_t ment_tools[] = { MDEF_CAPTION("------ Misc -------", 0xFF0AB9E6), MDEF_HANDLER("Dump package1", dump_package1), MDEF_HANDLER("Fix SD files attributes", fix_sd_attr), - MDEF_HANDLER("Fix battery de-sync", &fix_battery_desync), + MDEF_HANDLER("Fix battery de-sync", fix_battery_desync), //MDEF_MENU("Fix fuel gauge configuration", &fix_fuel_gauge_configuration), MDEF_CHGLINE(), MDEF_CAPTION("---- Dangerous ----", 0xFFFF0000), diff --git a/ipl/se.c b/ipl/se.c index 0b2d4aa..9d0f92d 100755 --- a/ipl/se.c +++ b/ipl/se.c @@ -1,5 +1,7 @@ /* * 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, @@ -19,6 +21,7 @@ #include "heap.h" #include "t210.h" #include "se_t210.h" +#include "util.h" typedef struct _se_ll_t { @@ -254,3 +257,29 @@ 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 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) = 1; + SE(SE_SHA_MSG_LENGTH_REG_OFFSET) = (u32)(src_size << 3); + SE(0x208) = 0; + SE(0x20C) = 0; + SE(0x210) = 0; + SE(SE_SHA_MSG_LEFT_REG_OFFSET) = (u32)(src_size << 3); + SE(0x218) = 0; + SE(0x21C) = 0; + SE(0x220) = 0; + + // Trigger the operation. + res = _se_execute(OP_START, NULL, 0, src, src_size); + + // 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))); + + return res; +}