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