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