]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/nessie_mac_test.c
fixing E-Mail-Address & Copyright
[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) 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  * 
21  * author: Daniel Otte
22  * email:  bg@nerilex.org
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 <stdio.h>
32 #include <avr/pgmspace.h>
33 #include "nessie_mac_test.h"
34 #include "nessie_common.h"
35 #include "dbz_strings.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 const 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         fputs_P(PSTR("\r\n                       message="), stdout);
60         fputs_P(desc, stdout);
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         fputs_P(PSTR("\r\n                       message="), stdout);
87         fputs_P(PSTR("1 million times \"a\""), stdout);
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         fputs_P(PSTR("\r\n                       message="), stdout);
110         fprintf_P(stdout, PSTR("%"PRIu16" zero bits"), n);
111         PRINTKEY;
112         
113         memset(block, 0, nessie_mac_ctx.blocksize_B); 
114         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
115         while(n>nessie_mac_ctx.blocksize_B*8){
116                 nessie_mac_ctx.mac_next(ctx, block);
117                 n   -= nessie_mac_ctx.blocksize_B*8;
118         }
119         nessie_mac_ctx.mac_last(ctx, block, n);
120         nessie_mac_ctx.mac_conv(mac, ctx);
121         PRINTMAC;
122 }
123
124 static
125 void one_in512_mac(uint16_t pos, uint8_t *key){
126         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
127         uint8_t mac[MACSIZE_B];
128         uint8_t block[nessie_mac_ctx.blocksize_B];
129         uint16_t n=512;
130         char *tab[8] = { "80", "40", "20", "10",
131                          "08", "04", "02", "01" };
132
133         pos&=511;
134         fputs_P(PSTR("\r\n                       message="), stdout);
135         fputs_P(PSTR("512-bit string: "), stdout);
136
137     fprintf_P(stdout, PSTR("%2"PRIu16"*00,%s,%2"PRIu16"*00"), pos / 8, tab[pos & 7], 63 - pos / 8);
138         PRINTKEY;
139         
140         /* now the real stuff */
141         memset(block, 0, 512/8);
142         block[pos>>3] = 0x80>>(pos&0x7);
143         uint8_t *bp;
144         bp = block;
145         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
146         while(n>nessie_mac_ctx.blocksize_B*8){
147                 nessie_mac_ctx.mac_next(ctx, bp);
148                 n   -= nessie_mac_ctx.blocksize_B*8;
149                 bp  += nessie_mac_ctx.blocksize_B;
150         }
151         nessie_mac_ctx.mac_last(ctx, bp, n);
152         nessie_mac_ctx.mac_conv(mac, ctx);
153         PRINTMAC;
154 }
155
156 static
157 void tv4_mac(void){
158         uint8_t ctx[nessie_mac_ctx.ctx_size_B];
159         uint8_t mac[MACSIZE_B];
160         uint8_t block[MACSIZE_B];
161         uint8_t key[KEYSIZE_B];
162         uint16_t n=MACSIZE_B*8;
163         uint32_t i;
164         
165         fputs_P(PSTR("\r\n                       message="), stdout);
166         fprintf_P(stdout, PSTR("%"PRIu16" zero bits"), nessie_mac_ctx.macsize_b);
167
168         memset(block, 0, MACSIZE_B);
169         for(i=0; i<KEYSIZE_B; ++i)
170                 key[i] = pgm_read_byte(&(keyproto[i%(3*8)]));
171         nessie_print_item("key", key, KEYSIZE_B);
172         nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
173         while(n>nessie_mac_ctx.blocksize_B*8){
174                 nessie_mac_ctx.mac_next(ctx, block);
175                 n    -= nessie_mac_ctx.blocksize_B*8;
176         }
177         nessie_mac_ctx.mac_last(ctx, block, n);
178         nessie_mac_ctx.mac_conv(mac, ctx);
179         PRINTMAC;
180         for(i=1; i<100000L; ++i){ /* this assumes BLOCKSIZE >= HASHSIZE */
181                 nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
182                 nessie_mac_ctx.mac_last(ctx, mac, nessie_mac_ctx.macsize_b);
183                 nessie_mac_ctx.mac_conv(mac, ctx);
184                 NESSIE_SEND_ALIVE_A(i);
185         }
186         nessie_print_item("iterated 100000 times", mac, MACSIZE_B);
187 }
188
189 void nessie_mac_run(void){
190         uint16_t i;
191         uint8_t set;
192         uint8_t key[KEYSIZE_B];
193         
194         nessie_print_header(nessie_mac_ctx.name, nessie_mac_ctx.keysize_b, 0, 0,
195                             nessie_mac_ctx.macsize_b, 0);
196         /* test set 1 */
197         const char *challange_dbz= PSTR(
198                   "\0"
199                 "\"\" (empty string)\0"
200                   "a\0"
201                 "\"a\"\0"
202                   "abc\0"
203                 "\"abc\"\0"
204                   "message digest\0"
205                 "\"message digest\"\0"
206                   "abcdefghijklmnopqrstuvwxyz\0"
207                 "\"abcdefghijklmnopqrstuvwxyz\"\0"
208                   "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\0"
209                 "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\0"
210                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
211                   "abcdefghijklmnopqrstuvwxyz"
212                   "0123456789\0"         
213                  "\"A...Za...z0...9\"\0"
214                  "1234567890123456789012345678901234567890" 
215                  "1234567890123456789012345678901234567890\0"
216                  "8 times \"1234567890\"\0"
217                   "Now is the time for all \0"
218                 "\"Now is the time for all \"\0"
219                   "Now is the time for it\0" 
220                 "\"Now is the time for it\"\0"
221         );
222
223         set=1;
224         nessie_print_setheader(set);
225         for(i=0; i<KEYSIZE_B; ++i){
226                 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
227         }
228         PGM_P challange[20];
229         dbz_splitup_P(challange_dbz, challange);
230         for(i=0; i<10; ++i){
231                 nessie_print_set_vector(set, i);
232                 ascii_mac_P(challange[2*i], challange[2*i+1], key);
233         }
234         nessie_print_set_vector(set, i);
235         amillion_mac(key);
236         for(i=0; i<KEYSIZE_B; ++i){
237                 key[i] = pgm_read_byte(&(keyproto[0x10+i%0x8]));
238         }
239         for(i=0; i<10; ++i){
240                 nessie_print_set_vector(set, 11+i);
241                 ascii_mac_P(challange[2*i], challange[2*i+1], key);
242         }
243         nessie_print_set_vector(set, 11+i);
244         amillion_mac(key);
245         /* test set 2 */
246         set=2;
247         for(i=0; i<KEYSIZE_B; ++i){
248                 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
249         }
250         nessie_print_setheader(set);
251         for(i=0; i<1024; ++i){
252                 nessie_print_set_vector(set, i);
253                 zero_mac(i, key);
254         }
255         /* test set 3 */
256         set=3;
257         nessie_print_setheader(set);
258         /* we use the same key as above */
259         for(i=0; i<512; ++i){
260                 nessie_print_set_vector(set, i);
261                 one_in512_mac(i, key);
262         }
263         /* test set 4 */
264         set=4;
265         nessie_print_setheader(set);
266         /* we use the same key as above */
267         nessie_print_set_vector(set, 0);
268         tv4_mac();
269         /* test set 5 */
270         set=5;
271         nessie_print_setheader(set);
272         for(i=0; i<nessie_mac_ctx.keysize_b; ++i){
273                 nessie_print_set_vector(set, i);
274                 memset(key, 0, KEYSIZE_B);
275                 key[i>>3]=0x80>>(i&0x7);
276                 ascii_mac_P(PSTR("ABC"), PSTR("\"ABC\""), key);
277         }
278         nessie_print_footer();
279 }