3 This file is part of the ARM-Crypto-Lib.
4 Copyright (C) 2006-2010 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/>.
23 * \license GPLv3 or later
31 #include "blockcipher_descriptor.h"
32 #include "bcal-basic.h"
33 #include "bcal-cmac.h"
35 #include "string-extras.h"
47 # include <util/delay.h>
50 bcdesc_t* cmacvs_algo=NULL;
51 bcdesc_t** cmacvs_algolist=NULL;
53 void cmacvs_listalgos(void){
58 cli_putstr("\r\nthe following algorithms are available:\r\n");
59 while(option<='z' && (t=(bcdesc_t*)(cmacvs_algolist[i]))){
61 cli_putc((t==cmacvs_algo)?'*':' ');
70 void cmacvs_setalgo(char* param){
71 param = strstrip(param);
72 if(param[1]=='\0'){ /* single letter specified */
73 uint8_t i,option = param[0]-'a';
76 cli_putstr("\r\nERROR: cmacvs_algolist not set!");
79 for(i=0; i<=option; ++i){
80 if((cmacvs_algolist[i])==NULL){
81 cli_putstr("\r\nERROR: invalid selection!");
85 cmacvs_algo=(bcdesc_t*)(cmacvs_algolist[option]);
86 } else { /* name specifyed */
89 while((t=(bcdesc_t*)(cmacvs_algolist[i])) &&
90 strcasecmp(param, t->name))
95 cli_putstr("\r\nERROR: could not find \"");
104 uint16_t buffersize_B;
111 static cmacvs_ctx_t cmacvs_ctx;
113 uint8_t buffer_add(char c){
115 if(cmacvs_ctx.buffer_idx==cmacvs_ctx.buffersize_B){
116 bcal_cmac_nextBlock(&(cmacvs_ctx.ctx), cmacvs_ctx.buffer);
118 cmacvs_ctx.buffer_idx=0;
119 cmacvs_ctx.in_byte=0;
121 memset(cmacvs_ctx.buffer, 0, cmacvs_ctx.buffersize_B);
123 if(c>='0' && c<='9'){
126 c &= (uint8_t)~('a' ^ 'A');
127 if(c>='A' && c<='F'){
133 t=cmacvs_ctx.buffer[cmacvs_ctx.buffer_idx];
134 if(cmacvs_ctx.in_byte){
136 cmacvs_ctx.buffer[cmacvs_ctx.buffer_idx]=t;
137 cmacvs_ctx.buffer_idx++;
138 cmacvs_ctx.in_byte = 0;
141 cmacvs_ctx.buffer[cmacvs_ctx.buffer_idx]=t;
142 cmacvs_ctx.in_byte = 1;
147 int32_t getValue(char* key){
152 memset(instr, 0, 21);
153 cli_getsn(instr, 20);
154 str2 = strstrip(instr);
155 if(!strncasecmp(str2, key, strlen(key))){
156 while(*str2 && *str2!='=')
161 }while(*str2 && !isdigit(*str2));
162 val=(uint32_t)strtoul(str2, NULL, 10);
166 if(!strncasecmp(str2, "EXIT", 4)){
167 cli_putstr("\r\n got exit ...");
175 uint8_t getKey(void* key_buffer, uint8_t klen_B){
178 memset(key_buffer, 0x00, klen_B);
180 c = cli_getc_cecho();
181 }while((c|('a'^'A'))!='k');
183 c = cli_getc_cecho();
184 }while((c|('a'^'A'))!='e');
186 c = cli_getc_cecho();
187 }while((c|('a'^'A'))!='y');
189 c = cli_getc_cecho();
194 c = cli_getc_cecho();
195 if(c>='0' && c<='9'){
199 if(c>='a' && c<='f'){
207 ((uint8_t*)key_buffer)[i/2] |= v;
215 uint8_t getMac(void* mac_buffer, uint8_t mlen_B){
218 memset(mac_buffer, 0x00, mlen_B);
220 c = cli_getc_cecho();
221 }while((c|('a'^'A'))!='m');
223 c = cli_getc_cecho();
224 }while((c|('a'^'A'))!='a');
226 c = cli_getc_cecho();
227 }while((c|('a'^'A'))!='c');
229 c = cli_getc_cecho();
234 c = cli_getc_cecho();
235 if(c>='0' && c<='9'){
239 if(c>='a' && c<='f'){
247 ((uint8_t*)mac_buffer)[i/2] |= v;
255 void cmacvs_test1(void){ /* Gen tests */
256 int32_t klen, mlen, tlen;
257 int32_t expect_input=0;
260 cli_putstr("\r\nERROR: select algorithm first!");
264 cmacvs_ctx.buffersize_B=(cmacvs_algo->blocksize_b)/8;
265 uint8_t tag[cmacvs_ctx.buffersize_B];
266 uint8_t buffer[cmacvs_ctx.buffersize_B+5];
267 cmacvs_ctx.buffer = buffer;
268 cli_putstr("\r\nbuffer_size = 0x");
269 cli_hexdump_rev(&(cmacvs_ctx.buffersize_B), 2);
270 cli_putstr(" bytes");
272 cmacvs_ctx.blocks = 0;
273 memset(buffer, 0, cmacvs_ctx.buffersize_B);
274 klen = getValue("Klen");
278 mlen = getValue("Mlen");
282 tlen = getValue("Tlen");
286 uint8_t key_buffer[klen];
288 cli_putstr("\r\nKLen == ");
289 cli_hexdump_rev(&klen, 4);
290 cli_putstr("\r\nMLen == ");
291 cli_hexdump_rev(&mlen, 4);
292 cli_putstr("\r\nTLen == ");
293 cli_hexdump_rev(&tlen, 4);
295 getKey(key_buffer, klen);
302 cli_putstr("\r\nexpected_input == ");
303 cli_hexdump_rev(&expect_input, 4);
305 cli_putstr("\r\nexpected_input == 0 !!!");
309 cli_putstr("\r\n CMAC init");
310 cli_putstr("\r\n (2) expected_input == ");
311 cli_hexdump_rev(&expect_input, 4);
313 ret = bcal_cmac_init(cmacvs_algo, key_buffer, klen*8, &(cmacvs_ctx.ctx));
315 cli_putstr("\r\n bcal_cmac_init returned with: ");
316 cli_hexdump(&ret, 1);
320 cli_putstr("\r\n (3) expected_input == ");
321 cli_hexdump_rev(&expect_input, 4);
324 while((c=cli_getc_cecho())!='M' && c!='m'){
326 cli_putstr("\r\nERROR: wrong input (1) [0x");
328 cli_putstr("]!\r\n");
329 bcal_cmac_free(&(cmacvs_ctx.ctx));
333 if((c=cli_getc_cecho())!='s' && c!='S'){
334 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
335 bcal_cmac_free(&(cmacvs_ctx.ctx));
338 if((c=cli_getc_cecho())!='g' && c!='G'){
339 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
340 bcal_cmac_free(&(cmacvs_ctx.ctx));
343 while((c=cli_getc_cecho())!='='){
345 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
346 bcal_cmac_free(&(cmacvs_ctx.ctx));
351 cli_putstr("\r\nparsing started");
353 cmacvs_ctx.buffer_idx = 0;
354 cmacvs_ctx.in_byte = 0;
355 cmacvs_ctx.blocks = 0;
356 while(expect_input>0){
359 cli_putstr("\r\n\t(");
360 cli_hexdump_rev(&expect_input, 4);
364 if(buffer_add(c)==0){
367 if(!isblank((uint16_t)c)){
368 cli_putstr("\r\nERROR: wrong input (5) (");
370 cli_putstr(")!\r\n");
371 bcal_cmac_free(&(cmacvs_ctx.ctx));
377 cli_putstr("\r\nBuffer-A:");
378 cli_hexdump_block(buffer, cmacvs_ctx.buffersize_B, 5, 8);
380 cli_putstr("\r\n starting finalisation");
381 cli_putstr("\r\n\tblocks == ");
382 cli_hexdump_rev(&(cmacvs_ctx.blocks),4);
383 cli_putstr("\r\n\tbuffer_idx == ");
384 cli_hexdump_rev(&(cmacvs_ctx.buffer_idx),2);
385 cli_putstr("\r\n\tin_byte == ");
386 cli_hexdump_rev(&(cmacvs_ctx.in_byte),1);
389 cli_putstr("\r\n starting last block");
390 cli_putstr("\r\n\tlength == ");
391 cli_hexdump_rev(&mlen,4);
392 cli_putstr("\r\n\tbuffersize_B == ");
393 cli_hexdump_rev(&(cmacvs_ctx.buffersize_B),2);
394 uint16_t temp=(mlen-cmacvs_ctx.blocks*cmacvs_ctx.buffersize_B)*8;
395 cli_putstr("\r\n\t (temp) == ");
396 cli_hexdump_rev(&temp,2);
399 uint16_t temp=(mlen-cmacvs_ctx.blocks*cmacvs_ctx.buffersize_B)*8;
400 bcal_cmac_lastBlock( &(cmacvs_ctx.ctx), buffer, /* be aware of freaking compilers!!! */
401 // length-(cmacvs_ctx.blocks)*((cmacvs_ctx.buffersize_B)*8));
404 cli_putstr("\r\n starting ctx2cmac");
407 bcal_cmac_ctx2mac(tag, tlen*8, &(cmacvs_ctx.ctx));
409 cli_putstr("\r\n starting cmac free");
411 bcal_cmac_free(&(cmacvs_ctx.ctx));
412 cli_putstr("\r\n Mac = ");
413 cli_hexdump(tag, tlen);
419 void cmacvs_test2(void){ /* Ver tests */
420 int32_t klen, mlen, tlen;
421 int32_t expect_input=0;
424 cli_putstr("\r\nERROR: select algorithm first!");
428 cmacvs_ctx.buffersize_B=(cmacvs_algo->blocksize_b)/8;
429 uint8_t tag[cmacvs_ctx.buffersize_B];
430 uint8_t tag_ref[cmacvs_ctx.buffersize_B];
431 uint8_t buffer[cmacvs_ctx.buffersize_B+5];
432 cmacvs_ctx.buffer = buffer;
433 cli_putstr("\r\nbuffer_size = 0x");
434 cli_hexdump_rev(&(cmacvs_ctx.buffersize_B), 2);
435 cli_putstr(" bytes");
437 cmacvs_ctx.blocks = 0;
438 memset(buffer, 0, cmacvs_ctx.buffersize_B);
439 klen = getValue("Klen");
443 mlen = getValue("Mlen");
447 tlen = getValue("Tlen");
451 uint8_t key_buffer[klen];
453 cli_putstr("\r\nKLen == ");
454 cli_hexdump_rev(&klen, 4);
455 cli_putstr("\r\nMLen == ");
456 cli_hexdump_rev(&mlen, 4);
457 cli_putstr("\r\nTLen == ");
458 cli_hexdump_rev(&tlen, 4);
460 getKey(key_buffer, klen);
467 cli_putstr("\r\nexpected_input == ");
468 cli_hexdump_rev(&expect_input, 4);
470 cli_putstr("\r\nexpected_input == 0 !!!");
474 cli_putstr("\r\n CMAC init");
475 cli_putstr("\r\n (2) expected_input == ");
476 cli_hexdump_rev(&expect_input, 4);
478 ret = bcal_cmac_init(cmacvs_algo, key_buffer, klen*8, &(cmacvs_ctx.ctx));
480 cli_putstr("\r\n bcal_cmac_init returned with: ");
481 cli_hexdump(&ret, 1);
485 cli_putstr("\r\n (3) expected_input == ");
486 cli_hexdump_rev(&expect_input, 4);
489 while((c=cli_getc_cecho())!='M' && c!='m'){
491 cli_putstr("\r\nERROR: wrong input (1) [0x");
493 cli_putstr("]!\r\n");
494 bcal_cmac_free(&(cmacvs_ctx.ctx));
498 if((c=cli_getc_cecho())!='s' && c!='S'){
499 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
500 bcal_cmac_free(&(cmacvs_ctx.ctx));
503 if((c=cli_getc_cecho())!='g' && c!='G'){
504 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
505 bcal_cmac_free(&(cmacvs_ctx.ctx));
508 while((c=cli_getc_cecho())!='='){
510 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
511 bcal_cmac_free(&(cmacvs_ctx.ctx));
516 cli_putstr("\r\nparsing started");
518 cmacvs_ctx.buffer_idx = 0;
519 cmacvs_ctx.in_byte = 0;
520 cmacvs_ctx.blocks = 0;
521 while(expect_input>0){
524 cli_putstr("\r\n\t(");
525 cli_hexdump_rev(&expect_input, 4);
529 if(buffer_add(c)==0){
532 if(!isblank((uint16_t)c)){
533 cli_putstr("\r\nERROR: wrong input (5) (");
535 cli_putstr(")!\r\n");
536 bcal_cmac_free(&(cmacvs_ctx.ctx));
542 cli_putstr("\r\nBuffer-A:");
543 cli_hexdump_block(buffer, cmacvs_ctx.buffersize_B, 5, 8);
545 cli_putstr("\r\n starting finalisation");
546 cli_putstr("\r\n\tblocks == ");
547 cli_hexdump_rev(&(cmacvs_ctx.blocks),4);
548 cli_putstr("\r\n\tbuffer_idx == ");
549 cli_hexdump_rev(&(cmacvs_ctx.buffer_idx),2);
550 cli_putstr("\r\n\tin_byte == ");
551 cli_hexdump_rev(&(cmacvs_ctx.in_byte),1);
554 cli_putstr("\r\n starting last block");
555 cli_putstr("\r\n\tlength == ");
556 cli_hexdump_rev(&mlen,4);
557 cli_putstr("\r\n\tbuffersize_B == ");
558 cli_hexdump_rev(&(cmacvs_ctx.buffersize_B),2);
559 uint16_t temp=(mlen-cmacvs_ctx.blocks*cmacvs_ctx.buffersize_B)*8;
560 cli_putstr("\r\n\t (temp) == ");
561 cli_hexdump_rev(&temp,2);
564 uint16_t temp=(mlen-cmacvs_ctx.blocks*cmacvs_ctx.buffersize_B)*8;
565 bcal_cmac_lastBlock( &(cmacvs_ctx.ctx), buffer, /* be aware of freaking compilers!!! */
566 // length-(cmacvs_ctx.blocks)*((cmacvs_ctx.buffersize_B)*8));
569 cli_putstr("\r\n starting ctx2cmac");
572 bcal_cmac_ctx2mac(tag, tlen*8, &(cmacvs_ctx.ctx));
574 cli_putstr("\r\n starting cmac free");
576 bcal_cmac_free(&(cmacvs_ctx.ctx));
577 cli_putstr("\r\n Mac = ");
578 cli_hexdump(tag, tlen);
579 getMac(tag_ref, tlen);
580 if(memcmp(tag, tag_ref, tlen)){
581 cli_putstr("\r\n Result = F");
583 cli_putstr("\r\n Result = P");