]> git.cryptolib.org Git - avr-crypto-lib.git/blob - scal/scal-nessie.c
4df9357468bd7768ed03d6135282c6be9a808095
[avr-crypto-lib.git] / scal / scal-nessie.c
1 /* scal-nessie.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006-2011 Daniel Otte (daniel.otte@rub.de)
5
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.
10
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.
15
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/>.
18 */
19
20 #include <stdint.h>
21 #include <string.h>
22 #include "streamcipher_descriptor.h"
23 #include "scal-basic.h"
24 #include "nessie_common.h"
25 #include "memxor.h"
26 #include <avr/pgmspace.h>
27
28 #ifndef NESSIE_ESTREAM
29 #define NESSIE_ESTREAM 0
30 #endif
31
32
33 static const uint8_t normal_hooks[] PROGMEM = {
34                 0, 192/64, 256/64, 448/64
35 };
36
37 static const uint16_t long_hooks[] PROGMEM = {
38                 0, 65472/64, 65536/64, 131008/64
39 };
40
41 static const char stream0_n[] PROGMEM = "stream[0..63]";
42 static const char stream1_n[] PROGMEM = "stream[192..255]";
43 static const char stream2_n[] PROGMEM = "stream[256..319]";
44 static const char stream3_n[] PROGMEM = "stream[448..511]";
45
46 #if NESSIE_ESTREAM
47 static const char streamX_n[] PROGMEM = "xor-digest";
48 #else
49 static const char streamX_n[] PROGMEM = "stream[0..511]xored";
50 #endif
51
52 static const char* stream_n_str[] PROGMEM = {
53                 stream0_n,
54                 stream1_n,
55                 stream2_n,
56                 stream3_n,
57                 streamX_n
58 };
59
60 static const char stream1_l[] PROGMEM = "stream[65472..65535]";
61 static const char stream2_l[] PROGMEM = "stream[65536..65599]";
62 static const char stream3_l[] PROGMEM = "stream[131008..131071]";
63 #if NESSIE_ESTREAM
64 static const char streamX_l[] PROGMEM = "xor-digest";
65 #else
66 static const char streamX_l[] PROGMEM = "stream[0..131071]xored";
67 #endif
68
69 static const char* stream_l_str[] PROGMEM = {
70                 stream0_n,
71                 stream1_l,
72                 stream2_l,
73                 stream3_l,
74                 streamX_l
75 };
76
77 static const uint8_t list_of_keys[][20] PROGMEM = {
78         { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
80         { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc,
81           0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x00, 0x00, 0x00 },
82         { 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba,
83           0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0 }
84 };
85
86 static const uint8_t list_of_ivs[][4] PROGMEM = {
87         { 0x00, 0x00, 0x00, 0x00 },
88         { 0x01, 0x01, 0x01, 0x01 },
89         { 0x01, 0x35, 0x77, 0xaf }
90 };
91
92 static
93 void normal_block(scgen_ctx_t *ctx){
94         uint8_t xor_block[64];
95         uint8_t block[64];
96         PGM_VOID_P hook_ptr = normal_hooks;
97         PGM_VOID_P hook_str_ptr = stream_n_str;
98         char str[21];
99         uint8_t i;
100
101         memset(xor_block, 0, 64);
102         for(i=0; i<=448/64; ++i){
103                 scal_cipher_gen_fillblock(block, 64, ctx);
104                 memxor(xor_block, block, 64);
105                 if(i==pgm_read_byte(hook_ptr)){
106                         hook_ptr = (uint8_t*)hook_ptr + 1;
107                         strcpy_P(str, (PGM_VOID_P)pgm_read_word(hook_str_ptr));
108                         hook_str_ptr = (uint8_t*)hook_str_ptr + 2;
109                         nessie_print_item(str, block, 64);
110                 }
111         }
112         strcpy_P(str, (PGM_VOID_P)pgm_read_word(hook_str_ptr));
113         nessie_print_item(str, xor_block, 64);
114 }
115
116 static
117 void long_block(scgen_ctx_t *ctx){
118         uint8_t xor_block[64];
119         uint8_t block[64];
120         PGM_VOID_P hook_ptr = long_hooks;
121         PGM_VOID_P hook_str_ptr = stream_l_str;
122         char str[24];
123         uint16_t i;
124
125         memset(xor_block, 0, 64);
126         for(i=0; i<=131008/64; ++i){
127                 scal_cipher_gen_fillblock(block, 64, ctx);
128                 memxor(xor_block, block, 64);
129                 if(i==pgm_read_word(hook_ptr)){
130                         hook_ptr = (uint8_t*)hook_ptr + 2;
131                         strcpy_P(str, (PGM_VOID_P)pgm_read_word(hook_str_ptr));
132                         hook_str_ptr =  (uint8_t*)hook_str_ptr + 2;
133                         nessie_print_item(str, block, 64);
134                 }
135                 if(i%64==0){
136                         NESSIE_SEND_ALIVE;
137                 }
138         }
139         strcpy_P(str, (PGM_VOID_P)pgm_read_word(hook_str_ptr));
140         nessie_print_item(str, xor_block, 64);
141 }
142
143 void scal_nessie_stream_run(const scdesc_t *desc, uint16_t keysize_b, uint16_t ivsize_b){
144         uint8_t name_length = strlen_P((PGM_VOID_P)pgm_read_word(&(desc->name)));
145         char name[name_length+1];
146         memcpy_P(name, (PGM_VOID_P)pgm_read_word(&(desc->name)), name_length+1);
147
148         uint8_t key[(keysize_b+7)/8];
149         uint8_t iv[(ivsize_b+7)/8];
150         uint16_t v;
151         scgen_ctx_t ctx;
152         nessie_print_header(name, keysize_b, 0, 0, 0, ivsize_b?ivsize_b:((uint16_t)-1));
153
154         memset(iv, 0, (ivsize_b+7)/8);
155         memset(key, 0, (keysize_b+7)/8);
156         /***  Test SET 1 ***/
157         nessie_print_setheader(1);
158 #if NESSIE_ESTREAM
159         for(v=0;v<keysize_b; v+=9){
160 #else
161         for(v=0;v<keysize_b; ++v){
162 #endif
163                 nessie_print_set_vector(1,v);
164                 key[v/8] |= 0x80>>(v&7);
165                 nessie_print_item("key", key, (keysize_b+7)/8);
166                 if(ivsize_b){
167                         nessie_print_item("IV", iv, (ivsize_b+7)/8);
168                 }
169                 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
170                 normal_block(&ctx);
171                 key[v/8] = 0;
172                 scal_cipher_free(&ctx);
173         }
174         /***  Test SET 2 ***/
175         nessie_print_setheader(2);
176 #if NESSIE_ESTREAM
177         for(v=0;v<256; v+=9){
178 #else
179         for(v=0;v<256; ++v){
180 #endif
181                 nessie_print_set_vector(2,v);
182                 memset(key, v&0xff, (keysize_b+7)/8);
183                 nessie_print_item("key", key, (keysize_b+7)/8);
184                 if(ivsize_b){
185                         nessie_print_item("IV", iv, (ivsize_b+7)/8);
186                 }
187                 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
188                 normal_block(&ctx);
189                 scal_cipher_free(&ctx);
190         }
191         /***  Test SET 3 ***/
192         nessie_print_setheader(3);
193 #if NESSIE_ESTREAM
194         for(v=0;v<256; v+=9){
195 #else
196         for(v=0;v<256; ++v){
197 #endif
198                 uint8_t i;
199                 nessie_print_set_vector(3,v);
200                 for(i=0; i<((keysize_b+7)/8); ++i){
201                         key[i]=(i+v)&0xff;
202                 }
203                 nessie_print_item("key", key, (keysize_b+7)/8);
204                 if(ivsize_b){
205                         nessie_print_item("IV", iv, (ivsize_b+7)/8);
206                 }
207                 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
208                 normal_block(&ctx);
209                 scal_cipher_free(&ctx);
210         }
211         /***  Test SET 4 ***/
212         nessie_print_setheader(4);
213         for(v=0;v<4; ++v){
214                 uint8_t i;
215                 nessie_print_set_vector(4,v);
216                 for(i=0; i<((keysize_b+7)/8); ++i){
217                         key[i]=(i*0x53+v*5)&0xff;
218                 }
219                 nessie_print_item("key", key, (keysize_b+7)/8);
220                 if(ivsize_b){
221                         nessie_print_item("IV", iv, (ivsize_b+7)/8);
222                 }
223                 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
224                 long_block(&ctx);
225                 scal_cipher_free(&ctx);
226         }
227         if(ivsize_b==0){ /* exit if there is no IV */
228                 nessie_print_footer();
229                 return;
230         }
231         /***  Test SET 5 ***/
232         nessie_print_setheader(5);
233         memset(key, 0, (keysize_b+7)/8);
234 #if NESSIE_ESTREAM
235         for(v=0;v<ivsize_b; v+=9){
236 #else
237         for(v=0;v<ivsize_b; ++v){
238 #endif
239                 nessie_print_set_vector(5,v);
240                 iv[v/8] |= 0x80>>(v&7);
241                 nessie_print_item("key", key, (keysize_b+7)/8);
242                 nessie_print_item("IV", iv, (ivsize_b+7)/8);
243                 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
244                 normal_block(&ctx);
245                 scal_cipher_free(&ctx);
246                 iv[v/8] = 0;
247         }
248         /***  Test SET 6 ***/
249         nessie_print_setheader(6);
250         for(v=0;v<4; ++v){
251                 uint8_t i;
252                 nessie_print_set_vector(6,v);
253                 for(i=0; i<((keysize_b+7)/8); ++i){
254                         key[i]=(i*0x53+v*5)&0xff;
255                 }
256                 for(i=0; i<((ivsize_b+7)/8); ++i){
257                         iv[i]=(i*0x67+v*9+13)&0xff;
258                 }
259                 nessie_print_item("key", key, (keysize_b+7)/8);
260                 nessie_print_item("IV", iv, (ivsize_b+7)/8);
261                 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
262                 long_block(&ctx);
263                 scal_cipher_free(&ctx);
264         }
265         /***  Test SET 7 ***/
266 #if !NESSIE_ESTREAM
267         nessie_print_setheader(7);
268         uint8_t u;
269         for(v=0;v<3; ++v){
270                 for(u=0; u<3; ++u){
271                         uint8_t i;
272                         nessie_print_set_vector(7,v*3+u);
273                         for(i=0; i<((keysize_b+7)/8); ++i){
274                                 key[i]=pgm_read_byte(list_of_keys+20*v+(i%20));
275                         }
276                         for(i=0; i<((ivsize_b+7)/8); ++i){
277                                 key[i]=pgm_read_byte(list_of_keys+4*u+(i%4));
278                         }
279                 }
280                 nessie_print_item("key", key, (keysize_b+7)/8);
281                 nessie_print_item("IV", iv, (ivsize_b+7)/8);
282                 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
283                 long_block(&ctx);
284                 scal_cipher_free(&ctx);
285         }
286 #endif
287         nessie_print_footer();
288 }
289
290 void scal_nessie_run(const scdesc_t* desc){
291         uint16_t keysizes_count, ivsizes_count,i,j;
292         uint16_t *keysizes=NULL, *ivsizes=NULL;
293         keysizes_count = get_keysizes((PGM_VOID_P)pgm_read_word(&(desc->valid_keysize_desc)), &keysizes);
294         ivsizes_count = get_keysizes((PGM_VOID_P)pgm_read_word(&(desc->valid_ivsize_desc)), &ivsizes);
295         for(i=0; i<keysizes_count; ++i){
296                 for(j=0; j<ivsizes_count; ++j){
297                         scal_nessie_stream_run(desc, keysizes[i], ivsizes[j]);
298                 }
299         }
300 }