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