本日重點: 用模擬器 (Renode) 跑一遍裸機實作 SLH-DSA 簽章的流程
我是在 Github 上將 Renode 整合進 CI 的流程, 然後手動觸發 workflow, 最後在裸機上執行的 ELF 會去對一個 uint8_t array 做簽章,並透過 uart 將簽章結果輸出,showAnalyzer sysbus.uart0
就是讓 Renode 開始顯示 uart 收到的訊息,於是,在 GitHub 就會看到
這版雖然簽出來了,但簽章的結果很明顯是錯的,本系列將在這個基礎上延伸開發,但今天的重點在於如何用模擬器跑完這個流程,所以我們接著看 CI 和 renode 的設定。
run_sign.resc 就是要給 renode 執行的 script,然後會在 Makefile 指定要用 docker 去執行它,$(RESC) 就是腳本 run_sign.resc,$(RENODE_IMG) 就是 docker renode 的 image
ci-run-nrf52840: $(ELF) $(RESC)
docker run --rm -v "$(WORKDIR):/w" $(RENODE_IMG) \
sh -lc 'cd /w && renode --console --disable-xwt -e "set ansi false; include @$(RESC); sleep 2; q"' | sed 's/\x1B\[[0-9;]*[A-Za-z]//g'
注意看 run_sign.resc 最後一行的 start,如果沒有 start,那就算有 include @$(RESC)
,也不會執行這個 script
set ansi false
mach create "nrf52840_sign"
machine LoadPlatformDescription @platforms/cpus/nrf52840.repl
sysbus LoadELF @sign_nrf52840.elf
showAnalyzer sysbus.uart0
start
然後修改 ci.yml,就能在 workflow 裡執行 make ci-run-nrf52840
- name: Run in Renode
run: make ci-run-nrf52840
至此,就是將 Renode 整合進 CI,裸機執行 ELF 的主要流程。
因為本系列將會分別在 nrf52840 dongle 和 nrf5340 DK 開發,所以 目錄 是這樣的。
nrf52840 和 nrf5340 各自有 rdrand.c
、linker.ld
和 startup.c
,這是為了跨平台所準備,如果新增一個平台,就提供這三個檔案就可以了,本系列會陸續對此進行實驗。rdrand.c
就是保留給不同硬體的亂數產生器使用,目前是用 uint32_t 做為一個假亂數,這是暫時的,之後會改成由 CryptoCell 提供 TRNG。
我們看一下 Makefile
ci-run-nrf52840: $(ELF) $(RESC)
在執行 ci-run-nrf52840 之前,他會先產生 $(ELF),這個 ELF file 叫什麼名字,取決於是執行 make TARGET=nrf52840 還是執行 make TARGET=nrf5340dk,他們會分別產生 sign_nrf52840.elf 和 sign_nrf5340dk.elf,對應到不同的 platform。於是,新的 platform 要加入的時候,只需要提供硬體相關的 rdrand.c
、linker.ld
和 startup.c
,然後修改 Makefile,重新 make 就可以了,不用去改既有程式,就能實現原始碼層級的跨平台。
我後來發現
rdrand.c
容易誤會是 x86 的 RDRAND,之後會 rename