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