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