3 This file is part of the AVR-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/>.
22 #include "streamcipher_descriptor.h"
23 #include "scal-basic.h"
24 #include "nessie_common.h"
26 #include <avr/pgmspace.h>
29 uint8_t estream_flag = 0;
31 void scal_nessie_set_estream(uint8_t v){
35 uint8_t scal_nessie_get_estream(void){
36 return estream_flag?1:0;
41 static const uint8_t normal_hooks[] PROGMEM = {
42 0, 192/64, 256/64, 448/64
45 static const uint16_t long_hooks[] PROGMEM = {
46 0, 65472/64, 65536/64, 131008/64
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]";
54 static const char streamX_n_estream[] PROGMEM = "xor-digest";
55 static const char streamX_n_nessie[] PROGMEM = "stream[0..511]xored";
57 static const char* stream_n_str[] = {
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";
71 static const char* stream_l_str[] = {
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 }
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 }
95 void normal_block(scgen_ctx_t *ctx){
96 uint8_t xor_block[64];
98 PGM_VOID_P hook_ptr = normal_hooks;
99 const char* *hook_str_ptr = stream_n_str;
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);
114 strcpy_P(str, *(hook_str_ptr));
115 nessie_print_item(str, xor_block, 64);
119 void long_block(scgen_ctx_t *ctx){
120 uint8_t xor_block[64];
122 PGM_VOID_P hook_ptr = long_hooks;
123 const char* *hook_str_ptr = stream_l_str;
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);
141 strcpy_P(str, *(hook_str_ptr));
142 nessie_print_item(str, xor_block, 64);
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);
150 uint8_t key[(keysize_b+7)/8];
151 uint8_t iv[(ivsize_b+7)/8];
154 nessie_print_header(name, keysize_b, 0, 0, 0, ivsize_b?ivsize_b:((uint16_t)-1));
156 stream_n_str[4] = streamX_n_estream;
157 stream_l_str[4] = streamX_l_estream;
159 stream_n_str[4] = streamX_n_nessie;
160 stream_l_str[4] = streamX_l_nessie;
162 memset(iv, 0, (ivsize_b+7)/8);
163 memset(key, 0, (keysize_b+7)/8);
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);
171 nessie_print_item("IV", iv, (ivsize_b+7)/8);
173 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
176 scal_cipher_free(&ctx);
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);
185 nessie_print_item("IV", iv, (ivsize_b+7)/8);
187 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
189 scal_cipher_free(&ctx);
192 nessie_print_setheader(3);
193 for(v=0;v<256; v+=estream_flag?9:1){
195 nessie_print_set_vector(3,v);
196 for(i=0; i<((keysize_b+7)/8); ++i){
199 nessie_print_item("key", key, (keysize_b+7)/8);
201 nessie_print_item("IV", iv, (ivsize_b+7)/8);
203 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
205 scal_cipher_free(&ctx);
208 nessie_print_setheader(4);
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;
215 nessie_print_item("key", key, (keysize_b+7)/8);
217 nessie_print_item("IV", iv, (ivsize_b+7)/8);
219 scal_cipher_init(desc, key, keysize_b, iv, ivsize_b, &ctx);
221 scal_cipher_free(&ctx);
223 if(ivsize_b==0){ /* exit if there is no IV */
224 nessie_print_footer();
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);
237 scal_cipher_free(&ctx);
241 nessie_print_setheader(6);
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;
248 for(i=0; i<((ivsize_b+7)/8); ++i){
249 iv[i]=(i*0x67+v*9+13)&0xff;
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);
255 scal_cipher_free(&ctx);
259 nessie_print_setheader(7);
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));
268 for(i=0; i<((ivsize_b+7)/8); ++i){
269 key[i]=pgm_read_byte(list_of_keys+4*u+(i%4));
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);
276 scal_cipher_free(&ctx);
279 nessie_print_footer();
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]);