]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/nessie_mac_test.c
backporting uart_i and cli
[avr-crypto-lib.git] / test_src / nessie_mac_test.c
1 /* nessie_mac_test.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2008  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  * 
21  * author: Daniel Otte
22  * email:  daniel.otte@rub.de
23  * license: GPLv3
24  * 
25  * a suit for running the nessie-tests for MACs
26  * 
27  * */
28 #include <stdint.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <avr/pgmspace.h>
32 #include "nessie_mac_test.h"
33 #include "nessie_common.h"
34 #include "dbz_strings.h"
35
36 nessie_mac_ctx_t nessie_mac_ctx;
37
38 #define KEYSIZE_B   ((nessie_mac_ctx.keysize_b+7)/8)
39 #define MACSIZE_B   ((nessie_mac_ctx.macsize_b+7)/8)
40 #define BLOCKSIZE_B (nessie_mac_ctx.blocksize_B)
41
42 #define PRINTKEY nessie_print_item("key", key, KEYSIZE_B)
43 #define PRINTMAC nessie_print_item("MAC", mac, MACSIZE_B)
44
45
46 static  uint8_t keyproto[] PROGMEM = {
47                                   0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
48                           0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
49                           0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
50
51 static
52 void ascii_mac_P(PGM_P data, PGM_P desc, uint8_t* key){
53         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
54         uint8_t mac[MACSIZE_B];
55         uint16_t sl;
56         uint8_t buffer[BLOCKSIZE_B];
57         
58         NESSIE_PUTSTR_P(PSTR("\r\n                       message="));
59         NESSIE_PUTSTR_P(desc);
60         PRINTKEY;
61         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
62         sl = strlen_P(data);
63         while(sl>nessie_mac_ctx.blocksize_B){
64                 memcpy_P(buffer, data, BLOCKSIZE_B);
65                 nessie_mac_ctx.mac_next(ctx, buffer);
66                 data += BLOCKSIZE_B;
67                 sl   -= BLOCKSIZE_B;
68         }
69         memcpy_P(buffer, data, sl);
70         nessie_mac_ctx.mac_last(ctx, buffer, sl*8);
71         nessie_mac_ctx.mac_conv(mac, ctx);
72         PRINTMAC;
73 }
74
75 // message=1 million times "a"
76
77 static
78 void amillion_mac(uint8_t* key){
79         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
80         uint8_t mac[MACSIZE_B];
81         uint8_t block[nessie_mac_ctx.blocksize_B];
82         uint32_t n=1000000LL;
83         uint16_t i=0;
84         
85         NESSIE_PUTSTR_P(PSTR("\r\n                       message="));
86         NESSIE_PUTSTR_P(PSTR("1 million times \"a\""));
87         PRINTKEY;
88         
89         memset(block, 'a', nessie_mac_ctx.blocksize_B);
90         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
91         while(n>=nessie_mac_ctx.blocksize_B){
92                 nessie_mac_ctx.mac_next(ctx, block);
93                 n    -= nessie_mac_ctx.blocksize_B;
94                 NESSIE_SEND_ALIVE_A(i++);
95         }
96         nessie_mac_ctx.mac_last(ctx, block, n*8);
97         nessie_mac_ctx.mac_conv(mac, ctx);
98         PRINTMAC;
99 }
100
101
102 static
103 void zero_mac(uint16_t n, uint8_t* key){
104         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
105         uint8_t mac[MACSIZE_B];
106         uint8_t block[nessie_mac_ctx.blocksize_B];
107         
108         NESSIE_PUTSTR_P(PSTR("\r\n                       message="));
109         if(n>=10000)
110                 NESSIE_PUTC('0'+n/10000);
111         if(n>=1000)
112                 NESSIE_PUTC('0'+(n/1000)%10);
113         if(n>=100)
114                 NESSIE_PUTC('0'+(n/100)%10);
115         if(n>=10)
116                 NESSIE_PUTC('0'+(n/10)%10);
117         NESSIE_PUTC('0'+n%10);
118         NESSIE_PUTSTR_P(PSTR(" zero bits"));
119         PRINTKEY;
120         
121         memset(block, 0, nessie_mac_ctx.blocksize_B); 
122         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
123         while(n>nessie_mac_ctx.blocksize_B*8){
124                 nessie_mac_ctx.mac_next(ctx, block);
125                 n   -= nessie_mac_ctx.blocksize_B*8;
126         }
127         nessie_mac_ctx.mac_last(ctx, block, n);
128         nessie_mac_ctx.mac_conv(mac, ctx);
129         PRINTMAC;
130 }
131
132 static
133 void one_in512_mac(uint16_t pos, uint8_t* key){
134         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
135         uint8_t mac[MACSIZE_B];
136         uint8_t block[nessie_mac_ctx.blocksize_B];
137         uint16_t n=512;
138         char* tab[8]={"80", "40", "20", "10", 
139                       "08", "04", "02", "01" };
140
141         pos&=511;
142         NESSIE_PUTSTR_P(PSTR("\r\n                       message="));
143         NESSIE_PUTSTR_P(PSTR("512-bit string: "));
144         if((pos/8) >=10){
145                 NESSIE_PUTC('0'+(pos/8/10)%10);
146         } else {
147                 NESSIE_PUTC(' ');
148         }
149         NESSIE_PUTC('0'+(pos/8)%10);
150         NESSIE_PUTSTR_P(PSTR("*00,"));
151         NESSIE_PUTSTR(tab[pos&7]);
152         NESSIE_PUTC(',');
153         if(63-(pos/8) >=10){
154                 NESSIE_PUTC('0'+((63-pos/8)/10)%10);
155         } else {
156                 NESSIE_PUTC(' ');
157         }
158         NESSIE_PUTC('0'+(63-pos/8)%10);
159         NESSIE_PUTSTR_P(PSTR("*00"));
160         PRINTKEY;
161         
162         /* now the real stuff */
163         memset(block, 0, 512/8);
164         block[pos>>3] = 0x80>>(pos&0x7);
165         uint8_t* bp;
166         bp = block;
167         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
168         while(n>nessie_mac_ctx.blocksize_B*8){
169                 nessie_mac_ctx.mac_next(ctx, bp);
170                 n   -= nessie_mac_ctx.blocksize_B*8;
171                 bp  += nessie_mac_ctx.blocksize_B;
172         }
173         nessie_mac_ctx.mac_last(ctx, bp, n);
174         nessie_mac_ctx.mac_conv(mac, ctx);
175         PRINTMAC;
176 }
177
178 static
179 void tv4_mac(void){
180         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
181         uint8_t mac[MACSIZE_B];
182         uint8_t block[MACSIZE_B];
183         uint8_t key[KEYSIZE_B];
184         uint16_t n=MACSIZE_B*8;
185         uint32_t i;
186         char str[6];
187         
188         NESSIE_PUTSTR_P(PSTR("\r\n                       message="));
189         utoa(MACSIZE_B*8, str, 10);
190         NESSIE_PUTSTR(str);
191         NESSIE_PUTSTR_P(PSTR(" zero bits"));
192         memset(block, 0, MACSIZE_B);
193         for(i=0; i<KEYSIZE_B; ++i)
194                 key[i] = pgm_read_byte(&(keyproto[i%(3*8)]));
195         nessie_print_item("key", key, KEYSIZE_B);
196         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
197         while(n>nessie_mac_ctx.blocksize_B*8){
198                 nessie_mac_ctx.mac_next(ctx, block);
199                 n    -= nessie_mac_ctx.blocksize_B*8;
200         }
201         nessie_mac_ctx.mac_last(ctx, block, n);
202         nessie_mac_ctx.mac_conv(mac, ctx);
203         PRINTMAC;
204         for(i=1; i<100000L; ++i){ /* this assumes BLOCKSIZE >= HASHSIZE */
205                 nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
206                 nessie_mac_ctx.mac_last(ctx, mac, nessie_mac_ctx.macsize_b);
207                 nessie_mac_ctx.mac_conv(mac, ctx);
208                 NESSIE_SEND_ALIVE_A(i);
209         }
210         nessie_print_item("iterated 100000 times", mac, MACSIZE_B);
211 }
212
213 void nessie_mac_run(void){
214         uint16_t i;
215         uint8_t set;
216         uint8_t key[KEYSIZE_B];
217         
218         nessie_print_header(nessie_mac_ctx.name, nessie_mac_ctx.keysize_b, 0, 0,
219                             nessie_mac_ctx.macsize_b, 0);
220         /* test set 1 */
221         char* challange_dbz= PSTR(
222                   "\0"
223                 "\"\" (empty string)\0"
224                   "a\0"
225                 "\"a\"\0"
226                   "abc\0"
227                 "\"abc\"\0"
228                   "message digest\0"
229                 "\"message digest\"\0"
230                   "abcdefghijklmnopqrstuvwxyz\0"
231                 "\"abcdefghijklmnopqrstuvwxyz\"\0"
232                   "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\0"
233                 "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\0"
234                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
235                   "abcdefghijklmnopqrstuvwxyz"
236                   "0123456789\0"         
237                  "\"A...Za...z0...9\"\0"
238                  "1234567890123456789012345678901234567890" 
239                  "1234567890123456789012345678901234567890\0"
240                  "8 times \"1234567890\"\0"
241                   "Now is the time for all \0"
242                 "\"Now is the time for all \"\0"
243                   "Now is the time for it\0" 
244                 "\"Now is the time for it\"\0"
245         );
246
247         set=1;
248         nessie_print_setheader(set);
249         for(i=0; i<KEYSIZE_B; ++i){
250                 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
251         }
252         PGM_P challange[20];
253         dbz_splitup_P(challange_dbz, challange);
254         for(i=0; i<10; ++i){
255                 nessie_print_set_vector(set, i);
256                 ascii_mac_P(challange[2*i], challange[2*i+1], key);
257         }
258         nessie_print_set_vector(set, i);
259         amillion_mac(key);
260         for(i=0; i<KEYSIZE_B; ++i){
261                 key[i] = pgm_read_byte(&(keyproto[0x10+i%0x8]));
262         }
263         for(i=0; i<10; ++i){
264                 nessie_print_set_vector(set, 11+i);
265                 ascii_mac_P(challange[2*i], challange[2*i+1], key);
266         }
267         nessie_print_set_vector(set, 11+i);
268         amillion_mac(key);
269         /* test set 2 */
270         set=2;
271         for(i=0; i<KEYSIZE_B; ++i){
272                 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
273         }
274         nessie_print_setheader(set);
275         for(i=0; i<1024; ++i){
276                 nessie_print_set_vector(set, i);
277                 zero_mac(i, key);
278         }
279         /* test set 3 */
280         set=3;
281         nessie_print_setheader(set);
282         /* we use the same key as above */
283         for(i=0; i<512; ++i){
284                 nessie_print_set_vector(set, i);
285                 one_in512_mac(i, key);
286         }
287         /* test set 4 */
288         set=4;
289         nessie_print_setheader(set);
290         /* we use the same key as above */
291         nessie_print_set_vector(set, 0);
292         tv4_mac();
293         /* test set 5 */
294         set=5;
295         nessie_print_setheader(set);
296         for(i=0; i<nessie_mac_ctx.keysize_b; ++i){
297                 nessie_print_set_vector(set, i);
298                 memset(key, 0, KEYSIZE_B);
299                 key[i>>3]=0x80>>(i&0x7);
300                 ascii_mac_P(PSTR("ABC"), PSTR("\"ABC\""), key);
301         }
302         nessie_print_footer();
303 }