option to disable solo bootloader

pull/39/head
Conor Patrick 2018-12-05 00:14:28 -05:00
rodzic b9ebde22e5
commit beedc24839
6 zmienionych plików z 101 dodań i 23 usunięć

Wyświetl plik

@ -24,6 +24,7 @@ typedef enum
BootVersion = 0x44,
BootReboot = 0x45,
BootBootloader = 0x46,
BootDisable = 0x47,
} BootOperation;
@ -46,12 +47,30 @@ static void erase_application()
}
}
#define LAST_ADDR (APPLICATION_END_ADDR-2048 + 8)
#define LAST_PAGE (APPLICATION_END_PAGE-1)
static void disable_bootloader()
{
uint8_t page[PAGE_SIZE];
memmove(page, (uint8_t*)LAST_ADDR, PAGE_SIZE);
memset(page+PAGE_SIZE -4, 0, 4);
flash_erase_page(LAST_PAGE);
flash_write(LAST_ADDR, page, PAGE_SIZE);
}
static void authorize_application()
{
uint32_t zero = 0;
uint32_t * ptr;
ptr = (uint32_t *)AUTH_WORD_ADDR;
flash_write((uint32_t)ptr, (uint8_t *)&zero, 4);
// uint32_t zero = 0;
// uint32_t * ptr;
// ptr = (uint32_t *)AUTH_WORD_ADDR;
// flash_write((uint32_t)ptr, (uint8_t *)&zero, 4);
uint8_t page[PAGE_SIZE];
if (is_authorized_to_boot())
return;
memmove(page, (uint8_t*)LAST_ADDR, PAGE_SIZE);
memset(page+PAGE_SIZE -8, 0, 4);
flash_erase_page(LAST_PAGE);
flash_write(LAST_ADDR, page, PAGE_SIZE);
}
int is_authorized_to_boot()
@ -60,6 +79,12 @@ int is_authorized_to_boot()
return *auth == 0;
}
int is_bootloader_disabled()
{
uint32_t * auth = (uint32_t *)(AUTH_WORD_ADDR+4);
return *auth == 0;
}
int bootloader_bridge(int klen, uint8_t * keyh)
{
static int has_erased = 0;
@ -150,7 +175,22 @@ int bootloader_bridge(int klen, uint8_t * keyh)
break;
case BootReboot:
printf1(TAG_BOOT, "BootReboot.\r\n");
device_reboot();
REBOOT_FLAG = 1;
break;
case BootDisable:
printf1(TAG_BOOT, "BootDisable %08lx.\r\n", *(uint32_t *)(AUTH_WORD_ADDR+4));
if (req->payload[0] == 0xcd && req->payload[1] == 0xde
&& req->payload[2] == 0xba && req->payload[3] == 0xaa)
{
disable_bootloader();
version = 0;
u2f_response_writeback(&version,1);
}
else
{
version = CTAP2_ERR_OPERATION_DENIED;
u2f_response_writeback(&version,1);
}
break;
#ifdef SOLO_HACKER
case BootBootloader:

Wyświetl plik

@ -95,22 +95,26 @@ int main(int argc, char * argv[])
}
}
#ifdef SOLO_HACKER
stboot_time = millis();
if ( RCC->CSR & (1<<29) )// check if there was independent watchdog reset
if (!is_bootloader_disabled())
{
RCC->CSR |= (1<<23); // clear reset flags
goto start_bootloader;
stboot_time = millis();
if ( RCC->CSR & (1<<29) )// check if there was independent watchdog reset
{
RCC->CSR |= (1<<23); // clear reset flags
goto start_bootloader;
}
}
#endif
if (boot && is_authorized_to_boot())
if (is_authorized_to_boot() && (boot || is_bootloader_disabled()))
{
BOOT_boot();
}
else
{
printf1(TAG_RED,"Not authorized to boot\r\n");
printf1(TAG_RED,"Not authorized to boot (%08x == %08lx)\r\n", AUTH_WORD_ADDR, *(uint32_t*)AUTH_WORD_ADDR);
}
start_bootloader:
@ -156,7 +160,7 @@ int main(int argc, char * argv[])
{
stboot_time = millis();
}
if ((millis() - stboot_time) > 2000)
if ((millis() - stboot_time) > 5000)
{
boot_st_bootloader();
}

Wyświetl plik

@ -25,4 +25,9 @@ first[AUTH_WORD_ADDR+1] = 0
first[AUTH_WORD_ADDR+2] = 0
first[AUTH_WORD_ADDR+3] = 0
first[AUTH_WORD_ADDR+4] = 0xff
first[AUTH_WORD_ADDR+5] = 0xff
first[AUTH_WORD_ADDR+6] = 0xff
first[AUTH_WORD_ADDR+7] = 0xff
first.tofile(sys.argv[len(sys.argv)-1], format='hex')

Wyświetl plik

@ -170,7 +170,7 @@ void heartbeat()
{
state = !state;
}
if (but) led_rgb((val*b));
if (but) led_rgb(((val * r)<<8) | ((val*b) << 16) | (val*g));
else
led_rgb(((val * g)<<8) | ((val*r) << 16) | (val*b));
}

Wyświetl plik

@ -20,8 +20,13 @@ static void flash_unlock()
// Locks flash and turns off DFU
void flash_option_bytes_init(int boot_from_dfu)
{
#if DEBUG_LEVEL
#ifndef FLASH_ROP
#define FLASH_ROP 0
#endif
#if FLASH_ROP == 0
uint32_t val = 0xfffff8aa;
#elif FLASH_ROP == 2
uint32_t val = 0xfffff8cc;
#else
uint32_t val = 0xfffff8b9;
#endif

Wyświetl plik

@ -24,6 +24,7 @@ class SoloBootloader:
version = 0x44
reboot = 0x45
st_dfu = 0x46
disable = 0x47
HIDCommandBoot = 0x50
HIDCommandEnterBoot = 0x51
@ -136,21 +137,24 @@ class Programmer():
self.send_data_hid(CTAPHID.INIT, '\x11\x11\x11\x11\x11\x11\x11\x11')
self.send_data_hid(SoloBootloader.HIDCommandEnterBoot, '')
def is_solo_bootloader(self,):
try:
p.version()
return True
except CtapError as e:
if e.code == CtapError.ERR.INVALID_COMMAND:
pass
else:
raise (e)
return False
def enter_st_dfu(self,):
"""
If solo is configured as solo hacker or something similar,
this command will tell the token to boot directly to the st DFU
so it can be reprogrammed. Warning, you could brick your device.
"""
soloboot = False
try:
p.version()
soloboot = True
except CtapError as e:
if e.code == CtapError.ERR.INVALID_COMMAND:
pass
else:
raise (e)
soloboot = self.is_solo_bootloader()
if soloboot or self.exchange == self.exchange_u2f:
req = Programmer.format_request(SoloBootloader.st_dfu)
@ -158,6 +162,21 @@ class Programmer():
else:
self.send_only_hid(SoloBootloader.HIDCommandEnterSTBoot, '')
def disable_solo_bootloader(self,):
"""
Disables the Solo bootloader. Only do this if you want to void the possibility
of any updates.
If you've started from a solo hacker, make you you've programmed a final/production build!
"""
ret = self.exchange(SoloBootloader.disable, 0, b'\xcd\xde\xba\xaa') # magic number
if ret[0] != CtapError.ERR.SUCCESS:
print('Failed to disable bootloader')
return False
time.sleep(0.1)
self.exchange(SoloBootloader.reboot)
return True
def program_file(self,name):
if name.lower().endswith('.json'):
@ -246,6 +265,7 @@ if __name__ == '__main__':
parser.add_argument("--reboot", action="store_true", help = 'Tell bootloader to reboot.')
parser.add_argument("--enter-bootloader", action="store_true", help = 'Don\'t write anything, try to enter bootloader. Typically only supported by Solo Hacker builds.')
parser.add_argument("--st-dfu", action="store_true", help = 'Don\'t write anything, try to enter ST DFU. Warning, you could brick your Solo if you overwrite everything. You should reprogram the option bytes just to be safe (boot to Solo bootloader first, then run this command).')
parser.add_argument("--disable", action="store_true", help = 'Disable the Solo bootloader. Cannot be undone. No future updates can be applied.')
args = parser.parse_args()
print()
@ -271,6 +291,10 @@ if __name__ == '__main__':
p.enter_st_dfu()
sys.exit(0)
if args.disable:
p.disable_solo_bootloader()
sys.exit(0)
try:
print('version is ', p.version())
except CtapError as e: