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