Initial import
[umurmur.git] / src / crypt.c
1 /* Copyright (C) 2009, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2009, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33  * This code implements OCB-AES128.
34  * In the US, OCB is covered by patents. The inventor has given a license
35  * to all programs distributed under the GPL.
36  * uMurmur is BSD (revised) licensed, meaning you can use the code in a
37  * closed-source program. If you do, you'll have to either replace
38  * OCB with something else or get yourself a license.
39  */
40
41 #include <string.h>
42 #include <arpa/inet.h>
43 #include "crypt.h"
44 #include "log.h"
45 static void CryptState_ocb_encrypt(cryptState_t *cs, const unsigned char *plain, unsigned char *encrypted, unsigned int len, const unsigned char *nonce, unsigned char *tag);
46 static void CryptState_ocb_decrypt(cryptState_t *cs, const unsigned char *encrypted, unsigned char *plain, unsigned int len, const unsigned char *nonce, unsigned char *tag);
47
48 void CryptState_init(cryptState_t *cs)
49 {
50         memset(cs->decrypt_history, 0, 0xff);
51         memset(cs->raw_key, 0, AES_BLOCK_SIZE);
52         memset(cs->encrypt_iv, 0, AES_BLOCK_SIZE);
53         memset(cs->decrypt_iv, 0, AES_BLOCK_SIZE);
54         cs->bInit = false;
55         cs->uiGood = cs->uiLate = cs->uiLost = cs->uiResync = 0;
56         cs->uiRemoteGood = cs->uiRemoteLate = cs->uiRemoteLost = cs->uiRemoteResync = 0;
57         Timer_init(&cs->tLastGood);
58         Timer_init(&cs->tLastRequest);
59 }
60
61 bool_t CryptState_isValid(cryptState_t *cs)
62 {
63         return cs->bInit;
64 }
65
66 void CryptState_genKey(cryptState_t *cs) {
67         RAND_bytes(cs->raw_key, AES_BLOCK_SIZE);
68         RAND_bytes(cs->encrypt_iv, AES_BLOCK_SIZE);
69         RAND_bytes(cs->decrypt_iv, AES_BLOCK_SIZE);
70         AES_set_encrypt_key(cs->raw_key, 128, &cs->encrypt_key);
71         AES_set_decrypt_key(cs->raw_key, 128, &cs->decrypt_key);
72         cs->bInit = true;
73 }
74
75 void CryptState_setKey(cryptState_t *cs, const unsigned char *rkey, const unsigned char *eiv, const unsigned char *div)
76 {
77         memcpy(cs->raw_key, rkey, AES_BLOCK_SIZE);
78         memcpy(cs->encrypt_iv, eiv, AES_BLOCK_SIZE);
79         memcpy(cs->decrypt_iv, div, AES_BLOCK_SIZE);
80         AES_set_encrypt_key(cs->raw_key, 128, &cs->encrypt_key);
81         AES_set_decrypt_key(cs->raw_key, 128, &cs->decrypt_key);
82         cs->bInit = true;
83 }
84
85 void CryptState_setDecryptIV(cryptState_t *cs, const unsigned char *iv)
86 {
87         memcpy(cs->decrypt_iv, iv, AES_BLOCK_SIZE);
88 }
89
90 void CryptState_encrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int plain_length)
91 {
92         unsigned char tag[AES_BLOCK_SIZE];
93         int i;
94         // First, increase our IV.
95         for (i = 0; i < AES_BLOCK_SIZE; i++)
96                 if (++cs->encrypt_iv[i])
97                         break;
98
99         CryptState_ocb_encrypt(cs, source, dst+4, plain_length, cs->encrypt_iv, tag);
100
101         dst[0] = cs->encrypt_iv[0];
102         dst[1] = tag[0];
103         dst[2] = tag[1];
104         dst[3] = tag[2];
105 }
106
107 bool_t CryptState_decrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int crypted_length)
108 {
109         if (crypted_length < 4)
110                 return false;
111
112         unsigned int plain_length = crypted_length - 4;
113
114         unsigned char saveiv[AES_BLOCK_SIZE];
115         unsigned char ivbyte = source[0];
116         bool_t restore = false;
117         unsigned char tag[AES_BLOCK_SIZE];
118
119         int lost = 0;
120         int late = 0;
121
122         memcpy(saveiv, cs->decrypt_iv, AES_BLOCK_SIZE);
123
124         if (((cs->decrypt_iv[0] + 1) & 0xFF) == ivbyte) {
125                 // In order as expected.
126                 if (ivbyte > cs->decrypt_iv[0]) {
127                         cs->decrypt_iv[0] = ivbyte;
128                 } else if (ivbyte < cs->decrypt_iv[0]) {
129                         int i;
130                         cs->decrypt_iv[0] = ivbyte;
131                         for (i = 1; i < AES_BLOCK_SIZE; i++)
132                                 if (++cs->decrypt_iv[i])
133                                         break;
134                 } else {
135                         return false;
136                 }
137         } else {
138                 // This is either out of order or a repeat.
139
140                 int diff = ivbyte - cs->decrypt_iv[0];
141                 if (diff > 128)
142                         diff = diff-256;
143                 else if (diff < -128)
144                         diff = diff+256;
145
146                 if ((ivbyte < cs->decrypt_iv[0]) && (diff > -30) && (diff < 0)) {
147                         // Late packet, but no wraparound.
148                         late = 1;
149                         lost = -1;
150                         cs->decrypt_iv[0] = ivbyte;
151                         restore = true;
152                 } else if ((ivbyte > cs->decrypt_iv[0]) && (diff > -30) && (diff < 0)) {
153                         int i;
154                         // Last was 0x02, here comes 0xff from last round
155                         late = 1;
156                         lost = -1;
157                         cs->decrypt_iv[0] = ivbyte;
158                         for (i = 1; i < AES_BLOCK_SIZE; i++)
159                                 if (cs->decrypt_iv[i]--)
160                                         break;
161                         restore = true;
162                 } else if ((ivbyte > cs->decrypt_iv[0]) && (diff > 0)) {
163                         // Lost a few packets, but beyond that we're good.
164                         lost = ivbyte - cs->decrypt_iv[0] - 1;
165                         cs->decrypt_iv[0] = ivbyte;
166                 } else if ((ivbyte < cs->decrypt_iv[0]) && (diff > 0)) {
167                         int i;
168                         // Lost a few packets, and wrapped around
169                         lost = 256 - cs->decrypt_iv[0] + ivbyte - 1;
170                         cs->decrypt_iv[0] = ivbyte;
171                         for (i = 1; i < AES_BLOCK_SIZE; i++)
172                                 if (++cs->decrypt_iv[i])
173                                         break;
174                 } else {
175                         return false;
176                 }
177
178                 if (cs->decrypt_history[cs->decrypt_iv[0]] == cs->decrypt_iv[1]) {
179                         memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE);
180                         return false;
181                 }
182         }
183
184         CryptState_ocb_decrypt(cs, source+4, dst, plain_length, cs->decrypt_iv, tag);
185
186         if (memcmp(tag, source+1, 3) != 0) {
187                 memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE);
188                 return false;
189         }
190         cs->decrypt_history[cs->decrypt_iv[0]] = cs->decrypt_iv[1];
191
192         if (restore)
193                 memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE);
194
195         cs->uiGood++;
196         cs->uiLate += late;
197         cs->uiLost += lost;
198
199         Timer_restart(&cs->tLastGood);
200         return true;
201 }
202
203 #if defined(__LP64__)
204 #define BLOCKSIZE 2
205 #define SHIFTBITS 63
206 typedef uint64_t subblock;
207
208 #if __BYTE_ORDER == __BIG_ENDIAN
209 #define SWAPPED(x) (x)
210 #else
211 #ifdef __x86_64__
212 #define SWAPPED(x) ({register uint64_t __out, __in = (x); __asm__("bswap %q0" : "=r"(__out) : "0"(__in)); __out;})
213 #else
214 #include <byteswap.h>
215 #define SWAPPED(x) bswap_64(x)
216 #endif
217 #endif
218
219 #else
220
221 #define BLOCKSIZE 4
222 #define SHIFTBITS 31
223 typedef uint32_t subblock;
224 #define SWAPPED(x) htonl(x)
225
226 #endif
227
228 #define HIGHBIT (1<<SHIFTBITS);
229
230
231 static void inline XOR(subblock *dst, const subblock *a, const subblock *b) {
232         int i;
233         for (i=0;i<BLOCKSIZE;i++) {
234                 dst[i] = a[i] ^ b[i];
235         }
236 }
237
238 static void inline S2(subblock *block) {
239         subblock carry = SWAPPED(block[0]) >> SHIFTBITS;
240         int i;
241         for (i=0;i<BLOCKSIZE-1;i++)
242                 block[i] = SWAPPED((SWAPPED(block[i]) << 1) | (SWAPPED(block[i+1]) >> SHIFTBITS));
243         block[BLOCKSIZE-1] = SWAPPED((SWAPPED(block[BLOCKSIZE-1]) << 1) ^(carry * 0x87));
244 }
245
246 static void inline S3(subblock *block) {
247         subblock carry = SWAPPED(block[0]) >> SHIFTBITS;
248         int i;
249         for (i=0;i<BLOCKSIZE-1;i++)
250                 block[i] ^= SWAPPED((SWAPPED(block[i]) << 1) | (SWAPPED(block[i+1]) >> SHIFTBITS));
251         block[BLOCKSIZE-1] ^= SWAPPED((SWAPPED(block[BLOCKSIZE-1]) << 1) ^(carry * 0x87));
252 }
253
254 static void inline ZERO(subblock *block) {
255         int i;
256         for (i=0;i<BLOCKSIZE;i++)
257                 block[i]=0;
258 }
259
260 #define AESencrypt(src,dst,key) AES_encrypt((unsigned char *)(src),(unsigned char *)(dst), key);
261 #define AESdecrypt(src,dst,key) AES_decrypt((unsigned char *)(src),(unsigned char *)(dst), key);
262
263 void CryptState_ocb_encrypt(cryptState_t *cs, const unsigned char *plain, unsigned char *encrypted, unsigned int len, const unsigned char *nonce, unsigned char *tag) {
264         subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE];
265
266         // Initialize
267         AESencrypt(nonce, delta, &cs->encrypt_key);
268         ZERO(checksum);
269
270         while (len > AES_BLOCK_SIZE) {
271                 S2(delta);
272                 XOR(tmp, delta, (const subblock *)(plain));
273                 AESencrypt(tmp, tmp, &cs->encrypt_key);
274                 XOR((subblock *)(encrypted), delta, tmp);
275                 XOR(checksum, checksum, (subblock *)(plain));
276                 len -= AES_BLOCK_SIZE;
277                 plain += AES_BLOCK_SIZE;
278                 encrypted += AES_BLOCK_SIZE;
279         }
280
281         S2(delta);
282         ZERO(tmp);
283         tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
284         XOR(tmp, tmp, delta);
285         AESencrypt(tmp, pad, &cs->encrypt_key);
286         memcpy(tmp, plain, len);
287         memcpy((unsigned char *)tmp + len, (unsigned char *)pad + len, AES_BLOCK_SIZE - len);
288         XOR(checksum, checksum, tmp);
289         XOR(tmp, pad, tmp);
290         memcpy(encrypted, tmp, len);
291
292         S3(delta);
293         XOR(tmp, delta, checksum);
294         AESencrypt(tmp, tag, &cs->encrypt_key);
295 }
296
297 void CryptState_ocb_decrypt(cryptState_t *cs, const unsigned char *encrypted, unsigned char *plain, unsigned int len, const unsigned char *nonce, unsigned char *tag) {
298         subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE];
299
300         // Initialize
301         AESencrypt(nonce, delta, &cs->encrypt_key);
302         ZERO(checksum);
303
304         while (len > AES_BLOCK_SIZE) {
305                 S2(delta);
306                 XOR(tmp, delta, (const subblock *)(encrypted));
307                 AESdecrypt(tmp, tmp, &cs->decrypt_key);
308                 XOR((subblock *)(plain), delta, tmp);
309                 XOR(checksum, checksum, (const subblock *)(plain));
310                 len -= AES_BLOCK_SIZE;
311                 plain += AES_BLOCK_SIZE;
312                 encrypted += AES_BLOCK_SIZE;
313         }
314
315         S2(delta);
316         ZERO(tmp);
317         tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
318         XOR(tmp, tmp, delta);
319         AESencrypt(tmp, pad, &cs->encrypt_key);
320         memset(tmp, 0, AES_BLOCK_SIZE);
321         memcpy(tmp, encrypted, len);
322         XOR(tmp, tmp, pad);
323         XOR(checksum, checksum, tmp);
324         memcpy(plain, tmp, len);
325
326         S3(delta);
327         XOR(tmp, delta, checksum);
328         AESencrypt(tmp, tag, &cs->encrypt_key);
329 }