-typedef bool (*send_data_t)(void *handle, const char *data, size_t len);
-typedef bool (*receive_record_t)(void *handle, uint8_t type, const char *data, uint16_t len);
+// Key exchange states
+typedef enum sptps_state_t {
+ SPTPS_KEX = 1, // Waiting for the first Key EXchange record
+ SPTPS_SECONDARY_KEX = 2, // Ready to receive a secondary Key EXchange record
+ SPTPS_SIG = 3, // Waiting for a SIGnature record
+ SPTPS_ACK = 4, // Waiting for an ACKnowledgement record
+} sptps_state_t;
+
+PACKED(struct sptps_kex_t {
+ uint8_t version;
+ uint8_t preferred_suite;
+ uint16_t cipher_suites;
+ uint8_t nonce[ECDH_SIZE];
+ uint8_t pubkey[ECDH_SIZE];
+});
+
+typedef struct sptps_kex_t sptps_kex_t;
+
+STATIC_ASSERT(sizeof(sptps_kex_t) == 68, "sptps_kex_t has invalid size");
+
+// Big enough to handle a 256 bit key + IV
+#define SPTPS_KEYLEN 64
+
+typedef union sptps_key_t {
+ struct {
+ uint8_t key0[SPTPS_KEYLEN];
+ uint8_t key1[SPTPS_KEYLEN];
+ };
+ uint8_t both[SPTPS_KEYLEN * 2];
+} sptps_key_t;
+
+STATIC_ASSERT(sizeof(sptps_key_t) == 128, "sptps_key_t has invalid size");
+
+// Public key suites
+enum {
+ SPTPS_ED25519 = 0,
+};
+
+// Cipher suites
+enum {
+ SPTPS_CHACHA_POLY1305 = 0,
+ SPTPS_AES256_GCM = 1,
+ SPTPS_ALL_CIPHER_SUITES = 0x3,
+};
+
+typedef struct sptps_params {
+ void *handle;
+ bool initiator;
+ bool datagram;
+ uint8_t preferred_suite;
+ uint16_t cipher_suites;
+ ecdsa_t *mykey;
+ ecdsa_t *hiskey;
+ const void *label;
+ size_t labellen;
+ send_data_t send_data;
+ receive_record_t receive_record;
+} sptps_params_t;