comparison src/proto.salty.c @ 42:c8d176154d7c

Added salty protocol (stateful, little overhead, PFS)
author Ivo Smits <Ivo@UCIS.nl>
date Thu, 16 May 2013 01:19:12 +0200
parents
children 4adbd9b67fe2
comparison
equal deleted inserted replaced
41:54d28a81ca99 42:c8d176154d7c
1 /* Copyright 2013 Ivo Smits <Ivo@UCIS.nl>. All rights reserved.
2 Redistribution and use in source and binary forms, with or without modification, are
3 permitted provided that the following conditions are met:
4
5 1. Redistributions of source code must retain the above copyright notice, this list of
6 conditions and the following disclaimer.
7
8 2. Redistributions in binary form must reproduce the above copyright notice, this list
9 of conditions and the following disclaimer in the documentation and/or other materials
10 provided with the distribution.
11
12 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
14 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
15 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
16 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
19 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
20 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
22 The views and conclusions contained in the software and documentation are those of the
23 authors and should not be interpreted as representing official policies, either expressed
24 or implied, of Ivo Smits.*/
25
26 /*
27 QuickTun Salty protocol
28 A curve25519xsalsa20poly1305 based VPN protocol providing encryption, authentication and PFS.
29 The Salty protocol is stateful; each side of the connection keeps track of the current and previous state of the local and remote encoder for minimal overhead and little to none packet loss during key transitions.
30
31 Wire format:
32 3 bit flags + 29 bit time + 16 byte checksum + encrypted data
33 flag 7 = 0
34 flag 6 = sender key id
35 flag 5 = recipient key id
36 8 bit flags + 64 bit time + 16 byte checksum + encrypted data
37 flag 7 = 1
38 encrypted data = 8 bit flags + 32 byte sender key + 24 byte sender nonce + 32 byte recipient key + 24 byte recipient nonce + 64 bit last received and accepted control timestamp
39 flag 7 = 0
40 flag 6 = sender key id
41 flag 5 = recipient key id
42 flag 4 = is acknowledgment
43
44 Key update (begin):
45 Generate new key pair <newkey> and nonce <newnonce> (last 4 bytes in nonce should be 0)
46 Set <keys[!<keyid>]> = <newkey>
47 Set <nonces[!<keyid>]> = <newnonce>
48 Send key update: sender key id = !<keyid>, sender key = <newkey>.Public, nonce = <newnonce>, recipient key id = <remotekeyid>, recipient key = <remotekey>, recipient nonce = <remotenonce>
49
50 Key update received:
51 Set <remotekeyid> = sender key id
52 Set <remotekey> = sender key
53 Set <remotenonce> = sender nonce
54 If <keys[0]> exists then
55 Set <decstate[0][<remotekeyid>]> = decoder(<keys[0]>, <remotekey>, <remotenonce>)
56 If <keys[1]> exists then
57 Set <decstate[1][<remotekeyid>]> = decoder(<keys[0]>, <remotekey>, <remotenonce>)
58 If <keys[recipient key id]> == recipient key && <nonces[recipient key id]> == recipient nonce
59 If recipient key id == <keyid> then
60 If encoder exists then
61 Set encodenonce = encoder.Nonce
62 Else
63 Set encodenonce = <nonces[<keyid>]>
64 Set encoder(<key>, <remotekey>, encodenonce)
65 Else if recipient key id == !<keyid> && <newkey> is set
66 Set <key> = <newkey>
67 Set <keyid> = !<keyid>
68 Set <newkey> = NULL
69 Set encoder(<key>, <remotekey>, <newnonce>)
70 If ! is acknowledgment then
71 Send key update: sender key id = <keyid>, sender key = <key>, nonce = <nonces[<keyid>], recipient key id = <remotekeyid>, recipient key = <remotekey>, recipient nonce = <remotenonce>
72 Else
73 Send key update: sender key id = <keyid>, sender key = <key>, nonce = <nonces[<keyid>], recipient key id = <remotekeyid>, recipient key = <remotekey>, recipient nonce = <remotenonce>
74
75 On startup:
76 Begin key update
77
78 Every 1 minute:
79 If <newkey> is set:
80 Send key update: sender key id = <keyid>, sender key = <key>, nonce = <nonces[<keyid>], recipient key id = <remotekeyid>, recipient key = <remotekey>, recipient nonce = <remotenonce>
81
82 Every 10 minutes:
83 Begin key update (if any packets have been sent with current key)
84
85 When sending packet:
86 If <key> and <remotekey> are set:
87 If packets sent with this key == (1<<29)-1
88 Switch to <newkey> or drop packet
89 If packets sent with this key > (1<<28)
90 If <newkey> is set:
91 Send key update: sender key id = !<keyid>, sender key = <newkey>.Public, nonce = <newnonce>, recipient key id = <remotekeyid>, recipient key = <remotekey>, recipient nonce = <remotenonce>
92 Else
93 Begin key update
94 Else
95 If <newkey> is set:
96 Send key update: sender key id = !<keyid>, sender key = <newkey>.Public, nonce = <newnonce>, recipient key id = <remotekeyid>, recipient key = <remotekey>, recipient nonce = <remotenonce>
97 Else
98 Begin key update
99
100 When receiving packet:
101 if flag 0 == 1
102 If time <= <lastcontroltime> then
103 Ignore packet
104 Decrypt packet
105 Set <lastcontroltime> = time
106 Key update received
107 Else
108 Use decoder decstate[recipient key id][sender key id]
109 Find index and value of lowest value in recenttimes as mintime and mintimeidx
110 If time <= mintime then
111 Ignore packet
112 Decode packet
113 Set recenttimes[mintimeidx] = time
114 Write packet to tunnel
115 */
116
117 #include "common.c"
118 #include "crypto_box_curve25519xsalsa20poly1305.h"
119 #include "crypto_scalarmult_curve25519.h"
120 #include <sys/types.h>
121 #include <sys/time.h>
122 #include <stdbool.h>
123
124 #define NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
125 #define BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
126 #define PRIVATEKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
127 #define PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
128
129 typedef unsigned int uint32;
130 typedef unsigned long long uint64;
131
132 struct qt_proto_data_salty_decstate {
133 unsigned char remotekey[PUBLICKEYBYTES];
134 unsigned char nonce[NONCEBYTES];
135 unsigned char sharedkey[BEFORENMBYTES];
136 uint32 timestamps[5];
137 };
138 struct qt_proto_data_salty_keyset {
139 unsigned char privatekey[PRIVATEKEYBYTES];
140 unsigned char publickey[PUBLICKEYBYTES];
141 unsigned char sharedkey[BEFORENMBYTES];
142 unsigned char nonce[NONCEBYTES];
143 };
144 struct qt_proto_data_salty {
145 time_t lastkeyupdate, lastkeyupdatesent;
146 unsigned char controlkey[BEFORENMBYTES];
147 bool controlencoderole;
148 uint64 controldecodetime;
149 uint64 controlencodetime;
150 struct qt_proto_data_salty_keyset* dataencoder;
151 struct qt_proto_data_salty_keyset datalocalkeys[2];
152 int datalocalkeyid;
153 int datalocalkeynextid;
154 int dataremotekeyid;
155 unsigned char dataremotekey[PUBLICKEYBYTES];
156 unsigned char dataremotenonce[NONCEBYTES];
157 struct qt_proto_data_salty_decstate datadecoders[4];
158 };
159
160 static void encodeuint32(char* b, uint32 v) {
161 b[0] = (v >> 24) & 255;
162 b[1] = (v >> 16) & 255;
163 b[2] = (v >> 8) & 255;
164 b[3] = (v >> 0) & 255;
165 }
166 static uint32 decodeuint32(char* sb) {
167 unsigned char* b = (unsigned char*)sb;
168 return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
169 }
170 static void encodeuint64(char* b, uint64 v) {
171 b[0] = (v >> 56) & 255;
172 b[1] = (v >> 48) & 255;
173 b[2] = (v >> 40) & 255;
174 b[3] = (v >> 32) & 255;
175 b[4] = (v >> 24) & 255;
176 b[5] = (v >> 16) & 255;
177 b[6] = (v >> 8) & 255;
178 b[7] = (v >> 0) & 255;
179 }
180 static uint64 decodeuint64(char* sb) {
181 unsigned char* b = (unsigned char*)sb;
182 return ((uint64)b[0] << 56) | ((uint64)b[1] << 48) | ((uint64)b[2] << 40) | ((uint64)b[3] << 32) | ((uint64)b[4] << 24) | ((uint64)b[5] << 16) | ((uint64)b[6] << 8) | (uint64)b[7];
183 }
184
185 static int devurandomfd = -1;
186
187 static void dumphex(unsigned char* lbl, unsigned char* buffer, int len) {
188 fprintf(stderr, "%s: ", lbl);
189 for (; len > 0; len--, buffer++) fprintf(stderr, "%02x", *buffer);
190 fprintf(stderr, "\n");
191 }
192
193 static bool randombytes(unsigned char* buffer, int len) {
194 if (devurandomfd == -1) devurandomfd = open("/dev/urandom", O_RDONLY);
195 if (devurandomfd == -1) return false;
196 while (len > 0) {
197 int got = read(devurandomfd, buffer, len);
198 if (got < 0) return false;
199 buffer += got;
200 len -= got;
201 }
202 return true;
203 }
204
205 static void initdecoder(struct qt_proto_data_salty_decstate* d, unsigned char rkey[], unsigned char lkey[], unsigned char nonce[]) {
206 memcpy(d->remotekey, rkey, PUBLICKEYBYTES);
207 memcpy(d->nonce, nonce, NONCEBYTES);
208 memset(d->timestamps, 0, 5 * sizeof(uint32));
209 if (debug) dumphex("INIT DECODER SK", lkey, 32);
210 if (debug) dumphex("INIT DECODER RK", rkey, 32);
211 crypto_box_curve25519xsalsa20poly1305_beforenm(d->sharedkey, rkey, lkey);
212 }
213
214 static void sendkeyupdate(struct qtsession* sess, bool ack) {
215 struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data;
216 unsigned char buffer[32 + (1 + 32 + 24 + 32 + 24 + 8)];
217 int keyid = (d->datalocalkeynextid == -1) ? d->datalocalkeyid : d->datalocalkeynextid;
218 if (debug) fprintf(stderr, "Sending key update nlkid=%d, rkid=%d, ack=%d\n", keyid, d->dataremotekeyid, ack);
219 buffer[32] = (0 << 7) | (keyid << 6) | (d->dataremotekeyid << 5) | (ack ? (1 << 4) : (0 << 4));
220 memcpy(buffer + 32 + 1, d->datalocalkeys[keyid].publickey, 32);
221 memcpy(buffer + 32 + 1 + 32, d->datalocalkeys[keyid].nonce, 24);
222 memcpy(buffer + 32 + 1 + 32 + 24, d->dataremotekey, 32);
223 memcpy(buffer + 32 + 1 + 32 + 24 + 32, d->dataremotenonce, 24);
224 encodeuint64(buffer + 32 + 1 + 32 + 24 + 32 + 24, d->controldecodetime);
225 memset(buffer, 0, 32);
226 d->controlencodetime++;
227 unsigned char nonce[24];
228 memset(nonce, 0, 24);
229 nonce[0] = d->controlencoderole ? 1 : 0;
230 encodeuint64(nonce + 16, d->controlencodetime);
231 unsigned char encbuffer[32 + 1 + 32 + 24 + 32 + 24 + 8];
232 if (crypto_box_curve25519xsalsa20poly1305_afternm(encbuffer, buffer, 32 + (1 + 32 + 24 + 32 + 24 + 8), nonce, d->controlkey)) return;
233 memcpy(encbuffer + 16 - 8, nonce + 16, 8);
234 encbuffer[16 - 1 - 8] = 0x80;
235 if (sess->sendnetworkpacket) sess->sendnetworkpacket(sess, encbuffer + 16 - 1 - 8, 1 + 8 + 16 + (1 + 32 + 24 + 32 + 24 + 8));
236 d->lastkeyupdatesent = time(NULL);
237 }
238
239 static bool beginkeyupdate(struct qtsession* sess) {
240 struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data;
241 d->datalocalkeynextid = (d->datalocalkeyid + 1) % 2;
242 if (debug) fprintf(stderr, "Beginning key update nlkid=%d, rkid=%d\n", d->datalocalkeynextid, d->dataremotekeyid);
243 struct qt_proto_data_salty_keyset* enckey = &d->datalocalkeys[d->datalocalkeynextid];
244 if (!randombytes(enckey->nonce, 20)) return false;
245 if (!randombytes(enckey->privatekey, PRIVATEKEYBYTES)) return false;
246 crypto_scalarmult_curve25519_base(enckey->publickey, enckey->privatekey);
247 memset(enckey->nonce + 20, 0, 4);
248 enckey->nonce[20] = 0x0F; //debugging
249 enckey->nonce[21] = 0xFF; //debugging
250 if (debug) dumphex("New public key", enckey->publickey, 32);
251 if (debug) dumphex("New base nonce", enckey->nonce, 24);
252 initdecoder(&d->datadecoders[(d->dataremotekeyid << 1) | d->datalocalkeynextid], d->dataremotekey, enckey->privatekey, d->dataremotenonce);
253 sendkeyupdate(sess, false);
254 d->lastkeyupdate = time(NULL);
255 }
256
257 static void beginkeyupdateifnecessary(struct qtsession* sess) {
258 struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data;
259 time_t t = time(NULL);
260 if (t - d->lastkeyupdate > 10) {
261 beginkeyupdate(sess);
262 } else if (d->datalocalkeynextid != -1 && t - d->lastkeyupdatesent > 0) {
263 sendkeyupdate(sess, false);
264 }
265 }
266
267 static int init(struct qtsession* sess) {
268 struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data;
269 char* envval;
270 printf("Initializing cryptography...\n");
271 unsigned char cpublickey[PUBLICKEYBYTES], csecretkey[PRIVATEKEYBYTES];
272 if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY");
273 if (strlen(envval) != 2*PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length");
274 hex2bin(cpublickey, envval, PUBLICKEYBYTES);
275 if (envval = getconf("PRIVATE_KEY")) {
276 if (strlen(envval) != 2 * PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length");
277 hex2bin(csecretkey, envval, PRIVATEKEYBYTES);
278 } else if (envval = getconf("PRIVATE_KEY_FILE")) {
279 FILE* pkfile = fopen(envval, "rb");
280 if (!pkfile) return errorexitp("Could not open PRIVATE_KEY_FILE");
281 char pktextbuf[PRIVATEKEYBYTES * 2];
282 size_t pktextsize = fread(pktextbuf, 1, sizeof(pktextbuf), pkfile);
283 if (pktextsize == PRIVATEKEYBYTES) {
284 memcpy(csecretkey, pktextbuf, PRIVATEKEYBYTES);
285 } else if (pktextsize = 2 * PRIVATEKEYBYTES) {
286 hex2bin(csecretkey, pktextbuf, PRIVATEKEYBYTES);
287 } else {
288 return errorexit("PRIVATE_KEY length");
289 }
290 fclose(pkfile);
291 } else {
292 return errorexit("Missing PRIVATE_KEY");
293 }
294 crypto_box_curve25519xsalsa20poly1305_beforenm(d->controlkey, cpublickey, csecretkey);
295 unsigned char cownpublickey[PUBLICKEYBYTES];
296 crypto_scalarmult_curve25519_base(cownpublickey, csecretkey);
297 d->controlencoderole = memcmp(cownpublickey, cpublickey, PUBLICKEYBYTES) > 0;
298 d->controldecodetime = 0;
299 d->controlencodetime = ((uint64)time(NULL)) << 8;
300 d->datalocalkeyid = 0;
301 d->datalocalkeynextid = -1;
302 d->dataremotekeyid = 0;
303 beginkeyupdate(sess);
304 d->datalocalkeyid = d->datalocalkeynextid;
305 sess->poll_timeout = 1000;
306 return 0;
307 }
308
309 static int encode(struct qtsession* sess, char* raw, char* enc, int len) {
310 beginkeyupdateifnecessary(sess);
311 struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data;
312 struct qt_proto_data_salty_keyset* e = d->dataencoder;
313 if (!e) {
314 if (debug) fprintf(stderr, "Discarding outgoing packet of %d bytes because encoder is not available\n", len);
315 return 0;
316 }
317 if (debug) fprintf(stderr, "Encoding packet of %d bytes from %p to %p\n", len, raw, enc);
318 //Check if nonce has exceeded half of maximum value (key update) or has exceeded maximum value (drop packet)
319 if (e->nonce[20] & 0xF0) {
320 if (d->datalocalkeynextid == -1) {
321 beginkeyupdate(sess);
322 } else {
323 sendkeyupdate(sess, false);
324 }
325 if (e->nonce[20] & 0xE0) return 0;
326 }
327 //Increment nonce in big endian
328 int i;
329 for (i = NONCEBYTES - 1; i >= 0 && ++e->nonce[i] == 0; i--) ;
330 if (e->nonce[20] & 0xE0) return 0;
331 if (debug) dumphex("ENCODE KEY", e->sharedkey, 32);
332 if (crypto_box_curve25519xsalsa20poly1305_afternm(enc, raw, len + 32, e->nonce, e->sharedkey)) return errorexit("Encryption failed");
333 enc[12] = (e->nonce[20] & 0x1F) | (0 << 7) | (d->datalocalkeyid << 6) | (d->dataremotekeyid << 5);
334 enc[13] = e->nonce[21];
335 enc[14] = e->nonce[22];
336 enc[15] = e->nonce[23];
337 if (debug) fprintf(stderr, "Encoded packet of %d bytes to %d bytes\n", len, len + 16 + 4);
338 return len + 16 + 4;
339 }
340
341 static int decode(struct qtsession* sess, char* enc, char* raw, int len) {
342 beginkeyupdateifnecessary(sess);
343 int i;
344 struct qt_proto_data_salty* d = (struct qt_proto_data_salty*)sess->protocol_data;
345 if (len < 1) {
346 fprintf(stderr, "Short packet received: %d\n", len);
347 return -1;
348 }
349 int flags = (unsigned char)enc[12];
350 if (!(flags & 0x80)) {
351 //<12 byte padding>|<4 byte timestamp><n+16 bytes encrypted data>
352 if (len < 4 + 16) {
353 fprintf(stderr, "Short data packet received: %d\n", len);
354 return -1;
355 }
356 struct qt_proto_data_salty_decstate* dec = &d->datadecoders[(flags >> 5) & 0x03];
357 uint32 ts = decodeuint32(enc + 12) & 0x1FFFFFFF;
358 if (debug) fprintf(stderr, "Decoding data packet of %d bytes with timestamp %u and flags %d\n", len, ts, flags & 0xE0);
359 int ltsi = 0;
360 uint32 ltsv = 0xFFFFFFFF;
361 for (i = 0; i < 5; i++) {
362 uint32 v = dec->timestamps[i];
363 if (ts == v) {
364 fprintf(stderr, "Duplicate data packet received: %u\n", ts);
365 return -1;
366 }
367 if (v < ltsv) {
368 ltsi = i;
369 ltsv = v;
370 }
371 }
372 if (ts <= ltsv) {
373 fprintf(stderr, "Late data packet received: %u\n", ts);
374 return -1;
375 }
376 dec->nonce[20] = enc[12] & 0x1F;
377 dec->nonce[21] = enc[13];
378 dec->nonce[22] = enc[14];
379 dec->nonce[23] = enc[15];
380 memset(enc, 0, 16);
381 if (debug) dumphex("DECODE KEY", dec->sharedkey, 32);
382 if (crypto_box_curve25519xsalsa20poly1305_open_afternm(raw, enc, len - 4 + 16, dec->nonce, dec->sharedkey)) {
383 fprintf(stderr, "Decryption of data packet failed len=%d\n", len);
384 return -1;
385 }
386 dec->timestamps[ltsi] = ts;
387 return len - 16 - 4;
388 } else {
389 //<12 byte padding>|<1 byte flags><8 byte timestamp><n+16 bytes encrypted control data>
390 if (len < 9 + 16 + 1 + 32 + 24 + 32 + 24 + 8) {
391 fprintf(stderr, "Short control packet received: %d\n", len);
392 return -1;
393 }
394 uint64 ts = decodeuint64(enc + 13);
395 if (debug) fprintf(stderr, "Decoding control packet of %d bytes with timestamp %llu and flags %d\n", len, ts, flags);
396 if (ts <= d->controldecodetime) {
397 fprintf(stderr, "Late control packet received: %llu < %llu\n", ts, d->controldecodetime);
398 return -1;
399 }
400 unsigned char cnonce[NONCEBYTES];
401 memset(cnonce, 0, 24);
402 cnonce[0] = d->controlencoderole ? 0 : 1;
403 memcpy(cnonce + 16, enc + 13, 8);
404 memset(enc + 12 + 1 + 8 - 16, 0, 16);
405 if (crypto_box_curve25519xsalsa20poly1305_open_afternm(raw, enc + 12 + 1 + 8 - 16, len - 1 - 8 + 16, cnonce, d->controlkey)) {
406 fprintf(stderr, "Decryption of control packet failed len=%d\n", len);
407 return -1;
408 }
409 d->controldecodetime = ts;
410 int dosendkeyupdate = 0;
411 //<32 byte padding><1 byte flags><32 byte sender key><24 byte sender nonce><32 byte recipient key><24 byte recipient nonce><8 byte timestamp>
412 int cflags = (unsigned char)raw[32];
413 d->dataremotekeyid = (cflags >> 6) & 0x01;
414 int lkeyid = (cflags >> 5) & 0x01;
415 if ((cflags & (1 << 4)) == 0) dosendkeyupdate |= 1;
416 memcpy(d->dataremotekey, raw + 32 + 1, 32);
417 memcpy(d->dataremotenonce, raw + 32 + 1 + 32, 24);
418 uint64 lexpectts = decodeuint64(raw + 32 + 1 + 32 + 24 + 32 + 24);
419 struct qt_proto_data_salty_keyset* enckey = &d->datalocalkeys[lkeyid];
420 if (memcmp(enckey->publickey, raw + 32 + 1 + 32 + 24, 32) || memcmp(enckey->nonce, raw + 32 + 1 + 32 + 24 + 32, 20)) {
421 dosendkeyupdate |= 2;
422 lkeyid = -1;
423 }
424 initdecoder(&d->datadecoders[(d->dataremotekeyid << 1) | 0x00], d->dataremotekey, d->datalocalkeys[0].privatekey, d->dataremotenonce);
425 initdecoder(&d->datadecoders[(d->dataremotekeyid << 1) | 0x01], d->dataremotekey, d->datalocalkeys[1].privatekey, d->dataremotenonce);
426 if (lkeyid != -1 && lkeyid == d->datalocalkeynextid) {
427 d->datalocalkeyid = lkeyid;
428 d->datalocalkeynextid = -1;
429 }
430 if (lkeyid == d->datalocalkeyid) {
431 crypto_box_curve25519xsalsa20poly1305_beforenm(enckey->sharedkey, d->dataremotekey, enckey->privatekey);
432 d->dataencoder = enckey;
433 }
434 if (debug) fprintf(stderr, "Decoded control packet: rkid=%d, lkid=%d, ack=%d, lkvalid=%d, uptodate=%d\n", d->dataremotekeyid, (cflags >> 5) & 0x01, (cflags >> 4) & 0x01, lkeyid != -1, d->datalocalkeynextid == -1);
435 if (d->datalocalkeynextid != -1) dosendkeyupdate |= 2;
436 if (dosendkeyupdate) sendkeyupdate(sess, (dosendkeyupdate & 2) == 0);
437 return 0;
438 }
439 }
440
441 static void idle(struct qtsession* sess) {
442 beginkeyupdateifnecessary(sess);
443 }
444
445 struct qtproto qtproto_salty = {
446 1,
447 MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
448 MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
449 crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
450 crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - 4,
451 encode,
452 decode,
453 init,
454 sizeof(struct qt_proto_data_salty),
455 idle,
456 };
457
458 #ifndef COMBINED_BINARY
459 int main(int argc, char** argv) {
460 print_header();
461 if (qtprocessargs(argc, argv) < 0) return -1;
462 return qtrun(&qtproto_salty);
463 }
464 #endif