]> git.cryptolib.org Git - arm-crypto-lib.git/blob - test_src/cmacvs.c
Adding Present
[arm-crypto-lib.git] / test_src / cmacvs.c
1 /* cmacvs.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  * \file        cmacvs.c
21  * \author  Daniel Otte
22  * \date    2010-02-02
23  * \license     GPLv3 or later
24  *
25  */
26
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include "blockcipher_descriptor.h"
32 #include "bcal-basic.h"
33 #include "bcal-cmac.h"
34 #include "cmacvs.h"
35 #include "string-extras.h"
36 #include "cli.h"
37
38
39 #ifdef DEBUG
40 #  undef DEBUG
41 #endif
42
43 #define DEBUG 0
44
45 #if DEBUG
46 #  include "config.h"
47 #  include <util/delay.h>
48 #endif
49
50 bcdesc_t*  cmacvs_algo=NULL;
51 bcdesc_t** cmacvs_algolist=NULL;
52
53 void cmacvs_listalgos(void){
54         char option = 'a';
55
56         bcdesc_t* t;
57         uint8_t i=0;
58         cli_putstr("\r\nthe following algorithms are available:\r\n");
59         while(option<='z' && (t=(bcdesc_t*)(cmacvs_algolist[i]))){
60                 cli_putc('\t');
61                 cli_putc((t==cmacvs_algo)?'*':' ');
62                 cli_putc(option++);
63                 cli_putstr(":\t");
64                 cli_putstr(t->name);
65                 cli_putstr("\r\n");
66                 i++;
67         }
68 }
69
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';
74
75                 if(!cmacvs_algolist){
76                         cli_putstr("\r\nERROR: cmacvs_algolist not set!");
77                         return;
78                 }
79                 for(i=0; i<=option; ++i){
80                         if((cmacvs_algolist[i])==NULL){
81                                 cli_putstr("\r\nERROR: invalid selection!");
82                                 return;
83                         }
84                 }
85                 cmacvs_algo=(bcdesc_t*)(cmacvs_algolist[option]);
86         } else { /* name specifyed */
87                 bcdesc_t* t=NULL;
88                 uint8_t i=0;
89                 while((t=(bcdesc_t*)(cmacvs_algolist[i])) &&
90                        strcasecmp(param, t->name))
91                         ++i;
92                 if(t){
93                         cmacvs_algo=t;
94                 }else{
95                         cli_putstr("\r\nERROR: could not find \"");
96                         cli_putstr(param);
97                         cli_putstr("\"!");
98                 }
99         }
100 }
101
102 typedef struct {
103         uint16_t buffer_idx;
104         uint16_t buffersize_B;
105         uint32_t blocks;
106         bcal_cmac_ctx_t ctx;
107         uint8_t* buffer;
108         uint8_t  in_byte;
109 } cmacvs_ctx_t;
110
111 static cmacvs_ctx_t cmacvs_ctx;
112
113 uint8_t buffer_add(char c){
114         uint8_t v,t;
115         if(cmacvs_ctx.buffer_idx==cmacvs_ctx.buffersize_B){
116                 bcal_cmac_nextBlock(&(cmacvs_ctx.ctx), cmacvs_ctx.buffer);
117                 ++cmacvs_ctx.blocks;
118                 cmacvs_ctx.buffer_idx=0;
119                 cmacvs_ctx.in_byte=0;
120                 cli_putc('.');
121                 memset(cmacvs_ctx.buffer, 0, cmacvs_ctx.buffersize_B);
122         }
123         if(c>='0' && c<='9'){
124                 v=c-'0';
125         }else{
126                 c &= (uint8_t)~('a' ^ 'A');
127                 if(c>='A' && c<='F'){
128                         v=c-'A'+10;
129                 }else{
130                         return 1;
131                 }
132         }
133         t=cmacvs_ctx.buffer[cmacvs_ctx.buffer_idx];
134         if(cmacvs_ctx.in_byte){
135                 t |= v;
136                 cmacvs_ctx.buffer[cmacvs_ctx.buffer_idx]=t;
137                 cmacvs_ctx.buffer_idx++;
138                 cmacvs_ctx.in_byte = 0;
139         }else{
140                 t |= v<<4;
141                 cmacvs_ctx.buffer[cmacvs_ctx.buffer_idx]=t;
142                 cmacvs_ctx.in_byte = 1;
143         }
144         return 0;
145 }
146
147 int32_t getValue(char* key){
148         uint32_t val=0;
149         char instr[21];
150         char* str2;
151         for(;;){
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!='=')
157                                 str2++;
158                         if(*str2=='='){
159                                 do{
160                                         str2++;
161                                 }while(*str2 && !isdigit(*str2));
162                                 val=(uint32_t)strtoul(str2, NULL, 10);
163                                 return val;
164                         }
165                 } else {
166                         if(!strncasecmp(str2, "EXIT", 4)){
167                                 cli_putstr("\r\n got exit ...");
168                                 return -1;
169                         }
170                 }
171         }
172         return -2;
173 }
174
175 uint8_t getKey(void* key_buffer, uint8_t klen_B){
176         char c;
177         uint8_t v,i=0;
178         memset(key_buffer, 0x00, klen_B);
179         do{
180                 c = cli_getc_cecho();
181         }while((c|('a'^'A'))!='k');
182         do{
183                 c = cli_getc_cecho();
184         }while((c|('a'^'A'))!='e');
185         do{
186                 c = cli_getc_cecho();
187         }while((c|('a'^'A'))!='y');
188         do{
189                 c = cli_getc_cecho();
190         }while(c!='=');
191         klen_B *= 2;
192         while(klen_B){
193                 v = 0x10;
194                 c = cli_getc_cecho();
195                 if(c>='0' && c<='9'){
196                         v = c-'0';
197                 }else{
198                         c |= 'A'^'a';
199                         if(c>='a' && c<='f'){
200                                 v= c-'a'+10;
201                         }
202                 }
203                 if(v<0x10){
204                         if((i&1)==0){
205                                 v<<=4;
206                         }
207                         ((uint8_t*)key_buffer)[i/2] |= v;
208                         ++i;
209                         --klen_B;
210                 }
211         }
212         return 0;
213 }
214
215 uint8_t getMac(void* mac_buffer, uint8_t mlen_B){
216         char c;
217         uint8_t v,i=0;
218         memset(mac_buffer, 0x00, mlen_B);
219         do{
220                 c = cli_getc_cecho();
221         }while((c|('a'^'A'))!='m');
222         do{
223                 c = cli_getc_cecho();
224         }while((c|('a'^'A'))!='a');
225         do{
226                 c = cli_getc_cecho();
227         }while((c|('a'^'A'))!='c');
228         do{
229                 c = cli_getc_cecho();
230         }while(c!='=');
231         mlen_B *= 2;
232         while(mlen_B){
233                 v = 0x10;
234                 c = cli_getc_cecho();
235                 if(c>='0' && c<='9'){
236                         v = c-'0';
237                 }else{
238                         c |= 'A'^'a';
239                         if(c>='a' && c<='f'){
240                                 v= c-'a'+10;
241                         }
242                 }
243                 if(v<0x10){
244                         if((i&1)==0){
245                                 v<<=4;
246                         }
247                         ((uint8_t*)mac_buffer)[i/2] |= v;
248                         ++i;
249                         --mlen_B;
250                 }
251         }
252         return 0;
253 }
254
255 void cmacvs_test1(void){ /* Gen tests */
256         int32_t klen, mlen, tlen;
257         int32_t expect_input=0;
258
259         if(!cmacvs_algo){
260                         cli_putstr("\r\nERROR: select algorithm first!");
261                 return;
262         }
263         char c;
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");
271         for(;;){
272                 cmacvs_ctx.blocks = 0;
273                 memset(buffer, 0, cmacvs_ctx.buffersize_B);
274                 klen = getValue("Klen");
275                 if(klen<0){
276                         return;
277                 }
278                 mlen = getValue("Mlen");
279                 if(mlen<0){
280                         return;
281                 }
282                 tlen = getValue("Tlen");
283                 if(tlen<0){
284                         return;
285                 }
286                 uint8_t key_buffer[klen];
287 #if DEBUG
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);
294 #endif
295                 getKey(key_buffer, klen);
296                 if(mlen==0){
297                         expect_input=2;
298                 }else{
299                         expect_input=mlen*2;
300                 }
301 #if DEBUG
302                 cli_putstr("\r\nexpected_input == ");
303                 cli_hexdump_rev(&expect_input, 4);
304                 if(expect_input==0)
305                         cli_putstr("\r\nexpected_input == 0 !!!");
306 #endif
307                 uint8_t ret;
308 #if DEBUG
309                 cli_putstr("\r\n CMAC init");
310                 cli_putstr("\r\n (2) expected_input == ");
311                 cli_hexdump_rev(&expect_input, 4);
312 #endif
313                 ret = bcal_cmac_init(cmacvs_algo, key_buffer, klen*8, &(cmacvs_ctx.ctx));
314                 if(ret){
315                         cli_putstr("\r\n bcal_cmac_init returned with: ");
316                         cli_hexdump(&ret, 1);
317                         return;
318                 }
319 #if DEBUG
320                 cli_putstr("\r\n (3) expected_input == ");
321                 cli_hexdump_rev(&expect_input, 4);
322                 cli_putstr("\r\n");
323 #endif
324                 while((c=cli_getc_cecho())!='M' && c!='m'){
325                         if(!isspace(c)){
326                                 cli_putstr("\r\nERROR: wrong input (1) [0x");
327                                 cli_hexdump(&c, 1);
328                                 cli_putstr("]!\r\n");
329                                 bcal_cmac_free(&(cmacvs_ctx.ctx));
330                                 return;
331                         }
332                 }
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));
336                                 return;
337                 }
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));
341                                 return;
342                 }
343                 while((c=cli_getc_cecho())!='='){
344                         if(!isspace(c)){
345                                 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
346                                 bcal_cmac_free(&(cmacvs_ctx.ctx));
347                                 return;
348                         }
349                 }
350 #if DEBUG
351                 cli_putstr("\r\nparsing started");
352 #endif
353                 cmacvs_ctx.buffer_idx = 0;
354                 cmacvs_ctx.in_byte    = 0;
355                 cmacvs_ctx.blocks     = 0;
356                 while(expect_input>0){
357                         c=cli_getc_cecho();
358 #if DEBUG
359                         cli_putstr("\r\n\t(");
360                         cli_hexdump_rev(&expect_input, 4);
361                         cli_putstr(") ");
362                         _delay_ms(500);
363 #endif
364                         if(buffer_add(c)==0){
365                                 --expect_input;
366                         }else{
367                                 if(!isblank((uint16_t)c)){
368                                         cli_putstr("\r\nERROR: wrong input (5) (");
369                                         cli_putc(c);
370                                         cli_putstr(")!\r\n");
371                                         bcal_cmac_free(&(cmacvs_ctx.ctx));
372                                         return;
373                                 }
374                         }
375                 }
376 #if DEBUG
377                 cli_putstr("\r\nBuffer-A:");
378                 cli_hexdump_block(buffer, cmacvs_ctx.buffersize_B, 5, 8);
379
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);
387 //              _delay_ms(500);
388
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);
397 //              _delay_ms(500);
398 #endif
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));
402                                     temp );
403 #if DEBUG
404                 cli_putstr("\r\n starting ctx2cmac");
405                 _delay_ms(500);
406 #endif
407                 bcal_cmac_ctx2mac(tag, tlen*8, &(cmacvs_ctx.ctx));
408 #if DEBUG
409                 cli_putstr("\r\n starting cmac free");
410 #endif
411                 bcal_cmac_free(&(cmacvs_ctx.ctx));
412                 cli_putstr("\r\n Mac = ");
413                 cli_hexdump(tag, tlen);
414
415         }
416 }
417
418
419 void cmacvs_test2(void){ /* Ver tests */
420         int32_t klen, mlen, tlen;
421         int32_t expect_input=0;
422
423         if(!cmacvs_algo){
424                         cli_putstr("\r\nERROR: select algorithm first!");
425                 return;
426         }
427         char c;
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");
436         for(;;){
437                 cmacvs_ctx.blocks = 0;
438                 memset(buffer, 0, cmacvs_ctx.buffersize_B);
439                 klen = getValue("Klen");
440                 if(klen<0){
441                         return;
442                 }
443                 mlen = getValue("Mlen");
444                 if(mlen<0){
445                         return;
446                 }
447                 tlen = getValue("Tlen");
448                 if(tlen<0){
449                         return;
450                 }
451                 uint8_t key_buffer[klen];
452 #if DEBUG
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);
459 #endif
460                 getKey(key_buffer, klen);
461                 if(mlen==0){
462                         expect_input=2;
463                 }else{
464                         expect_input=mlen*2;
465                 }
466 #if DEBUG
467                 cli_putstr("\r\nexpected_input == ");
468                 cli_hexdump_rev(&expect_input, 4);
469                 if(expect_input==0)
470                         cli_putstr("\r\nexpected_input == 0 !!!");
471 #endif
472                 uint8_t ret;
473 #if DEBUG
474                 cli_putstr("\r\n CMAC init");
475                 cli_putstr("\r\n (2) expected_input == ");
476                 cli_hexdump_rev(&expect_input, 4);
477 #endif
478                 ret = bcal_cmac_init(cmacvs_algo, key_buffer, klen*8, &(cmacvs_ctx.ctx));
479                 if(ret){
480                         cli_putstr("\r\n bcal_cmac_init returned with: ");
481                         cli_hexdump(&ret, 1);
482                         return;
483                 }
484 #if DEBUG
485                 cli_putstr("\r\n (3) expected_input == ");
486                 cli_hexdump_rev(&expect_input, 4);
487                 cli_putstr("\r\n");
488 #endif
489                 while((c=cli_getc_cecho())!='M' && c!='m'){
490                         if(!isspace(c)){
491                                 cli_putstr("\r\nERROR: wrong input (1) [0x");
492                                 cli_hexdump(&c, 1);
493                                 cli_putstr("]!\r\n");
494                                 bcal_cmac_free(&(cmacvs_ctx.ctx));
495                                 return;
496                         }
497                 }
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));
501                                 return;
502                 }
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));
506                                 return;
507                 }
508                 while((c=cli_getc_cecho())!='='){
509                         if(!isspace(c)){
510                                 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
511                                 bcal_cmac_free(&(cmacvs_ctx.ctx));
512                                 return;
513                         }
514                 }
515 #if DEBUG
516                 cli_putstr("\r\nparsing started");
517 #endif
518                 cmacvs_ctx.buffer_idx = 0;
519                 cmacvs_ctx.in_byte    = 0;
520                 cmacvs_ctx.blocks     = 0;
521                 while(expect_input>0){
522                         c=cli_getc_cecho();
523 #if DEBUG
524                         cli_putstr("\r\n\t(");
525                         cli_hexdump_rev(&expect_input, 4);
526                         cli_putstr(") ");
527                         _delay_ms(500);
528 #endif
529                         if(buffer_add(c)==0){
530                                 --expect_input;
531                         }else{
532                                 if(!isblank((uint16_t)c)){
533                                         cli_putstr("\r\nERROR: wrong input (5) (");
534                                         cli_putc(c);
535                                         cli_putstr(")!\r\n");
536                                         bcal_cmac_free(&(cmacvs_ctx.ctx));
537                                         return;
538                                 }
539                         }
540                 }
541 #if DEBUG
542                 cli_putstr("\r\nBuffer-A:");
543                 cli_hexdump_block(buffer, cmacvs_ctx.buffersize_B, 5, 8);
544
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);
552 //              _delay_ms(500);
553
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);
562 //              _delay_ms(500);
563 #endif
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));
567                                     temp );
568 #if DEBUG
569                 cli_putstr("\r\n starting ctx2cmac");
570                 _delay_ms(500);
571 #endif
572                 bcal_cmac_ctx2mac(tag, tlen*8, &(cmacvs_ctx.ctx));
573 #if DEBUG
574                 cli_putstr("\r\n starting cmac free");
575 #endif
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");
582                 }else{
583                         cli_putstr("\r\n Result = P");
584                 }
585         }
586 }