Programming the FST-01 (gnuk) with a Bus Pirate + OpenOCD
Last year at DebConf14 Lucas authorized the purchase of a handful of gnuk devices, one of which I obtained. At the time it only supported 2048 bit RSA keys. I took a look at what might be involved in adding 4096 bit support during DebConf and managed to brick my device several times in doing so. Thankfully gniibe was on hand with his STLinkV2 to help me recover. However subsequently I was loathe to experiment further at home until I had a suitable programmer.
As it is this year has been busy and the 1.1.x release train is supposed to have 4K RSA (as well as ECC) support. DebConf15 is coming up and I felt I should finally sort out playing with the device properly. I still didn’t have a suitable programmer. Or did I? Could my trusty Bus Pirate help?
The FST-01 has an STM32F103TB on it. There is an exposed SWD port. I found a few projects that claimed to do SWD with a Bus Pirate - Will Donnelly has a much cloned Python project, the MC HCK project have a programmer in Ruby and there’s LibSWD though that’s targeted to smarter programmers. None of them worked for me; I could get the Python bits as far as correctly doing the ID of the device, but not reading the option bytes or successfully flashing (though I did manage an erase).
Enter the old favourite, OpenOCD. This already has SWD support and there’s an outstanding commit request to add Bus Pirate support. NodoNogard has a post on using the ST-Link/V2 with OpenOCD and the FST-01 which provided some useful pointers. I grabbed the patch from Gerrit, applied it to OpenOCD git and built an
openocd.cfg that contained:
source [find interface/buspirate.cfg] buspirate_port /dev/ttyUSB0 buspirate_vreg 1 buspirate_mode normal transport select swd source [find target/stm32f1x.cfg]
My BP has the Seeed Studio probe cable, so my hookups look like this:
That’s BP MOSI (grey) to SWD IO, BP CLK (purple) to SWD CLK, BP 3.3V (red) to FST-01 PWR and BP GND (brown) to FST-01 GND. Once that was done I fired up OpenOCD in one terminal and did the following in another:
$ telnet localhost 4444 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > reset halt target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc Info : device id = 0x20036410 Info : SWD IDCODE 0x1ba01477 Error: Failed to read memory at 0x1ffff7e2 Warn : STM32 flash size failed, probe inaccurate - assuming 128k flash Info : flash size = 128kbytes > stm32f1x unlock 0 Device Security Bit Set stm32x unlocked. INFO: a reset or power cycle is required for the new settings to take effect. > reset halt target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc > flash write_image erase /home/noodles/checkouts/gnuk/src/build/gnuk.elf auto erase enabled wrote 109568 bytes from file /home/noodles/checkouts/gnuk/src/build/gnuk.elf in 95.055603s (1.126 KiB/s) > stm32f1x lock 0 stm32x locked > reset halt target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08000280 msp: 0x20005000
Then it was a matter of disconnecting the gnuk from the BP, plugging it into my USB port and seeing it come up successfully:
usb 1-2: new full-speed USB device number 11 using xhci_hcd usb 1-2: New USB device found, idVendor=234b, idProduct=0000 usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 usb 1-2: Product: Gnuk Token usb 1-2: Manufacturer: Free Software Initiative of Japan usb 1-2: SerialNumber: FSIJ-1.1.7-87063020 usb 1-2: ep 0x82 - rounding interval to 1024 microframes, ep desc says 2040 microframes
More once I actually have a 4K key loaded on it.