前言
看到了這篇文章 想搞 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
此時應該輸出你的智慧卡的詳細資訊。
刷壞了/想重刷
以下文章我或多或少參考了一些,推薦閱讀 [2:4][1:1][3][4]
這篇文章 講述了 64KB 主控如何刷支援 64KB 的舊版 GNUK