annotate src/proto.salty.c @ 53:15d651dec8e9 V2.2.3

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