]> Cypherpunks.ru repositories - govpn.git/blob - README
078c42e7917bf7dffbd3ac999202275a71f3c2e1
[govpn.git] / README
1                                  GoVPN
2                                  =====
3 SYNOPSIS
4
5 govpn is simple high-performance secure virtual private network daemon.
6 It uses DH-EKE for mutual zero-knowledge authentication and
7 authenticated encrypted transport. It runs under GNU/Linux and FreeBSD.
8
9 DESCRIPTION
10
11 All packets captured on network interface are encrypted, authenticated
12 and sent to remote server, that writes them to his interface, and vice
13 versa. Client and server use pre-shared authentication key (PSK).
14 Because of stateless UDP nature, after some timeout of inactivity peers
15 forget about each other and have to retry handshake process again. As a
16 rule, there are enough time-to-time traffic in ordinary Ethernet
17 networks to heartbeat connection.
18
19 Handshake is used to mutually authenticate peers, exchange common secret
20 per-session encryption key and checks UDP transport availability.
21
22 Because of UDP and authentication overhead: each packet grows in size
23 during transmission, so you have to lower you maximum transmission unit
24 (MTU) on network interface.
25
26 High security and high performance are the goals for that daemon. It
27 uses fast cryptography algorithms with 128bit security margin, strong
28 mutual zero-knowledge authentication and perfect-forward secrecy
29 property. An attacker can not know anything from captured traffic, even
30 if pre-shared key is compromised.
31
32 COMPARISON TO OpenVPN
33
34 * Faster handshake
35 * Perfect-forward secrecy (if long-term pre-shared keys are compromised,
36   no captured traffic can be decrypted anyway)
37 * Mutual two-side authentication (noone will send real network interface
38   data unless the other side is authenticated)
39 * Zero-knowledge authentication (pre-shared key is not transmitted in
40   any form between the peers, not even it's hash value)
41 * Higher performance in some cases
42 * Fully IPv6 compatible
43
44 CONSOLE OUTPUT LEGEND
45
46 B -- bad or timeouted UDP packet (maybe network is inactive)
47 T -- bad tag on packet (MiTM, unordered packet)
48 R -- invalid sequence number (MiTM, unordered packet)
49 [HS?] -- unknown handshake message
50 w -- successful write to remote peer
51 r -- successful read from remote peer
52 [HS1], [HS2], [HS3], [HS4] -- handshake packet stage
53 [rS?] -- invalid server's random authentication number received (MiTM, bad PSK)
54 [rC?] -- invalid client's random authentication number received (MiTM, bad PSK)
55 [S?] -- invalid handshake stage is trying to perform (MiTM, duplicate packet)
56 [OK] -- handshake's stage passed
57
58 EXAMPLE USAGE
59
60 Let's assume that there is some insecure link between your computer and
61 WiFi-reachable gateway. You have got preconfigured wlan0 network
62 interface with 192.168.0/24 network. You want to create virtual
63 encrypted and authenticated 172.16.0/24 network and use it as a default
64 transport. MTU for that wlan0 is 1500 bytes. GoVPN will say that maximum
65 MTU for the link is 1476, however it does not take in account TAP's
66 Ethernet frame header length, that in my case is 14 bytes long (1476 - 14).
67
68     common% umask 066
69     common% echo MYLONG64HEXKEY > key.txt
70
71 GNU/Linux IPv4 client-server example:
72
73     server% ip addr add 192.168.0.1/24 dev wlan0
74     server% tunctl -t tap10
75     server% ip link set mtu 1462 dev tap10
76     server% ip addr add 172.16.0.1/24 dev tap10
77     server% ip link set up dev tap10
78     server% govpn -key key.txt -iface tap10 -bind 192.168.0.1:1194
79
80     client% ip addr add 192.168.0.2/24 dev wlan0
81     client% tunctl -t tap10
82     client% ip link set mtu 1462 dev tap10
83     client% ip addr add 172.16.0.2/24 dev tap10
84     client% ip link set up dev tap10
85     client% ip route add default via 172.16.0.1
86     client% while :; do govpn -key key.txt -iface tap10 -remote 192.168.0.1:1194; done
87
88 FreeBSD IPv6 client-server example:
89
90     server% ifconfig em0 inet6 fe80::1/64
91     server% ifconfig tap10 create
92     server% ifconfig tap10 inet6 fc00::1/96 mtu 1462 up
93     server% govpn -key key.txt -face tap10 -bind fe80::1%em0
94
95     client% ifconfig me0 inet6 -ifdisabled auto_linklocal
96     client% ifconfig tap10
97     client% ifconfig tap10 inet6 fc00::2/96 mtu 1462 up
98     client% route -6 add default fc00::1
99     client% while :; do govpn -key key.txt -iface tap10 -remote [fe80::1%me0]:1194; done
100
101 If client won't finish handshake during -timeout, then it will exit.
102 If no packets are received from remote side during timeout, then daemon
103 will stop sending packets to the client and client will exit. In all
104 cases you have to rehandshake again.
105
106 TECHNICAL INTERNALS
107
108 Encryption: Salsa20
109 Message authentication: Poly1305
110 Password authenticated key agreement: Curve25519 based DH-EKE
111 Packet overhead: 24 bytes per packet
112 Handshake overhead: 4 UDP (2 from client, 2 from server) packets,
113                     232 bytes total payload
114
115                            Transport protocol
116
117     SERIAL + ENC(KEY, SERIAL, DATA) + AUTH(SERIAL + ENC_DATA)
118
119 where SERIAL is message serial number. Odds are reserved for
120 client->server, evens are for server->client. SERIAL is used as a nonce
121 for DATA encryption: encryption key is different during each handshake,
122 so (key, nonce) pair is always used once.
123
124 We generate Salsa20's output using this key and nonce for each message:
125 * first 256 bits are used as a one-time key for Poly1305 authentication
126 * next 256 bits of output are ignored
127 * and all remaining ones XORed with the data, encrypting it
128
129                            Handshake protocol
130      ┌──────┐                                  ┌──────┐
131      │Client│                                  │Server│
132      └──┬───┘                                  └──┬───┘
133         │────┐
134         │    │ R=rand(64bit); CPrivKey=rand(256bit)
135         │<───┘
136         │                                         │
137         │         R, enc(PSK, R, CPubKey)         │
138         │ ────────────────────────────────────────>
139         │                                         │
140         │                                         │────┐
141         │                                         │    │ SPrivKey=rand(256bit)
142         │                                         │<───┘
143         │                                         │
144         │                                         │────┐
145         │                                         │    │ K=DH(SPrivKey, CPubKey)
146         │                                         │<───┘
147         │                                         │
148         │                                         │────┐
149         │                                         │    │ RS=rand(64bit); SS=rand(256bit)
150         │                                         │<───┘
151         │                                         │
152         │ enc(PSK, R+1, SPubKey); enc(K, R, RS+SS)│
153         │ <────────────────────────────────────────
154         │                                         │
155         │────┐                                    │
156         │    │ K=DH(CPrivKey, SPubKey)            │
157         │<───┘                                    │
158         │                                         │
159         │────┐                                    │
160         │    │ RC=rand(64bit); SC=rand(256bit)    │
161         │<───┘                                    │
162         │                                         │
163         │          enc(K, R+1, RS+RC+SC)          │
164         │ ────────────────────────────────────────>
165         │                                         │
166         │                                         │────┐
167         │                                         │    │ compare(RS)
168         │                                         │<───┘
169         │                                         │
170         │                                         │────┐
171         │                                         │    │ MasterKey=SS XOR SC
172         │                                         │<───┘
173         │                                         │
174         │             enc(K, 0x00, RC)            │
175         │ <────────────────────────────────────────
176         │                                         │
177         │────┐                                    │
178         │    │ compare(RC)                        │
179         │<───┘                                    │
180         │                                         │
181         │────┐                                    │
182         │    │ MasterKey=SS XOR SC                │
183         │<───┘                                    │
184      ┌──┴───┐                                  ┌──┴───┐
185      │Client│                                  │Server│
186      └──────┘                                  └──────┘
187
188 * client generates CPubKey, random 64bit R that is used as a nonce
189   for encryption
190 * R + enc(PSK, R, CPubKey) + NULLs -> Server [56 bytes]
191 * server remembers clients address, decrypt CPubKey, generates
192   SPrivKey/SPubKey, computes common shared key K (based on
193   CPubKey and SPrivKey), generates 64bit random number RS and
194   256bit random SS. PSK-encryption uses incremented R (from previous
195   message) for nonce
196 * enc(PSK, SPubKey) + enc(K, RS + SS) + NULLs -> Client [88 bytes]
197 * client decrypt SPubKey, computes K, decrypts RS, SS with key K,
198   remembers SS, generates 64bit random number RC and 256bit random SC,
199 * enc(K, RS + RC + SC) + NULLs -> Server [64 bytes]
200 * server decrypt RS, RC, SC with key K, compares RS with it's own one
201   send before, computes final main encryption key S = SS XOR SC
202 * ENC(K, RC) + NULLs -> Client [24 bytes]
203 * server switches to the new client
204 * client decrypts RC and compares with it's own generated one, computes
205   final main encryption key S
206
207 Where PSK is 256bit pre-shared key, NULLs are 16 null-bytes. R* are
208 required for handshake randomization and two-way authentication. K key
209 is used only during handshake. NULLs are required to differentiate
210 common transport protocol messages from handshake ones. DH public keys
211 can be trivially derived from private ones.
212
213
214 RELATED DOCUMENTS
215
216 * http://cr.yp.to/ecdh.html
217 * http://cr.yp.to/snuffle.html
218 * http://cr.yp.to/mac.html
219 * http://grouper.ieee.org/groups/1363/passwdPK/contributions/jablon.pdf
220 * Applied Cryptography (C) 1996 Bruce Schneier
221
222 TODO
223
224 * Move decryption and encryption processes into goroutines
225 * Add identity management (client can send it's identification, server has
226   on-disk id↔key plaintext database)
227 * Implement alternative Secure Remote Password protocol (it is much slower,
228   technically has more code, but human memorized passwords can be used
229   instead of keys)
230
231 LICENCE
232
233 This program is free software: you can redistribute it and/or modify
234 it under the terms of the GNU General Public License as published by
235 the Free Software Foundation, either version 3 of the License, or
236 any later version.
237
238 This program is distributed in the hope that it will be useful,
239 but WITHOUT ANY WARRANTY; without even the implied warranty of
240 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
241 GNU General Public License for more details.