經歷了前幾天連結 Mbed TLS 的失敗,自已 fork Mbed TLS 重新 make 也失敗,在 GitHub Actions 上用 Renode 整合 CI 做純軟環境的模擬我都失敗,所以我要改變策略,在 Renode 模擬的時候,底層的 library 不去連結 Mbed TLS,由我自己提供一份 便宜行事 的底層實作。
這個底層實作並不安全,純粹就是把演算法走完而已,等到 NIST KAT [2
] 驗證完成後,接到實體版子的時候再換成 Mbed TLS 和 nrf_cc3xx_platform library。
從 Day 24 的 psa_generate_key
開始
psa_status_t psa_generate_key(const psa_key_attributes_t * attributes,
psa_key_id_t * key);
psa_key_attributes_t 的結構己有定義, 對每一個attributes 的設定是透過以下的 function
psa_set_key_id()
psa_set_key_lifetime()
psa_set_key_type()
psa_set_key_bits()
psa_set_key_usage_flags()
psa_set_key_algorithm()
由於我這一版純粹是一個 便宜行事 的版本,所以這幾個 function 我不需要實作。因為我產生出來的 key 會直接做成一個 static storage,每一個用 key id 傳遞的function 都會直接去 static storage 拿 key pair 來用,至於接受 key id 做參數只是為了符合 PSA Certified Crypto API,方便之後直接換成 Mbed TLS library 而己。
再一次強調,直接把私鑰放在 static storage 是不安全的,在這裡純粹只是為了實現演算法而己。
因為我這一版的目的是實現演算法,所以為了方便觀察,psa_generate_key
裡有一些不該做的事情我就直接做了,包括不該把 key pair 輸出到 UART 但我還是輸出到 UART,反正換成 Mbed TLS 後這些都不復存在。
我希望 psa_generate_key
能產生這兩個 key
因為現在的目的是實現 SLH-DSA 演算法,所以我暫時不去管 psa_key_attributes_t 每一個 attributes 各有什麼作用,等到演算法實現完成再回頭來改也不遲。
以上是 psa_generate_key
的前提,所以 source code 大概會是這樣
psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
psa_key_id_t *key)
{
psa_generate_random(sk_seed, SPX_N);
psa_generate_random(sk_prf, SPX_N);
psa_generate_random(pk_seed, SPX_N);
ADRS adrs;
memset(adrs, 0, 32);
set_layer_addr(adrs, d-1);
// PK.root ← xmss_node(SK.seed, 0, ℎ′, PK.seed, ADRS)
xmss_node(pk_root, sk_seed, 0, h', pk_seed, adrs);
}
上述的實作,是參考 FIPS 205 的 Algorithm 18 slh_keygen_internal
和 Algorithm 21 slh_keygen
psa_key_id_t
*key 是要用來返回 key handle,但我這版對 key handle 視若無睹,所以暫時不管他,等演算法實作完成了再回頭來處理 psa_key_id_t
的賦值。