4b1b4f4261af769c09cb7b741eb6c6b29ac5b64d
[umurmur.git] / src / crypt.c
1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2014, 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 "ssl.h"
45
46 #if defined(USE_POLARSSL_HAVEGE) || defined(USE_MBEDTLS_HAVEGE)
47 extern havege_state hs;
48 #endif
49
50 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);
51 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);
52
53 void CryptState_init(cryptState_t *cs)
54 {
55         memset(cs->decrypt_history, 0, 0xff);
56         memset(cs->raw_key, 0, AES_BLOCK_SIZE);
57         memset(cs->encrypt_iv, 0, AES_BLOCK_SIZE);
58         memset(cs->decrypt_iv, 0, AES_BLOCK_SIZE);
59         cs->bInit = false;
60         cs->uiGood = cs->uiLate = cs->uiLost = cs->uiResync = 0;
61         cs->uiRemoteGood = cs->uiRemoteLate = cs->uiRemoteLost = cs->uiRemoteResync = 0;
62         Timer_init(&cs->tLastGood);
63         Timer_init(&cs->tLastRequest);
64 }
65
66 bool_t CryptState_isValid(cryptState_t *cs)
67 {
68         return cs->bInit;
69 }
70
71 void CryptState_genKey(cryptState_t *cs)
72 {
73         CRYPT_RANDOM_BYTES(&cs->raw_key, AES_BLOCK_SIZE);
74         CRYPT_RANDOM_BYTES(&cs->encrypt_iv, AES_BLOCK_SIZE);
75         CRYPT_RANDOM_BYTES(&cs->decrypt_iv, AES_BLOCK_SIZE);
76
77         CRYPT_SET_ENC_KEY(&cs->encrypt_key, cs->raw_key, 128);
78         CRYPT_SET_DEC_KEY(&cs->decrypt_key, cs->raw_key, 128);
79
80         cs->bInit = true;
81 }
82
83 void CryptState_setKey(cryptState_t *cs, const unsigned char *rkey, const unsigned char *eiv, const unsigned char *div)
84 {
85         memcpy(cs->raw_key, rkey, AES_BLOCK_SIZE);
86         memcpy(cs->encrypt_iv, eiv, AES_BLOCK_SIZE);
87         memcpy(cs->decrypt_iv, div, AES_BLOCK_SIZE);
88
89         CRYPT_SET_ENC_KEY(&cs->encrypt_key, cs->decrypt_iv, 128);
90         CRYPT_SET_DEC_KEY(&cs->decrypt_key, cs->raw_key, 128);
91
92         cs->bInit = true;
93 }
94
95 void CryptState_setDecryptIV(cryptState_t *cs, const unsigned char *iv)
96 {
97         memcpy(cs->decrypt_iv, iv, AES_BLOCK_SIZE);
98 }
99
100 void CryptState_encrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int plain_length)
101 {
102         unsigned char tag[AES_BLOCK_SIZE];
103         int i;
104         // First, increase our IV.
105         for (i = 0; i < AES_BLOCK_SIZE; i++)
106                 if (++cs->encrypt_iv[i])
107                         break;
108
109         CryptState_ocb_encrypt(cs, source, dst+4, plain_length, cs->encrypt_iv, tag);
110
111         dst[0] = cs->encrypt_iv[0];
112         dst[1] = tag[0];
113         dst[2] = tag[1];
114         dst[3] = tag[2];
115 }
116
117 bool_t CryptState_decrypt(cryptState_t *cs, const unsigned char *source, unsigned char *dst, unsigned int crypted_length)
118 {
119         if (crypted_length < 4)
120                 return false;
121
122         unsigned int plain_length = crypted_length - 4;
123
124         unsigned char saveiv[AES_BLOCK_SIZE];
125         unsigned char ivbyte = source[0];
126         bool_t restore = false;
127         unsigned char tag[AES_BLOCK_SIZE];
128
129         int lost = 0;
130         int late = 0;
131
132         memcpy(saveiv, cs->decrypt_iv, AES_BLOCK_SIZE);
133
134         if (((cs->decrypt_iv[0] + 1) & 0xFF) == ivbyte) {
135                 // In order as expected.
136                 if (ivbyte > cs->decrypt_iv[0]) {
137                         cs->decrypt_iv[0] = ivbyte;
138                 } else if (ivbyte < cs->decrypt_iv[0]) {
139                         int i;
140                         cs->decrypt_iv[0] = ivbyte;
141                         for (i = 1; i < AES_BLOCK_SIZE; i++)
142                                 if (++cs->decrypt_iv[i])
143                                         break;
144                 } else {
145                         return false;
146                 }
147         } else {
148                 // This is either out of order or a repeat.
149
150                 int diff = ivbyte - cs->decrypt_iv[0];
151                 if (diff > 128)
152                         diff = diff-256;
153                 else if (diff < -128)
154                         diff = diff+256;
155
156                 if ((ivbyte < cs->decrypt_iv[0]) && (diff > -30) && (diff < 0)) {
157                         // Late packet, but no wraparound.
158                         late = 1;
159                         lost = -1;
160                         cs->decrypt_iv[0] = ivbyte;
161                         restore = true;
162                 } else if ((ivbyte > cs->decrypt_iv[0]) && (diff > -30) && (diff < 0)) {
163                         int i;
164                         // Last was 0x02, here comes 0xff from last round
165                         late = 1;
166                         lost = -1;
167                         cs->decrypt_iv[0] = ivbyte;
168                         for (i = 1; i < AES_BLOCK_SIZE; i++)
169                                 if (cs->decrypt_iv[i]--)
170                                         break;
171                         restore = true;
172                 } else if ((ivbyte > cs->decrypt_iv[0]) && (diff > 0)) {
173                         // Lost a few packets, but beyond that we're good.
174                         lost = ivbyte - cs->decrypt_iv[0] - 1;
175                         cs->decrypt_iv[0] = ivbyte;
176                 } else if ((ivbyte < cs->decrypt_iv[0]) && (diff > 0)) {
177                         int i;
178                         // Lost a few packets, and wrapped around
179                         lost = 256 - cs->decrypt_iv[0] + ivbyte - 1;
180                         cs->decrypt_iv[0] = ivbyte;
181                         for (i = 1; i < AES_BLOCK_SIZE; i++)
182                                 if (++cs->decrypt_iv[i])
183                                         break;
184                 } else {
185                         return false;
186                 }
187
188                 if (cs->decrypt_history[cs->decrypt_iv[0]] == cs->decrypt_iv[1]) {
189                         memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE);
190                         return false;
191                 }
192         }
193
194         CryptState_ocb_decrypt(cs, source+4, dst, plain_length, cs->decrypt_iv, tag);
195
196         if (memcmp(tag, source+1, 3) != 0) {
197                 memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE);
198                 return false;
199         }
200         cs->decrypt_history[cs->decrypt_iv[0]] = cs->decrypt_iv[1];
201
202         if (restore)
203                 memcpy(cs->decrypt_iv, saveiv, AES_BLOCK_SIZE);
204
205         cs->uiGood++;
206         cs->uiLate += late;
207         cs->uiLost += lost;
208
209         Timer_restart(&cs->tLastGood);
210         return true;
211 }
212
213 static void inline XOR(subblock *dst, const subblock *a, const subblock *b) {
214         int i;
215         for (i=0;i<BLOCKSIZE;i++) {
216                 dst[i] = a[i] ^ b[i];
217         }
218 }
219
220 static void inline S2(subblock *block) {
221         subblock carry = SWAPPED(block[0]) >> SHIFTBITS;
222         int i;
223         for (i=0;i<BLOCKSIZE-1;i++)
224                 block[i] = SWAPPED((SWAPPED(block[i]) << 1) | (SWAPPED(block[i+1]) >> SHIFTBITS));
225         block[BLOCKSIZE-1] = SWAPPED((SWAPPED(block[BLOCKSIZE-1]) << 1) ^(carry * 0x87));
226 }
227
228 static void inline S3(subblock *block) {
229         subblock carry = SWAPPED(block[0]) >> SHIFTBITS;
230         int i;
231         for (i=0;i<BLOCKSIZE-1;i++)
232                 block[i] ^= SWAPPED((SWAPPED(block[i]) << 1) | (SWAPPED(block[i+1]) >> SHIFTBITS));
233         block[BLOCKSIZE-1] ^= SWAPPED((SWAPPED(block[BLOCKSIZE-1]) << 1) ^(carry * 0x87));
234 }
235
236 static void inline ZERO(subblock *block) {
237         int i;
238         for (i=0;i<BLOCKSIZE;i++)
239                 block[i]=0;
240 }
241
242 void CryptState_ocb_encrypt(cryptState_t *cs, const unsigned char *plain, unsigned char *encrypted, unsigned int len, const unsigned char *nonce, unsigned char *tag) {
243         subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE];
244
245         // Initialize
246         CRYPT_AES_ENCRYPT(nonce, delta, cs);
247         ZERO(checksum);
248
249         while (len > AES_BLOCK_SIZE) {
250                 S2(delta);
251                 XOR(tmp, delta, (const subblock *)(plain));
252                 CRYPT_AES_ENCRYPT(tmp, tmp, cs);
253                 XOR((subblock *)(encrypted), delta, tmp);
254                 XOR(checksum, checksum, (subblock *)(plain));
255                 len -= AES_BLOCK_SIZE;
256                 plain += AES_BLOCK_SIZE;
257                 encrypted += AES_BLOCK_SIZE;
258         }
259
260         S2(delta);
261         ZERO(tmp);
262         tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
263         XOR(tmp, tmp, delta);
264         CRYPT_AES_ENCRYPT(tmp, pad, cs);
265         memcpy(tmp, plain, len);
266         memcpy((unsigned char *)tmp + len, (unsigned char *)pad + len, AES_BLOCK_SIZE - len);
267         XOR(checksum, checksum, tmp);
268         XOR(tmp, pad, tmp);
269         memcpy(encrypted, tmp, len);
270
271         S3(delta);
272         XOR(tmp, delta, checksum);
273         CRYPT_AES_ENCRYPT(tmp, tag, cs);
274 }
275
276 void CryptState_ocb_decrypt(cryptState_t *cs, const unsigned char *encrypted, unsigned char *plain, unsigned int len, const unsigned char *nonce, unsigned char *tag) {
277         subblock checksum[BLOCKSIZE], delta[BLOCKSIZE], tmp[BLOCKSIZE], pad[BLOCKSIZE];
278         // Initialize
279         CRYPT_AES_ENCRYPT(nonce, delta, cs);
280         ZERO(checksum);
281
282         while (len > AES_BLOCK_SIZE) {
283                 S2(delta);
284                 XOR(tmp, delta, (const subblock *)(encrypted));
285                 CRYPT_AES_DECRYPT(tmp, tmp, cs);
286                 XOR((subblock *)(plain), delta, tmp);
287                 XOR(checksum, checksum, (const subblock *)(plain));
288                 len -= AES_BLOCK_SIZE;
289                 plain += AES_BLOCK_SIZE;
290                 encrypted += AES_BLOCK_SIZE;
291         }
292
293         S2(delta);
294         ZERO(tmp);
295         tmp[BLOCKSIZE - 1] = SWAPPED(len * 8);
296         XOR(tmp, tmp, delta);
297         CRYPT_AES_ENCRYPT(tmp, pad, cs);
298         memset(tmp, 0, AES_BLOCK_SIZE);
299         memcpy(tmp, encrypted, len);
300         XOR(tmp, tmp, pad);
301         XOR(checksum, checksum, tmp);
302         memcpy(plain, tmp, len);
303
304         S3(delta);
305         XOR(tmp, delta, checksum);
306         CRYPT_AES_ENCRYPT(tmp, tag, cs);
307 }