You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

119 lines
3.2 KiB

#ifndef SECURE_CHANNEL_H
#define SECURE_CHANNEL_H
#include <stdint.h>
#include <stddef.h>
#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 */