74 lines
2.9 KiB
C
74 lines
2.9 KiB
C
// Secure serial link — convenience wrapper tying rs232 + packet + security
|
|
//
|
|
// 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
|
|
//
|
|
// Each packet carries a one-byte header: bit 7 = encrypted flag,
|
|
// bits 6..0 = channel number (0-127). The callback receives plaintext
|
|
// regardless of whether encryption was used.
|
|
|
|
#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 255
|
|
|
|
// 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
|