annotate src/proto.salty.c @ 55:5685fad38195

Fixed compiler warnings from clang (including small bug in private key loading)
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 31 Jan 2014 22:52:46 +0100
parents 15d651dec8e9
children 66d9d80215f0
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>
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
123 #include <time.h>
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 #define NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 #define BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 #define PRIVATEKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 #define PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 typedef unsigned int uint32;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 typedef unsigned long long uint64;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 struct qt_proto_data_salty_decstate {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 unsigned char remotekey[PUBLICKEYBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 unsigned char nonce[NONCEBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 unsigned char sharedkey[BEFORENMBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137 uint32 timestamps[5];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 };
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 struct qt_proto_data_salty_keyset {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
140 unsigned char privatekey[PRIVATEKEYBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 unsigned char publickey[PUBLICKEYBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 unsigned char sharedkey[BEFORENMBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 unsigned char nonce[NONCEBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 };
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 struct qt_proto_data_salty {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 time_t lastkeyupdate, lastkeyupdatesent;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 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
148 int controlroles;
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149 uint64 controldecodetime;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 uint64 controlencodetime;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 struct qt_proto_data_salty_keyset* dataencoder;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152 struct qt_proto_data_salty_keyset datalocalkeys[2];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 int datalocalkeyid;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 int datalocalkeynextid;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 int dataremotekeyid;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 unsigned char dataremotekey[PUBLICKEYBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 unsigned char dataremotenonce[NONCEBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 struct qt_proto_data_salty_decstate datadecoders[4];
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
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 static void encodeuint32(char* b, uint32 v) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 b[0] = (v >> 24) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 b[1] = (v >> 16) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164 b[2] = (v >> 8) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165 b[3] = (v >> 0) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 static uint32 decodeuint32(char* sb) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 unsigned char* b = (unsigned char*)sb;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 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
170 }
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
171 static void encodeuint64(unsigned char* b, uint64 v) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172 b[0] = (v >> 56) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 b[1] = (v >> 48) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 b[2] = (v >> 40) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175 b[3] = (v >> 32) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 b[4] = (v >> 24) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177 b[5] = (v >> 16) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 b[6] = (v >> 8) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179 b[7] = (v >> 0) & 255;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181 static uint64 decodeuint64(char* sb) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 unsigned char* b = (unsigned char*)sb;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183 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
184 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 static int devurandomfd = -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
188 static void dumphex(char* lbl, unsigned char* buffer, int len) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
189 fprintf(stderr, "%s: ", lbl);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
190 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
191 fprintf(stderr, "\n");
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
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
194 static bool randombytes(unsigned char* buffer, int len) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
195 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
196 if (devurandomfd == -1) return false;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
197 while (len > 0) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
198 int got = read(devurandomfd, buffer, len);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
199 if (got < 0) return false;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
200 buffer += got;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
201 len -= got;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
202 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
203 return true;
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
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
206 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
207 memcpy(d->remotekey, rkey, PUBLICKEYBYTES);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
208 memcpy(d->nonce, nonce, NONCEBYTES);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
209 memset(d->timestamps, 0, 5 * sizeof(uint32));
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
210 if (debug) dumphex("INIT DECODER SK", lkey, 32);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
211 if (debug) dumphex("INIT DECODER RK", rkey, 32);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
212 crypto_box_curve25519xsalsa20poly1305_beforenm(d->sharedkey, rkey, lkey);
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
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
215 static void sendkeyupdate(struct qtsession* sess, bool ack) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
216 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
217 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
218 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
219 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
220 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
221 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
222 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
223 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
224 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
225 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
226 memset(buffer, 0, 32);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
227 d->controlencodetime++;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
228 unsigned char nonce[24];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
229 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
230 nonce[0] = d->controlroles & 1;
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
231 encodeuint64(nonce + 16, d->controlencodetime);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
232 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
233 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
234 memcpy(encbuffer + 16 - 8, nonce + 16, 8);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
235 encbuffer[16 - 1 - 8] = 0x80;
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
236 if (sess->sendnetworkpacket) sess->sendnetworkpacket(sess, (char*)encbuffer + 16 - 1 - 8, 1 + 8 + 16 + (1 + 32 + 24 + 32 + 24 + 8));
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
237 d->lastkeyupdatesent = time(NULL);
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
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
240 static bool beginkeyupdate(struct qtsession* sess) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
241 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
242 d->datalocalkeynextid = (d->datalocalkeyid + 1) % 2;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
243 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
244 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
245 if (!randombytes(enckey->nonce, 20)) return false;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
246 if (!randombytes(enckey->privatekey, PRIVATEKEYBYTES)) return false;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
247 crypto_scalarmult_curve25519_base(enckey->publickey, enckey->privatekey);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
248 memset(enckey->nonce + 20, 0, 4);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
249 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
250 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
251 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
252 sendkeyupdate(sess, false);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
253 d->lastkeyupdate = time(NULL);
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
254 return true;
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
255 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
256
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
257 static void beginkeyupdateifnecessary(struct qtsession* sess) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
258 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
259 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
260 if (t - d->lastkeyupdate > 300) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
261 beginkeyupdate(sess);
45
671d640390f2 Removed/changed some debug/test code in salty protocol
Ivo Smits <Ivo@UCIS.nl>
parents: 43
diff changeset
262 } 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
263 sendkeyupdate(sess, false);
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 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
266
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
267 static int init(struct qtsession* sess) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
268 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
269 char* envval;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
270 printf("Initializing cryptography...\n");
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
271 unsigned char cpublickey[PUBLICKEYBYTES], csecretkey[PRIVATEKEYBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
272 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
273 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
274 hex2bin(cpublickey, envval, PUBLICKEYBYTES);
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
275 if ((envval = getconf("PRIVATE_KEY"))) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
276 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
277 hex2bin(csecretkey, envval, PRIVATEKEYBYTES);
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
278 } else if ((envval = getconf("PRIVATE_KEY_FILE"))) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
279 FILE* pkfile = fopen(envval, "rb");
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
280 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
281 char pktextbuf[PRIVATEKEYBYTES * 2];
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
282 const size_t pktextsize = fread(pktextbuf, 1, sizeof(pktextbuf), pkfile);
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
283 if (pktextsize == PRIVATEKEYBYTES) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
284 memcpy(csecretkey, pktextbuf, PRIVATEKEYBYTES);
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
285 } else if (pktextsize == 2 * PRIVATEKEYBYTES) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
286 hex2bin(csecretkey, pktextbuf, PRIVATEKEYBYTES);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
287 } else {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
288 return errorexit("PRIVATE_KEY length");
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
289 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
290 fclose(pkfile);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
291 } else {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
292 return errorexit("Missing PRIVATE_KEY");
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
293 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
294 crypto_box_curve25519xsalsa20poly1305_beforenm(d->controlkey, cpublickey, csecretkey);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
295 unsigned char cownpublickey[PUBLICKEYBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
296 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
297 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
298 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
299 d->controldecodetime = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
300 d->controlencodetime = ((uint64)time(NULL)) << 8;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
301 d->datalocalkeyid = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
302 d->datalocalkeynextid = -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
303 d->dataremotekeyid = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
304 beginkeyupdate(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
305 d->datalocalkeyid = d->datalocalkeynextid;
45
671d640390f2 Removed/changed some debug/test code in salty protocol
Ivo Smits <Ivo@UCIS.nl>
parents: 43
diff changeset
306 sess->poll_timeout = 5000;
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
307 return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
308 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
309
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
310 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
311 beginkeyupdateifnecessary(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
312 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
313 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
314 if (!e) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
315 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
316 return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
317 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
318 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
319 //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
320 if (e->nonce[20] & 0xF0) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
321 if (d->datalocalkeynextid == -1) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
322 beginkeyupdate(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
323 } else {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
324 sendkeyupdate(sess, false);
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 if (e->nonce[20] & 0xE0) return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
327 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
328 //Increment nonce in big endian
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
329 int i;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
330 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
331 if (e->nonce[20] & 0xE0) return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
332 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
333 memset(raw, 0, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES);
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
334 if (crypto_box_curve25519xsalsa20poly1305_afternm((unsigned char*)enc, (unsigned char*)raw, len + 32, e->nonce, e->sharedkey)) return errorexit("Encryption failed");
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
335 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
336 enc[13] = e->nonce[21];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
337 enc[14] = e->nonce[22];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
338 enc[15] = e->nonce[23];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
339 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
340 return len + 16 + 4;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
341 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
342
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
343 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
344 beginkeyupdateifnecessary(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
345 int i;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
346 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
347 if (len < 1) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
348 fprintf(stderr, "Short packet received: %d\n", len);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
349 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
350 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
351 int flags = (unsigned char)enc[12];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
352 if (!(flags & 0x80)) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
353 //<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
354 if (len < 4 + 16) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
355 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
356 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
357 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
358 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
359 uint32 ts = decodeuint32(enc + 12) & 0x1FFFFFFF;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
360 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
361 int ltsi = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
362 uint32 ltsv = 0xFFFFFFFF;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
363 for (i = 0; i < 5; i++) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
364 uint32 v = dec->timestamps[i];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
365 if (ts == v) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
366 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
367 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
368 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
369 if (v < ltsv) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
370 ltsi = i;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
371 ltsv = v;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
372 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
373 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
374 if (ts <= ltsv) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
375 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
376 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
377 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
378 dec->nonce[20] = enc[12] & 0x1F;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
379 dec->nonce[21] = enc[13];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
380 dec->nonce[22] = enc[14];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
381 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
382 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
383 if (debug) dumphex("DECODE KEY", dec->sharedkey, 32);
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
384 if (crypto_box_curve25519xsalsa20poly1305_open_afternm((unsigned char*)raw, (unsigned char*)enc, len - 4 + 16, dec->nonce, dec->sharedkey)) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
385 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
386 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
387 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
388 dec->timestamps[ltsi] = ts;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
389 return len - 16 - 4;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
390 } else {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
391 //<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
392 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
393 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
394 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
395 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
396 uint64 ts = decodeuint64(enc + 13);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
397 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
398 if (ts <= d->controldecodetime) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
399 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
400 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
401 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
402 unsigned char cnonce[NONCEBYTES];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
403 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
404 cnonce[0] = (d->controlroles >> 1) & 1;
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
405 memcpy(cnonce + 16, enc + 13, 8);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
406 memset(enc + 12 + 1 + 8 - 16, 0, 16);
55
5685fad38195 Fixed compiler warnings from clang (including small bug in private key loading)
Ivo Smits <Ivo@UCIS.nl>
parents: 53
diff changeset
407 if (crypto_box_curve25519xsalsa20poly1305_open_afternm((unsigned char*)raw, (unsigned char*)enc + 12 + 1 + 8 - 16, len - 1 - 8 + 16, cnonce, d->controlkey)) {
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
408 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
409 return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
410 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
411 d->controldecodetime = ts;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
412 int dosendkeyupdate = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
413 //<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
414 int cflags = (unsigned char)raw[32];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
415 d->dataremotekeyid = (cflags >> 6) & 0x01;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
416 int lkeyid = (cflags >> 5) & 0x01;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
417 if ((cflags & (1 << 4)) == 0) dosendkeyupdate |= 1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
418 memcpy(d->dataremotekey, raw + 32 + 1, 32);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
419 memcpy(d->dataremotenonce, raw + 32 + 1 + 32, 24);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
420 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
421 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
422 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
423 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
424 }
42
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
425 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
426 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
427 dosendkeyupdate |= 2;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
428 lkeyid = -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
429 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
430 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
431 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
432 if (lkeyid != -1 && lkeyid == d->datalocalkeynextid) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
433 d->datalocalkeyid = lkeyid;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
434 d->datalocalkeynextid = -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
435 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
436 if (lkeyid == d->datalocalkeyid) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
437 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
438 d->dataencoder = enckey;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
439 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
440 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
441 if (d->datalocalkeynextid != -1) dosendkeyupdate |= 2;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
442 if (dosendkeyupdate) sendkeyupdate(sess, (dosendkeyupdate & 2) == 0);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
443 return 0;
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 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
446
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
447 static void idle(struct qtsession* sess) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
448 beginkeyupdateifnecessary(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
449 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
450
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
451 struct qtproto qtproto_salty = {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
452 1,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
453 MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
454 MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
455 crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
456 crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - 4,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
457 encode,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
458 decode,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
459 init,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
460 sizeof(struct qt_proto_data_salty),
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
461 idle,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
462 };
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
463
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
464 #ifndef COMBINED_BINARY
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
465 int main(int argc, char** argv) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
466 print_header();
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
467 if (qtprocessargs(argc, argv) < 0) return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
468 return qtrun(&qtproto_salty);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
469 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
470 #endif