GitHub CI: update list of container images
[tinc] / src / sptps.c
1 /*
2     sptps.c -- Simple Peer-to-Peer Security
3     Copyright (C) 2011-2015 Guus Sliepen <guus@tinc-vpn.org>,
4                   2010      Brandon L. Black <blblack@gmail.com>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "system.h"
22
23 #include "chacha-poly1305/chacha-poly1305.h"
24 #include "ecdh.h"
25 #include "ecdsa.h"
26 #include "prf.h"
27 #include "sptps.h"
28 #include "random.h"
29 #include "xalloc.h"
30
31 unsigned int sptps_replaywin = 16;
32
33 /*
34    Nonce MUST be exchanged first (done)
35    Signatures MUST be done over both nonces, to guarantee the signature is fresh
36    Otherwise: if ECDHE key of one side is compromised, it can be reused!
37
38    Add explicit tag to beginning of structure to distinguish the client and server when signing. (done)
39
40    Sign all handshake messages up to ECDHE kex with long-term public keys. (done)
41
42    HMACed KEX finished message to prevent downgrade attacks and prove you have the right key material (done by virtue of Ed25519 over the whole ECDHE exchange?)
43
44    Explicit close message needs to be added.
45
46    Maybe do add some alert messages to give helpful error messages? Not more than TLS sends.
47
48    Use counter mode instead of OFB. (done)
49
50    Make sure ECC operations are fixed time (aka prevent side-channel attacks).
51 */
52
53 void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap) {
54         (void)s;
55         (void)s_errno;
56         (void)format;
57         (void)ap;
58 }
59
60 void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap) {
61         (void)s;
62         (void)s_errno;
63
64         vfprintf(stderr, format, ap);
65         fputc('\n', stderr);
66 }
67
68 void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap) = sptps_log_stderr;
69
70 // Log an error message.
71 static bool error(sptps_t *s, int s_errno, const char *format, ...) ATTR_FORMAT(printf, 3, 4);
72 static bool error(sptps_t *s, int s_errno, const char *format, ...) {
73         (void)s;
74         (void)s_errno;
75
76         if(format) {
77                 va_list ap;
78                 va_start(ap, format);
79                 sptps_log(s, s_errno, format, ap);
80                 va_end(ap);
81         }
82
83         errno = s_errno;
84         return false;
85 }
86
87 static void warning(sptps_t *s, const char *format, ...) ATTR_FORMAT(printf, 2, 3);
88 static void warning(sptps_t *s, const char *format, ...) {
89         va_list ap;
90         va_start(ap, format);
91         sptps_log(s, 0, format, ap);
92         va_end(ap);
93 }
94
95 static sptps_kex_t *new_sptps_kex(void) {
96         return xzalloc(sizeof(sptps_kex_t));
97 }
98
99 static void free_sptps_kex(sptps_kex_t *kex) {
100         xzfree(kex, sizeof(sptps_kex_t));
101 }
102
103 static sptps_key_t *new_sptps_key(void) {
104         return xzalloc(sizeof(sptps_key_t));
105 }
106
107 static void free_sptps_key(sptps_key_t *key) {
108         xzfree(key, sizeof(sptps_key_t));
109 }
110
111 // Send a record (datagram version, accepts all record types, handles encryption and authentication).
112 static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const void *data, uint16_t len) {
113         uint8_t *buffer = alloca(len + 21UL);
114
115         // Create header with sequence number, length and record type
116         uint32_t seqno = s->outseqno++;
117         uint32_t netseqno = ntohl(seqno);
118
119         memcpy(buffer, &netseqno, 4);
120         buffer[4] = type;
121         memcpy(buffer + 5, data, len);
122
123         if(s->outstate) {
124                 // If first handshake has finished, encrypt and HMAC
125                 chacha_poly1305_encrypt(s->outcipher, seqno, buffer + 4, len + 1, buffer + 4, NULL);
126                 return s->send_data(s->handle, type, buffer, len + 21UL);
127         } else {
128                 // Otherwise send as plaintext
129                 return s->send_data(s->handle, type, buffer, len + 5UL);
130         }
131 }
132 // Send a record (private version, accepts all record types, handles encryption and authentication).
133 static bool send_record_priv(sptps_t *s, uint8_t type, const void *data, uint16_t len) {
134         if(s->datagram) {
135                 return send_record_priv_datagram(s, type, data, len);
136         }
137
138         uint8_t *buffer = alloca(len + 19UL);
139
140         // Create header with sequence number, length and record type
141         uint32_t seqno = s->outseqno++;
142         uint16_t netlen = htons(len);
143
144         memcpy(buffer, &netlen, 2);
145         buffer[2] = type;
146         memcpy(buffer + 3, data, len);
147
148         if(s->outstate) {
149                 // If first handshake has finished, encrypt and HMAC
150                 chacha_poly1305_encrypt(s->outcipher, seqno, buffer + 2, len + 1, buffer + 2, NULL);
151                 return s->send_data(s->handle, type, buffer, len + 19UL);
152         } else {
153                 // Otherwise send as plaintext
154                 return s->send_data(s->handle, type, buffer, len + 3UL);
155         }
156 }
157
158 // Send an application record.
159 bool sptps_send_record(sptps_t *s, uint8_t type, const void *data, uint16_t len) {
160         // Sanity checks: application cannot send data before handshake is finished,
161         // and only record types 0..127 are allowed.
162         if(!s->outstate) {
163                 return error(s, EINVAL, "Handshake phase not finished yet");
164         }
165
166         if(type >= SPTPS_HANDSHAKE) {
167                 return error(s, EINVAL, "Invalid application record type");
168         }
169
170         return send_record_priv(s, type, data, len);
171 }
172
173 // Send a Key EXchange record, containing a random nonce and an ECDHE public key.
174 static bool send_kex(sptps_t *s) {
175         // Make room for our KEX message, which we will keep around since send_sig() needs it.
176         if(s->mykex) {
177                 return false;
178         }
179
180         s->mykex = new_sptps_kex();
181
182         // Set version byte to zero.
183         s->mykex->version = SPTPS_VERSION;
184
185         // Create a random nonce.
186         randomize(s->mykex->nonce, ECDH_SIZE);
187
188         // Create a new ECDH public key.
189         if(!(s->ecdh = ecdh_generate_public(s->mykex->pubkey))) {
190                 return error(s, EINVAL, "Failed to generate ECDH public key");
191         }
192
193         return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, sizeof(sptps_kex_t));
194 }
195
196 static size_t sigmsg_len(size_t labellen) {
197         return 1 + 2 * sizeof(sptps_kex_t) + labellen;
198 }
199
200 static void fill_msg(uint8_t *msg, bool initiator, const sptps_kex_t *kex0, const sptps_kex_t *kex1, const sptps_t *s) {
201         *msg = initiator, msg++;
202         memcpy(msg, kex0, sizeof(*kex0)), msg += sizeof(*kex0);
203         memcpy(msg, kex1, sizeof(*kex1)), msg += sizeof(*kex1);
204         memcpy(msg, s->label, s->labellen);
205 }
206
207 // Send a SIGnature record, containing an Ed25519 signature over both KEX records.
208 static bool send_sig(sptps_t *s) {
209         // Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label
210         size_t msglen = sigmsg_len(s->labellen);
211         uint8_t *msg = alloca(msglen);
212         fill_msg(msg, s->initiator, s->mykex, s->hiskex, s);
213
214         // Sign the result.
215         size_t siglen = ecdsa_size(s->mykey);
216         uint8_t *sig = alloca(siglen);
217
218         if(!ecdsa_sign(s->mykey, msg, msglen, sig)) {
219                 return error(s, EINVAL, "Failed to sign SIG record");
220         }
221
222         // Send the SIG exchange record.
223         return send_record_priv(s, SPTPS_HANDSHAKE, sig, siglen);
224 }
225
226 // Generate key material from the shared secret created from the ECDHE key exchange.
227 static bool generate_key_material(sptps_t *s, const uint8_t *shared, size_t len) {
228         // Initialise cipher and digest structures if necessary
229         if(!s->outstate) {
230                 s->incipher = chacha_poly1305_init();
231                 s->outcipher = chacha_poly1305_init();
232
233                 if(!s->incipher || !s->outcipher) {
234                         return error(s, EINVAL, "Failed to open cipher");
235                 }
236         }
237
238         // Allocate memory for key material
239         s->key = new_sptps_key();
240
241         // Create the HMAC seed, which is "key expansion" + session label + server nonce + client nonce
242         const size_t msglen = sizeof("key expansion") - 1;
243         const size_t seedlen = msglen + s->labellen + ECDH_SIZE * 2;
244         uint8_t *seed = alloca(seedlen);
245
246         uint8_t *ptr = seed;
247         memcpy(ptr, "key expansion", msglen);
248         ptr += msglen;
249
250         memcpy(ptr, (s->initiator ? s->mykex : s->hiskex)->nonce, ECDH_SIZE);
251         ptr += ECDH_SIZE;
252
253         memcpy(ptr, (s->initiator ? s->hiskex : s->mykex)->nonce, ECDH_SIZE);
254         ptr += ECDH_SIZE;
255
256         memcpy(ptr, s->label, s->labellen);
257
258         // Use PRF to generate the key material
259         if(!prf(shared, len, seed, seedlen, s->key->both, sizeof(sptps_key_t))) {
260                 return error(s, EINVAL, "Failed to generate key material");
261         }
262
263         return true;
264 }
265
266 // Send an ACKnowledgement record.
267 static bool send_ack(sptps_t *s) {
268         return send_record_priv(s, SPTPS_HANDSHAKE, "", 0);
269 }
270
271 // Receive an ACKnowledgement record.
272 static bool receive_ack(sptps_t *s, const uint8_t *data, uint16_t len) {
273         (void)data;
274
275         if(len) {
276                 return error(s, EIO, "Invalid ACK record length");
277         }
278
279         uint8_t *key = s->initiator ? s->key->key0 : s->key->key1;
280
281         if(!chacha_poly1305_set_key(s->incipher, key)) {
282                 return error(s, EINVAL, "Failed to set counter");
283         }
284
285         free_sptps_key(s->key);
286         s->key = NULL;
287         s->instate = true;
288
289         return true;
290 }
291
292 // Receive a Key EXchange record, respond by sending a SIG record.
293 static bool receive_kex(sptps_t *s, const uint8_t *data, uint16_t len) {
294         // Verify length of the HELLO record
295         if(len != sizeof(sptps_kex_t)) {
296                 return error(s, EIO, "Invalid KEX record length");
297         }
298
299         if(*data != SPTPS_VERSION) {
300                 return error(s, EINVAL, "Received incorrect version %d", *data);
301         }
302
303         // Make a copy of the KEX message, send_sig() and receive_sig() need it
304         if(s->hiskex) {
305                 return error(s, EINVAL, "Received a second KEX message before first has been processed");
306         }
307
308         s->hiskex = new_sptps_kex();
309         memcpy(s->hiskex, data, sizeof(sptps_kex_t));
310
311         if(s->initiator) {
312                 return send_sig(s);
313         } else {
314                 return true;
315         }
316 }
317
318 // Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys.
319 static bool receive_sig(sptps_t *s, const uint8_t *data, uint16_t len) {
320         // Verify length of KEX record.
321         if(len != ecdsa_size(s->hiskey)) {
322                 return error(s, EIO, "Invalid KEX record length");
323         }
324
325         // Concatenate both KEX messages, plus tag indicating if it is from the connection originator
326         const size_t msglen = sigmsg_len(s->labellen);
327         uint8_t *msg = alloca(msglen);
328         fill_msg(msg, !s->initiator, s->hiskex, s->mykex, s);
329
330         // Verify signature.
331         if(!ecdsa_verify(s->hiskey, msg, msglen, data)) {
332                 return error(s, EIO, "Failed to verify SIG record");
333         }
334
335         // Compute shared secret.
336         uint8_t shared[ECDH_SHARED_SIZE];
337
338         if(!ecdh_compute_shared(s->ecdh, s->hiskex->pubkey, shared)) {
339                 memzero(shared, sizeof(shared));
340                 return error(s, EINVAL, "Failed to compute ECDH shared secret");
341         }
342
343         s->ecdh = NULL;
344
345         // Generate key material from shared secret.
346         bool generated = generate_key_material(s, shared, sizeof(shared));
347         memzero(shared, sizeof(shared));
348
349         if(!generated) {
350                 return false;
351         }
352
353         if(!s->initiator && !send_sig(s)) {
354                 return false;
355         }
356
357         free_sptps_kex(s->mykex);
358         s->mykex = NULL;
359
360         free_sptps_kex(s->hiskex);
361         s->hiskex = NULL;
362
363         // Send cipher change record
364         if(s->outstate && !send_ack(s)) {
365                 return false;
366         }
367
368         // TODO: only set new keys after ACK has been set/received
369         uint8_t *key = s->initiator ? s->key->key1 : s->key->key0;
370
371         if(!chacha_poly1305_set_key(s->outcipher, key)) {
372                 return error(s, EINVAL, "Failed to set key");
373         }
374
375         return true;
376 }
377
378 // Force another Key EXchange (for testing purposes).
379 bool sptps_force_kex(sptps_t *s) {
380         if(!s->outstate || s->state != SPTPS_SECONDARY_KEX) {
381                 return error(s, EINVAL, "Cannot force KEX in current state");
382         }
383
384         s->state = SPTPS_KEX;
385         return send_kex(s);
386 }
387
388 // Receive a handshake record.
389 static bool receive_handshake(sptps_t *s, const uint8_t *data, uint16_t len) {
390         // Only a few states to deal with handshaking.
391         switch(s->state) {
392         case SPTPS_SECONDARY_KEX:
393
394                 // We receive a secondary KEX request, first respond by sending our own.
395                 if(!send_kex(s)) {
396                         return false;
397                 }
398
399         // Fall through
400         case SPTPS_KEX:
401
402                 // We have sent our KEX request, we expect our peer to sent one as well.
403                 if(!receive_kex(s, data, len)) {
404                         return false;
405                 }
406
407                 s->state = SPTPS_SIG;
408                 return true;
409
410         case SPTPS_SIG:
411
412                 // If we already sent our secondary public ECDH key, we expect the peer to send his.
413                 if(!receive_sig(s, data, len)) {
414                         return false;
415                 }
416
417                 if(s->outstate) {
418                         s->state = SPTPS_ACK;
419                 } else {
420                         s->outstate = true;
421
422                         if(!receive_ack(s, NULL, 0)) {
423                                 return false;
424                         }
425
426                         s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0);
427                         s->state = SPTPS_SECONDARY_KEX;
428                 }
429
430                 return true;
431
432         case SPTPS_ACK:
433
434                 // We expect a handshake message to indicate transition to the new keys.
435                 if(!receive_ack(s, data, len)) {
436                         return false;
437                 }
438
439                 s->receive_record(s->handle, SPTPS_HANDSHAKE, NULL, 0);
440                 s->state = SPTPS_SECONDARY_KEX;
441                 return true;
442
443         // TODO: split ACK into a VERify and ACK?
444         default:
445                 return error(s, EIO, "Invalid session state %d", s->state);
446         }
447 }
448
449 static bool sptps_check_seqno(sptps_t *s, uint32_t seqno, bool update_state) {
450         // Replay protection using a sliding window of configurable size.
451         // s->inseqno is expected sequence number
452         // seqno is received sequence number
453         // s->late[] is a circular buffer, a 1 bit means a packet has not been received yet
454         // The circular buffer contains bits for sequence numbers from s->inseqno - s->replaywin * 8 to (but excluding) s->inseqno.
455         if(s->replaywin) {
456                 if(seqno != s->inseqno) {
457                         if(seqno >= s->inseqno + s->replaywin * 8) {
458                                 // Prevent packets that jump far ahead of the queue from causing many others to be dropped.
459                                 bool farfuture = s->farfuture < s->replaywin >> 2;
460
461                                 if(update_state) {
462                                         s->farfuture++;
463                                 }
464
465                                 if(farfuture) {
466                                         return update_state ? error(s, EIO, "Packet is %d seqs in the future, dropped (%u)\n", seqno - s->inseqno, s->farfuture) : false;
467                                 }
468
469                                 // Unless we have seen lots of them, in which case we consider the others lost.
470                                 if(update_state) {
471                                         warning(s, "Lost %d packets\n", seqno - s->inseqno);
472                                 }
473
474                                 if(update_state) {
475                                         // Mark all packets in the replay window as being late.
476                                         memset(s->late, 255, s->replaywin);
477                                 }
478                         } else if(seqno < s->inseqno) {
479                                 // If the sequence number is farther in the past than the bitmap goes, or if the packet was already received, drop it.
480                                 if((s->inseqno >= s->replaywin * 8 && seqno < s->inseqno - s->replaywin * 8) || !(s->late[(seqno / 8) % s->replaywin] & (1 << seqno % 8))) {
481                                         return update_state ? error(s, EIO, "Received late or replayed packet, seqno %d, last received %d\n", seqno, s->inseqno) : false;
482                                 }
483                         } else if(update_state) {
484                                 // We missed some packets. Mark them in the bitmap as being late.
485                                 for(uint32_t i = s->inseqno; i < seqno; i++) {
486                                         s->late[(i / 8) % s->replaywin] |= 1 << i % 8;
487                                 }
488                         }
489                 }
490
491                 if(update_state) {
492                         // Mark the current packet as not being late.
493                         s->late[(seqno / 8) % s->replaywin] &= ~(1 << seqno % 8);
494                         s->farfuture = 0;
495                 }
496         }
497
498         if(update_state) {
499                 if(seqno >= s->inseqno) {
500                         s->inseqno = seqno + 1;
501                 }
502
503                 if(!s->inseqno) {
504                         s->received = 0;
505                 } else {
506                         s->received++;
507                 }
508         }
509
510         return true;
511 }
512
513 // Check datagram for valid HMAC
514 bool sptps_verify_datagram(sptps_t *s, const void *vdata, size_t len) {
515         if(!s->instate || len < 21) {
516                 return error(s, EIO, "Received short packet");
517         }
518
519         const uint8_t *data = vdata;
520         uint32_t seqno;
521         memcpy(&seqno, data, 4);
522         seqno = ntohl(seqno);
523
524         if(!sptps_check_seqno(s, seqno, false)) {
525                 return false;
526         }
527
528         uint8_t *buffer = alloca(len);
529         size_t outlen;
530         return chacha_poly1305_decrypt(s->incipher, seqno, data + 4, len - 4, buffer, &outlen);
531 }
532
533 // Receive incoming data, datagram version.
534 static bool sptps_receive_data_datagram(sptps_t *s, const uint8_t *data, size_t len) {
535         if(len < (s->instate ? 21 : 5)) {
536                 return error(s, EIO, "Received short packet");
537         }
538
539         uint32_t seqno;
540         memcpy(&seqno, data, 4);
541         seqno = ntohl(seqno);
542         data += 4;
543         len -= 4;
544
545         if(!s->instate) {
546                 if(seqno != s->inseqno) {
547                         return error(s, EIO, "Invalid packet seqno: %d != %d", seqno, s->inseqno);
548                 }
549
550                 s->inseqno = seqno + 1;
551
552                 uint8_t type = *(data++);
553                 len--;
554
555                 if(type != SPTPS_HANDSHAKE) {
556                         return error(s, EIO, "Application record received before handshake finished");
557                 }
558
559                 return receive_handshake(s, data, len);
560         }
561
562         // Decrypt
563
564         uint8_t *buffer = alloca(len);
565         size_t outlen;
566
567         if(!chacha_poly1305_decrypt(s->incipher, seqno, data, len, buffer, &outlen)) {
568                 return error(s, EIO, "Failed to decrypt and verify packet");
569         }
570
571         if(!sptps_check_seqno(s, seqno, true)) {
572                 return false;
573         }
574
575         // Append a NULL byte for safety.
576         buffer[outlen] = 0;
577
578         data = buffer;
579         len = outlen;
580
581         uint8_t type = *(data++);
582         len--;
583
584         if(type < SPTPS_HANDSHAKE) {
585                 if(!s->instate) {
586                         return error(s, EIO, "Application record received before handshake finished");
587                 }
588
589                 if(!s->receive_record(s->handle, type, data, len)) {
590                         return false;
591                 }
592         } else if(type == SPTPS_HANDSHAKE) {
593                 if(!receive_handshake(s, data, len)) {
594                         return false;
595                 }
596         } else {
597                 return error(s, EIO, "Invalid record type %d", type);
598         }
599
600         return true;
601 }
602
603 // Receive incoming data. Check if it contains a complete record, if so, handle it.
604 size_t sptps_receive_data(sptps_t *s, const void *vdata, size_t len) {
605         const uint8_t *data = vdata;
606         size_t total_read = 0;
607
608         if(!s->state) {
609                 return error(s, EIO, "Invalid session state zero");
610         }
611
612         if(s->datagram) {
613                 return sptps_receive_data_datagram(s, data, len) ? len : false;
614         }
615
616         // First read the 2 length bytes.
617         if(s->buflen < 2) {
618                 size_t toread = 2 - s->buflen;
619
620                 if(toread > len) {
621                         toread = len;
622                 }
623
624                 memcpy(s->inbuf + s->buflen, data, toread);
625
626                 total_read += toread;
627                 s->buflen += toread;
628                 len -= toread;
629                 data += toread;
630
631                 // Exit early if we don't have the full length.
632                 if(s->buflen < 2) {
633                         return total_read;
634                 }
635
636                 // Get the length bytes
637
638                 memcpy(&s->reclen, s->inbuf, 2);
639                 s->reclen = ntohs(s->reclen);
640
641                 // If we have the length bytes, ensure our buffer can hold the whole request.
642                 s->inbuf = realloc(s->inbuf, s->reclen + 19UL);
643
644                 if(!s->inbuf) {
645                         return error(s, errno, "%s", strerror(errno));
646                 }
647
648                 // Exit early if we have no more data to process.
649                 if(!len) {
650                         return total_read;
651                 }
652         }
653
654         // Read up to the end of the record.
655         size_t toread = s->reclen + (s->instate ? 19UL : 3UL) - s->buflen;
656
657         if(toread > len) {
658                 toread = len;
659         }
660
661         memcpy(s->inbuf + s->buflen, data, toread);
662         total_read += toread;
663         s->buflen += toread;
664
665         // If we don't have a whole record, exit.
666         if(s->buflen < s->reclen + (s->instate ? 19UL : 3UL)) {
667                 return total_read;
668         }
669
670         // Update sequence number.
671
672         uint32_t seqno = s->inseqno++;
673
674         // Check HMAC and decrypt.
675         if(s->instate) {
676                 if(!chacha_poly1305_decrypt(s->incipher, seqno, s->inbuf + 2UL, s->reclen + 17UL, s->inbuf + 2UL, NULL)) {
677                         return error(s, EINVAL, "Failed to decrypt and verify record");
678                 }
679         }
680
681         // Append a NULL byte for safety.
682         s->inbuf[s->reclen + 3UL] = 0;
683
684         uint8_t type = s->inbuf[2];
685
686         if(type < SPTPS_HANDSHAKE) {
687                 if(!s->instate) {
688                         return error(s, EIO, "Application record received before handshake finished");
689                 }
690
691                 if(!s->receive_record(s->handle, type, s->inbuf + 3, s->reclen)) {
692                         return false;
693                 }
694         } else if(type == SPTPS_HANDSHAKE) {
695                 if(!receive_handshake(s, s->inbuf + 3, s->reclen)) {
696                         return false;
697                 }
698         } else {
699                 return error(s, EIO, "Invalid record type %d", type);
700         }
701
702         s->buflen = 0;
703
704         return total_read;
705 }
706
707 // Start a SPTPS session.
708 bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const void *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) {
709         // Initialise struct sptps
710         memset(s, 0, sizeof(*s));
711
712         s->handle = handle;
713         s->initiator = initiator;
714         s->datagram = datagram;
715         s->mykey = mykey;
716         s->hiskey = hiskey;
717         s->replaywin = sptps_replaywin;
718
719         if(s->replaywin) {
720                 s->late = malloc(s->replaywin);
721
722                 if(!s->late) {
723                         return error(s, errno, "%s", strerror(errno));
724                 }
725
726                 memset(s->late, 0, s->replaywin);
727         }
728
729         s->label = malloc(labellen);
730
731         if(!s->label) {
732                 return error(s, errno, "%s", strerror(errno));
733         }
734
735         if(!datagram) {
736                 s->inbuf = malloc(7);
737
738                 if(!s->inbuf) {
739                         return error(s, errno, "%s", strerror(errno));
740                 }
741
742                 s->buflen = 0;
743         }
744
745         memcpy(s->label, label, labellen);
746         s->labellen = labellen;
747
748         s->send_data = send_data;
749         s->receive_record = receive_record;
750
751         // Do first KEX immediately
752         s->state = SPTPS_KEX;
753         return send_kex(s);
754 }
755
756 // Stop a SPTPS session.
757 bool sptps_stop(sptps_t *s) {
758         // Clean up any resources.
759         chacha_poly1305_exit(s->incipher);
760         chacha_poly1305_exit(s->outcipher);
761         ecdh_free(s->ecdh);
762         free(s->inbuf);
763         free_sptps_kex(s->mykex);
764         free_sptps_kex(s->hiskex);
765         free_sptps_key(s->key);
766         free(s->label);
767         free(s->late);
768         memset(s, 0, sizeof(*s));
769         return true;
770 }