1 /* nessie_mac_test.c */
3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
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.
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.
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/>.
22 * email: daniel.otte@rub.de
25 * a suit for running the nessie-tests for MACs
31 #include <avr/pgmspace.h>
32 #include "nessie_mac_test.h"
33 #include "nessie_common.h"
34 #include "dbz_strings.h"
36 nessie_mac_ctx_t nessie_mac_ctx;
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)
42 #define PRINTKEY nessie_print_item("key", key, KEYSIZE_B)
43 #define PRINTMAC nessie_print_item("MAC", mac, MACSIZE_B)
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 };
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];
56 uint8_t buffer[BLOCKSIZE_B];
58 NESSIE_PUTSTR_P(PSTR("\r\n message="));
59 NESSIE_PUTSTR_P(desc);
61 nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
63 while(sl>nessie_mac_ctx.blocksize_B){
64 memcpy_P(buffer, data, BLOCKSIZE_B);
65 nessie_mac_ctx.mac_next(ctx, buffer);
69 memcpy_P(buffer, data, sl);
70 nessie_mac_ctx.mac_last(ctx, buffer, sl*8);
71 nessie_mac_ctx.mac_conv(mac, ctx);
75 // message=1 million times "a"
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];
85 NESSIE_PUTSTR_P(PSTR("\r\n message="));
86 NESSIE_PUTSTR_P(PSTR("1 million times \"a\""));
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++);
96 nessie_mac_ctx.mac_last(ctx, block, n*8);
97 nessie_mac_ctx.mac_conv(mac, ctx);
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];
108 NESSIE_PUTSTR_P(PSTR("\r\n message="));
110 NESSIE_PUTC('0'+n/10000);
112 NESSIE_PUTC('0'+(n/1000)%10);
114 NESSIE_PUTC('0'+(n/100)%10);
116 NESSIE_PUTC('0'+(n/10)%10);
117 NESSIE_PUTC('0'+n%10);
118 NESSIE_PUTSTR_P(PSTR(" zero bits"));
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;
127 nessie_mac_ctx.mac_last(ctx, block, n);
128 nessie_mac_ctx.mac_conv(mac, ctx);
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];
138 char* tab[8]={"80", "40", "20", "10",
139 "08", "04", "02", "01" };
142 NESSIE_PUTSTR_P(PSTR("\r\n message="));
143 NESSIE_PUTSTR_P(PSTR("512-bit string: "));
145 NESSIE_PUTC('0'+(pos/8/10)%10);
149 NESSIE_PUTC('0'+(pos/8)%10);
150 NESSIE_PUTSTR_P(PSTR("*00,"));
151 NESSIE_PUTSTR(tab[pos&7]);
154 NESSIE_PUTC('0'+((63-pos/8)/10)%10);
158 NESSIE_PUTC('0'+(63-pos/8)%10);
159 NESSIE_PUTSTR_P(PSTR("*00"));
162 /* now the real stuff */
163 memset(block, 0, 512/8);
164 block[pos>>3] = 0x80>>(pos&0x7);
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;
173 nessie_mac_ctx.mac_last(ctx, bp, n);
174 nessie_mac_ctx.mac_conv(mac, ctx);
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;
188 NESSIE_PUTSTR_P(PSTR("\r\n message="));
189 utoa(MACSIZE_B*8, str, 10);
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;
201 nessie_mac_ctx.mac_last(ctx, block, n);
202 nessie_mac_ctx.mac_conv(mac, ctx);
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);
210 nessie_print_item("iterated 100000 times", mac, MACSIZE_B);
213 void nessie_mac_run(void){
216 uint8_t key[KEYSIZE_B];
218 nessie_print_header(nessie_mac_ctx.name, nessie_mac_ctx.keysize_b, 0, 0,
219 nessie_mac_ctx.macsize_b, 0);
221 char* challange_dbz= PSTR(
223 "\"\" (empty string)\0"
229 "\"message digest\"\0"
230 "abcdefghijklmnopqrstuvwxyz\0"
231 "\"abcdefghijklmnopqrstuvwxyz\"\0"
232 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\0"
233 "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\0"
234 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
235 "abcdefghijklmnopqrstuvwxyz"
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"
248 nessie_print_setheader(set);
249 for(i=0; i<KEYSIZE_B; ++i){
250 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
253 dbz_splitup_P(challange_dbz, challange);
255 nessie_print_set_vector(set, i);
256 ascii_mac_P(challange[2*i], challange[2*i+1], key);
258 nessie_print_set_vector(set, i);
260 for(i=0; i<KEYSIZE_B; ++i){
261 key[i] = pgm_read_byte(&(keyproto[0x10+i%0x8]));
264 nessie_print_set_vector(set, 11+i);
265 ascii_mac_P(challange[2*i], challange[2*i+1], key);
267 nessie_print_set_vector(set, 11+i);
271 for(i=0; i<KEYSIZE_B; ++i){
272 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
274 nessie_print_setheader(set);
275 for(i=0; i<1024; ++i){
276 nessie_print_set_vector(set, i);
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);
289 nessie_print_setheader(set);
290 /* we use the same key as above */
291 nessie_print_set_vector(set, 0);
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);
302 nessie_print_footer();