iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0
Security

裸機實作 SLH-DSA 簽章:FIPS 205 之演算法實作、測試、防禦與跨平台系列 第 27

Day 27 將 psa_key_id_t 整合到 SLH-DSA 簽章演算法的實作裡

  • 分享至 

  • xImage
  •  

今日重點: 將 sk_seed, pk_seed, sk_prf 換成 psa_key_id_t

SLH-DSA 簽章演算法的 function 是直接傳 sk_seed, pk_seed, sk_prf,因為 FIPS 205 的重點是規範演算法,所以直接傳 sk_seed, pk_seed, sk_prf 完全沒問題,但落實到一個安全的產品,就不能真把私鑰當參數直接在各 function 之間傳遞,所以 PSA Crypto API 就是以 psa_key_id_t 做為 function parameter。

在我盤點之前的實作有哪些要改的時候,發現全部以 sk.seed 或 sk.prf 當參數傳遞的 function,最終都是把 sk.seed 或 sk.prf 傳到 PRF (或者是 H_msg, PRF_msg),所以修改主要有三部份,其一,產生 sk.prf, sk.seed, pk.seed 三個亂數,細節後述;其二,是各 function 修改 function parameter list 和 implementation 的參數傳遞,這個部份雖然要改的地方比較多,不過屬於勞力密集,技術含量不高,將 source code 貼上來也略顯多餘,有興趣的直接在 GitHub 上看就可以了;其三就比較棘手了,因為要讓 PRF (或者是 H_msg, PRF_msg) 能使用 key id 取得 sk.seed, sk.prf 做 SHA-256 或 concatenation (或是 HMAC-SHA-256, MGF1-SHA-256),就要考慮到 key 能不能export,能不能直接把 key id 給 CC310/CC312 做 HMAC-SHA-256 或 SHA-256

產生 sk.prf, sk.seed, pk.seed 三個種子

首先就是產生種子的環節(sk.prf, sk.seed, pk.root, pk.seed),因為 sk.prf 在 SLH-DSA 演算法裡並不需要和其他變數做 concatenation,所以理論上,直接拿 sk.prf 的 key id 給 CC310/CC312 算 HMAC-SHA-256 應該是沒問題,但我不確定,所以我會呼叫 psa_generate_key 來拿到 sk.prf, sk.seed, pk.seed。其中 call psa_generate_key 產生 sk.prf 的時候是另外寫一個 function 來取得 sk_prf_key_id。之後在實體的開發版會實驗看看能否真的直接把 sk_prf_key_id 給 CC310/CC312 就能算 HMAC-SHA-256,但在Renode模擬環境執行的時候,sk.prf, sk.seed, pk.seed 是直接用 static storage duration。

有一件事值得提,sk.seed, pk.seed 其實更適合用 psa_generate_random,因為目前 Mbed TLS 還不支援 SLH-DSA,所以 sk.seed, pk.seed 並沒有適合的 key type 能用,他們不像 sk.prf,因為 sk.prf 在整個 SLH-DSA 演算法裡只會拿去算 HMAC-SHA-256,所以 sk.prf 用 psa_generate_key 來產生是合適的。但我還是用 psa_generate_key,主要是因為我希望參數傳遞能一致以 psa_key_id_t 為基礎。

底下是產生三個 key_id 的 source code,只有 sk_prf_key_id 有另外指定 PSA_ALG_HMAC(PSA_ALG_SHA_256),因為之後在實體的開發版需要靠他去實驗硬體的 HMAC-SHA-256。

psa_status_t create_sk_prf(psa_key_id_t desired_id, psa_key_id_t *sk_prf_key_id) {
    psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;

    psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
    psa_set_key_bits(&attr, (psa_key_bits_t)(8 * SPX_N));
    psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
    psa_set_key_lifetime(&attr, PSA_KEY_LIFETIME_PERSISTENT);
    psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_MESSAGE);
    psa_set_key_id(&attr, desired_id);

    return psa_generate_key(&attr, sk_prf_key_id);
}

void generate_key(psa_key_id_t *p_sk_seed_key_id, 
                  psa_key_id_t *p_sk_prf_key_id, 
                  psa_key_id_t *p_pk_key_id)
{
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT);

    psa_set_key_id(&attributes, 1);
    psa_status_t status = psa_generate_key(&attributes, p_sk_seed_key_id);  // sk_seed
    ...
    status = create_sk_prf(2, p_sk_prf_key_id);           // sk_prf
    ...
    psa_set_key_id(&attributes, 3);
    status = psa_generate_key(&attributes, p_pk_key_id);  // pk_seed
    ...
}

PRF, H_msg, PRF_msg 使用 sk.seed, sk.prf

sk.prf, sk.seed, pk.seed 是直接用 static storage duration,這樣是不安全的,千萬別在正式環境這麼做,我這裡純粹只是基於方便實現 SLH-DSA 簽章演算法,所採用的 便宜行事 的策略。

static uint8_t sk_seed[SPX_N] = {0};
static uint8_t sk_prf[SPX_N] = {0};
static uint8_t pk_seed[SPX_N] = {0};

明天就會在 Renode 的模擬環境裡,把上述的修改配合 NIST KAT 做簽章結果的驗證。


上一篇
Day 26 psa_mac_compute, psa_hash_compute, PRFmsg
系列文
裸機實作 SLH-DSA 簽章:FIPS 205 之演算法實作、測試、防禦與跨平台27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言