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
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 */
|
|
|