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