#ifndef SECURE_CHANNEL_H #define SECURE_CHANNEL_H #include #include #ifdef __cplusplus extern "C" { #endif /* ===== Константы ===== */ #define SC_PUBKEY_SIZE 64 /* secp256r1: X || Y */ #define SC_PRIVKEY_SIZE 32 #define SC_SHARED_SECRET_SIZE 32 #define SC_SESSION_KEY_SIZE 16 /* AES-128 key size */ #define SC_NONCE_SIZE 13 #define SC_TAG_SIZE 16 /* ===== Коды ошибок ===== */ typedef enum { SC_OK = 0, SC_ERR_INVALID_ARG, SC_ERR_CRYPTO, SC_ERR_NOT_INITIALIZED, SC_ERR_AUTH_FAILED } sc_status_t; /* ===== Контекст защищённого канала ===== */ typedef struct { /* Локальные ключи */ uint8_t private_key[SC_PRIVKEY_SIZE]; uint8_t public_key[SC_PUBKEY_SIZE]; /* Ключ пира */ uint8_t peer_public_key[SC_PUBKEY_SIZE]; uint8_t peer_key_set; /* Производные ключи */ uint8_t session_key[SC_SESSION_KEY_SIZE]; /* Nonce / counters */ uint32_t tx_counter; uint32_t rx_counter; /* Флаги состояния */ uint8_t initialized; uint8_t session_ready; } sc_context_t; /* ===== API ===== */ /** * @brief Сгенерировать пару ECDH ключей * * @param ctx Контекст * @return SC_OK или ошибка */ sc_status_t sc_generate_keypair(sc_context_t *ctx); /** * @brief Инициализация контекста с уже существующими ключами * * @param ctx Контекст * @param public_key Указатель на публичный ключ (64 байта) * @param private_key Указатель на приватный ключ (32 байта) */ sc_status_t sc_init_local_keys(sc_context_t *ctx, const uint8_t *public_key, const uint8_t *private_key); /** * @brief Установить публичный ключ пира и вычислить session key * * @param ctx Контекст * @param peer_public_key Публичный ключ пира (64 байта) */ sc_status_t sc_set_peer_public_key(sc_context_t *ctx, const uint8_t *peer_public_key); /** * @brief Зашифровать сообщение * * @param ctx Контекст * @param plaintext Входные данные * @param plaintext_len Длина * @param ciphertext Выход (может совпадать с plaintext) * @param tag MAC-тег (16 байт) */ sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, uint8_t *tag); /** * @brief Расшифровать и проверить сообщение * * @param ctx Контекст * @param ciphertext Зашифрованные данные * @param ciphertext_len Длина * @param tag MAC-тег * @param plaintext Выход */ sc_status_t sc_decrypt(sc_context_t *ctx, const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *tag, uint8_t *plaintext); #ifdef __cplusplus } #endif #endif /* SECURE_CHANNEL_H */