ST-Link v2 刷寫 GNUK,年輕人的第一個 OpenPGP 智慧卡!

Tibrella發表於2023-11-08

前言

看到了這篇文章 想搞 PGP 智慧卡玩,但是 yubikey 死貴 還涉及到某些傻逼政治問題 於是就想找找有無開源實現什麼的。

然後就看見了 smartcard 的製作教程,可惜能找到的便宜 javacard 都是需要讀卡器的。

本來死心了,但是看見 ST-link v2 刷 GNUK 教程 突然就想折騰了,不得不說,還是 GNU 牛逼。專案由 $\stackrel{\textsf{Free Software Initiative of Japan}}{\textsf{FSIJ}}$ 維護。

這玩意比 yubikey 牛逼,支援最新的 x448 橢圓曲線加密演算法(但是已經棄用 RSA 了)

材料準備

一般 ST-Link v2 及其仿品都只提供 SWDIO SWCLK 而無 RXD TXD 這種直接串列埠就能刷的口,所以最好再買個 ST-Link v2 當燒錄器(買別的也行,主要是這個便宜),我買的是 PowerWriter Lite 2。本來想刷這個的,結果外殼都拆不開

所以:

  • 一個燒錄器(ST-Link v2)
  • 待燒錄的 ST-Link v2(確保主控是 STM32F103C8T6 或 STM32F103CBT6,GD32F103 一般不會在仿品裡出現,網上有關於這款主控的刷寫教程),購買踩坑這裡有[1]
  • 四根杜邦線,有一端是公頭用於連線待燒錄的 ST-Link,另一端連線燒錄器,公母視情況而定
  • 一臺電腦

我採用了 Arch Linux,其他系統編譯韌體的教程在這裡有[2]

為啥主控要求是這兩個版本

首先 GNUK 支援 STM32F103 系列。

然後 GNUK 需要 128KB 快閃記憶體容量。

最後 STM32F103C8T6 和 STM32F103CBT6 用了一套東西,後者官方給定容量 128KB,前者雖然標了 64KB 但是實際上有 128KB 的空間可用。恰好,ST-Link 2 官方使用的主控就是前者。仿品中可能出現後者。

GD32F103 能 pin2pin 替換 STM32F103 自然也能用。但是需要換燒錄方式。

編譯韌體

安裝依賴

pacman -S arm-none-eabi-gcc

官網:In 2.5, we added GD32VF103 support. Please note that default libc is now picolibc (instead of newlib).

老教程會教你安裝 newlib,但是現在需要安裝 picolibc。但是這個東西不僅只在 aur 裡,而且過期了。實測直接更改 pkgver 也可以正常構建新版本

所以:

git clone https://aur.archlinux.org/arm-none-eabi-picolibc.git
cd arm-none-eabi-picolibc.git
vim PKGBUILD # 將 pkgver 改成最新版本號,可以在上面 picolibc 專案 release 頁面看
makepkg -sif

編譯韌體

git clone --recursive https://salsa.debian.org/gnuk-team/gnuk/gnuk.git gnuk
cd gnuk/src
./configure --vidpid=234b:0000 --target=ST_DONGLE
make build/gnuk-vidpid.bin

然後 build/gnuk-vidpid.bin 就是待燒錄的韌體檔案,我們把它單獨取出來待用。

燒寫

安裝軟體

pacman -S openocd inetutils

inetutils 用來提供 telnet 支援。putty 用不了,不知道是不是不相容 XWayland 的問題。

連線裝置

ST-Link v2 連線系統板教程挺多的,直接搜就行。這個裡面也有[2:1]

PW Lite 2 的話官方文件有接線教程。

我的是這樣

如果像[2:2]裡面這樣是非常好的,直接插進去隨便固定一下就行。但是我不是這種情況。我買的 ST-Link 只提供了四個焊盤!!!

這意味著你需要用除錯排針湊合連線一下,連線刷寫過程中需要用手按住!除錯排針...就是四根杜邦線粘成一排 ?

連線失敗了好幾次,刷寫完了之後杜邦線的頭都讓我按歪了!

圖待補

配置 openocd

隨便新建一個 xxx.cfg,內容:

telnet_port 4444
source [find interface/stlink-v2.cfg]
source [find target/stm32f1x.cfg]
set WORKAREASIZE 0x10000

STM32F103C8T6 需要這句 set WORKAREASIZE 0x10000,這句使得程式可以刷寫到額外的 64KB 空間中。如果儲存足夠 128KB 就不用這句。

如果你像我一樣用 PWLink 2,需要把 source [find interface/stlink-v2.cfg] 換成 source [find interface/cmsis-dap.cfg](在一個求助帖看見的,地址找不到了)

連線好裝置後 openocd -f ./xxx.cfg,如果跑起來之後沒報錯沒退出就說明你搞對了。

刷寫韌體

telnet 127.0.0.1:4444

然後輸入以下指令

stm32f1x unlock 0
reset halt
flash write_bank 0 ./src/build/gnuk-vidpid.bin 0
stm32f1x lock 0
reset halt

./src/build/gnuk-vidpid.bin 這個是你剛才編譯出來的韌體

然後就沒了,退出 telnet 和 openocd,斷開裝置連線就行。

測試

插入你刷好的 GNUK 智慧卡,輸入

gpg --card-status

此時應該輸出你的智慧卡的詳細資訊。

image

刷壞了/想重刷

[2:3]


以下文章我或多或少參考了一些,推薦閱讀 [2:4][1:1][3][4]

這篇文章 講述了 64KB 主控如何刷支援 64KB 的舊版 GNUK


  1. https://blog.dylanwu.space/2020/01/24/stm32-gnuk.html ↩︎ ↩︎

  2. https://nx3d.org/gnuk-st-link-v2/ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  3. https://kgame.tw/gnupg/stm32-gnuk/ ↩︎

  4. https://techie-s.work/posts/2021/04/homemade-gnuk/ ↩︎

相關文章