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 "hashfunction_descriptor.h"
32 #include "hfal-basic.h"
34 #include "string-extras.h"
45 #include "uart_lowlevel.h"
46 //# include "config.h"
47 //# include <util/delay.h>
50 hfdesc_t* shavs_algo=NULL;
51 hfdesc_t** shavs_algolist=NULL;
53 void shavs_listalgos(void){
58 cli_putstr("\r\nthe following algorithms are available:\r\n");
59 while(option<='z' && (t=shavs_algolist[i])){
61 cli_putc((t==shavs_algo)?'*':' ');
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';
76 cli_putstr("\r\nERROR: shavs_algolist not set!");
79 for(i=0; i<=option; ++i){
80 if((shavs_algolist[i])==NULL){
81 cli_putstr("\r\nERROR: invalid selection!");
85 shavs_algo=(hfdesc_t*)(shavs_algolist[option]);
86 } else { /* name specified */
89 while((t=shavs_algolist[i]) && strcasecmp(param, t->name)){
95 cli_putstr("\r\nERROR: could not find \"");
104 uint16_t buffersize_B;
111 static shavs_ctx_t shavs_ctx;
113 uint8_t buffer_add(char c){
115 if(shavs_ctx.buffer_idx==shavs_ctx.buffersize_B){
116 hfal_hash_nextBlock(&(shavs_ctx.ctx), shavs_ctx.buffer);
118 shavs_ctx.buffer_idx=0;
121 memset(shavs_ctx.buffer, 0, shavs_ctx.buffersize_B);
123 if(c>='0' && c<='9'){
126 c &= (uint8_t)~('a' ^ 'A');
127 if(c>='A' && c<='F'){
133 t=shavs_ctx.buffer[shavs_ctx.buffer_idx];
134 if(shavs_ctx.in_byte){
136 shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
137 shavs_ctx.buffer_idx++;
138 shavs_ctx.in_byte = 0;
141 shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
142 shavs_ctx.in_byte = 1;
148 uint32_t my_strtoul(const char* str){
150 while(*str && (*str<'0' || *str>'9')){
156 while(*str && (*str>='0' && *str<='9')){
164 int32_t getLength(void){
169 memset(lenstr, 0, 21);
170 cli_getsn(lenstr, 20);
171 len2 = strstrip(lenstr);
172 if(!strncasecmp(len2, "LEN", 3)){
173 while(*len2 && *len2!='=')
178 }while(*len2 && !isdigit((uint8_t)*len2));
179 len = my_strtoul(len2);
180 //len=(uint32_t)strtoul(len2, NULL, 10);
184 if(!strncasecmp(len2, "EXIT", 4)){
191 void shavs_test1(void){ /* KAT tests */
193 int32_t expect_input=0;
196 cli_putstr("\r\nERROR: select algorithm first!");
200 uint8_t diggest[shavs_algo->hashsize_b/8];
201 shavs_ctx.buffersize_B=shavs_algo->blocksize_b/8;
202 uint8_t buffer[shavs_ctx.buffersize_B+5];
203 shavs_ctx.buffer = buffer;
204 cli_putstr("\r\nbuffer_size = 0x");
205 cli_hexdump_rev(&(shavs_ctx.buffersize_B), 2);
206 cli_putstr(" bytes");
208 shavs_ctx.blocks = 0;
209 memset(buffer, 0, shavs_ctx.buffersize_B);
210 length = getLength();
211 if((int32_t)length<0){
213 cli_putstr("\r\n(x) Len == ");
214 cli_hexdump_rev(&length, 4);
221 cli_putstr("\r\nLen == ");
222 cli_hexdump_rev(&length, 4);
228 expect_input=((length+7)>>2)&(~1L);
231 cli_putstr("\r\nexpected_input == ");
232 cli_hexdump_rev(&expect_input, 4);
234 cli_putstr("\r\nexpected_input == 0 !!!");
236 shavs_ctx.buffer_idx = 0;
237 shavs_ctx.in_byte = 0;
238 shavs_ctx.blocks = 0;
241 cli_putstr("\r\n HFAL init");
242 cli_putstr("\r\n (2) expected_input == ");
243 cli_hexdump_rev(&expect_input, 4);
245 ret = hfal_hash_init(shavs_algo, &(shavs_ctx.ctx));
247 cli_putstr("\r\n HFAL init returned with: ");
248 cli_hexdump(&ret, 1);
252 cli_putstr("\r\n (3) expected_input == ");
253 cli_hexdump_rev(&expect_input, 4);
256 while((c=cli_getc_cecho())!='M' && c!='m'){
257 if(!isblank((uint8_t)c)){
258 cli_putstr("\r\nERROR: wrong input (1) [0x");
260 cli_putstr("]!\r\n");
261 hfal_hash_free(&(shavs_ctx.ctx));
265 if((c=cli_getc_cecho())!='s' && c!='S'){
266 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
267 hfal_hash_free(&(shavs_ctx.ctx));
270 if((c=cli_getc_cecho())!='g' && c!='G'){
271 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
272 hfal_hash_free(&(shavs_ctx.ctx));
275 while((c=cli_getc_cecho())!='='){
276 if(!isblank((uint8_t)c)){
277 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
278 hfal_hash_free(&(shavs_ctx.ctx));
283 cli_putstr("\r\nparsing started");
285 shavs_ctx.buffer_idx = 0;
286 shavs_ctx.in_byte = 0;
287 shavs_ctx.blocks = 0;
288 while(expect_input>0){
291 cli_putstr("\r\n\t(");
292 cli_hexdump_rev(&expect_input, 4);
295 if(buffer_add(c)==0){
298 if(!isblank((uint16_t)c)){
299 cli_putstr("\r\nERROR: wrong input (5) (");
301 cli_putstr(")!\r\n");
302 hfal_hash_free(&(shavs_ctx.ctx));
308 cli_putstr("\r\nBuffer-A:");
309 cli_hexdump_block(buffer, shavs_ctx.buffersize_B, 5, 8);
311 cli_putstr("\r\n starting finalisation");
312 cli_putstr("\r\n\tblocks == ");
313 cli_hexdump_rev(&(shavs_ctx.blocks),4);
314 cli_putstr("\r\n\tbuffer_idx == ");
315 cli_hexdump_rev(&(shavs_ctx.buffer_idx),2);
316 cli_putstr("\r\n\tin_byte == ");
317 cli_hexdump_rev(&(shavs_ctx.in_byte),1);
319 cli_putstr("\r\n starting last block");
320 cli_putstr("\r\n\tlength == ");
321 cli_hexdump_rev(&length,4);
322 cli_putstr("\r\n\tbuffersize_B == ");
323 cli_hexdump_rev(&(shavs_ctx.buffersize_B),2);
324 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
325 cli_putstr("\r\n\t (temp) == ");
326 cli_hexdump_rev(&temp,2);
327 temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
329 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
331 /* cli_putstr("\r\n\t (temp) == ");
332 cli_hexdump_rev(&temp,2); */
333 hfal_hash_lastBlock( &(shavs_ctx.ctx), buffer, /* be aware of freaking compilers!!! */
334 // length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8));
337 cli_putstr("\r\n starting ctx2hash");
339 hfal_hash_ctx2hash(diggest, &(shavs_ctx.ctx));
341 cli_putstr("\r\n starting hash free");
343 hfal_hash_free(&(shavs_ctx.ctx));
344 cli_putstr("\r\n MD = ");
345 cli_hexdump(diggest, shavs_algo->hashsize_b/8);
350 void shavs_test2(void){ /* Monte Carlo tests for SHA-1 & SHA-2 */
351 uint16_t expected_input;
357 cli_putstr("\r\nERROR: select algorithm first!");
360 uint8_t ml=shavs_algo->hashsize_b/8;
363 while((c=cli_getc_cecho())!='S' && c!='s'){
364 if(!isblank((uint8_t)c)){
365 cli_putstr("\r\nERROR: wrong input (1) [0x");
367 cli_putstr("]!\r\n");
371 if((c=cli_getc_cecho())!='e' && c!='e'){
372 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
375 if((c=cli_getc_cecho())!='e' && c!='e'){
376 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
379 if((c=cli_getc_cecho())!='d' && c!='D'){
380 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
383 while((c=cli_getc_cecho())!='='){
384 if(!isblank((uint8_t)c)){
385 cli_putstr("\r\nERROR: wrong input (5)!\r\n");
389 expected_input = ml*2;
390 memset(m+2*ml, 0, ml);
394 if(c>='0' && c<='9'){
398 if(c>='a' && c<='f'){
413 }while(expected_input);
414 /* so we have the seed */
415 cli_putstr("\r\nstarting processing");
417 for(count=0; count<100; ++count){
418 memcpy(m, m+ml*2, ml);
419 memcpy(m+ml, m+ml*2, ml);
420 for(j=0; j<1000; ++j){
421 hfal_hash_mem(shavs_algo, m+ml*3, m, ml*3*8);
422 memmove(m, m+ml, 3*ml);
424 cli_putstr("\r\n\r\nCOUNT = ");
426 cli_putc(count/10+'0');
428 cli_putc(count%10+'0');
429 cli_putstr("\r\nMD = ");
430 cli_hexdump(m+ml*2, ml);
435 void shavs_test3(void){ /* Monte Carlo tests for SHA-3 */
436 uint16_t expected_input;
442 cli_putstr("\r\nERROR: select algorithm first!");
445 uint8_t ml=shavs_algo->hashsize_b/8;
448 while((c=cli_getc_cecho())!='S' && c!='s'){
449 if(!isblank((uint8_t)c)){
450 cli_putstr("\r\nERROR: wrong input (1) [0x");
452 cli_putstr("]!\r\n");
456 if((c=cli_getc_cecho())!='e' && c!='e'){
457 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
460 if((c=cli_getc_cecho())!='e' && c!='e'){
461 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
464 if((c=cli_getc_cecho())!='d' && c!='D'){
465 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
468 while((c=cli_getc_cecho())!='='){
469 if(!isblank((uint8_t)c)){
470 cli_putstr("\r\nERROR: wrong input (5)!\r\n");
474 expected_input = 1024/4;
475 memset(m+ml, 0, 1024/8);
479 if(c>='0' && c<='9'){
483 if(c>='a' && c<='f'){
498 }while(expected_input);
499 /* so we have the seed */
500 cli_putstr("\r\nstarting processing");
502 for(count=0; count<100; ++count){
503 for(j=0; j<1000; ++j){
504 hfal_hash_mem(shavs_algo, m, m+ml, 1024);
505 memmove(m+ml, m, 1024/8);
507 cli_putstr("\r\n\r\nj = ");
509 cli_putc(count/10+'0');
511 cli_putc(count%10+'0');
512 cli_putstr("\r\nMD = ");
513 cli_hexdump(m+ml, ml);