Homemade GnuK with ST-Dongle
Table of contents
THIS IS NOT A DETAILED TUTORIAL!
IF THERE IS ANY PROBLEM, YOU’RE ON YOUR OWN!
Objectives¶
- Convert ST-Link clones (ST-Dongle) to GnuK.
- Add a button to the dongles and use GnuK’s built-in support for it.
- Upgrade existing GnuK dongles.
Environment¶
- OS: Manjaro
- Software
- Python 3.9 (PipEnv)
- GNU Arm Embedded Toolchain (10.3-2021.07)
- GnuK v1.2.19
STABLE-BRANCH-1-2
(57fdadf)
Modify the hardware to add a button¶
According to related datasheets, PA5(CLK) is available as an input pulled high. So, I soldered a button between PA5(CLK) and GND. The extra reason why I choose PA5(CLK) instead of other pins is written in the next section.
Modify the source code of Gnuk¶
Get a copy of the code first.
git clone --recursive https://salsa.debian.org/gnuk-team/gnuk/gnuk.git gnuk
When writing this post, the latest version of Gnuk is 1.2.19, and is available
at branch STABLE-BRANCH-1-2
(57fdadf). I’m working on this branch in this post,
so make sure you’ve checked it out.
The latest Gnuk firmware has already implemented the acknowledge button, and the
only problem is to decide the pin to use. After digging around, I found the core
part is a function called ackbtn_init
in chopstx/contrib/ackbtn-stm32f103.c
in
a switch-case block, and that is what to be patched.
By reading the board definition in chopstx/board/board-st-dongle.h
, I found
that almost all pins from GPIO A are configured as input pulled high, and I
happened to notice that the CLK(PA5) pin is right at the edge of the board. At
that time, I decided to use PA5(CLK) as input pin to minimize the modification
to the code.
The patch is provided as an attachment below as 0001-add-pa5-as-switch-pin-for-st-dongle.patch
.
Basically, it’s to choose the right hardware interrupt signal.
Build the firmware¶
This is quite easy since no research have to be done.
# assuming pwd is gnuk
cd src
export kdf_do=optional # recommended(?) for v1.2.19
./configure --enable-factory-reset --target=ST_DONGLE --vidpid=234b:0000 --enable-certdo
make
Get gnuk.bin
, gnuk.hex
in src/build
, these are the built firmware. The file with bin
suffix is used for direct download(to a base address) or upgrading existing dongles, while
the other one is easier to use with a debugger as it contains address information.
Flash the firmware¶
Choice 1: using the debugger¶
Here we need gnuk.hex
.
I use Black Magic Probe as the debugger. I wrote a custom .gdbinit
to automate
the process, take it as an example. Note that if you cannot probe or attach to
the target, enable connect_srst
of the BMP.
There a lot of materials on the web about st-dongle’s pin definition and how to flash them, eg. rot42’s gist or Danman’s post.
Choice 2: upgrade existing tokens¶
THIS WILL INREVERSABLELY WIPE THE KEYS STORED ON YOUR TOKENS!
Here we need gnuk.bin
.
You might want to upgrade your existing Gnuk tokens to the latest firmware.
Go to src/regnual
, and make the update helper.
cd src/regnual
make
Note
For v1.2.19, you might want to comment out regnual/regnual.c:29
as a
quick workaround for a typing conflict.
For v1.2.20, The bug is fixed.
Now you get regnual.bin
/ reGNUal
(the update program).
Prepare your Python virtual environment and update the firmware. The Pipfile
is provided as
an attachment. (BTW, the necessary packages for tests are included as well.)
Then go to tool
and we’ll use upgrade_by_passwd.py
.
Note
There’s a bug at line 132, change while len(sys.argv) > 1:
to while len(sys.argv) > 3:
.
v1.2.19 fixed the bug.
# assuming pwd is gnuk and you have the provided Pipfile here
pipenv install
cd tool
# upgrade the token
# -f means using factory passwd automaticly
# -s means ignore the target string difference
python upgrade_by_passwd.py -f ../regnual/regnual.bin ../src/build/gnuk.bin
#python upgrade_by_passwd.py -f -s ../regnual/regnual.bin ../src/build/gnuk.bin # force
Read official doc or Remy’s tutorial for more detail.
Configure the Gnuk – Enable the Acknowledge Button¶
Please import your key to the card following the official documents first.
I found from the mailing list that only the latest develop version(at least v2.3?) of GnuPG supports modifiying the UIF(User Interaction Flag) on the Gnuk. It seems the feature will not be backported to v2.2(LTS release). So you have to build v2.3 and install it. Note that you have to completely replace the old 2.x version in order to avoid errors.
On Arch-like distros or distros use pacman as package manager, you can use aur package aur/gnupg23. For other distros, you are on your own.
After installing GnuPG v2.3, use the following commands to activate the button. These commands will work only if there is any key presented on the GnuK!
Assuming you’ve already imported your key to GnuK and customized it following the official documents, here are commands to enable the acknowledge button(for gnupg v2.3 and above):
gpg --card-edit
gpg/card> admin # enter admin mode
gpg/card> uif # show help info
gpg/card> uif 1 on # sign
gpg/card> uif 2 on # decrypt
gpg/card> uif 3 on # auth
gpg/card> q # quit
Attachments¶
Reference¶
- STM32 GPIO Setup: https://gist.github.com/iwalpola/6c36c9573fd322a268ce890a118571ca
Change log¶
2022-06-09¶
- Add more details
- Fix errors
- update gnupg 2.3 aur package link
2021-10-26¶
- minor tweaks
- move to my own blog
2021-10-14¶
- update for Gnuk v1.2.19
- remove file:
requirements.txt
- add file:
gnuk-no-vidpid-v1.2.19-ST_DONGLE.elf
- add file:
Pipfile