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

Added salty protocol (stateful, little overhead, PFS)
author Ivo Smits <Ivo@UCIS.nl>
date Thu, 16 May 2013 01:19:12 +0200
parents
children 4adbd9b67fe2
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];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 bool controlencoderole;
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
229 nonce[0] = d->controlencoderole ? 1 : 0;
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 enckey->nonce[20] = 0x0F; //debugging
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
249 enckey->nonce[21] = 0xFF; //debugging
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
250 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
251 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
252 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
253 sendkeyupdate(sess, false);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
254 d->lastkeyupdate = time(NULL);
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
260 if (t - d->lastkeyupdate > 10) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
261 beginkeyupdate(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
262 } else if (d->datalocalkeynextid != -1 && t - d->lastkeyupdatesent > 0) {
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
275 if (envval = getconf("PRIVATE_KEY")) {
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
278 } else if (envval = getconf("PRIVATE_KEY_FILE")) {
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];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
282 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
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
285 } else if (pktextsize = 2 * PRIVATEKEYBYTES) {
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
297 d->controlencoderole = memcmp(cownpublickey, cpublickey, PUBLICKEYBYTES) > 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
298 d->controldecodetime = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
299 d->controlencodetime = ((uint64)time(NULL)) << 8;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
300 d->datalocalkeyid = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
301 d->datalocalkeynextid = -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
302 d->dataremotekeyid = 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
303 beginkeyupdate(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
304 d->datalocalkeyid = d->datalocalkeynextid;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
305 sess->poll_timeout = 1000;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
306 return 0;
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
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
309 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
310 beginkeyupdateifnecessary(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
311 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
312 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
313 if (!e) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
314 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
315 return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
316 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
317 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
318 //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
319 if (e->nonce[20] & 0xF0) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
320 if (d->datalocalkeynextid == -1) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
321 beginkeyupdate(sess);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
322 } else {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
323 sendkeyupdate(sess, false);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
324 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
325 if (e->nonce[20] & 0xE0) return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
326 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
327 //Increment nonce in big endian
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
328 int i;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
329 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
330 if (e->nonce[20] & 0xE0) return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
331 if (debug) dumphex("ENCODE KEY", e->sharedkey, 32);
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];
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
380 memset(enc, 0, 16);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
381 if (debug) dumphex("DECODE KEY", dec->sharedkey, 32);
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
402 cnonce[0] = d->controlencoderole ? 0 : 1;
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);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
419 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
420 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
421 dosendkeyupdate |= 2;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
422 lkeyid = -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
423 }
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
424 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
425 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
426 if (lkeyid != -1 && lkeyid == d->datalocalkeynextid) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
427 d->datalocalkeyid = lkeyid;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
428 d->datalocalkeynextid = -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 if (lkeyid == d->datalocalkeyid) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
431 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
432 d->dataencoder = enckey;
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 (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
435 if (d->datalocalkeynextid != -1) dosendkeyupdate |= 2;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
436 if (dosendkeyupdate) sendkeyupdate(sess, (dosendkeyupdate & 2) == 0);
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
437 return 0;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
438 }
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
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
441 static void idle(struct qtsession* sess) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
442 beginkeyupdateifnecessary(sess);
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 struct qtproto qtproto_salty = {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
446 1,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
447 MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
448 MAX_PACKET_LEN + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
449 crypto_box_curve25519xsalsa20poly1305_ZEROBYTES,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
450 crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - 4,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
451 encode,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
452 decode,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
453 init,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
454 sizeof(struct qt_proto_data_salty),
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
455 idle,
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
456 };
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
457
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
458 #ifndef COMBINED_BINARY
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
459 int main(int argc, char** argv) {
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
460 print_header();
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
461 if (qtprocessargs(argc, argv) < 0) return -1;
c8d176154d7c Added salty protocol (stateful, little overhead, PFS)
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
462 return qtrun(&qtproto_salty);
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 #endif