1 /* nessie_mac_test.c */
3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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: bg@nerilex.org
25 * a suit for running the nessie-tests for MACs
32 #include <avr/pgmspace.h>
33 #include "nessie_mac_test.h"
34 #include "nessie_common.h"
35 #include "dbz_strings.h"
37 nessie_mac_ctx_t nessie_mac_ctx;
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)
43 #define PRINTKEY nessie_print_item("key", key, KEYSIZE_B)
44 #define PRINTMAC nessie_print_item("MAC", mac, MACSIZE_B)
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 };
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];
57 uint8_t buffer[BLOCKSIZE_B];
59 fputs_P(PSTR("\r\n message="), stdout);
60 fputs_P(desc, stdout);
62 nessie_mac_ctx.mac_init(ctx, key, nessie_mac_ctx.keysize_b);
64 while(sl>nessie_mac_ctx.blocksize_B){
65 memcpy_P(buffer, data, BLOCKSIZE_B);
66 nessie_mac_ctx.mac_next(ctx, buffer);
70 memcpy_P(buffer, data, sl);
71 nessie_mac_ctx.mac_last(ctx, buffer, sl*8);
72 nessie_mac_ctx.mac_conv(mac, ctx);
76 // message=1 million times "a"
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];
86 fputs_P(PSTR("\r\n message="), stdout);
87 fputs_P(PSTR("1 million times \"a\""), stdout);
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++);
97 nessie_mac_ctx.mac_last(ctx, block, n*8);
98 nessie_mac_ctx.mac_conv(mac, ctx);
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];
109 fputs_P(PSTR("\r\n message="), stdout);
110 fprintf_P(stdout, PSTR("%"PRIu16" zero bits"), n);
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;
119 nessie_mac_ctx.mac_last(ctx, block, n);
120 nessie_mac_ctx.mac_conv(mac, ctx);
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];
130 char *tab[8] = { "80", "40", "20", "10",
131 "08", "04", "02", "01" };
134 fputs_P(PSTR("\r\n message="), stdout);
135 fputs_P(PSTR("512-bit string: "), stdout);
137 fprintf_P(stdout, PSTR("%2"PRIu16"*00,%s,%2"PRIu16"*00"), pos / 8, tab[pos & 7], 63 - pos / 8);
140 /* now the real stuff */
141 memset(block, 0, 512/8);
142 block[pos>>3] = 0x80>>(pos&0x7);
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;
151 nessie_mac_ctx.mac_last(ctx, bp, n);
152 nessie_mac_ctx.mac_conv(mac, ctx);
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;
165 fputs_P(PSTR("\r\n message="), stdout);
166 fprintf_P(stdout, PSTR("%"PRIu16" zero bits"), nessie_mac_ctx.macsize_b);
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;
177 nessie_mac_ctx.mac_last(ctx, block, n);
178 nessie_mac_ctx.mac_conv(mac, ctx);
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);
186 nessie_print_item("iterated 100000 times", mac, MACSIZE_B);
189 void nessie_mac_run(void){
192 uint8_t key[KEYSIZE_B];
194 nessie_print_header(nessie_mac_ctx.name, nessie_mac_ctx.keysize_b, 0, 0,
195 nessie_mac_ctx.macsize_b, 0);
197 const char *challange_dbz= PSTR(
199 "\"\" (empty string)\0"
205 "\"message digest\"\0"
206 "abcdefghijklmnopqrstuvwxyz\0"
207 "\"abcdefghijklmnopqrstuvwxyz\"\0"
208 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\0"
209 "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\0"
210 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
211 "abcdefghijklmnopqrstuvwxyz"
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"
224 nessie_print_setheader(set);
225 for(i=0; i<KEYSIZE_B; ++i){
226 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
229 dbz_splitup_P(challange_dbz, challange);
231 nessie_print_set_vector(set, i);
232 ascii_mac_P(challange[2*i], challange[2*i+1], key);
234 nessie_print_set_vector(set, i);
236 for(i=0; i<KEYSIZE_B; ++i){
237 key[i] = pgm_read_byte(&(keyproto[0x10+i%0x8]));
240 nessie_print_set_vector(set, 11+i);
241 ascii_mac_P(challange[2*i], challange[2*i+1], key);
243 nessie_print_set_vector(set, 11+i);
247 for(i=0; i<KEYSIZE_B; ++i){
248 key[i] = pgm_read_byte(&(keyproto[i%sizeof(keyproto)]));
250 nessie_print_setheader(set);
251 for(i=0; i<1024; ++i){
252 nessie_print_set_vector(set, i);
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);
265 nessie_print_setheader(set);
266 /* we use the same key as above */
267 nessie_print_set_vector(set, 0);
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);
278 nessie_print_footer();