/** * @file se050_wireguard.h * @brief WireGuard VPN Protocol - Public API */ #ifndef SE050_WIREGUARD_H #define SE050_WIREGUARD_H #include #include #include #ifdef __cplusplus extern "C" { #endif /* ========================================================================= * Type Definitions * ========================================================================= */ /** * @brief WireGuard session context * * Contains all state needed for WireGuard communication: * - Local keypair * - Peer public key * - Session keys (sending/receiving) * - Cookie state for DoS protection */ typedef struct se050_wireguard_session { /* Local keys */ uint8_t private_key[32]; uint8_t public_key[32]; /* Peer keys */ uint8_t peer_public_key[32]; /* Handshake state */ uint8_t handshake_secret[32]; uint8_t chain_key[32]; uint8_t sending_key[32]; uint8_t receiving_key[32]; uint64_t sending_nonce; uint64_t receiving_nonce; /* Cookie state */ uint8_t cookie_secret[32]; uint64_t cookie_timestamp; uint8_t last_mac1[16]; /* State flags */ int is_initiator; int handshake_complete; } se050_wireguard_session_t; /* ========================================================================= * Session Management * ========================================================================= */ /** * @brief Initialize a WireGuard session * * @param session Output: session context to initialize * @param private_key Local private key (32 bytes) * @param peer_public_key Peer's public key (32 bytes) * @return 0 on success, -1 on error */ int se050_wireguard_session_init(se050_wireguard_session_t *session, const uint8_t *private_key, const uint8_t *peer_public_key); /** * @brief Clean up and zeroize session data * * @param session Session to cleanup */ void se050_wireguard_session_cleanup(se050_wireguard_session_t *session); /* ========================================================================= * Key Derivation * ========================================================================= */ /** * @brief Derive session keys from shared secret * * After performing X25519 key exchange, use this to derive * the actual encryption keys for the session. * * @param session Session context * @param shared_secret X25519 shared secret (32 bytes) * @return 0 on success, -1 on error */ int se050_wireguard_derive_keys(se050_wireguard_session_t *session, const uint8_t *shared_secret); /* ========================================================================= * Packet Encryption/Decryption * ========================================================================= */ /** * @brief Encrypt a WireGuard packet * * Format: [header (16 bytes)] [ciphertext] [auth tag (16 bytes)] * * @param session Session context * @param out Output buffer for encrypted packet * @param out_len Output: actual length of encrypted packet * @param plaintext Plaintext payload * @param plaintext_len Length of plaintext * @return 0 on success, -1 on error */ int se050_wireguard_encrypt_packet(se050_wireguard_session_t *session, uint8_t *out, size_t *out_len, const uint8_t *plaintext, size_t plaintext_len); /** * @brief Decrypt a WireGuard packet * * @param session Session context * @param plaintext Output buffer for decrypted payload * @param plaintext_len Output: actual length of plaintext * @param packet Encrypted packet * @param packet_len Length of encrypted packet * @return 0 on success, -1 on error (including replay detection) */ int se050_wireguard_decrypt_packet(se050_wireguard_session_t *session, uint8_t *plaintext, size_t *plaintext_len, const uint8_t *packet, size_t packet_len); /* ========================================================================= * Cookie Mechanism (DoS Protection) * ========================================================================= */ /** * @brief Compute MAC1 for a packet * * MAC1 provides proof of knowledge of peer's public key * * @param session Session context * @param packet Packet data (excluding MAC1/MAC2) * @param packet_len Length of packet data * @param mac1 Output: computed MAC1 (16 bytes) * @return 0 on success, -1 on error */ int se050_wireguard_compute_mac1(se050_wireguard_session_t *session, const uint8_t *packet, size_t packet_len, uint8_t *mac1); /** * @brief Compute MAC2 for a packet * * MAC2 provides proof of cookie knowledge (DoS protection) * * @param session Session context * @param mac1 Previously computed MAC1 * @param packet Packet data * @param packet_len Length of packet data * @param mac2 Output: computed MAC2 (16 bytes) * @return 0 on success, -1 on error */ int se050_wireguard_compute_mac2(se050_wireguard_session_t *session, const uint8_t *mac1, const uint8_t *packet, size_t packet_len, uint8_t *mac2); /* ========================================================================= * Key Generation * ========================================================================= */ /** * @brief Generate a new WireGuard keypair * * Uses system RNG (/dev/urandom on POSIX). * For SE050 hardware RNG, use se050_wireguard_generate_keypair_se050(). * For CSPRNG (seeded from SE050), use se050_wireguard_generate_keypair_csprng(). * * @param private_key Output: private key (32 bytes) * @param public_key Output: public key (32 bytes) * @return 0 on success, -1 on error */ int se050_wireguard_generate_keypair(uint8_t *private_key, uint8_t *public_key); /** * @brief Generate WireGuard keypair using SE050 hardware RNG * * This function uses the SE050 chip's built-in True Random Number Generator * for cryptographically secure key generation. * * @param session SE050 session context (initialized via se050_session_init()) * @param private_key Output: private key (32 bytes) * @param public_key Output: public key (32 bytes) * @return 0 on success, -1 on error */ #ifdef SE050_ENABLED int se050_wireguard_generate_keypair_se050(se050_session_ctx_t *session, uint8_t *private_key, uint8_t *public_key); #endif /** * @brief Initialize CSPRNG with seed from SE050 * * This should be called once at system startup. After initialization, * the CSPRNG can generate random numbers without further SE050 access. * * @param seed_func Function to get seed from SE050 (called once) * @param seed_ctx Context for seed function * @return 0 on success, -1 on error */ int se050_csprng_init(int (*seed_func)(uint8_t *out, size_t len, void *ctx), void *seed_ctx); /** * @brief Generate WireGuard keypair using CSPRNG * * After calling se050_csprng_init(), use this function to generate keypairs. * This is ideal for ESP32 and other embedded platforms where I2C access should be minimized. * * @param private_key Output: private key (32 bytes) * @param public_key Output: public key (32 bytes) * @return 0 on success, -1 on error */ int se050_wireguard_generate_keypair_csprng(uint8_t *private_key, uint8_t *public_key); /** * @brief Generate random bytes using CSPRNG * * @param out Output buffer * @param len Number of bytes to generate * @return 0 on success, -1 on error */ int se050_csprng_random(uint8_t *out, size_t len); /** * @brief Cleanup CSPRNG and zeroize sensitive data */ void se050_csprng_cleanup(void); /* ========================================================================= * Constants * ========================================================================= */ #define WG_KEY_LEN 32 /**< Key length in bytes */ #define WG_NONCE_LEN 12 /**< Nonce length in bytes */ #define WG_MAX_PACKET_SIZE 65535 /**< Maximum packet size */ #define WG_HEADER_SIZE 16 /**< Packet header size */ #define WG_MAC1_SIZE 16 /**< MAC1 size */ #define WG_MAC2_SIZE 16 /**< MAC2 size */ #define WG_AUTH_TAG_SIZE 16 /**< AEAD authentication tag size */ #ifdef __cplusplus } #endif #endif /* SE050_WIREGUARD_H */