]> git.cryptolib.org Git - arm-crypto-lib.git/blob - test_src/shavs.c
works with three tests; contains a lot debug foo
[arm-crypto-lib.git] / test_src / shavs.c
1 /* shavs.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        shavs.c
21  * \author  Daniel Otte
22  * \date    2006-05-16
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 "hashfunction_descriptor.h"
32 #include "hfal-basic.h"
33 #include "shavs.h"
34 #include "string-extras.h"
35 #include "cli.h"
36
37
38 #ifdef DEBUG
39 #  undef DEBUG
40 #endif
41
42 #define DEBUG 0
43
44 #if DEBUG
45 #include "uart_lowlevel.h"
46 //#  include "config.h"
47 //#  include <util/delay.h>
48 #endif
49
50 hfdesc_t*  shavs_algo=NULL;
51 hfdesc_t** shavs_algolist=NULL;
52
53 void shavs_listalgos(void){
54         char option = 'a';
55
56         hfdesc_t* t;
57         uint8_t i=0;
58         cli_putstr("\r\nthe following algorithms are available:\r\n");
59         while(option<='z' && (t=shavs_algolist[i])){
60                 cli_putc('\t');
61                 cli_putc((t==shavs_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 shavs_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(!shavs_algolist){
76                         cli_putstr("\r\nERROR: shavs_algolist not set!");
77                         return;
78                 }
79                 for(i=0; i<=option; ++i){
80                         if((shavs_algolist[i])==NULL){
81                                 cli_putstr("\r\nERROR: invalid selection!");
82                                 return;
83                         }
84                 }
85                 shavs_algo=(hfdesc_t*)(shavs_algolist[option]);
86         } else { /* name specified */
87                 hfdesc_t* t=NULL;
88                 uint8_t i=0;
89                 while((t=shavs_algolist[i]) && strcasecmp(param, t->name)){
90                         ++i;
91                 }
92                 if(t){
93                         shavs_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         hfgen_ctx_t ctx;
107         uint8_t* buffer;
108         uint8_t  in_byte;
109 } shavs_ctx_t;
110
111 static shavs_ctx_t shavs_ctx;
112
113 static
114 uint8_t buffer_add(char c){
115         uint8_t v,t;
116         if(shavs_ctx.buffer_idx==shavs_ctx.buffersize_B){
117                 hfal_hash_nextBlock(&(shavs_ctx.ctx), shavs_ctx.buffer);
118                 ++shavs_ctx.blocks;
119                 shavs_ctx.buffer_idx=0;
120                 shavs_ctx.in_byte=0;
121                 cli_putc('.');
122                 memset(shavs_ctx.buffer, 0, shavs_ctx.buffersize_B);
123         }
124         if(c>='0' && c<='9'){
125                 v=c-'0';
126         }else{
127                 c &= (uint8_t)~('a' ^ 'A');
128                 if(c>='A' && c<='F'){
129                         v=c-'A'+10;
130                 }else{
131                         return 1;
132                 }
133         }
134         t=shavs_ctx.buffer[shavs_ctx.buffer_idx];
135         if(shavs_ctx.in_byte){
136                 t |= v;
137                 shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
138                 shavs_ctx.buffer_idx++;
139                 shavs_ctx.in_byte = 0;
140         }else{
141                 t |= v<<4;
142                 shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
143                 shavs_ctx.in_byte = 1;
144         }
145         return 0;
146 }
147
148 static
149 uint32_t my_strtoul(const char* str){
150         uint32_t r=0;
151         while(*str && (*str<'0' || *str>'9')){
152                 str++;
153         }
154         if(!*str){
155                 return 0;
156         }
157         while(*str && (*str>='0' && *str<='9')){
158                 r *= 10;
159                 r += *str-'0';
160                 str++;
161         }
162         return r;
163 }
164
165 int32_t getLength(void){
166         uint32_t len=0;
167         char lenstr[25];
168         char* len2;
169         for(;;){
170                 memset(lenstr, 0, 21);
171                 cli_getsn(lenstr, 20);
172                 len2 = strstrip(lenstr);
173                 if(!strncasecmp(len2, "LEN", 3)){
174                         while(*len2 && *len2!='=')
175                                 len2++;
176                         if(*len2=='='){
177                                 do{
178                                         len2++;
179                                 }while(*len2 && !isdigit((uint8_t)*len2));
180                                 len = my_strtoul(len2);
181                                 //len=(uint32_t)strtoul(len2, NULL, 10);
182                                 return len;
183                         }
184                 } else {
185                         if(!strncasecmp(len2, "EXIT", 4)){
186                                 return -1;
187                         }
188                 }
189         }
190 }
191
192 void shavs_test1(void){ /* KAT tests */
193         uint32_t length=0;
194         int32_t expect_input=0;
195
196         if(!shavs_algo){
197                         cli_putstr("\r\nERROR: select algorithm first!");
198                 return;
199         }
200         char c;
201         uint8_t diggest[shavs_algo->hashsize_b/8];
202         shavs_ctx.buffersize_B=shavs_algo->blocksize_b/8;
203         uint8_t buffer[shavs_ctx.buffersize_B+5];
204         shavs_ctx.buffer = buffer;
205         cli_putstr("\r\nbuffer_size = 0x");
206         cli_hexdump_rev(&(shavs_ctx.buffersize_B), 2);
207         cli_putstr(" bytes");
208         for(;;){
209                 shavs_ctx.blocks = 0;
210                 memset(buffer, 0, shavs_ctx.buffersize_B);
211                 length = getLength();
212                 if((int32_t)length<0){
213 #if DEBUG
214                         cli_putstr("\r\n(x) Len == ");
215                         cli_hexdump_rev(&length, 4);
216                         uart_flush(0);
217 #endif
218                         return;
219                 }
220
221 #if DEBUG
222                 cli_putstr("\r\nLen == ");
223                 cli_hexdump_rev(&length, 4);
224                 uart_flush(0);
225 #endif
226                 if(length==0){
227                         expect_input=2;
228                 }else{
229                         expect_input=((length+7)>>2)&(~1L);
230                 }
231 #if DEBUG
232                 cli_putstr("\r\nexpected_input == ");
233                 cli_hexdump_rev(&expect_input, 4);
234                 if(expect_input==0)
235                         cli_putstr("\r\nexpected_input == 0 !!!");
236 #endif
237                 shavs_ctx.buffer_idx = 0;
238                 shavs_ctx.in_byte    = 0;
239                 shavs_ctx.blocks     = 0;
240                 uint8_t ret;
241 #if DEBUG
242                 cli_putstr("\r\n HFAL init");
243                 cli_putstr("\r\n (2) expected_input == ");
244                 cli_hexdump_rev(&expect_input, 4);
245 #endif
246                 ret = hfal_hash_init(shavs_algo, &(shavs_ctx.ctx));
247                 if(ret){
248                         cli_putstr("\r\n HFAL init returned with: ");
249                         cli_hexdump(&ret, 1);
250                         return;
251                 }
252 #if DEBUG
253                 cli_putstr("\r\n (3) expected_input == ");
254                 cli_hexdump_rev(&expect_input, 4);
255                 cli_putstr("\r\n");
256 #endif
257                 while((c=cli_getc_cecho())!='M' && c!='m'){
258                         if(!isblank((uint8_t)c)){
259                                 cli_putstr("\r\nERROR: wrong input (1) [0x");
260                                 cli_hexdump(&c, 1);
261                                 cli_putstr("]!\r\n");
262                                 hfal_hash_free(&(shavs_ctx.ctx));
263                                 return;
264                         }
265                 }
266                 if((c=cli_getc_cecho())!='s' && c!='S'){
267                                 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
268                                 hfal_hash_free(&(shavs_ctx.ctx));
269                                 return;
270                 }
271                 if((c=cli_getc_cecho())!='g' && c!='G'){
272                                 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
273                                 hfal_hash_free(&(shavs_ctx.ctx));
274                                 return;
275                 }
276                 while((c=cli_getc_cecho())!='='){
277                         if(!isblank((uint8_t)c)){
278                                 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
279                                 hfal_hash_free(&(shavs_ctx.ctx));
280                                 return;
281                         }
282                 }
283 #if DEBUG
284                 cli_putstr("\r\nparsing started");
285 #endif
286                 shavs_ctx.buffer_idx = 0;
287                 shavs_ctx.in_byte    = 0;
288                 shavs_ctx.blocks     = 0;
289                 while(expect_input>0){
290                         c=cli_getc_cecho();
291 #if DEBUG
292                         cli_putstr("\r\n\t(");
293                         cli_hexdump_rev(&expect_input, 4);
294                         cli_putstr(") ");
295 #endif
296                         if(buffer_add(c)==0){
297                                 --expect_input;
298                         }else{
299                                 if(!isblank((uint16_t)c)){
300                                         cli_putstr("\r\nERROR: wrong input (5) (");
301                                         cli_putc(c);
302                                         cli_putstr(")!\r\n");
303                                         hfal_hash_free(&(shavs_ctx.ctx));
304                                         return;
305                                 }
306                         }
307                 }
308 #if DEBUG
309                 cli_putstr("\r\nBuffer-A:");
310                 cli_hexdump_block(buffer, shavs_ctx.buffersize_B, 5, 8);
311
312                 cli_putstr("\r\n starting finalisation");
313                 cli_putstr("\r\n\tblocks     == ");
314                 cli_hexdump_rev(&(shavs_ctx.blocks),4);
315                 cli_putstr("\r\n\tbuffer_idx == ");
316                 cli_hexdump_rev(&(shavs_ctx.buffer_idx),2);
317                 cli_putstr("\r\n\tin_byte    == ");
318                 cli_hexdump_rev(&(shavs_ctx.in_byte),1);
319
320                 cli_putstr("\r\n starting last block");
321                 cli_putstr("\r\n\tlength       == ");
322                 cli_hexdump_rev(&length,4);
323                 cli_putstr("\r\n\tbuffersize_B == ");
324                 cli_hexdump_rev(&(shavs_ctx.buffersize_B),2);
325                 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
326                 cli_putstr("\r\n\t (temp)      == ");
327                 cli_hexdump_rev(&temp,2);
328                 temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
329 #else
330                 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
331 #endif
332                 /*              cli_putstr("\r\n\t (temp)      == ");
333                 cli_hexdump_rev(&temp,2); */
334                 hfal_hash_lastBlock( &(shavs_ctx.ctx), buffer, /* be aware of freaking compilers!!! */
335 //                                                      length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8));
336                                     temp );
337 #if DEBUG
338                 cli_putstr("\r\n starting ctx2hash");
339 #endif
340                 hfal_hash_ctx2hash(diggest, &(shavs_ctx.ctx));
341 #if DEBUG
342                 cli_putstr("\r\n starting hash free");
343 #endif
344                 hfal_hash_free(&(shavs_ctx.ctx));
345                 cli_putstr("\r\n MD = ");
346                 cli_hexdump(diggest, shavs_algo->hashsize_b/8);
347
348         }
349 }
350
351 void shavs_test2(void){ /* Monte Carlo tests for SHA-1 & SHA-2 */
352         uint16_t expected_input;
353         uint16_t count;
354         uint8_t v;
355         uint8_t index=0;
356         char c;
357         if(!shavs_algo){
358                         cli_putstr("\r\nERROR: select algorithm first!");
359                 return;
360         }
361         uint8_t ml=shavs_algo->hashsize_b/8;
362         uint8_t m[ml*4+8];
363         for(;;){
364                 while((c=cli_getc_cecho())!='S' && c!='s'){
365                         if(!isblank((uint8_t)c)){
366                                 cli_putstr("\r\nERROR: wrong input (1) [0x");
367                                 cli_hexdump(&c, 1);
368                                 cli_putstr("]!\r\n");
369                                 return;
370                         }
371                 }
372                 if((c=cli_getc_cecho())!='e' && c!='E'){
373                                 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
374                                 return;
375                 }
376                 if((c=cli_getc_cecho())!='e' && c!='E'){
377                                 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
378                                 return;
379                 }
380                 if((c=cli_getc_cecho())!='d' && c!='D'){
381                                 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
382                                 return;
383                 }
384                 while((c=cli_getc_cecho())!='='){
385                         if(!isblank((uint8_t)c)){
386                                 cli_putstr("\r\nERROR: wrong input (5)!\r\n");
387                                 return;
388                         }
389                 }
390                 expected_input = ml*2;
391                 memset(m+2*ml, 0, ml);
392                 do{
393                         v=0xff;
394                         c=cli_getc_cecho();
395                         if(c>='0' && c<='9'){
396                                 v = c - '0';
397                         }else{
398                                 c |= 'A'^'a';
399                                 if(c>='a' && c<='f'){
400                                         v = c - 'a' +10;
401                                 }
402                         }
403                         if(v<0x10){
404                                 c=m[ml*2+index/2];
405                                 if(index&1){
406                                         c |= v;
407                                 }else{
408                                         c |=v<<4;
409                                 }
410                                 m[ml*2+index/2]=c;
411                                 index++;
412                                 expected_input--;
413                         }
414                 }while(expected_input);
415                 /* so we have the seed */
416                 cli_putstr("\r\nstarting processing");
417                 uint16_t j;
418                 for(count=0; count<100; ++count){
419                         memcpy(m, m+ml*2, ml);
420                         memcpy(m+ml, m+ml*2, ml);
421                         for(j=0; j<1000; ++j){
422                                 hfal_hash_mem(shavs_algo, m+ml*3, m, ml*3*8);
423                                 memmove(m, m+ml, 3*ml);
424                         }
425                         cli_putstr("\r\n\r\nCOUNT = ");
426                         if(count>=10){
427                                 cli_putc(count/10+'0');
428                         }
429                         cli_putc(count%10+'0');
430                         cli_putstr("\r\nMD = ");
431                         cli_hexdump(m+ml*2, ml);
432                 }
433         }
434 }
435
436 void shavs_test3(void){ /* Monte Carlo tests for SHA-3 */
437         uint16_t expected_input;
438         uint16_t count;
439         uint8_t v;
440         uint8_t index=0;
441         char c;
442         if(!shavs_algo){
443                         cli_putstr("\r\nERROR: select algorithm first!");
444                 return;
445         }
446         uint8_t ml=shavs_algo->hashsize_b/8;
447         uint8_t m[ml+128];
448         for(;;){
449                 while((c=cli_getc_cecho())!='S' && c!='s'){
450                         if(!isblank((uint8_t)c)){
451                                 cli_putstr("\r\nERROR: wrong input (1) [0x");
452                                 cli_hexdump(&c, 1);
453                                 cli_putstr("]!\r\n");
454                                 return;
455                         }
456                 }
457                 if((c=cli_getc_cecho())!='e' && c!='E'){
458                                 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
459                                 return;
460                 }
461                 if((c=cli_getc_cecho())!='e' && c!='E'){
462                                 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
463                                 return;
464                 }
465                 if((c=cli_getc_cecho())!='d' && c!='D'){
466                                 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
467                                 return;
468                 }
469                 while((c=cli_getc_cecho())!='='){
470                         if(!isblank((uint8_t)c)){
471                                 cli_putstr("\r\nERROR: wrong input (5)!\r\n");
472                                 return;
473                         }
474                 }
475                 expected_input = 1024/4;
476                 memset(m+ml, 0, 1024/8);
477                 do{
478                         v=0xff;
479                         c=cli_getc_cecho();
480                         if(c>='0' && c<='9'){
481                                 v = c - '0';
482                         }else{
483                                 c |= 'A'^'a';
484                                 if(c>='a' && c<='f'){
485                                         v = c - 'a' +10;
486                                 }
487                         }
488                         if(v<0x10){
489                                 c=m[ml+index/2];
490                                 if(index&1){
491                                         c |= v;
492                                 }else{
493                                         c |=v<<4;
494                                 }
495                                 m[ml+index/2]=c;
496                                 index++;
497                                 expected_input--;
498                         }
499                 }while(expected_input);
500                 /* so we have the seed */
501                 cli_putstr("\r\nstarting processing");
502                 uint16_t j;
503                 for(count=0; count<100; ++count){
504                         for(j=0; j<1000; ++j){
505                                 hfal_hash_mem(shavs_algo, m, m+ml, 1024);
506                                 memmove(m+ml, m, 1024/8);
507                         }
508                         cli_putstr("\r\n\r\nj = ");
509                         if(count>=10){
510                                 cli_putc(count/10+'0');
511                         }
512                         cli_putc(count%10+'0');
513                         cli_putstr("\r\nMD = ");
514                         cli_hexdump(m+ml, ml);
515
516                 }
517         }
518 }