forked from len0rd/rockbox
Nano2G: Initial (non-working) attempt to load an encrypted copy of the original firmware from the "osbk" image in the firmware partition. Code based on iloader.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23123 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
5a4ce22b77
commit
f2bf463d90
1 changed files with 104 additions and 2 deletions
|
@ -84,10 +84,96 @@ void fatal_error(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* aes_decrypt() and readfw() functions taken from iloader - (C)
|
||||||
|
Michael Sparmann and licenced under GPL v2 or later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void aes_decrypt(void* data, uint32_t size)
|
||||||
|
{
|
||||||
|
uint32_t ptr, i;
|
||||||
|
uint32_t go = 1;
|
||||||
|
|
||||||
|
PWRCONEXT &= ~0x400;
|
||||||
|
AESTYPE = 1;
|
||||||
|
AESUNKREG0 = 1;
|
||||||
|
AESUNKREG0 = 0;
|
||||||
|
AESCONTROL = 1;
|
||||||
|
AESKEYLEN = 8;
|
||||||
|
AESOUTSIZE = size;
|
||||||
|
AESAUXSIZE = 0x10;
|
||||||
|
AESINSIZE = 0x10;
|
||||||
|
AESSIZE3 = 0x10;
|
||||||
|
for (ptr = (size >> 2) - 4; ; ptr -= 4)
|
||||||
|
{
|
||||||
|
AESOUTADDR = (uint32_t)data + (ptr << 2);
|
||||||
|
AESINADDR = (uint32_t)data + (ptr << 2);
|
||||||
|
AESAUXADDR = (uint32_t)data + (ptr << 2);
|
||||||
|
AESSTATUS = 6;
|
||||||
|
AESGO = go;
|
||||||
|
go = 3;
|
||||||
|
while ((AESSTATUS & 6) == 0);
|
||||||
|
if (ptr == 0) break;
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
((uint32_t*)data)[ptr + i] ^= ((uint32_t*)data)[ptr + i - 4];
|
||||||
|
}
|
||||||
|
AESCONTROL = 0;
|
||||||
|
PWRCONEXT |= 0x400;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int readfw(char* filename, void* address, int* size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint32_t startsector = 0;
|
||||||
|
uint32_t buffer[0x200];
|
||||||
|
|
||||||
|
if (nand_read_sectors(0, 1, buffer) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (*((uint16_t*)((uint32_t)buffer + 0x1FE)) != 0xAA55)
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
for (i = 0x1C2; i < 0x200; i += 0x10) {
|
||||||
|
if (((uint8_t*)buffer)[i] == 0) {
|
||||||
|
startsector = *((uint16_t*)((uint32_t)buffer + i + 4))
|
||||||
|
| (*((uint16_t*)((uint32_t)buffer + i + 6)) << 16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startsector == 0)
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
if (nand_read_sectors(startsector, 1, buffer) != 0)
|
||||||
|
return -4;
|
||||||
|
|
||||||
|
if (buffer[0x40] != 0x5B68695D)
|
||||||
|
return -5;
|
||||||
|
|
||||||
|
if (nand_read_sectors(startsector + 1 + (buffer[0x41] >> 11), 1, buffer) != 0)
|
||||||
|
return -6;
|
||||||
|
|
||||||
|
for (i = 0; i < 0x1FE; i += 10) {
|
||||||
|
if (memcmp(&buffer[i], filename, 8) == 0) {
|
||||||
|
uint32_t filesector = startsector + 1 + (buffer[i + 3] >> 11);
|
||||||
|
*size = buffer[i + 4];
|
||||||
|
|
||||||
|
if (nand_read_sectors(filesector, ((*size + 0x7FF) >> 11), address) != 0)
|
||||||
|
return -7;
|
||||||
|
|
||||||
|
/* Success! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nothing found */
|
||||||
|
return -8;
|
||||||
|
}
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int btn;
|
int btn;
|
||||||
|
int size;
|
||||||
int rc;
|
int rc;
|
||||||
bool button_was_held;
|
bool button_was_held;
|
||||||
|
|
||||||
|
@ -144,10 +230,18 @@ void main(void)
|
||||||
/* If either the hold switch was on, or the Menu button was held, then
|
/* If either the hold switch was on, or the Menu button was held, then
|
||||||
try the Apple firmware */
|
try the Apple firmware */
|
||||||
|
|
||||||
|
verbose = true;
|
||||||
printf("Loading original firmware...");
|
printf("Loading original firmware...");
|
||||||
|
|
||||||
/* TODO */
|
if ((rc = readfw("DNANkbso", (void*)0x08000000, &size)) < 0) {
|
||||||
fatal_error();
|
printf("readfw error %d",rc);
|
||||||
|
fatal_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we need to decrypt it */
|
||||||
|
printf("Decrypting %d bytes...",size);
|
||||||
|
|
||||||
|
aes_decrypt((void*)0x08000000, size);
|
||||||
} else {
|
} else {
|
||||||
printf("Loading Rockbox...");
|
printf("Loading Rockbox...");
|
||||||
rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE);
|
rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE);
|
||||||
|
@ -162,10 +256,18 @@ void main(void)
|
||||||
printf("Rockbox loaded.");
|
printf("Rockbox loaded.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* If we get here, we have a new firmware image at 0x08000000, run it */
|
/* If we get here, we have a new firmware image at 0x08000000, run it */
|
||||||
|
printf("Executing...");
|
||||||
|
|
||||||
disable_irq();
|
disable_irq();
|
||||||
|
|
||||||
|
/* Remap the bootrom back to zero - that's how the NOR bootloader leaves
|
||||||
|
it.
|
||||||
|
*/
|
||||||
|
// This won't work, as we are running from IRAM mapped to 0x0...
|
||||||
|
//MIUCON &= ~1;
|
||||||
|
|
||||||
/* Branch to start of DRAM */
|
/* Branch to start of DRAM */
|
||||||
asm volatile("ldr pc, =0x08000000");
|
asm volatile("ldr pc, =0x08000000");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue