]> git.cryptolib.org Git - avr-crypto-lib.git/blob - nessie_mac_test.c
hmac-sha256 bugfix + hmac-sha256 test suit
[avr-crypto-lib.git] / nessie_mac_test.c
1 /**
2  * 
3  * author: Daniel Otte
4  * email:  daniel.otte@rub.de
5  * license: GPLv3
6  * 
7  * a suit for running the nessie-tests for MACs
8  * 
9  * */
10 #include <stdint.h>
11 #include <string.h>
12 #include "nessie_mac_test.h"
13 #include "uart.h"
14
15 nessie_mac_ctx_t nessie_mac_ctx;
16
17 #define KEYSIZE_B ((nessie_mac_ctx.keysize_b+7)/8)
18 #define MACSIZE_B ((nessie_mac_ctx.macsize_b+7)/8)
19
20 #define PRINTKEY printitem("key", key, KEYSIZE_B)
21 #define PRINTMAC printitem("MAC", mac, MACSIZE_B)
22
23 static void printblock(uint8_t* block, uint16_t blocksize_bit){
24         char tab [] = {'0', '1', '2', '3', 
25                                    '4', '5', '6', '7', 
26                                    '8', '9', 'A', 'B', 
27                                    'C', 'D', 'E', 'F'};
28         uint16_t i;
29         for(i=0; i<(blocksize_bit+7)/8; ++i){
30                 uart_putc(tab[(block[i])>>4]);
31                 uart_putc(tab[(block[i])&0xf]);
32         }                                  
33 }
34
35 #define SPACES 31
36 #define BYTESPERLINE 16
37
38 static void printitem(char* name, uint8_t* buffer, uint16_t size_B){
39         uint8_t name_len;
40         uint8_t i;
41         name_len=strlen(name);
42         if(name_len>SPACES-1){
43                 uart_putstr_P(PSTR("\r\n!!! formatting error !!!\r\n"));
44                 return;
45         }
46         uart_putstr_P(PSTR("\r\n"));
47         for(i=0; i<SPACES-name_len-1; ++i){
48                 uart_putc(' ');
49         }
50         uart_putstr(name);
51         uart_putc('=');
52         /* now the data printing begins */
53         if(size_B<=BYTESPERLINE){
54                 /* one line seems sufficient */
55                 printblock(buffer, size_B*8);
56         } else {
57                 /* we need more lines */
58                 printblock(buffer, BYTESPERLINE*8); /* first line */
59                 int16_t toprint = size_B - BYTESPERLINE;
60                 buffer += BYTESPERLINE;
61                 while(toprint > 0){
62                         uart_putstr_P(PSTR("\r\n"));
63                         for(i=0; i<SPACES; ++i){
64                                 uart_putc(' ');
65                         }
66                         printblock(buffer, ((toprint>BYTESPERLINE)?BYTESPERLINE:toprint)*8);
67                         buffer  += BYTESPERLINE;
68                         toprint -= BYTESPERLINE;
69                 }
70         }
71
72
73 static void print_set_vector(uint8_t set, uint16_t vector){
74         uart_putstr_P(PSTR("\r\n\r\nSet "));
75         uart_putc('0'+set%10);
76         uart_putstr_P(PSTR(", vector#"));
77         uart_putc((vector<100)?' ':'0'+vector/100);
78         uart_putc((vector<10 )?' ':'0'+(vector/10)%10);
79         uart_putc('0'+vector%10);
80         uart_putc(':');
81 }
82
83 /* example:
84 Test vectors -- set 3
85 =====================
86  */ 
87 static void print_setheader(uint8_t set){
88         uart_putstr_P(PSTR("\r\n\r\nTest vectors -- set "));
89         uart_putc('0'+set%10);
90         uart_putstr_P(PSTR("\r\n====================="));
91 }
92
93 /* example:
94 ********************************************************************************
95 *Project NESSIE - New European Schemes for Signature, Integrity, and Encryption*
96 ********************************************************************************
97
98 Primitive Name: Serpent
99 =======================
100 Key size: 256 bits
101 Block size: 128 bits
102 */
103
104 static void print_header(void){
105         uint16_t i;
106         uart_putstr_P(PSTR("\r\n\r\n"
107         "********************************************************************************\r\n"
108         "* micro-cryt - crypto primitives for microcontrolles by Daniel Otte            *\r\n"
109         "********************************************************************************\r\n"
110         "\r\n"));
111         uart_putstr_P(PSTR("Primitive Name: "));
112         uart_putstr(nessie_mac_ctx.name);
113         uart_putstr_P(PSTR("\r\n"));
114         for(i=0; i<16+strlen(nessie_mac_ctx.name); ++i){
115                 uart_putc('=');
116         }
117         uart_putstr_P(PSTR("\r\nHash size: "));
118         if(nessie_mac_ctx.macsize_b >100){
119                 uart_putc('0'+nessie_mac_ctx.macsize_b/100);
120         }
121         if(nessie_mac_ctx.macsize_b>10){
122                 uart_putc('0'+(nessie_mac_ctx.macsize_b/10)%10);
123         }
124         uart_putc('0'+nessie_mac_ctx.macsize_b%10);
125         uart_putstr_P(PSTR(" bits\r\n"));
126 }
127
128 static void print_footer(void){
129         uart_putstr_P(PSTR("\r\n\r\n\r\n\r\nEnd of test vectors\r\n\r\n"));
130 }
131
132 static
133 void ascii_mac(char* data, char* desc, uint8_t* key){
134         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
135         uint8_t mac[MACSIZE_B];
136         uint16_t sl;
137         
138         uart_putstr_P(PSTR("\r\n                       message="));
139         uart_putstr(desc);
140         PRINTKEY;
141         nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);
142         sl = strlen(data);
143         while(sl>=nessie_mac_ctx.blocksize_B){
144                 nessie_mac_ctx.mac_next(data, ctx);
145                 data += nessie_mac_ctx.blocksize_B;
146                 sl   -= nessie_mac_ctx.blocksize_B;
147         }
148         nessie_mac_ctx.mac_last(data, sl*8, key, nessie_mac_ctx.keysize_b, ctx);
149         nessie_mac_ctx.mac_conv(mac, ctx);
150         PRINTMAC;
151 }
152
153 // message=1 million times "a"
154
155 static
156 void amillion_mac(uint8_t* key){
157         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
158         uint8_t mac[MACSIZE_B];
159         uint8_t block[nessie_mac_ctx.blocksize_B];
160         uint32_t n=1000000LL;
161         
162         uart_putstr_P(PSTR("\r\n                       message="));
163         uart_putstr_P(PSTR("1 million times \"a\""));
164         PRINTKEY;
165         
166         memset(block, 'a', nessie_mac_ctx.blocksize_B);
167         nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);
168         while(n>=nessie_mac_ctx.blocksize_B){
169                 nessie_mac_ctx.mac_next(block, ctx);
170                 n    -= nessie_mac_ctx.blocksize_B;
171         }
172         nessie_mac_ctx.mac_last(block, n*8, key, nessie_mac_ctx.keysize_b, ctx);
173         nessie_mac_ctx.mac_conv(mac, ctx);
174         PRINTMAC;
175 }
176
177
178 static
179 void zero_mac(uint16_t n, uint8_t* key){
180         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
181         uint8_t mac[MACSIZE_B];
182         uint8_t block[nessie_mac_ctx.blocksize_B];
183         
184         uart_putstr_P(PSTR("\r\n                       message="));
185         if(n>=10000)
186                 uart_putc('0'+n/10000);
187         if(n>=1000)
188                 uart_putc('0'+(n/1000)%10);
189         if(n>=100)
190                 uart_putc('0'+(n/100)%10);
191         if(n>=10)
192                 uart_putc('0'+(n/10)%10);
193         uart_putc('0'+n%10);
194         uart_putstr_P(PSTR(" zero bits"));
195         PRINTKEY;
196         
197         memset(block, 0, nessie_mac_ctx.blocksize_B); 
198         nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b,ctx);;
199         while(n>=nessie_mac_ctx.blocksize_B*8){
200                 nessie_mac_ctx.mac_next(block, ctx);
201                 n   -= nessie_mac_ctx.blocksize_B*8;
202         }
203         nessie_mac_ctx.mac_last(block, n, key, nessie_mac_ctx.keysize_b, ctx);
204         nessie_mac_ctx.mac_conv(mac, ctx);
205         PRINTMAC;
206 }
207
208 static
209 void one_in512_mac(uint16_t pos, uint8_t* key){
210         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
211         uint8_t mac[MACSIZE_B];
212         uint8_t block[nessie_mac_ctx.blocksize_B];
213         uint16_t n=512;
214         char* tab[8]={"80", "40", "20", "10", 
215                       "08", "04", "02", "01" };
216
217         pos&=511;
218         uart_putstr_P(PSTR("\r\n                       message="));
219         uart_putstr_P(PSTR("512-bit string: "));
220         if((pos/8) >=10){
221                 uart_putc('0'+(pos/8/10)%10);
222         } else {
223                 uart_putc(' ');
224         }
225         uart_putc('0'+(pos/8)%10);
226         uart_putstr_P(PSTR("*00,"));
227         uart_putstr(tab[pos&7]);
228         uart_putc(',');
229         if(63-(pos/8) >=10){
230                 uart_putc('0'+((63-pos/8)/10)%10);
231         } else {
232                 uart_putc(' ');
233         }
234         uart_putc('0'+(63-pos/8)%10);
235         uart_putstr_P(PSTR("*00"));
236         PRINTKEY;
237         
238         /* now the real stuff */
239         memset(block, 0, 512/8);
240         block[pos>>3] = 0x80>>(pos&0x7);
241         nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);;
242         while(n>=nessie_mac_ctx.blocksize_B*8){
243                 nessie_mac_ctx.mac_next(block, ctx);
244                 n   -= nessie_mac_ctx.blocksize_B*8;
245         }
246         nessie_mac_ctx.mac_last(block, n, key, nessie_mac_ctx.keysize_b, ctx);
247         nessie_mac_ctx.mac_conv(mac, ctx);
248         PRINTMAC;
249 }
250
251 static
252 void tv4_mac(uint8_t* key){
253         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
254         uint8_t mac[MACSIZE_B];
255         uint8_t block[256/8];
256         uint16_t n=256;
257         uint32_t i;
258         
259         uart_putstr_P(PSTR("\r\n                       message="));
260         uart_putstr(PSTR("256 zero bits"));
261         memset(block, 0, 256/8);
262         
263         nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);;
264         while(n>=nessie_mac_ctx.blocksize_B*8){
265                 nessie_mac_ctx.mac_next(block, ctx);
266                 n    -= nessie_mac_ctx.blocksize_B*8;
267         }
268         nessie_mac_ctx.mac_last(block, n, key, nessie_mac_ctx.keysize_b, ctx);
269         nessie_mac_ctx.mac_conv(mac, ctx);
270         PRINTMAC;
271         for(i=1; i<100000L; ++i){ /* this assumes BLOCKSIZE >= HASHSIZE */
272                 nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);;
273                 nessie_mac_ctx.mac_last(mac, nessie_mac_ctx.macsize_b, key, nessie_mac_ctx.keysize_b, ctx);
274                 nessie_mac_ctx.mac_conv(mac, ctx);
275         }
276         printitem("iterated 100000 times", mac, MACSIZE_B);
277 }
278
279
280 void nessie_mac_run(void){
281         uint16_t i;
282         uint8_t set;
283         uint8_t keyproto[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
284                           0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
285                           0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
286         uint8_t key[KEYSIZE_B];
287         
288         print_header();
289         /* test set 1 */
290         char* challange[10][2]= {
291                 {"", "\"\" (empty string)"},
292                 {"a", "\"a\""},
293                 {"abc", "\"abc\""},
294                 {"message digest", "\"message digest\""},
295                 {"abcdefghijklmnopqrstuvwxyz","\"abcdefghijklmnopqrstuvwxyz\""},
296                 {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
297                         "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\""},
298                 {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
299                  "abcdefghijklmnopqrstuvwxyz"
300                  "0123456789"   , "\"A...Za...z0...9\""},
301                 {"1234567890" "1234567890" "1234567890" "1234567890" 
302                  "1234567890" "1234567890" "1234567890" "1234567890",
303                  "8 times \"1234567890\""},
304                 {"Now is the time for all ", "\"Now is the time for all \""},
305                 {"Now is the time for it", "\"Now is the time for it\""}
306         };
307         set=1;
308         print_setheader(set);
309         for(i=0; i<KEYSIZE_B; ++i){
310                 key[i] = keyproto[i%sizeof(keyproto)];
311         }
312         for(i=0; i<10; ++i){
313                 print_set_vector(set, i);
314                 ascii_mac(challange[i][0], challange[i][1], key);
315         }
316         print_set_vector(set, i);
317         amillion_mac(key);
318         for(i=0; i<KEYSIZE_B; ++i){
319                 key[i] = keyproto[16+i%8];
320         }
321         for(i=0; i<10; ++i){
322                 print_set_vector(set, 11+i);
323                 ascii_mac(challange[i][0], challange[i][1], key);
324         }
325         print_set_vector(set, 11+i);
326         amillion_mac(key);
327         /* test set 2 */
328         set=2;
329         for(i=0; i<KEYSIZE_B; ++i){
330                 key[i] = keyproto[i%sizeof(keyproto)];
331         }
332         print_setheader(set);
333         for(i=0; i<1024; ++i){
334                 print_set_vector(set, i);
335                 zero_mac(i, key);
336         }
337         /* test set 3 */
338         set=3;
339         print_setheader(set);
340         /* we use the same key as above */
341         for(i=0; i<512; ++i){
342                 print_set_vector(set, i);
343                 one_in512_mac(i, key);
344         }
345         /* test set 4 */
346         set=4;
347         print_setheader(set);
348         /* we use the same key as above */
349         print_set_vector(set, 0);
350         tv4_mac(key);
351         /* test set 5 */
352         for(i=0; i<nessie_mac_ctx.keysize_b; ++i){
353                 print_set_vector(set, i);
354                 memset(key, 0, KEYSIZE_B);
355                 key[i>>3]=0x80>>(i&0x7);
356                 ascii_mac("ABC", "\"ABC\"", key);
357         }
358         print_footer();
359 }