boot directly st bootlaoder
This commit is contained in:
parent
97b715881b
commit
5a636d1ebe
@ -711,7 +711,12 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
|||||||
ctaphid_write(&wb, NULL, 0);
|
ctaphid_write(&wb, NULL, 0);
|
||||||
is_busy = 0;
|
is_busy = 0;
|
||||||
break;
|
break;
|
||||||
|
case CTAPHID_ENTERSTBOOT:
|
||||||
|
printf1(TAG_HID,"CTAPHID_ENTERBOOT\n");
|
||||||
|
boot_st_bootloader();
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
|
printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
|
||||||
ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND);
|
ctaphid_send_error(cid, CTAP1_ERR_INVALID_COMMAND);
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
// Custom commands between 0x40-0x7f
|
// Custom commands between 0x40-0x7f
|
||||||
#define CTAPHID_BOOT (TYPE_INIT | 0x50)
|
#define CTAPHID_BOOT (TYPE_INIT | 0x50)
|
||||||
#define CTAPHID_ENTERBOOT (TYPE_INIT | 0x51)
|
#define CTAPHID_ENTERBOOT (TYPE_INIT | 0x51)
|
||||||
|
#define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52)
|
||||||
|
|
||||||
#define ERR_INVALID_CMD 0x01
|
#define ERR_INVALID_CMD 0x01
|
||||||
#define ERR_INVALID_PAR 0x02
|
#define ERR_INVALID_PAR 0x02
|
||||||
|
@ -96,7 +96,7 @@ void ctap_overwrite_rk(int index,CTAP_residentKey * rk);
|
|||||||
|
|
||||||
// For Solo hacker
|
// For Solo hacker
|
||||||
void boot_solo_bootloader();
|
void boot_solo_bootloader();
|
||||||
|
void boot_st_bootloader();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@ typedef enum
|
|||||||
BootCheck = 0x42,
|
BootCheck = 0x42,
|
||||||
BootErase = 0x43,
|
BootErase = 0x43,
|
||||||
BootVersion = 0x44,
|
BootVersion = 0x44,
|
||||||
|
BootReboot = 0x45,
|
||||||
|
BootBootloader = 0x46,
|
||||||
} BootOperation;
|
} BootOperation;
|
||||||
|
|
||||||
|
|
||||||
@ -143,6 +145,17 @@ int bootloader_bridge(int klen, uint8_t * keyh)
|
|||||||
u2f_response_writeback(&version,1);
|
u2f_response_writeback(&version,1);
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
case BootReboot:
|
||||||
|
printf1(TAG_BOOT, "BootReboot.\r\n");
|
||||||
|
device_reboot();
|
||||||
|
break;
|
||||||
|
#ifndef SOLO_HACKER
|
||||||
|
case BootBootloader:
|
||||||
|
printf1(TAG_BOOT, "BootBootloader.\r\n");
|
||||||
|
flash_option_bytes_init(1);
|
||||||
|
boot_st_bootloader();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return CTAP1_ERR_INVALID_COMMAND;
|
return CTAP1_ERR_INVALID_COMMAND;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,7 @@ int main(int argc, char * argv[])
|
|||||||
{
|
{
|
||||||
uint8_t hidmsg[64];
|
uint8_t hidmsg[64];
|
||||||
uint32_t t1 = 0;
|
uint32_t t1 = 0;
|
||||||
|
uint32_t stboot_time = 0;
|
||||||
uint32_t boot = 1;
|
uint32_t boot = 1;
|
||||||
|
|
||||||
set_logging_mask(
|
set_logging_mask(
|
||||||
@ -94,6 +95,7 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SOLO_HACKER
|
#ifdef SOLO_HACKER
|
||||||
|
stboot_time = millis();
|
||||||
if ( RCC->CSR & (1<<29) )// check if there was independent watchdog reset
|
if ( RCC->CSR & (1<<29) )// check if there was independent watchdog reset
|
||||||
{
|
{
|
||||||
RCC->CSR |= (1<<23); // clear reset flags
|
RCC->CSR |= (1<<23); // clear reset flags
|
||||||
@ -147,6 +149,17 @@ int main(int argc, char * argv[])
|
|||||||
delay(250);
|
delay(250);
|
||||||
device_reboot();
|
device_reboot();
|
||||||
}
|
}
|
||||||
|
#ifdef SOLO_HACKER
|
||||||
|
// Boot ST bootloader if button is held for 2s
|
||||||
|
if (!device_is_button_pressed())
|
||||||
|
{
|
||||||
|
stboot_time = millis();
|
||||||
|
}
|
||||||
|
if ((millis() - stboot_time) > 2000)
|
||||||
|
{
|
||||||
|
boot_st_bootloader();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should never get here
|
// Should never get here
|
||||||
|
@ -486,6 +486,18 @@ void ctap_overwrite_rk(int index,CTAP_residentKey * rk)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void boot_st_bootloader()
|
||||||
|
{
|
||||||
|
__disable_irq();
|
||||||
|
|
||||||
|
__set_MSP(*((uint32_t *)0x1fff0000));
|
||||||
|
|
||||||
|
((void (*)(void)) (*((uint32_t *)0x1fff0004)))();
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
void boot_solo_bootloader()
|
void boot_solo_bootloader()
|
||||||
{
|
{
|
||||||
LL_IWDG_Enable(IWDG);
|
LL_IWDG_Enable(IWDG);
|
||||||
|
@ -22,9 +22,12 @@ class SoloBootloader:
|
|||||||
check = 0x42
|
check = 0x42
|
||||||
erase = 0x43
|
erase = 0x43
|
||||||
version = 0x44
|
version = 0x44
|
||||||
|
reboot = 0x45
|
||||||
|
st_dfu = 0x46
|
||||||
|
|
||||||
HIDCommandBoot = 0x50
|
HIDCommandBoot = 0x50
|
||||||
HIDCommandEnterBoot = 0x51
|
HIDCommandEnterBoot = 0x51
|
||||||
|
HIDCommandEnterSTBoot = 0x52
|
||||||
|
|
||||||
TAG = b'\x8C\x27\x90\xf6'
|
TAG = b'\x8C\x27\x90\xf6'
|
||||||
|
|
||||||
@ -45,6 +48,13 @@ class Programmer():
|
|||||||
""" option to reboot after programming """
|
""" option to reboot after programming """
|
||||||
self.reboot = val
|
self.reboot = val
|
||||||
|
|
||||||
|
def reboot(self,val):
|
||||||
|
""" option to reboot after programming """
|
||||||
|
try:
|
||||||
|
self.exchange(SoloBootloader.reboot)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
def find_device(self,):
|
def find_device(self,):
|
||||||
dev = next(CtapHidDevice.list_devices(), None)
|
dev = next(CtapHidDevice.list_devices(), None)
|
||||||
if not dev:
|
if not dev:
|
||||||
@ -64,6 +74,11 @@ class Programmer():
|
|||||||
|
|
||||||
return cmd + addr[:3] + SoloBootloader.TAG + length + data
|
return cmd + addr[:3] + SoloBootloader.TAG + length + data
|
||||||
|
|
||||||
|
def send_only_hid(self, cmd, data):
|
||||||
|
if type(data) != type(b''):
|
||||||
|
data = struct.pack('%dB' % len(data), *[ord(x) for x in data])
|
||||||
|
self.dev._dev.InternalSend(0x80 | cmd, bytearray(data))
|
||||||
|
|
||||||
def send_data_hid(self, cmd, data):
|
def send_data_hid(self, cmd, data):
|
||||||
if type(data) != type(b''):
|
if type(data) != type(b''):
|
||||||
data = struct.pack('%dB' % len(data), *[ord(x) for x in data])
|
data = struct.pack('%dB' % len(data), *[ord(x) for x in data])
|
||||||
@ -121,6 +136,18 @@ class Programmer():
|
|||||||
self.send_data_hid(CTAPHID.INIT, '\x11\x11\x11\x11\x11\x11\x11\x11')
|
self.send_data_hid(CTAPHID.INIT, '\x11\x11\x11\x11\x11\x11\x11\x11')
|
||||||
self.send_data_hid(SoloBootloader.HIDCommandEnterBoot, '')
|
self.send_data_hid(SoloBootloader.HIDCommandEnterBoot, '')
|
||||||
|
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
if self.exchange == self.exchange_hid:
|
||||||
|
self.send_only_hid(SoloBootloader.HIDCommandEnterSTBoot, '')
|
||||||
|
else:
|
||||||
|
req = Programmer.format_request(SoloBootloader.st_dfu)
|
||||||
|
self.send_only_hid(SoloBootloader.HIDCommandBoot, req)
|
||||||
|
|
||||||
def program_file(self,name):
|
def program_file(self,name):
|
||||||
|
|
||||||
if name.lower().endswith('.json'):
|
if name.lower().endswith('.json'):
|
||||||
@ -201,12 +228,14 @@ def attempt_to_boot_bootloader(p):
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("<firmware>", help = 'firmware file. Either a JSON or hex file. JSON file contains signature while hex does not.')
|
parser.add_argument("[firmware]", nargs='?', default='', help = 'firmware file. Either a JSON or hex file. JSON file contains signature while hex does not.')
|
||||||
parser.add_argument("--use-hid", action="store_true", help = 'Programs using custom HID command (default). Quicker than using U2F authenticate which is what a browser has to use.')
|
parser.add_argument("--use-hid", action="store_true", help = 'Programs using custom HID command (default). Quicker than using U2F authenticate which is what a browser has to use.')
|
||||||
parser.add_argument("--use-u2f", action="store_true", help = 'Programs using U2F authenticate. This is what a web application will use.')
|
parser.add_argument("--use-u2f", action="store_true", help = 'Programs using U2F authenticate. This is what a web application will use.')
|
||||||
parser.add_argument("--no-reset", action="store_true", help = 'Don\'t reset after writing firmware. Stay in bootloader mode.')
|
parser.add_argument("--no-reset", action="store_true", help = 'Don\'t reset after writing firmware. Stay in bootloader mode.')
|
||||||
parser.add_argument("--reset-only", action="store_true", help = 'Don\'t write anything, try to boot without a signature.')
|
parser.add_argument("--reset-only", action="store_true", help = 'Don\'t write anything, try to boot without a signature.')
|
||||||
|
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("--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. Make sure to reprogram the option bytes just to be safe.')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
print()
|
print()
|
||||||
|
|
||||||
@ -223,6 +252,15 @@ if __name__ == '__main__':
|
|||||||
attempt_to_boot_bootloader(p)
|
attempt_to_boot_bootloader(p)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
if args.reboot:
|
||||||
|
p.reboot()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if args.st_dfu:
|
||||||
|
print('Sending command to boot into ST DFU...')
|
||||||
|
p.enter_st_dfu()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print('version is ', p.version())
|
print('version is ', p.version())
|
||||||
except CtapError as e:
|
except CtapError as e:
|
||||||
@ -234,6 +272,11 @@ if __name__ == '__main__':
|
|||||||
attempt_to_boot_bootloader(p)
|
attempt_to_boot_bootloader(p)
|
||||||
|
|
||||||
if not args.reset_only:
|
if not args.reset_only:
|
||||||
p.program_file(args.__dict__['<firmware>'])
|
fw = args.__dict__['[firmware]']
|
||||||
|
if fw == '':
|
||||||
|
print('Need to supply firmware filename.')
|
||||||
|
args.print_help()
|
||||||
|
sys.exit(1)
|
||||||
|
p.program_file(fw)
|
||||||
else:
|
else:
|
||||||
p.exchange(SoloBootloader.done,0,b'A'*64)
|
p.exchange(SoloBootloader.done,0,b'A'*64)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user