1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 /******************************************************************************
5 * This Rabbit C source code was morphed fm the EU eSTREAM ECRYPT submission
6 * and should run on any conforming C implementation (C90 or later).
7 *
8 * This implementation supports any key length up to 128 bits (16 bytes) and
9 * works in increments of 8-bit bytes. Keys must be submitted as whole bytes
10 * and shorter keys will be right-null-padded to 16 bytes. Likewise, an iv
11 * may be any length up to 8 bytes and will be padded out to 8 bytes.
12 *
13 * The eSTREAM submission was rather picky about the calling sequence of
14 * ECRYPT_process_blocks() and ECRYPT_process_bytes(). That version allowed
15 * calling ECRYPT_process_blocks() multiple times for a multiple of whole
16 * 16-byte blocks, but once ECRYPT_process_bytes() was called. no more calls
17 * were supported correctly. This implementation handles the keystream
18 * differently and rabbit_crypt() may be called as many times as desired,
19 * crypting any number of bytes each time.
20 *
21 * http://www.ecrypt.eu.org/stream/e2-rabbit.html
22 *
23 * NB: One of the test vectors distributed by the eSTREAM site in the file
24 * "rabbit_p3source.zip" is in error. Referring to "test-vectors.txt"
25 * in that ZIP file, the 3rd line in "out1" should be
26 * "96 D6 73 16 88 D1 68 DA 51 D4 0C 70 C3 A1 16 F4".
27 *
28 * Here is the original legal notice accompanying the Rabbit submission
29 * to the EU eSTREAM competition.
30 *---------------------------------------------------------------------------
31 * Copyright (C) Cryptico A/S. All rights reserved.
32 *
33 * YOU SHOULD CAREFULLY READ THIS LEGAL NOTICE BEFORE USING THIS SOFTWARE.
34 *
35 * This software is developed by Cryptico A/S and/or its suppliers.
36 * All title and intellectual property rights in and to the software,
37 * including but not limited to patent rights and copyrights, are owned
38 * by Cryptico A/S and/or its suppliers.
39 *
40 * The software may be used solely for non-commercial purposes
41 * without the prior written consent of Cryptico A/S. For further
42 * information on licensing terms and conditions please contact
43 * Cryptico A/S at info@cryptico.com
44 *
45 * Cryptico, CryptiCore, the Cryptico logo and "Re-thinking encryption"
46 * are either trademarks or registered trademarks of Cryptico A/S.
47 *
48 * Cryptico A/S shall not in any way be liable for any use of this
49 * software. The software is provided "as is" without any express or
50 * implied warranty.
51 *---------------------------------------------------------------------------
52 * On October 6, 2008, Rabbit was "released into the public domain and
53 * may be used freely for any purpose."
54 * http://www.ecrypt.eu.org/stream/rabbitpf.html
55 * https://web.archive.org/web/20090630021733/http://www.ecrypt.eu.org/stream/phorum/read.php?1,1244
56 ******************************************************************************/
57
58
59 #include "tomcrypt_private.h"
60
61 #ifdef LTC_RABBIT
62
63 /* local/private prototypes (NB: rabbit_ctx and rabbit_state are different) */
64 static LTC_INLINE ulong32 ss_rabbit_g_func(ulong32 x);
65 static LTC_INLINE void ss_rabbit_next_state(rabbit_ctx *p_instance);
66 static LTC_INLINE void ss_rabbit_gen_1_block(rabbit_state* st, unsigned char *out);
67
68 /* -------------------------------------------------------------------------- */
69
70 /* Square a 32-bit unsigned integer to obtain the 64-bit result and return */
71 /* the upper 32 bits XOR the lower 32 bits */
ss_rabbit_g_func(ulong32 x)72 static LTC_INLINE ulong32 ss_rabbit_g_func(ulong32 x)
73 {
74 ulong32 a, b, h, l;
75
76 /* Construct high and low argument for squaring */
77 a = x & 0xFFFF;
78 b = x >> 16;
79
80 /* Calculate high and low result of squaring */
81 h = ((((ulong32)(a*a)>>17) + (ulong32)(a*b))>>15) + b*b;
82 l = x * x;
83
84 /* Return high XOR low */
85 return (ulong32)(h^l);
86 }
87
88 /* -------------------------------------------------------------------------- */
89
90 /* Calculate the next internal state */
ss_rabbit_next_state(rabbit_ctx * p_instance)91 static LTC_INLINE void ss_rabbit_next_state(rabbit_ctx *p_instance)
92 {
93 ulong32 g[8], c_old[8], i;
94
95 /* Save old counter values */
96 for (i=0; i<8; i++) {
97 c_old[i] = p_instance->c[i];
98 }
99
100 /* Calculate new counter values */
101 p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry);
102 p_instance->c[1] = (ulong32)(p_instance->c[1] + 0xD34D34D3 + (p_instance->c[0] < c_old[0]));
103 p_instance->c[2] = (ulong32)(p_instance->c[2] + 0x34D34D34 + (p_instance->c[1] < c_old[1]));
104 p_instance->c[3] = (ulong32)(p_instance->c[3] + 0x4D34D34D + (p_instance->c[2] < c_old[2]));
105 p_instance->c[4] = (ulong32)(p_instance->c[4] + 0xD34D34D3 + (p_instance->c[3] < c_old[3]));
106 p_instance->c[5] = (ulong32)(p_instance->c[5] + 0x34D34D34 + (p_instance->c[4] < c_old[4]));
107 p_instance->c[6] = (ulong32)(p_instance->c[6] + 0x4D34D34D + (p_instance->c[5] < c_old[5]));
108 p_instance->c[7] = (ulong32)(p_instance->c[7] + 0xD34D34D3 + (p_instance->c[6] < c_old[6]));
109 p_instance->carry = (p_instance->c[7] < c_old[7]);
110
111 /* Calculate the g-values */
112 for (i=0;i<8;i++) {
113 g[i] = ss_rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i]));
114 }
115
116 /* Calculate new state values */
117 p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16));
118 p_instance->x[1] = (ulong32)(g[1] + ROLc(g[0], 8) + g[7]);
119 p_instance->x[2] = (ulong32)(g[2] + ROLc(g[1],16) + ROLc(g[0], 16));
120 p_instance->x[3] = (ulong32)(g[3] + ROLc(g[2], 8) + g[1]);
121 p_instance->x[4] = (ulong32)(g[4] + ROLc(g[3],16) + ROLc(g[2], 16));
122 p_instance->x[5] = (ulong32)(g[5] + ROLc(g[4], 8) + g[3]);
123 p_instance->x[6] = (ulong32)(g[6] + ROLc(g[5],16) + ROLc(g[4], 16));
124 p_instance->x[7] = (ulong32)(g[7] + ROLc(g[6], 8) + g[5]);
125 }
126
127 /* ------------------------------------------------------------------------- */
128
ss_rabbit_gen_1_block(rabbit_state * st,unsigned char * out)129 static LTC_INLINE void ss_rabbit_gen_1_block(rabbit_state* st, unsigned char *out)
130 {
131 ulong32 *ptr;
132
133 /* Iterate the work context once */
134 ss_rabbit_next_state(&(st->work_ctx));
135
136 /* Generate 16 bytes of pseudo-random data */
137 ptr = (ulong32*)&(st->work_ctx.x);
138 STORE32L((ptr[0] ^ (ptr[5]>>16) ^ (ulong32)(ptr[3]<<16)), out+ 0);
139 STORE32L((ptr[2] ^ (ptr[7]>>16) ^ (ulong32)(ptr[5]<<16)), out+ 4);
140 STORE32L((ptr[4] ^ (ptr[1]>>16) ^ (ulong32)(ptr[7]<<16)), out+ 8);
141 STORE32L((ptr[6] ^ (ptr[3]>>16) ^ (ulong32)(ptr[1]<<16)), out+12);
142 }
143
144 /* -------------------------------------------------------------------------- */
145
146 /* Key setup */
rabbit_setup(rabbit_state * st,const unsigned char * key,unsigned long keylen)147 int rabbit_setup(rabbit_state* st, const unsigned char *key, unsigned long keylen)
148 {
149 ulong32 k0, k1, k2, k3, i;
150 unsigned char tmpkey[16] = {0};
151
152 LTC_ARGCHK(st != NULL);
153 LTC_ARGCHK(key != NULL);
154 LTC_ARGCHK(keylen <= 16);
155
156 /* init state */
157 XMEMSET(st, 0, sizeof(rabbit_state));
158
159 /* pad key in tmpkey */
160 XMEMCPY(tmpkey, key, keylen);
161
162 /* Generate four subkeys */
163 LOAD32L(k0, tmpkey+ 0);
164 LOAD32L(k1, tmpkey+ 4);
165 LOAD32L(k2, tmpkey+ 8);
166 LOAD32L(k3, tmpkey+12);
167
168 #ifdef LTC_CLEAN_STACK
169 /* done with tmpkey, wipe it */
170 zeromem(tmpkey, sizeof(tmpkey));
171 #endif
172
173 /* Generate initial state variables */
174 st->master_ctx.x[0] = k0;
175 st->master_ctx.x[2] = k1;
176 st->master_ctx.x[4] = k2;
177 st->master_ctx.x[6] = k3;
178 st->master_ctx.x[1] = (ulong32)(k3<<16) | (k2>>16);
179 st->master_ctx.x[3] = (ulong32)(k0<<16) | (k3>>16);
180 st->master_ctx.x[5] = (ulong32)(k1<<16) | (k0>>16);
181 st->master_ctx.x[7] = (ulong32)(k2<<16) | (k1>>16);
182
183 /* Generate initial counter values */
184 st->master_ctx.c[0] = ROLc(k2, 16);
185 st->master_ctx.c[2] = ROLc(k3, 16);
186 st->master_ctx.c[4] = ROLc(k0, 16);
187 st->master_ctx.c[6] = ROLc(k1, 16);
188 st->master_ctx.c[1] = (k0&0xFFFF0000) | (k1&0xFFFF);
189 st->master_ctx.c[3] = (k1&0xFFFF0000) | (k2&0xFFFF);
190 st->master_ctx.c[5] = (k2&0xFFFF0000) | (k3&0xFFFF);
191 st->master_ctx.c[7] = (k3&0xFFFF0000) | (k0&0xFFFF);
192
193 /* Clear carry bit */
194 st->master_ctx.carry = 0;
195
196 /* Iterate the master context four times */
197 for (i=0; i<4; i++) {
198 ss_rabbit_next_state(&(st->master_ctx));
199 }
200
201 /* Modify the counters */
202 for (i=0; i<8; i++) {
203 st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7];
204 }
205
206 /* Copy master instance to work instance */
207 for (i=0; i<8; i++) {
208 st->work_ctx.x[i] = st->master_ctx.x[i];
209 st->work_ctx.c[i] = st->master_ctx.c[i];
210 }
211 st->work_ctx.carry = st->master_ctx.carry;
212 /* ...and prepare block for crypt() */
213 XMEMSET(&(st->block), 0, sizeof(st->block));
214 st->unused = 0;
215
216 return CRYPT_OK;
217 }
218
219 /* -------------------------------------------------------------------------- */
220
221 /* IV setup */
rabbit_setiv(rabbit_state * st,const unsigned char * iv,unsigned long ivlen)222 int rabbit_setiv(rabbit_state* st, const unsigned char *iv, unsigned long ivlen)
223 {
224 ulong32 i0, i1, i2, i3, i;
225 unsigned char tmpiv[8] = {0};
226
227 LTC_ARGCHK(st != NULL);
228 LTC_ARGCHK(iv != NULL || ivlen == 0);
229 LTC_ARGCHK(ivlen <= 8);
230
231 /* pad iv in tmpiv */
232 if (iv && ivlen > 0) XMEMCPY(tmpiv, iv, ivlen);
233
234 /* Generate four subvectors */
235 LOAD32L(i0, tmpiv+0);
236 LOAD32L(i2, tmpiv+4);
237 i1 = (i0>>16) | (i2&0xFFFF0000);
238 i3 = (i2<<16) | (i0&0x0000FFFF);
239
240 /* Modify counter values */
241 st->work_ctx.c[0] = st->master_ctx.c[0] ^ i0;
242 st->work_ctx.c[1] = st->master_ctx.c[1] ^ i1;
243 st->work_ctx.c[2] = st->master_ctx.c[2] ^ i2;
244 st->work_ctx.c[3] = st->master_ctx.c[3] ^ i3;
245 st->work_ctx.c[4] = st->master_ctx.c[4] ^ i0;
246 st->work_ctx.c[5] = st->master_ctx.c[5] ^ i1;
247 st->work_ctx.c[6] = st->master_ctx.c[6] ^ i2;
248 st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3;
249
250 /* Copy state variables */
251 for (i=0; i<8; i++) {
252 st->work_ctx.x[i] = st->master_ctx.x[i];
253 }
254 st->work_ctx.carry = st->master_ctx.carry;
255
256 /* Iterate the work context four times */
257 for (i=0; i<4; i++) {
258 ss_rabbit_next_state(&(st->work_ctx));
259 }
260
261 /* reset keystream buffer and unused count */
262 XMEMSET(&(st->block), 0, sizeof(st->block));
263 st->unused = 0;
264
265 return CRYPT_OK;
266 }
267
268 /* ------------------------------------------------------------------------- */
269
270 /* Crypt a chunk of any size (encrypt/decrypt) */
rabbit_crypt(rabbit_state * st,const unsigned char * in,unsigned long inlen,unsigned char * out)271 int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, unsigned char *out)
272 {
273 unsigned char buf[16];
274 unsigned long i, j;
275
276 if (inlen == 0) return CRYPT_OK; /* nothing to do */
277
278 LTC_ARGCHK(st != NULL);
279 LTC_ARGCHK(in != NULL);
280 LTC_ARGCHK(out != NULL);
281
282 if (st->unused > 0) {
283 j = MIN(st->unused, inlen);
284 for (i = 0; i < j; ++i, st->unused--) out[i] = in[i] ^ st->block[16 - st->unused];
285 inlen -= j;
286 if (inlen == 0) return CRYPT_OK;
287 out += j;
288 in += j;
289 }
290 for (;;) {
291 /* gen a block for buf */
292 ss_rabbit_gen_1_block(st, buf);
293 if (inlen <= 16) {
294 /* XOR and send to out */
295 for (i = 0; i < inlen; ++i) out[i] = in[i] ^ buf[i];
296 st->unused = 16 - inlen;
297 /* copy remainder to block */
298 for (i = inlen; i < 16; ++i) st->block[i] = buf[i];
299 return CRYPT_OK;
300 }
301 /* XOR entire buf and send to out */
302 for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i];
303 inlen -= 16;
304 out += 16;
305 in += 16;
306 }
307 }
308
309 /* ------------------------------------------------------------------------- */
310
rabbit_keystream(rabbit_state * st,unsigned char * out,unsigned long outlen)311 int rabbit_keystream(rabbit_state *st, unsigned char *out, unsigned long outlen)
312 {
313 if (outlen == 0) return CRYPT_OK; /* nothing to do */
314
315 LTC_ARGCHK(out != NULL);
316
317 XMEMSET(out, 0, outlen);
318 return rabbit_crypt(st, out, outlen, out);
319 }
320
321 /* -------------------------------------------------------------------------- */
322
rabbit_done(rabbit_state * st)323 int rabbit_done(rabbit_state *st)
324 {
325 LTC_ARGCHK(st != NULL);
326
327 zeromem(st, sizeof(rabbit_state));
328 return CRYPT_OK;
329 }
330
331 /* -------------------------------------------------------------------------- */
332
rabbit_test(void)333 int rabbit_test(void)
334 {
335 #ifndef LTC_TEST
336 return CRYPT_NOP;
337 #else
338 rabbit_state st;
339 int err;
340 unsigned char out[1000] = { 0 };
341 {
342 /* all 3 tests use key and iv fm set 6, vector 3, the last vector in:
343 http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/rabbit/verified.test-vectors?rev=210&view=log
344 */
345
346 /* --- Test 1 (generate whole blocks) --------------------------------- */
347
348 {
349 unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
350 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
351 unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
352 char pt[64] = { 0 };
353 unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
354 0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
355 0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
356 0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
357 0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D, 0x7C,
358 0x0C, 0x10, 0x9B, 0x79, 0xD5, 0x74, 0x94, 0x39,
359 0xB7, 0xEF, 0xA4, 0xC4, 0xC9, 0xC8, 0xD2, 0x9D,
360 0xC5, 0xB3, 0x88, 0x83, 0x14, 0xA6, 0x81, 0x6F };
361 unsigned long ptlen = sizeof(pt);
362
363 /* crypt 64 nulls */
364 if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
365 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
366 if ((err = rabbit_crypt(&st, (unsigned char*)pt, ptlen, out)) != CRYPT_OK) return err;
367 if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV1", 1)) return CRYPT_FAIL_TESTVECTOR;
368 }
369
370 /* --- Test 2 (generate unusual number of bytes each time) ------------ */
371
372 {
373 unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
374 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
375 unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
376 char pt[39] = { 0 };
377 unsigned char ct[] = { 0x61, 0x3C, 0xB0, 0xBA, 0x96, 0xAF, 0xF6, 0xCA,
378 0xCF, 0x2A, 0x45, 0x9A, 0x10, 0x2A, 0x7F, 0x78,
379 0xCA, 0x98, 0x5C, 0xF8, 0xFD, 0xD1, 0x47, 0x40,
380 0x18, 0x75, 0x8E, 0x36, 0xAE, 0x99, 0x23, 0xF5,
381 0x19, 0xD1, 0x3D, 0x71, 0x8D, 0xAF, 0x8D };
382 unsigned long ptlen = sizeof(pt);
383
384 /* crypt piece by piece (hit at least one 16-byte boundary) */
385 if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
386 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
387 if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
388 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 11, out + 5)) != CRYPT_OK) return err;
389 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 16, 14, out + 16)) != CRYPT_OK) return err;
390 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 30, 2, out + 30)) != CRYPT_OK) return err;
391 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 32, 7, out + 32)) != CRYPT_OK) return err;
392 if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV2", 1)) return CRYPT_FAIL_TESTVECTOR;
393 }
394
395 /* --- Test 3 (use non-null data) ------------------------------------- */
396
397 {
398 unsigned char k[] = { 0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
399 0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC };
400 unsigned char iv[] = { 0x28, 0x8F, 0xF6, 0x5D, 0xC4, 0x2B, 0x92, 0xF9 };
401 char pt[] = "Kilroy was here, there, and everywhere!";
402 unsigned char ct[] = { 0x2a, 0x55, 0xdc, 0xc8, 0xf9, 0xd6, 0xd6, 0xbd,
403 0xae, 0x59, 0x65, 0xf2, 0x75, 0x58, 0x1a, 0x54,
404 0xea, 0xec, 0x34, 0x9d, 0x8f, 0xb4, 0x6b, 0x60,
405 0x79, 0x1b, 0xea, 0x16, 0xcb, 0xef, 0x46, 0x87,
406 0x60, 0xa6, 0x55, 0x14, 0xff, 0xca, 0xac };
407 unsigned long ptlen = XSTRLEN(pt);
408 unsigned char out2[1000] = { 0 };
409 unsigned char nulls[1000] = { 0 };
410
411 /* crypt piece by piece */
412 if ((err = rabbit_setup(&st, k, sizeof(k))) != CRYPT_OK) return err;
413 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
414 if ((err = rabbit_crypt(&st, (unsigned char*)pt, 5, out)) != CRYPT_OK) return err;
415 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 29, out + 5)) != CRYPT_OK) return err;
416 if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34, 5, out + 34)) != CRYPT_OK) return err;
417 if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1)) return CRYPT_FAIL_TESTVECTOR;
418
419 /* --- Test 4 (crypt in a single call) ------------------------------------ */
420
421 if ((err = rabbit_memory(k, sizeof(k), iv, sizeof(iv),
422 (unsigned char*)pt, sizeof(pt), out)) != CRYPT_OK) return err;
423 if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV4", 1)) return CRYPT_FAIL_TESTVECTOR;
424 /* use 'out' (ciphertext) in the next decryption test */
425
426 /* --- Test 5 (decrypt ciphertext) ------------------------------------ */
427
428 /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */
429 if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err;
430 if ((err = rabbit_crypt(&st, out, ptlen, out2)) != CRYPT_OK) return err;
431 if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV5", 1)) return CRYPT_FAIL_TESTVECTOR;
432
433 /* --- Test 6 (wipe state, incl key) ---------------------------------- */
434
435 if ((err = rabbit_done(&st)) != CRYPT_OK) return err;
436 if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV6", 1)) return CRYPT_FAIL_TESTVECTOR;
437
438 }
439
440 return CRYPT_OK;
441 }
442 #endif
443 }
444
445 /* -------------------------------------------------------------------------- */
446
447 #endif
448