diff --git a/source/incognito/incognito.c b/source/incognito/incognito.c index 320706a..20863bc 100644 --- a/source/incognito/incognito.c +++ b/source/incognito/incognito.c @@ -96,6 +96,29 @@ LIST_INIT(gpt); static bool _key_exists(const void *data) { return memcmp(data, zeros, 0x10); }; static void _generate_kek(u32 ks, const void *key_source, void *master_key, const void *kek_seed, const void *key_seed); +unsigned int crc_16_table[16] = { + 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, + 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; + +unsigned short int get_crc_16 (const char *p, int n) { + unsigned short int crc = 0x55AA; + int r; + + while (n-- > 0) { + r = crc_16_table[crc & 0xF]; + crc = (crc >> 4) & 0x0FFF; + crc = crc ^ r ^ crc_16_table[*p & 0xF]; + + r = crc_16_table[crc & 0xF]; + crc = (crc >> 4) & 0x0FFF; + crc = crc ^ r ^ crc_16_table[(*p >> 4) & 0xF]; + + p++; + } + + return(crc); +} + bool dump_keys() { display_backlight_brightness(100, 1000); @@ -307,17 +330,33 @@ bool dump_keys() return false; } - char serial[15] = ""; - readData((u8 *)serial, 0x250, 14, NULL); + char serial[31] = ""; + readData((u8 *)serial, 0x250, 30, NULL); - gfx_printf("%kCurrent serial:%s\n\n", COLOR_BLUE, serial); + gfx_printf("%kCurrent serial: [%s]\n\n", COLOR_BLUE, serial); + + // Determine stored crc + u8 *storedCrc = (u8 *)calloc(2, sizeof(u8)); + readData((u8 *)storedCrc, 0x250 + 30, 2, NULL); + + // Calculate crc + const char *serialBytes = serial; + u16 crcValue = get_crc_16(serialBytes, 30); + u8 crc[2] = { crcValue & 0xff, crcValue >> 8 }; // bytes of u16 + + // Validate crc + if (memcmp(storedCrc, crc, 0x2) == 0) + gfx_printf("%kValid serial crc\n", COLOR_GREEN); + else + gfx_printf("%kWarning - invalid serial crc\n", COLOR_RED); + + free(storedCrc); return true; } bool erase(u32 offset, u32 length) { - u8 *tmp = (u8 *)calloc(length, sizeof(u8)); bool result = writeData(tmp, offset, length, NULL); free(tmp); @@ -336,7 +375,21 @@ bool writeSerial() junkSerial = "XAW00000000001"; } - return writeData((u8 *)junkSerial, 0x250, 14, NULL); + const u32 serialOffset = 0x250; + const u32 serialBlockSize = 0x1E; + + if (!writeData((u8 *)junkSerial, serialOffset, 14, NULL)) + return false; + + // write crc at end of serial-number block + char serial[31] = ""; + readData((u8 *)serial, serialOffset, serialBlockSize, NULL); + + const char *serialBytes = serial; + u16 crcValue = get_crc_16(serialBytes, serialBlockSize); + u8 crc[2] = { crcValue & 0xff, crcValue >> 8 }; // bytes of u16 + + return writeData(crc, serialOffset + serialBlockSize, 2, NULL); } bool incognito() diff --git a/source/main.c b/source/main.c index 763b5f0..ad7434c 100644 --- a/source/main.c +++ b/source/main.c @@ -138,10 +138,12 @@ int sd_save_to_file(void *buf, u32 size, const char *filename) #define PATCHED_RELOC_ENTRY 0x40010000 #define EXT_PAYLOAD_ADDR 0xC03C0000 #define RCM_PAYLOAD_ADDR (EXT_PAYLOAD_ADDR + ALIGN(PATCHED_RELOC_SZ, 0x10)) -#define COREBOOT_ADDR (0xD0000000 - 0x100000) +#define COREBOOT_END_ADDR 0xD0000000 #define CBFS_DRAM_EN_ADDR 0x4003e000 #define CBFS_DRAM_MAGIC 0x4452414D // "DRAM" +static void *coreboot_addr; + void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size) { memcpy((u8 *)payload_src, (u8 *)IPL_LOAD_ADDR, PATCHED_RELOC_SZ); @@ -155,7 +157,7 @@ void reloc_patcher(u32 payload_dst, u32 payload_src, u32 payload_size) if (payload_size == 0x7000) { - memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), (u8 *)COREBOOT_ADDR, 0x7000); //Bootblock + memcpy((u8 *)(payload_src + ALIGN(PATCHED_RELOC_SZ, 0x10)), coreboot_addr, 0x7000); //Bootblock *(vu32 *)CBFS_DRAM_EN_ADDR = CBFS_DRAM_MAGIC; } } @@ -185,7 +187,10 @@ int launch_payload(char *path) if (size < 0x30000) buf = (void *)RCM_PAYLOAD_ADDR; else - buf = (void *)COREBOOT_ADDR; + { + coreboot_addr = (void *)(COREBOOT_END_ADDR - size); + buf = coreboot_addr; + } if (f_read(&fp, buf, size, NULL)) {