DVX_GUI/seclink/secLink.h

88 lines
3.6 KiB
C

// Secure serial link -- convenience wrapper tying rs232 + packet + security
//
// This is the top-level API for the serial/networking stack. It composes
// three layers into one:
// rs232 -- ISR-driven UART I/O with ring buffers
// packet -- HDLC framing + CRC-16 + Go-Back-N ARQ (reliable delivery)
// security -- DH key exchange + XTEA-CTR encryption
//
// Usage:
// 1. secLinkOpen() -- opens COM port, sets up packet framing
// 2. secLinkHandshake() -- DH key exchange (blocks until both sides complete)
// 3. secLinkSend() -- send data (optionally encrypted) on a channel
// 4. secLinkPoll() -- receive, decrypt if needed, deliver to callback
// 5. secLinkClose() -- tear everything down
//
// Channel multiplexing:
// Each packet carries a one-byte header: bit 7 = encrypted flag,
// bits 6..0 = channel number (0-127). This allows multiple logical streams
// (e.g., terminal data, file transfer, control messages) over a single
// serial link without needing separate framing or sequencing per stream.
// The callback receives plaintext regardless of whether encryption was used.
//
// Mixed clear/encrypted traffic:
// Unencrypted packets can be sent before or after the handshake. This
// allows a startup protocol (e.g., version negotiation) before keys are
// exchanged. Encrypted packets require a completed handshake.
#ifndef SECLINK_H
#define SECLINK_H
#include <stdint.h>
#include <stdbool.h>
// Error codes
#define SECLINK_SUCCESS 0
#define SECLINK_ERR_PARAM -1
#define SECLINK_ERR_SERIAL -2
#define SECLINK_ERR_ALLOC -3
#define SECLINK_ERR_HANDSHAKE -4
#define SECLINK_ERR_NOT_READY -5
#define SECLINK_ERR_SEND -6
// Max plaintext payload per send (packet max minus 1-byte channel header)
#define SECLINK_MAX_PAYLOAD 254
// Channel limits
#define SECLINK_MAX_CHANNEL 127
// Receive callback -- delivers plaintext with channel number
typedef void (*SecLinkRecvT)(void *ctx, const uint8_t *data, int len, uint8_t channel);
// Opaque handle
typedef struct SecLinkS SecLinkT;
// Open a secure serial link. Opens the COM port and packet layer.
// Handshake must be called separately before sending encrypted data.
SecLinkT *secLinkOpen(int com, int32_t bps, int dataBits, char parity, int stopBits, int handshake, SecLinkRecvT callback, void *ctx);
// Close the link. Frees all resources and closes the COM port.
void secLinkClose(SecLinkT *link);
// Perform DH key exchange. Blocks until both sides have exchanged keys
// and derived cipher keys. RNG must be seeded before calling this.
int secLinkHandshake(SecLinkT *link);
// Get number of unacknowledged packets in the transmit window.
int secLinkGetPending(SecLinkT *link);
// Returns true if handshake is complete and link is ready for data.
bool secLinkIsReady(SecLinkT *link);
// Poll for incoming data. Decrypts if needed and delivers to callback.
// Returns number of packets delivered, or negative on error.
int secLinkPoll(SecLinkT *link);
// Send data on a channel. If encrypt is true, data is encrypted before
// sending (requires completed handshake). Clear packets can be sent
// without a handshake. len must be 1..SECLINK_MAX_PAYLOAD.
// If block is true, waits for transmit window space.
int secLinkSend(SecLinkT *link, const uint8_t *data, int len, uint8_t channel, bool encrypt, bool block);
// Send an arbitrarily large buffer by splitting it into SECLINK_MAX_PAYLOAD
// chunks. Always blocks until all data is sent. Returns SECLINK_SUCCESS
// or the first error encountered.
int secLinkSendBuf(SecLinkT *link, const uint8_t *data, int len, uint8_t channel, bool encrypt);
#endif