$2 USB crypto token for use with GPG and SSH

If you are interrested in security devices this post may be for you. Recently I’ve found a software which makes a GPG security device out of a STM32. It’s called Gnuk. You just need a compatible board, programmer, flash the firmware and you are ready to go. I was just hoping to find some cheap device to flash to play with it.

My next condition was it has to come with nice casing – I won’t carry some unprotected dev board in my pocket – ideally an USB key. Devices recommended in project itself were either not available anymore or expensive or just plain boards.


After a short research on google and aliexpress I found ST-link programmer clones. They are very cheap, have nice aluminium case and should contain STM32F103. So I ordered one. The advantage is that if you don’t have STM programmer, you can order two and you will have everything needed.

When it came it looked very nice so I tore it right down:

It was a little disappointment when I saw the chip – STM32F101. I was afraid that I’ll need to port the software and moreover according to specs it shouldn’t have USB phy so I though they bit-banged the USB interface. Then I found one page where they discussed these devices and and they mentioned that in fact they have USB and they are compatible with F103.

So I gave it a try.


First I built the firmware:

danman@silverhorse:~$ git clone git://anonscm.debian.org/gnuk/gnuk/gnuk.git
Cloning into 'gnuk'...
remote: Counting objects: 11644, done.
remote: Compressing objects: 100% (3812/3812), done.
remote: Total 11644 (delta 8560), reused 10561 (delta 7749)
Receiving objects: 100% (11644/11644), 12.04 MiB | 1.69 MiB/s, done.
Resolving deltas: 100% (8560/8560), done.
danman@silverhorse:~$ cd gnuk/
danman@silverhorse:~/gnuk$ git submodule update --init
Submodule 'chopstx' (git://anonscm.debian.org/gnuk/chopstx/chopstx.git) registered for path 'chopstx'
Cloning into '/home/danman/gnuk/chopstx'...
Submodule path 'chopstx': checked out '87767f1be5d8d4adac8d23a285250299eccee3fb'
danman@silverhorse:~/gnuk$ cd src/
danman@silverhorse:~/gnuk/src$ ./configure --vidpid=234b:0000 --target=ST_DONGLE
Header file is: board-st-dongle.h
Debug option disabled
Configured for bare system (no-DFU)
PIN pad option disabled
CERT.3 Data Object is NOT supported
Card insert/removal by HID device is NOT supported
Life cycle management is NOT supported
danman@silverhorse:~/gnuk/src$ make
mkdir -p build

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/main.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/main.o.d -I. -I../polarssl/include -I../chopstx main.c -o build/main.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/call-rsa.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/call-rsa.o.d -I. -I../polarssl/include -I../chopstx call-rsa.c -o build/call-rsa.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/mcu-stm32f103.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/mcu-stm32f103.o.d -I. -I../polarssl/include -I../chopstx mcu-stm32f103.c -o build/mcu-stm32f103.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/usb_desc.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/usb_desc.o.d -I. -I../polarssl/include -I../chopstx usb_desc.c -o build/usb_desc.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/usb_ctrl.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/usb_ctrl.o.d -I. -I../polarssl/include -I../chopstx usb_ctrl.c -o build/usb_ctrl.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/usb-ccid.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/usb-ccid.o.d -I. -I../polarssl/include -I../chopstx usb-ccid.c -o build/usb-ccid.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/openpgp.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/openpgp.o.d -I. -I../polarssl/include -I../chopstx openpgp.c -o build/openpgp.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/ac.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/ac.o.d -I. -I../polarssl/include -I../chopstx ac.c -o build/ac.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/openpgp-do.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/openpgp-do.o.d -I. -I../polarssl/include -I../chopstx openpgp-do.c -o build/openpgp-do.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/flash.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/flash.o.d -I. -I../polarssl/include -I../chopstx flash.c -o build/flash.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/bn.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/bn.o.d -I. -I../polarssl/include -I../chopstx bn.c -o build/bn.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/mod.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/mod.o.d -I. -I../polarssl/include -I../chopstx mod.c -o build/mod.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/modp256r1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/modp256r1.o.d -I. -I../polarssl/include -I../chopstx modp256r1.c -o build/modp256r1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/jpc_p256r1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/jpc_p256r1.o.d -I. -I../polarssl/include -I../chopstx jpc_p256r1.c -o build/jpc_p256r1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/ec_p256r1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/ec_p256r1.o.d -I. -I../polarssl/include -I../chopstx ec_p256r1.c -o build/ec_p256r1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/call-ec_p256r1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/call-ec_p256r1.o.d -I. -I../polarssl/include -I../chopstx call-ec_p256r1.c -o build/call-ec_p256r1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/modp256k1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/modp256k1.o.d -I. -I../polarssl/include -I../chopstx modp256k1.c -o build/modp256k1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/jpc_p256k1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/jpc_p256k1.o.d -I. -I../polarssl/include -I../chopstx jpc_p256k1.c -o build/jpc_p256k1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/ec_p256k1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/ec_p256k1.o.d -I. -I../polarssl/include -I../chopstx ec_p256k1.c -o build/ec_p256k1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/call-ec_p256k1.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/call-ec_p256k1.o.d -I. -I../polarssl/include -I../chopstx call-ec_p256k1.c -o build/call-ec_p256k1.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/mod25638.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/mod25638.o.d -I. -I../polarssl/include -I../chopstx mod25638.c -o build/mod25638.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/ecc-edwards.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/ecc-edwards.o.d -I. -I../polarssl/include -I../chopstx ecc-edwards.c -o build/ecc-edwards.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/ecc-mont.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/ecc-mont.o.d -I. -I../polarssl/include -I../chopstx ecc-mont.c -o build/ecc-mont.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/sha512.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/sha512.o.d -I. -I../polarssl/include -I../chopstx sha512.c -o build/sha512.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/random.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/random.o.d -I. -I../polarssl/include -I../chopstx random.c -o build/random.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/neug.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/neug.o.d -I. -I../polarssl/include -I../chopstx neug.c -o build/neug.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/sha256.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/sha256.o.d -I. -I../polarssl/include -I../chopstx sha256.c -o build/sha256.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -g -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/bignum.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/bignum.o.d -I. -I../polarssl/include -I../chopstx ../polarssl/library/bignum.c -o build/bignum.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/rsa.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/rsa.o.d -I. -I../polarssl/include -I../chopstx ../polarssl/library/rsa.c -o build/rsa.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/aes.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/aes.o.d -I. -I../polarssl/include -I../chopstx ../polarssl/library/aes.c -o build/aes.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/entry.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/entry.o.d -I. -I../polarssl/include -I../chopstx ../chopstx/entry.c -o build/entry.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/chopstx.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/chopstx.o.d -I. -I../polarssl/include -I../chopstx ../chopstx/chopstx.c -o build/chopstx.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/eventflag.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/eventflag.o.d -I. -I../polarssl/include -I../chopstx ../chopstx/eventflag.c -o build/eventflag.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/sys-stm32f103.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/sys-stm32f103.o.d -I. -I../polarssl/include -I../chopstx ../chopstx/mcu/sys-stm32f103.c -o build/sys-stm32f103.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/usb-stm32f103.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/usb-stm32f103.o.d -I. -I../polarssl/include -I../chopstx ../chopstx/mcu/usb-stm32f103.c -o build/usb-stm32f103.o

arm-none-eabi-gcc -c -mcpu=cortex-m3 -O3 -Os -g -ffunction-sections -fdata-sections -fno-common -Wall -Wextra -Wstrict-prototypes -Wa,-alms=build/adc-stm32f103.lst -mthumb -mno-thumb-interwork -DTHUMB -MD -MP -MF .dep/adc-stm32f103.o.d -I. -I../polarssl/include -I../chopstx ../chopstx/contrib/adc-stm32f103.c -o build/adc-stm32f103.o

arm-none-eabi-gcc build/main.o build/call-rsa.o build/mcu-stm32f103.o build/usb_desc.o build/usb_ctrl.o build/usb-ccid.o build/openpgp.o build/ac.o build/openpgp-do.o build/flash.o build/bn.o build/mod.o build/modp256r1.o build/jpc_p256r1.o build/ec_p256r1.o build/call-ec_p256r1.o build/modp256k1.o build/jpc_p256k1.o build/ec_p256k1.o build/call-ec_p256k1.o build/mod25638.o build/ecc-edwards.o build/ecc-mont.o build/sha512.o build/random.o build/neug.o build/sha256.o build/bignum.o build/rsa.o build/aes.o build/entry.o build/chopstx.o build/eventflag.o build/sys-stm32f103.o build/usb-stm32f103.o build/adc-stm32f103.o -mcpu=cortex-m3 -nostartfiles -Tgnuk.ld -Wl,-Map=build/gnuk.map,--cref,--no-warn-mismatch,--gc-sections -mthumb -mno-thumb-interwork -o build/gnuk.elf
arm-none-eabi-objcopy -O binary build/gnuk.elf build/gnuk.bin


Then I connected my J-link programmer. VCC and GND was easy to probe and the rest two pins (SWD, SWCLK) were identified by trying. The order of pins is following (first is closest to USB):

  • GND
  • 3V3

For connecting using openocd I used a config which I had used before for F103.

#daemon configuration
telnet_port 4444
gdb_port 3333

interface jlink
transport select swd

# The chip has 64KB sram
set WORKAREASIZE 0x10000

source [find target/stm32f1x.cfg]
#adapter_khz 100
gdb_breakpoint_override hard

After starting openocd, I unlocked flash, and burned new firmware:

$ openocd stm32f103.cfg

#in new shell
$ telnet localhost 4444> 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
> stm32f1x unlock 0
Device Security Bit Set
target halted due to breakpoint, current mode: Thread 
xPSR: 0x61000000 pc: 0x2000003a msp: 0x20000800
stm32x unlocked.
INFO: a reset or power cycle is required for the new settings to take effect.
> reset halt 
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
> flash write_bank 0 ./src/build/gnuk.bin 0 
wrote 115712 bytes from file ./src/build/gnuk.bin to flash bank 0 at offset 0x00000000 in 3.776280s (29.924 KiB/s)
> reset

The device identified to PC as Gnuk!

3011.693402] usb 2-3: New USB device found, idVendor=234b, idProduct=0000
[ 3011.693406] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 3011.693408] usb 2-3: Product: Gnuk Token
[ 3011.693410] usb 2-3: Manufacturer: Free Software Initiative of Japan
[ 3011.693412] usb 2-3: SerialNumber: FSIJ-1.2.4-67055638

After some brief tests it was clear that it works.

Physical button

This was nice but I wanted to push it further – I wanted to implement HW button to confirm crypto operations. For this I used the breakout IO pins. First I used just some jumper wires to test my patches to gnuk:

When I was happy with the function I was going to add a real button, so I desoldered the pin header.

I’ve had some PCB button at hand and I wanted to solder it directly to the edge of the board. For this I needed one IO pin which will be in the right distance from GND pin. Unfortunately there no such pin. So as a workaround, I soldered the button between two IO pins (NRST, SWIM) and I set one of them (SWIM) to zero by firmware.

Now I have USB GPG token which is small, looks nice and have desired features.

You can download my patches here gnuk-button.


Now lets see how the whole thing works with SSH. You can get more info on these sites:

I’m going to provide just some crash-course here.

  1. disable pcscd
    $ sudo systemctl disable pcscd
    Synchronizing state of pcscd.service with SysV service script with /lib/systemd/systemd-sysv-install.
    Executing: /lib/systemd/systemd-sysv-install disable pcscd
    Removed /etc/systemd/system/sockets.target.wants/pcscd.socket.
  2. install packages:
    $ sudo apt-get install opensc pcscd paperkey haveged gnupg2 gnupg-agent pinentry-curses libccid scdaemon libksba8 libpth20
  3. check token info
    $ gpg --card-status
    Reader ...........: 234B:0000:FSIJ-1.2.4-67055638:0
    Application ID ...: D276000124010200FFFE670556380000
    Version ..........: 2.0
    Manufacturer .....: unmanaged S/N range
    Serial number ....: 67055638
    Name of cardholder: [not set]
    Language prefs ...: [not set]
    Sex ..............: unspecified
    URL of public key : [not set]
    Login data .......: [not set]
    Signature PIN ....: forced
    Key attributes ...: rsa2048 rsa2048 rsa2048
    Max. PIN lengths .: 127 127 127
    PIN retry counter : 3 3 3
    Signature counter : 0
    Signature key ....: [none]
    Encryption key....: [none]
    Authentication key: [none]
    General key info..: [none]
  4. generate keys on token (private key never leaves token)
    $ gpg --card-edit
    gpg/card> admin
    Admin commands are allowed
    gpg/card> generate
    Make off-card backup of encryption key? (Y/n) n
    Please note that the factory settings of the PINs are
     PIN = '123456' Admin PIN = '12345678'
    You should change them using the command --change-pin
    What keysize do you want for the Signature key? (2048) 
    What keysize do you want for the Encryption key? (2048) 
    What keysize do you want for the Authentication key? (2048) 
    Please specify how long the key should be valid.
     0 = key does not expire
     <n> = key expires in n days
     <n>w = key expires in n weeks
     <n>m = key expires in n months
     <n>y = key expires in n years
    Key is valid for? (0) 
    Key does not expire at all
    Is this correct? (y/N) y
    GnuPG needs to construct a user ID to identify your key.
    Real name: Igor Timko
    Email address: 
    You selected this USER-ID:
     "Igor Timko"
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
    ...this will take about 5 min and no progress is shown instead of shining LED on token...
    gpg: key F0A5780AA5B8E99F marked as ultimately trusted
    gpg: revocation certificate stored as '/home/danman/.gnupg/openpgp-revocs.d/322A0733037B0B3854A4959EF0A5780AA5B8E99F.rev'
    public and secret key created and signed.
    gpg/card> quit
    pub rsa2048 2017-08-01 [SC]
    uid Igor Timko
    sub rsa2048 2017-08-01 [A]
    sub rsa2048 2017-08-01 [E]
  5. create or edit ~/.gnupg/gpg-agent.conf
    default-cache-ttl 600
    max-cache-ttl 7200
  6. (re)start gpg-agent
    $ killall -9 gpg-agent ; gpg-agent --daemon
    SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh; export SSH_AUTH_SOCK;
  7. add this line into your ~/.bashrc
    SSH_AUTH_SOCK=/run/user/1000/gnupg/S.gpg-agent.ssh; export SSH_AUTH_SOCK;
  8. open new shell and list your key
    $ ssh-add -L
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCzKNLGBEjXxFVrKS5/ivBMBjfnCJn404bUpoHFbhUXiuIyklWSwc6uhA+HO3pLvQPESkN834DYEy4uJoJIdzKOIBia+JtgtWOItKWVIvd90QThYsVtPdEYpbiMLS/hJ7BrFOuJ2A0L9sPPm9+8QiOZtXc5Qv5E6ua1skn6whwPxSx4QFqVL9TQ7pAxYusDGVmdPwUMSJyKj0sICPGYJBb+PSGa3KuDV3O53keJMj0SaLlVrruBeTUZXNsZ44s58g8TEC6hrKDPoZCxNyGf3l97iX2a0BB8HbmjXSyaaMQyHye09ITeQTAZqArxLxYd21m82iO+d2or9K4y/7S/DD/5 cardno:FFFE67055638
  9. Now you can add this key to your server and try to log-in.

If you have applied my patch with button, ssh starts logging in and then LED on your token starts to flash quickly. Now you have to press button on token to confirm authentication. You can see it on this video:

Feel free to ask any questions or comment.




9 thoughts on “$2 USB crypto token for use with GPG and SSH”

  1. I saw this article a few weeks ago and ordered two of these dongles almost immediately. They arrived today and I plan to get my hands dirty and test your project in a few days. One thing I noticed while setting up the code to compile is that the repos of gnuk and chopstx are a bit ahead and your code now has some limited “patcheability”. I’d suggest that instead of making the patches available, set up a repository with them already applied. This way everyone taking advantage of this wonderful discover can get the functionality you implemented and also receive the latest fixes for the original code. Nice work. Thank you!

    1. I wanted to include it in upstream but NIIBE doesn’t like this way of confirmation. Let me know if it worked for you.

  2. You did a good job detailing this post to a level, when even a novice can reproduce this project. I have ordered a pair of this tokens and successfully flashed the firmware.

    Here is some tweaks that I had to do.
    1) I have used this configuration for openocd:
    telnet_port 4444
    source [find interface/stlink-v2.cfg]
    source [find target/stm32f1x.cfg]

    2) openocd was giving me an error:
    Error: jtag status contains invalid mode value – communication failure
    To fix this just plug in both programmer and token to usb when flashing.

    3) Next flashes require erasing memory
    flash erase_sector 0 last

    4) patch could be applied still (12 dec 2017, revision c81544fffd2f89cb3cf1b791fe7adf21c75200ad)

    5) Button confirmation doesn’t work for me. The LED is flashing, but shorting pins RST and SWIM makes no effect (RST to GND didn’t work either)

    6) If you wish to remove keys from token, you can use tool/gnuk_remove_keys_libusb.py from gnuk.
    Don’t forget to kill gpg-agent/scdaemon etc (whatever could be using the usb device).

      1. It was authentication. Key generation was way too slow (I have waited 10 minutes without success), so I have ended with generating key on my PC.

        Btw, do you think it is a good idea to add some timeout to wait_button function?

Leave a Reply

Your email address will not be published. Required fields are marked *