HMAC-BLAKE2s, HKDF, TAI64N 実装追加
暗号プリミティブ実装: - HMAC-BLAKE2s (RFC 2104): BLAKE2s ベースの HMAC - HKDF-BLAKE2s (RFC 586): 鍵導出関数 - HKDF-Extract: 入力鍵から PRK を導出 - HKDF-Expand: PRK から必要な長さの鍵を導出 - TAI64N: WireGuard プロトコル層のタイムスタンプ(12 バイト) WireGuard での使用: - ハンドシェイク中の鍵導出チェーン - チェーン鍵 (Ck)・セッション鍵 (tk) の導出 - リプレイ防止用タイムスタンプ テスト: - test_hmac_blake2s: HMAC-BLAKE2s 検証 ✅ - test_hkdf_blake2s: HKDF 検証 ✅ - test_tai64n: TAI64N エンコード/デコード ✅
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* @file se050_hkdf_blake2s.c
|
||||
* @brief HKDF Implementation using HMAC-BLAKE2s (RFC 586)
|
||||
*/
|
||||
|
||||
#include "se050_hkdf_blake2s.h"
|
||||
#include "se050_hmac_blake2s.h"
|
||||
#include <string.h>
|
||||
|
||||
#define HKDF_MAX_BYTES (255 * HMAC_BLAKE2S_DIGEST_SIZE)
|
||||
|
||||
int se050_hkdf_extract(uint8_t prk[32],
|
||||
const uint8_t *salt, size_t saltlen,
|
||||
const uint8_t *ikm, size_t ikmlen)
|
||||
{
|
||||
uint8_t zero_salt[HMAC_BLAKE2S_BLOCK_SIZE] = {0};
|
||||
|
||||
if (!prk || !ikm || ikmlen == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!salt || saltlen == 0) {
|
||||
salt = zero_salt;
|
||||
saltlen = HMAC_BLAKE2S_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return se050_hmac_blake2s(prk, salt, saltlen, ikm, ikmlen);
|
||||
}
|
||||
|
||||
int se050_hkdf_expand(uint8_t *okm, size_t okmlen,
|
||||
const uint8_t prk[32],
|
||||
const uint8_t *info, size_t infolen)
|
||||
{
|
||||
uint8_t t[HMAC_BLAKE2S_DIGEST_SIZE];
|
||||
uint8_t t_prev[HMAC_BLAKE2S_DIGEST_SIZE];
|
||||
uint8_t info_with_counter[65];
|
||||
size_t n, i, written;
|
||||
|
||||
if (!okm || !prk || okmlen == 0 || okmlen > HKDF_MAX_BYTES) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = (okmlen + HMAC_BLAKE2S_DIGEST_SIZE - 1) / HMAC_BLAKE2S_DIGEST_SIZE;
|
||||
if (n > 255) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(t, 0, sizeof(t));
|
||||
memset(t_prev, 0, sizeof(t_prev));
|
||||
memset(okm, 0, okmlen);
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
info_with_counter[0] = (uint8_t)i;
|
||||
if (info && infolen > 0) {
|
||||
memcpy(info_with_counter + 1, info, infolen);
|
||||
}
|
||||
|
||||
int ret = se050_hmac_blake2s(t, prk, 32,
|
||||
info_with_counter, infolen + 1);
|
||||
if (ret != 0) {
|
||||
memset(t, 0, sizeof(t));
|
||||
memset(t_prev, 0, sizeof(t_prev));
|
||||
return ret;
|
||||
}
|
||||
|
||||
written = (i == n) ? (okmlen % HMAC_BLAKE2S_DIGEST_SIZE) : HMAC_BLAKE2S_DIGEST_SIZE;
|
||||
if (written == 0) written = HMAC_BLAKE2S_DIGEST_SIZE;
|
||||
memcpy(okm + (i - 1) * HMAC_BLAKE2S_DIGEST_SIZE, t, written);
|
||||
|
||||
memcpy(t_prev, t, sizeof(t_prev));
|
||||
memset(t, 0, sizeof(t));
|
||||
}
|
||||
|
||||
memset(t_prev, 0, sizeof(t_prev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int se050_hkdf(uint8_t *okm, size_t okmlen,
|
||||
const uint8_t *salt, size_t saltlen,
|
||||
const uint8_t *ikm, size_t ikmlen,
|
||||
const uint8_t *info, size_t infolen)
|
||||
{
|
||||
uint8_t prk[32];
|
||||
int ret;
|
||||
|
||||
if (!okm || okmlen == 0 || !ikm || ikmlen == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = se050_hkdf_extract(prk, salt, saltlen, ikm, ikmlen);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = se050_hkdf_expand(okm, okmlen, prk, info, infolen);
|
||||
memset(prk, 0, sizeof(prk));
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user