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