3 This file is part of the ARM-Crypto-Lib.
4 Copyright (C) 2006-2011 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <avr/pgmspace.h>
30 void dump_ctx(rabbit_ctx_t *ctx){
32 cli_putstr_P(PSTR("\r\n --- ctx dump ---\r\n b = "));
33 cli_hexdump_byte(ctx->carry);
36 cli_putstr_P(PSTR("\r\n"));
38 cli_putstr_P(PSTR(" X"));
40 cli_putstr_P(PSTR(" = 0x"));
41 cli_hexdump_rev(&(ctx->x[i]), 4);
46 cli_putstr_P(PSTR("\r\n"));
48 cli_putstr_P(PSTR(" C"));
50 cli_putstr_P(PSTR(" = 0x"));
51 cli_hexdump_rev(&(ctx->c[i]), 4);
57 const uint32_t c_const[8] PROGMEM = {
58 0x4D34D34D, 0xD34D34D3,
59 0x34D34D34, 0x4D34D34D,
60 0xD34D34D3, 0x34D34D34,
61 0x4D34D34D, 0xD34D34D3
65 void gen_g(uint32_t *dest, rabbit_ctx_t *ctx){
73 a = ((uint64_t)t)*((uint64_t)t);
74 dest[i] = (uint32_t)(a^(a>>32));
79 void update_c(rabbit_ctx_t *ctx){
89 a += pgm_read_dword(con++);
96 #define ROT16(a) (((a)<<16) | ((a)>>16))
97 #define ROT8(a) (((a)<< 8) | ((a)>>24))
100 void step(rabbit_ctx_t *ctx){
105 memcpy(ctx->x, g, 8*4);
107 ctx->x[i] += ROT16(g[(i+8-1)%8]) + ROT16(g[(i+8-2)%8]);
109 ctx->x[i] += ROT8(g[(i+8-1)%8]) + g[(i+8-2)%8];
114 void keysetup(rabbit_ctx_t *ctx, const void *key){
117 x = (uint16_t*)(ctx->x);
118 c = (uint16_t*)(ctx->c);
121 *x++ = ((uint16_t*)key)[i];
122 *x++ = ((uint16_t*)key)[(i+1)%8];
123 *c++ = ((uint16_t*)key)[(i+5)%8];
124 *c++ = ((uint16_t*)key)[(i+4)%8];
126 *x++ = ((uint16_t*)key)[(i+4)%8];
127 *x++ = ((uint16_t*)key)[(i+5)%8];
128 *c++ = ((uint16_t*)key)[(i+1)%8];
129 *c++ = ((uint16_t*)key)[i];
137 ctx->c[i] ^= ctx->x[(i+4)%8];
142 void ivsetup(rabbit_ctx_t *ctx, const void *iv){
145 union __attribute__((packed)){
152 memcpy(t_iv.v8, iv, 8);
155 t_iv.v8[i] = ((uint8_t*)iv)[7-i];
156 t_iv.v8[7-i] = ((uint8_t*)iv)[i];
159 ctx->c[0] ^= t_iv.v32[0];
160 ctx->c[4] ^= t_iv.v32[0];
161 ctx->c[2] ^= t_iv.v32[1];
162 ctx->c[6] ^= t_iv.v32[1];
163 t = ( ((uint32_t)(t_iv.v16[3]))<<16) | (t_iv.v16[1]);
166 t = ( ((uint32_t)(t_iv.v16[2]))<<16) | (t_iv.v16[0]);
176 void extract(rabbit_ctx_t *ctx){
183 v = ((uint16_t*)(ctx->x))[(2*(i+ 8)+1)%16]
184 ^ ((uint16_t*)(ctx->x))[(2*(i+11)+0)%16];
187 v = ((uint16_t*)(ctx->x))[(2*(i+ 8)+0)%16]
188 ^ ((uint16_t*)(ctx->x))[(2*(i+13)+1)%16];
199 ctx->buffer[i] = ctx->buffer[15-i];
200 ctx->buffer[15-i] = x;
205 static const uint8_t key80_pad[] PROGMEM = { 0xDE, 0x05, 0x6E, 0xAC, 0x8A, 0x11 };
207 void rabbit_init(const void *key, uint16_t keysize_b,
212 memcpy(t_key, key, 10);
213 memcpy_P(t_key+10, key80_pad, 6);
215 memcpy(t_key, key, 16);
221 t_key[i] = t_key[15-i];
225 keysetup(ctx, t_key);
232 ctx->buffer_idx = 16;
235 uint8_t rabbit_gen(rabbit_ctx_t *ctx){
236 if(ctx->buffer_idx==16){
241 return ctx->buffer[ctx->buffer_idx++];