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