WireGuard プロトコル層実装

鍵導出チェーン (KDF):
- wg_kdf_init(): 初期化(ゼロ鍵)
- wg_kdf1(): IKM -> CK1, TK1(最初の導出)
- wg_kdf2(): CK, TK1 -> CK2, TK2(2 番目の導出)
- wg_kdf3(): CK, TK2, data -> CK3(データ混合)

ハンドシェイクメッセージ構造:
- wg_handshake_init (148 bytes): Initiation message
- wg_handshake_resp (92 bytes): Response message
- wg_cookie_reply (64 bytes): Cookie reply

実装詳細:
- RFC 5861 HKDF ベース
- WireGuard 固有ラベル (K1, K2, K3)
- チェーン鍵 (Ck) とセッション鍵 (tk) の導出

テスト:
- tests/test_wireguard_kdf.c (5/5 PASS)
- 完全なハンドシェイクチェーンシミュレーション
This commit is contained in:
km
2026-03-26 21:17:38 +09:00
parent 0c9237324e
commit c9844dc0ba
4 changed files with 318 additions and 1 deletions
+114
View File
@@ -0,0 +1,114 @@
/**
* @file se050_wireguard_proto.h
* @brief WireGuard Protocol Layer
* Key derivation chains and handshake message structures
*/
#ifndef SE050_WIREGUARD_PROTO_H
#define SE050_WIREGUARD_PROTO_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define WG_KEY_LEN 32
#define WG_MAC_LEN 16
#define WG_NONCE_LEN 12
/* ============================================================================
* WireGuard Key Derivation Chains
* ============================================================================ */
/**
* @brief Initialize keying material with zero key
* @param ck Output chain key (32 bytes)
* @param tk Output temp key (32 bytes, can be NULL)
*/
void wg_kdf_init(uint8_t ck[32], uint8_t tk[32]);
/**
* @brief HKDF-1: ck, tk1 = KDF1(ck, input_key_material)
* @param ck Chain key (updated in place)
* @param tk1 Output temp key
* @param ikm Input keying material
* @param ikmlen IKM length
*/
void wg_kdf1(uint8_t ck[32], uint8_t tk1[32],
const uint8_t ikm[32], size_t ikmlen);
/**
* @brief HKDF-2: ck, tk2 = KDF2(ck, tk1)
* @param ck Chain key (updated in place)
* @param tk2 Output temp key
* @param tk1 Previous temp key
*/
void wg_kdf2(uint8_t ck[32], uint8_t tk2[32],
const uint8_t ck_old[32], const uint8_t tk1[32]);
/**
* @brief HKDF-3: ck, tk3 = KDF3(ck, tk2, data)
* @param ck Chain key (updated in place)
* @param tk3 Output temp key
* @param data Additional data to mix
* @param datalen Data length
*/
void wg_kdf3(uint8_t ck[32], uint8_t tk3[32],
const uint8_t ck_old[32], const uint8_t tk2[32],
const uint8_t *data, size_t datalen);
/* ============================================================================
* WireGuard Handshake Message Types
* ============================================================================ */
#define WG_MESSAGE_INITIATION 1
#define WG_MESSAGE_RESPONSE 2
#define WG_MESSAGE_COOKIE_REPLY 3
/* ============================================================================
* Handshake Message Structures
* ============================================================================ */
/**
* @brief Initiation message (148 bytes)
*/
struct wg_handshake_init {
uint32_t type; /* 4 bytes: message type */
uint8_t sender_index[4]; /* 4 bytes: sender's public key index */
uint8_t unencrypted_ephemeral[32]; /* 32 bytes: ephemeral public key */
uint8_t encrypted_static[100]; /* 100 bytes: static pubkey + MAC */
uint8_t encrypted_timestamp[64]; /* 64 bytes: timestamp + MAC */
uint8_t mac1[16]; /* 16 bytes: MAC1 */
uint8_t mac2[16]; /* 16 bytes: MAC2 */
} __attribute__((packed));
/**
* @brief Response message (92 bytes)
*/
struct wg_handshake_resp {
uint32_t type; /* 4 bytes */
uint8_t sender_index[4]; /* 4 bytes */
uint8_t receiver_index[4]; /* 4 bytes */
uint8_t unencrypted_ephemeral[32]; /* 32 bytes */
uint8_t encrypted_payload[48]; /* 48 bytes: MAC only */
uint8_t mac1[16]; /* 16 bytes */
uint8_t mac2[16]; /* 16 bytes */
} __attribute__((packed));
/**
* @brief Cookie reply message (64 bytes)
*/
struct wg_cookie_reply {
uint32_t type; /* 4 bytes */
uint8_t receiver_index[4]; /* 4 bytes */
uint8_t nonce[24]; /* 24 bytes */
uint8_t encrypted_cookie[64]; /* 64 bytes: cookie + MAC */
} __attribute__((packed));
#ifdef __cplusplus
}
#endif
#endif /* SE050_WIREGUARD_PROTO_H */