Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
GaryOderNichts committed Feb 25, 2024
1 parent c4a20ef commit be398c7
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
4 changes: 2 additions & 2 deletions ios_mcp/source/imports.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ int IOSC_DeleteObject(int keyHandle);
int IOSC_GenerateRand(uint8_t* randBytes, uint32_t numBytes);
int IOSC_ImportSecretKey(IOSCSecretKeyHandle importedHandle, IOSCSecretKeyHandle verifyHandle, IOSCSecretKeyHandle decryptHandle, IOSCSecretKeySecurity flag, uint8_t* signbuffer, uint32_t signbufferSize, uint8_t* ivData, uint32_t ivSize, uint8_t* keybuffer, uint32_t keybufferSize);
int IOSC_ImportPublicKey(uint8_t* publicKeyData, uint32_t dataSize, uint8_t* exponent, uint32_t exponentSize, IOSCPublicKeyHandle publicKeyHandle);
int IOSC_Decrypt(IOSCSecretKeyHandle decryptHandle, uint8_t* ivData, uint32_t ivSize, uint8_t* inputData, uint32_t inputSize, uint8_t* outputData, uint32_t outputSize);
int IOSC_Encrypt(IOSCSecretKeyHandle encryptHandle, uint8_t* ivData, uint32_t ivSize, uint8_t* inputData, uint32_t inputSize, uint8_t* outputData, uint32_t outputSize);
int IOSC_Decrypt(IOSCSecretKeyHandle decryptHandle, void* ivData, uint32_t ivSize, void* inputData, uint32_t inputSize, void* outputData, uint32_t outputSize);
int IOSC_Encrypt(IOSCSecretKeyHandle encryptHandle, void* ivData, uint32_t ivSize, void* inputData, uint32_t inputSize, void* outputData, uint32_t outputSize);

#define WUP_CERT_SIGTYPE_ECC_SHA1 0x00010002 /* ECC with SHA-1 */
#define WUP_CERT_SIGTYPE_ECC_SHA256 0x00010005 /* ECC with SHA-256 */
Expand Down
56 changes: 38 additions & 18 deletions ios_mcp/source/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,7 @@ int read_otp_seeprom(void *buf, int index)
return 0;
}

static int preparePrshHax(void)
static int preparePrshHax(uint32_t boootInfoPtr)
{
// RAM vars
uint32_t ram_start_addr = 0x10000000;
Expand All @@ -943,7 +943,7 @@ static int preparePrshHax(void)
}

// Change boot_info to point inside boot1 memory
*(uint32_t *) boot_info_ptr_addr = 0x0D40AC6D;
*(uint32_t *) boot_info_ptr_addr = boootInfoPtr;

// Re-calculate PRSH checksum
uint32_t checksum = 0;
Expand Down Expand Up @@ -983,6 +983,8 @@ typedef struct {
uint16_t reserved[4];
uint32_t crc;
} Boot1Params;
static_assert(sizeof(Boot1Params) == 0x10);

Boot1Params boot1Params[2] __attribute__ ((aligned (0x10)));

static int decryptBoot1Params(int index)
Expand All @@ -999,12 +1001,12 @@ static int readBoot1Params(void)
{
int ret;

ret = EEPROM_Read(0xe8, 8, &boot1Params[0]);
ret = EEPROM_Read(0xe8, 8, (uint16_t*)&boot1Params[0]);
if (ret != 0) {
return ret;
}

ret = EEPROM_Read(0xf0, 8, &boot1Params[1]);
ret = EEPROM_Read(0xf0, 8, (uint16_t*)&boot1Params[1]);
if (ret != 0) {
return ret;
}
Expand All @@ -1021,7 +1023,7 @@ static int determineActiveBoot1Slot(void)
// Calculate crcs
uint32_t validMask = 0;
for (int i = 0; i < 2; i++) {
if (crc32(0xffffffff, &boot1Params[i], 0xc) == boot1Params[i].crc) {
if (~crc32(0xffffffff, &boot1Params[i], 0xc) == boot1Params[i].crc) {
validMask |= 1 << i;
}
}
Expand Down Expand Up @@ -1068,19 +1070,34 @@ static void option_LoadBoot1Payload(void)
return;

gfx_printf(16, index, 0, "Checking BOOT1 version...");
index += CHAR_SIZE_DRC_Y + 4;

if (!readBoot1Params()) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to read boot1 parameters");
waitButtonInput();
return;
}

int activeSlot;
if (readBoot1Params() != 1 || (activeSlot = determineActiveBoot1Slot()) < 0) {
if ((activeSlot = determineActiveBoot1Slot()) < 0) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to determine boot1 version");
gfx_printf(16, index, 0, "Failed to determine active boot1 version");
waitButtonInput();
return;
}

uint16_t activeVersion = boot1Params[activeSlot].version;
gfx_printf(16, index, 0, "Active BOOT1 version: %d (slot %d)", activeVersion, activeSlot);
index += CHAR_SIZE_DRC_Y + 4;

// TODO we could probably support more versions
if (activeVersion != 8377) {
// TODO support more versions / check for dev/retail
uint32_t boootInfoPtr;
switch (activeVersion) {
case 8377:
boootInfoPtr = 0x0D40AC6D;
break;
default:
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Unsupported BOOT1 version: %d", activeVersion);
waitButtonInput();
Expand Down Expand Up @@ -1119,15 +1136,15 @@ static void option_LoadBoot1Payload(void)
// Check ancast magic
if (dataBuffer[0] != 0xEFA282D9) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Invalid ancast header magic: %08x", dataBuffer[0]);
gfx_printf(16, index, 0, "Invalid ancast header magic: %08lx", dataBuffer[0]);
waitButtonInput();
IOS_HeapFree(CROSS_PROCESS_HEAP_ID, dataBuffer);
FSA_CloseFile(fsaHandle, fileHandle);
return;
}

// Check unencrypted flag
if (((dataBuffer[0x68] >> 2) & 1) == 0) {
if (((dataBuffer[0x68] >> 16) & 1) == 0) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Ancast image is encrypted!");
waitButtonInput();
Expand All @@ -1136,6 +1153,8 @@ static void option_LoadBoot1Payload(void)
return;
}

uint32_t bodySize = dataBuffer[0x6B];

// read and write payload to mem1
uint32_t payloadOffset = 0x00000050;
int bytesRead = 0;
Expand All @@ -1147,7 +1166,8 @@ static void option_LoadBoot1Payload(void)
}
}

gfx_printf(16, index, 0, "Read %d bytes", bytesRead);
gfx_printf(16, index, 0, "Read %d / %ld bytes", bytesRead, bodySize);
index += CHAR_SIZE_DRC_Y + 4;

IOS_HeapFree(CROSS_PROCESS_HEAP_ID, dataBuffer);
FSA_CloseFile(fsaHandle, fileHandle);
Expand All @@ -1159,24 +1179,24 @@ static void option_LoadBoot1Payload(void)
return;
}

// Check payload size
if (dataBuffer[0x6B] != bytesRead) {
// Check body size
if (bytesRead < bodySize) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to read ancast image (%d / %d bytes)", bytesRead, dataBuffer[0x6B]);
gfx_printf(16, index, 0, "Failed to read ancast body (%d / %ld bytes)", bytesRead, bodySize);
waitButtonInput();
return;
}

res = preparePrshHax();
res = preparePrshHax(boootInfoPtr);
if (res < 0) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to prepare prshhax: %x", res);
waitButtonInput();
return;
}

// Setup branch to MEM1 payload (skip ancast header)
kernWrite32(0x00000000, 0xEA000092); // b #0x250
// Setup branch to MEM1 payload
kernWrite32(0x00000000, 0xEA000012); // b #0x50
kernWrite32(0x00000004, 0xDEADC0DE);
kernWrite32(0x00000008, 0xDEADC0DE);

Expand Down

0 comments on commit be398c7

Please sign in to comment.