1Secure Framework
2================
3
4This layer provides wrappers around sendto(2) and recvfrom(2), the
5secure versions expect an additional 'struct security_association *sa'.
6
7The security association describes the encryption/authentication and
8decryption/validation functions that are used to provide confidentiality
9and integrity for sent messages.
10
11The implementation heavily draws on the following IPsec related RFCs,
12
13    RFC 2401 -- Security Architecture for the Internet Protocol
14    RFC 2406 -- IP Encapsulating Security Payload (ESP)
15    RFC 3948 -- UDP Encapsulation of IPsec ESP Packets
16
17The main difference is that in our case the security layer does not work
18between a pair of hosts, but assists the application to create secure
19tunnels between (logical) application level endpoints. Unlike IPsec, our
20payload does not include the TCP or UDP, and IP headers.
21
22Similar to IPsec, this layer does not implement any key exchange and
23setup, that step is left up to the application.
24
25Here is a short description of the important structures and functions,
26
27    struct security_association {
28    /* incoming packets */
29
30	/* identifier to match an incoming packet with the the correct
31	 * logical connection. Really only here for the convenience of
32	 * the application, it is not used by secure_recvfrom.
33	 * Security identifiers < 256 are considered 'reserved', see
34	 * secure_sendto/secure_recvfrom */
35	uint32_t recv_spi;
36
37	/* The following are used for to detect replay attacks and
38	 * should be initialized to 0 */
39	uint32_t recv_seq;
40	unsigned long recv_win;
41
42	/* function descriptor and state for packet validation */
43	const struct secure_auth *validate;
44	void *validate_context;
45
46	/* function descriptor and state for decryption */
47	const struct secure_encr *decrypt;
48	void *decrypt_context;
49
50    /* outgoing packets */
51	/* remote connection identifier */
52	uint32_t peer_spi;
53
54	/* sequence number used for outgoing packets, should be
55	 * initialized to 0 */
56	uint32_t peer_seq;
57
58	/* trusted address of the peer, outgoing encrypted packets will
59	 * be sent to this address, incoming packets that are correctly
60	 * validated will update this address */
61	struct sockaddr_storage peer;
62	socklen_t peerlen;
63
64	/* initialization vector/counter, should be initialized to a
65	 * random value, secure_sendto will properly increment it */
66	uint8_t send_iv[MAXIVLEN];
67
68	/* function descriptor and context for encryption */
69	const struct secure_encr *encrypt;
70	void *encrypt_context;
71
72	/* function descriptor and context for packet authentication */
73	const struct secure_auth *authenticate;
74	void *authenticate_context;
75    };
76
77This structure contains all the information required to securely send
78and receive encrypted and authenticated packets.
79
80
81    ssize_t secure_recvfrom(int s, void *buf, size_t len, int flags,
82			    struct sockaddr *peer, socklen_t *peerlen,
83			    struct security_association **sa,
84			    struct security_association *(*GETSA)(uint32_t spi))
85
86Wrapper around recvfrom to decrypt/validate incoming packets. If the
87packet is smaller than 8 bytes, or the first big-endian 32-bit word is
88less than 256, the packet is considered unencrypted and passed through
89without any futher processing.
90
91Otherwise, the GETSA callback is called with the 32-bit identifier (in
92native byte order). If GETSA returns NULL, the packet is dropped and we
93return EAGAIN which is (in Linux) identical to a received packet with a
94bad UDP checksum.
95
96If GETSA did return a valid security association,
97   - the sequence number is checked (anti-replay)
98   - we validate the message checksum
99   - update the receive window and sa->peer
100   - decrypt the packet
101   - check the padding
102
103If any of these steps fail, the packet is dropped and EAGAIN is
104returned. 'peer' is set whenever the packet is received, but sa->peer
105is only updated when the packet has been successfully validated.
106
107
108    ssize_t secure_sendto(int s, const void *buf, size_t len, int flags,
109			  const struct sockaddr *to, socklen_t tolen,
110			  struct security_association *sa)
111
112Send a packet securely. If sa is NULL or does not have an encryption and
113authentication function defined, and the first 32-bit big-endian word in
114buf is less than 256 then the data in 'buf' is sent as-is to the address
115specified by the 'to' argument. The check if the value is less than 256
116is to make sure the packet does not get interpreted by the receiver side
117as a valid encrypted packet.
118
119If we do have a valid security association, the payload is padded,
120encrypted and authenticated. The result is sent to the address in
121sa->peer (i.e. NOT to the 'to' address).
122
123Implemented authentication and encryption modes
124===============================================
125
126The framework is pretty flexible and should be able to support many
127encryption and authentication algorithms, however the provided ones are
128all based on the AES block cipher.
129
130AES-XCBC-MAC-96 authentication
131==============================
132
133    RFC 3566 -- The AES-XCBC-MAC-96 Algorithm and Its Use With IPsec
134
135AES-CBC based message integrity checksum, requires a 128-bit (16-byte)
136key and adds 12 checksum bytes to the packet.
137
138
139AES-CBC encryption
140==================
141
142    NIST Special Publication 800-38A -- Recommendation for Block Cipher
143					Modes of Operation
144    RFC 3602 -- The AES-CBC Cipher Algorithm and Its Use with IPsec
145
146This is a pretty straightforward and well understood cipher block
147chaining mode using AES as the encryption algorithm. CBC encryption
148requires the initialization vector to be the same size as the encryption
149block (which is 16-bytes for AES) The initialization vector has to be
150unpredictable, so we encrypt the IV-counter that was set up by the
151generic code in secure_sendto to obtain a pseudo random sequence.
152
153Can be used with 128, 192, and 256 bit keys (16, 24, and 32 bytes).
154
155
156AES-CCM encryption
157==================
158
159    NIST Special Publication 800-38C -- Recommendation for Block Cipher
160					Modes of Operation: The CCM Mode for
161					Authentication and Confidentiality
162    RFC 4309 -- Using Advanced Encryption Standard (AES) CCM Mode with
163		IPsec Encapsulating Security Payload (ESP)
164
165This is a combined encryption and authentication algorithm, so we do not
166need a separate authentication function. It also only needs 8 bytes for
167the initialization vector. The checksum can be either 8, 12, or 16
168bytes. As a result this algorithm has a lower per packet overhead, only
169between 16 and 24 bytes instead of the 28 bytes we need for AES-CBC with
170AES-XCBC-MAC-96.
171
172We also need less key material because we do not need a separate key for
173the message authentication algorithm. Finally, this algorithm lends
174itself well for several optimizations, it only uses the AES encrypt
175operation, initializing the encryption stream can be done off-line
176by the sender before the packet has be be sent and it is highly
177parallelizable.
178
179This encryption mode uses 152, 206, or 280-bits of key material
180(19, 27, or 35 bytes).
181
182Although there are several advantages, there is one pretty significant
183disadvantage. When a combination of the same key and initialization
184vector is reused at any time it becomes a trivial operation to obtain
185the plaintext of both messages. As such it is not recommended to use
186this encryption mode when we have static keys, such as during the
187initial handshake (user passwords, the keys in a Coda token, etc).
188
189
190AES implementation
191==================
192
193The used AES implementation is the Rijndael reference implementation (v3.0).
194I picked this because it seems to be fairly portable ANSI-C and we do not have
195to deal with trying to teach automake/autoconf about various platform specific
196assembly implementations and they pose no licensing conflicts wrt. to RPC2's
197LGPL license.
198
199As an alternative there is also the very small implementation by Mike Scott,
200however that code relies on global variables for the encryption/decryption
201state, only supports in-place operations and uses fairly generic naming. So it
202could use a bit of cleaning up so that the context can be passed avoid
203name-clashes.
204
205To make it simply to replace the AES implementation, the remaining code
206expects to be able to include "aes.h", which defines 5 functions to
207initialize, setup keys and to encrypt/decrypt a single block.
208
209There are several alternative implementation that can be used,
210
211- A more optimized implementation by Dr. Brian Gladman, his code is dual
212  licensed as BSD with an advertising clause, or alternatively pure GPL.
213  Neither of these mix well with RPC2's LGPL license so we probably can't
214  distribute binaries that are linked using his code. If you really need the
215  extra performance and make sure you comply with his license terms (as this
216  code is LGPL that would be the BSD license + advertising clause) and provide
217  the required copyright notice and disclaimer in any documentation and/or
218  associated materials that you distribute, you can find his version at,
219
220	http://fp.gladman.plus.com/AES/index.htm
221
222- There is also a modified version of the rijndael v3.0 reference code
223  available as part of the wpa_supplicant sources. It can optionally use
224  smaller tables which make the code 8KB smaller, and possibly make the code
225  less vulnerable to timing attacks, however it only supports 128-bit keys.
226  The modification are by Jouni Malinen and it seems to be dual licensed as
227  BSD without advertising clause or GPL,
228
229	http://hostap.epitest.fi/wpa_supplicant/
230
231- There are more, but from what I've seen most implementations are based on,
232
233  * original NIST submission (aka. rijndael v2.2 reference implementation),
234  * The optimized/cleaned-up Rijndael v3.0 reference implementation,
235  * Mike Scott's code, when the requirements tend to favour small size,
236  * Brian Gladman's code, when the requirements are mostly performance.
237
238- If you feel brave you can implement your own, the following is an excellent
239  article that explains a lot of the implementations details,
240
241	http://msdn.microsoft.com/msdnmag/issues/03/11/AES/
242
243
244AES testvectors
245===============
246
247testvectors.h contains several AES testvectors from
248
249    http://csrc.nist.gov/CryptoToolkit/aes/rijndael/rijndael-vals.zip
250
251If you want to regenerate or expand the number of tests that are run
252during initialization, unzip the testvalues in a subdirectory named
253'testvalues' and run gen_testvectors.sh to rebuild. At the top of the
254script are some comments and possible settings to vary the memory
255overhead/execution time to run these tests.
256
257We run the complete set of included test vectors during every startup.
258It only adds a delay of about 0.43 seconds on a 600MHz PIII, and less
259than 0.07 seconds on a 3.2GHz P4. But the delay does add a tiny amount
260of non-deterministic entropy for the PRNG initialization.
261
262
263PRNG implementation
264===================
265
266A deterministic pseudo random number generator based on ANSI X9.31, with
267the NIST recommended usage for using AES as a mixing function. The
268algorithm is fairly close to CBC mode encryption.
269
270There is a 16-byte pool of random data that we use as the IV. Then when
271we want to get random data we generate an initial seed based on the
272current timestamp, some uninitialized data from the stack, and a counter.
273
274This block is then encrypted using AES-CBC where the pool is used as the
275IV. This results in a block of 16-bytes of random data. The random block
276is then xor-ed with the original seed to get the next block of seed
277data. We then refresh the pool of random data by encrypting the seed
278block. These steps are repeated until we've returned the number of
279random bytes that were requested.
280
281To initialize the pool of random data and the AES128 encryption key, we
282get the current timestamp, and read random data from /dev/random (or
283/dev/urandom). When /dev/random is unavailable we fall back on several
284lower entropy sources such as times(), getpid(), and libc's random().
285
286The first block of random data is discarded, and we run a couple of
287statistical tests to see if the resulting random data actually looks
288reasonable. Passing these tests does not guarantee that the generated
289random numbers are cryptographically strong, but it should detect
290serious breakage.
291
292
293RPC2 secure handshake
294=====================
295
296The modified RPC2 handshake is based on the analysis and proposed
297implementation of the Andrew Secure RPC Handshake in 'A Logic of
298Authentication', by Michael Burrows, Martin Abadi, and Roger Needham.
299
300The handshake uses 4 steps so set up separate server->client and
301client->server encryption and authentication keys.
302
303 1. client -> server: Na, A
304
305    this is a normal RPC2 INIT1 packet, but with the RPC2SEC_CAPABLE
306    flag set in a header field. Na is a nonce which is used to avoid
307    replay attacks. A is the client identifier, it can be a username
308    or an encrypted Coda token.
309
310 2. server -> client: {Na, K'ab}Kab
311
312    The server sends back the nonce and a random key which will be used
313    for client -> server traffic encrypted with the shared secret that
314    was obtained from the client identifier. The client knows this is in
315    response to it's INIT1 packet because of the value of the nonce.
316
317    This packet is encrypted with AES-CBC and authenticated with
318    AES-XCBC-MAC-96
319
320 3. client -> server: {Na, K'ba}K'ab
321
322    The client responds with the nonce and a random key that will be
323    used for any further server -> client traffic, this is encrypted and
324    authenticated with the random session key we received in step 2.
325
326    The packet is encrypted with the encryption algorithm that server
327    chose and sent in step 2 along with the key. Currently this is
328    AES-CCM8.
329
330 4. server -> client: {Na, Nb}K'ba
331
332    The server sends back the nonce and an initial sequence number (Nb)
333    encrypted with the session key and algorithm it received from the
334    client in step 3.
335
336