/** * @file se050_chacha20_poly1305.h * @brief ChaCha20-Poly1305 AEAD Implementation * * Software implementation for WireGuard protocol. * Based on RFC 7539 (ChaCha20-Poly1305) and RFC 8434 (WireGuard). * * License: MIT (Clean-room implementation) */ #ifndef SE050_CHACHA20_POLY1305_H #define SE050_CHACHA20_POLY1305_H #include #include #ifdef __cplusplus extern "C" { #endif /* ============================================================================ * Constants * ============================================================================ */ #define CHACHA20_KEY_SIZE 32 #define CHACHA20_NONCE_SIZE 12 #define CHACHA20_BLOCK_SIZE 64 #define POLY1305_KEY_SIZE 32 #define POLY1305_TAG_SIZE 16 #define CHACHA20_POLY1305_AEAD_KEY_SIZE 32 #define CHACHA20_POLY1305_AEAD_NONCE_SIZE 12 #define CHACHA20_POLY1305_TAG_SIZE 16 /* WireGuard-specific constants */ #define WG_KEY_SIZE 32 #define WG_NONCE_SIZE 12 /* ============================================================================ * Type Definitions * ============================================================================ */ /** * @brief ChaCha20-Poly1305 AEAD context */ typedef struct { uint8_t key[CHACHA20_KEY_SIZE]; } se050_chacha20_poly1305_ctx_t; /* ============================================================================ * ChaCha20 Core Functions * ============================================================================ */ /** * @brief ChaCha20 quarter round * * @param a Pointer to a * @param b Pointer to b * @param c Pointer to c * @param d Pointer to d */ void se050_chacha20_quarter_round(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d); /** * @brief ChaCha20 block function * * @param output Output buffer (64 bytes) * @param key Key (32 bytes) * @param counter Initial counter (4 bytes) * @param nonce Nonce (12 bytes) */ void se050_chacha20_block(uint8_t output[64], const uint8_t key[32], uint32_t counter, const uint8_t nonce[12]); /** * @brief ChaCha20 encrypt/decrypt * * @param output Output buffer * @param input Input buffer * @param len Length * @param key Key (32 bytes) * @param counter Initial counter * @param nonce Nonce (12 bytes) */ void se050_chacha20(uint8_t *output, const uint8_t *input, size_t len, const uint8_t key[32], uint32_t counter, const uint8_t nonce[12]); /* ============================================================================ * Poly1305 Core Functions * ============================================================================ */ /** * @brief Poly1305 MAC generation * * @param mac Output MAC (16 bytes) * @param key Key (32 bytes) * @param data Data to authenticate * @param len Data length */ void se050_poly1305_mac(uint8_t mac[16], const uint8_t key[32], const uint8_t *data, size_t len); /* ============================================================================ * ChaCha20-Poly1305 AEAD * ============================================================================ */ /** * @brief Initialize ChaCha20-Poly1305 context * * @param ctx Context to initialize * @param key Key (32 bytes) * @return 0 on success, -1 on error */ int se050_chacha20_poly1305_init(se050_chacha20_poly1305_ctx_t *ctx, const uint8_t key[CHACHA20_KEY_SIZE]); /** * @brief ChaCha20-Poly1305 AEAD encryption * * @param ctx Context * @param nonce Nonce (12 bytes) * @param plaintext Plaintext data * @param plaintext_len Plaintext length * @param aad Additional authenticated data * @param aad_len AAD length * @param ciphertext Output ciphertext * @param tag Output authentication tag (16 bytes) * @return 0 on success, -1 on error */ int se050_chacha20_poly1305_encrypt(se050_chacha20_poly1305_ctx_t *ctx, const uint8_t nonce[CHACHA20_NONCE_SIZE], const uint8_t *plaintext, size_t plaintext_len, const uint8_t *aad, size_t aad_len, uint8_t *ciphertext, uint8_t tag[POLY1305_TAG_SIZE]); /** * @brief ChaCha20-Poly1305 AEAD decryption * * @param ctx Context * @param nonce Nonce (12 bytes) * @param ciphertext Ciphertext data * @param ciphertext_len Ciphertext length * @param aad Additional authenticated data * @param aad_len AAD length * @param tag Authentication tag (16 bytes) * @param plaintext Output plaintext * @return 0 on success, -1 on error (tag mismatch) */ int se050_chacha20_poly1305_decrypt(se050_chacha20_poly1305_ctx_t *ctx, const uint8_t nonce[CHACHA20_NONCE_SIZE], const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *aad, size_t aad_len, const uint8_t tag[POLY1305_TAG_SIZE], uint8_t *plaintext); /** * @brief WireGuard-specific encrypt * * WireGuard uses ChaCha20-Poly1305 with: * - 32-byte key * - 12-byte nonce * - No AAD * * @param key Key (32 bytes) * @param nonce Nonce (12 bytes) * @param plaintext Plaintext * @param len Length * @param ciphertext Output ciphertext * @param tag Output tag (16 bytes) * @return 0 on success, -1 on error */ int se050_wireguard_encrypt(const uint8_t key[WG_KEY_SIZE], const uint8_t nonce[WG_NONCE_SIZE], const uint8_t *plaintext, size_t len, uint8_t *ciphertext, uint8_t tag[POLY1305_TAG_SIZE]); /** * @brief WireGuard-specific decrypt * * @param key Key (32 bytes) * @param nonce Nonce (12 bytes) * @param ciphertext Ciphertext * @param len Length * @param tag Tag (16 bytes) * @param plaintext Output plaintext * @return 0 on success, -1 on error */ int se050_wireguard_decrypt(const uint8_t key[WG_KEY_SIZE], const uint8_t nonce[WG_NONCE_SIZE], const uint8_t *ciphertext, size_t len, const uint8_t tag[POLY1305_TAG_SIZE], uint8_t *plaintext); /** * @brief Securely zeroize context * * @param ctx Context to zeroize */ void se050_chacha20_poly1305_zeroize(se050_chacha20_poly1305_ctx_t *ctx); #ifdef __cplusplus } #endif #endif /* SE050_CHACHA20_POLY1305_H */