HMAC-BLAKE2s, HKDF, TAI64N 実装完了

HMAC-BLAKE2s (RFC 2104):
- include/se050_hmac_blake2s.h
- src/se050_hmac_blake2s.c
- Block size: 64 bytes, Digest: 32 bytes
- ipad=0x36, opad=0x5c

HKDF (RFC 5861):
- include/se050_hkdf_blake2s.h
- src/se050_hkdf_blake2s.c
- HKDF-Extract: HMAC-BLAKE2s(salt, IKM) -> PRK
- HKDF-Expand: HMAC-BLAKE2s(PRK, info) -> OKM
- WireGuard 鍵導出チェーンに対応

TAI64N タイムスタンプ:
- include/se050_tai64n.h
- src/se050_tai64n.c
- 12 bytes (64-bit TAI + 32-bit nanoseconds)
- リプレイ防止用
- Window check 機能

テスト:
- tests/test_hmac_hkdf.c (7/7 PASS)
- BLAKE2s, HMAC, HKDF, TAI64N すべて動作確認済み
This commit is contained in:
km
2026-03-26 21:14:47 +09:00
parent c892e6ca01
commit 0c9237324e
6 changed files with 237 additions and 338 deletions
+28 -36
View File
@@ -1,27 +1,28 @@
/**
* @file se050_hkdf_blake2s.c
* @brief HKDF Implementation using HMAC-BLAKE2s (RFC 586)
* @brief HKDF Implementation using HMAC-BLAKE2s (RFC 5861)
*/
#include "se050_hkdf_blake2s.h"
#include "se050_hmac_blake2s.h"
#include <string.h>
#define HKDF_MAX_BYTES (255 * HMAC_BLAKE2S_DIGEST_SIZE)
#define HMAC_BLAKE2S_DIGEST_SIZE 32
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};
uint8_t default_salt[HMAC_BLAKE2S_DIGEST_SIZE];
if (!prk || !ikm || ikmlen == 0) {
if (!prk || !ikm) {
return -1;
}
if (!salt || saltlen == 0) {
salt = zero_salt;
saltlen = HMAC_BLAKE2S_BLOCK_SIZE;
memset(default_salt, 0, HMAC_BLAKE2S_DIGEST_SIZE);
salt = default_salt;
saltlen = HMAC_BLAKE2S_DIGEST_SIZE;
}
return se050_hmac_blake2s(prk, salt, saltlen, ikm, ikmlen);
@@ -32,46 +33,41 @@ int se050_hkdf_expand(uint8_t *okm, size_t okmlen,
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;
size_t n;
int ret;
if (!okm || !prk || okmlen == 0 || okmlen > HKDF_MAX_BYTES) {
if (!okm || !prk || okmlen == 0 || okmlen > HKDF_BLAKE2S_MAX_OUTPUT) {
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);
for (size_t i = 1; i <= n; i++) {
size_t data_len = (i == 1) ? 0 : HMAC_BLAKE2S_DIGEST_SIZE;
ret = se050_hmac_blake2s(t, prk, HMAC_BLAKE2S_DIGEST_SIZE,
t, data_len);
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);
if (info && infolen > 0) {
ret = se050_hmac_blake2s_variable(t, HMAC_BLAKE2S_DIGEST_SIZE,
prk, HMAC_BLAKE2S_DIGEST_SIZE,
info, infolen);
if (ret != 0) {
return ret;
}
}
memcpy(t_prev, t, sizeof(t_prev));
memset(t, 0, sizeof(t));
size_t block_len = (i < n) ? HMAC_BLAKE2S_DIGEST_SIZE :
(okmlen - (i - 1) * HMAC_BLAKE2S_DIGEST_SIZE);
memcpy(okm + (i - 1) * HMAC_BLAKE2S_DIGEST_SIZE, t, block_len);
}
memset(t_prev, 0, sizeof(t_prev));
memset(t, 0, sizeof(t));
return 0;
}
@@ -80,13 +76,9 @@ int se050_hkdf(uint8_t *okm, size_t okmlen,
const uint8_t *ikm, size_t ikmlen,
const uint8_t *info, size_t infolen)
{
uint8_t prk[32];
uint8_t prk[HMAC_BLAKE2S_DIGEST_SIZE];
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;