3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006 2007 2008 2009 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
27 #include <avr/pgmspace.h>
32 #include "hashfunction_descriptor.h"
33 #include "hfal-basic.h"
35 #include "string-extras.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_P(PSTR("\r\nthe following algorithms are available:\r\n"));
59 while(option<='z' && (t=(hfdesc_t*)pgm_read_word(&(shavs_algolist[i])))){
61 cli_putc((t==shavs_algo)?'*':' ');
63 cli_putstr_P(PSTR(":\t"));
64 cli_putstr_P((void*)(pgm_read_word(&(t->name))));
65 cli_putstr_P(PSTR("\r\n"));
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_P(PSTR("\r\nERROR: shavs_algolist not set!"));
79 for(i=0; i<=option; ++i){
80 if((void*)pgm_read_word(&(shavs_algolist[i]))==NULL){
81 cli_putstr_P(PSTR("\r\nERROR: invalid selection!"));
85 shavs_algo=(hfdesc_t*)pgm_read_word(&(shavs_algolist[option]));
86 } else { /* name specifyed */
89 while((t=(hfdesc_t*)pgm_read_word(&(shavs_algolist[i]))) &&
90 strcasecmp_P(param, (void*)pgm_read_word(&(t->name))))
95 cli_putstr_P(PSTR("\r\nERROR: could not find \""));
97 cli_putstr_P(PSTR("\"!"));
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 if(c>='0' && c<='9'){
124 c &= (uint8_t)~('a' ^ 'A');
125 if(c>='A' && c<='F'){
131 t=shavs_ctx.buffer[shavs_ctx.buffer_idx];
132 if(shavs_ctx.in_byte){
134 shavs_ctx.buffer[shavs_ctx.buffer_idx] = t;
135 shavs_ctx.buffer_idx++;
136 shavs_ctx.in_byte = 0;
139 shavs_ctx.buffer[shavs_ctx.buffer_idx] = t;
140 shavs_ctx.in_byte = 1;
146 uint32_t my_strtoul(const char* str){
148 while(*str && (*str<'0' || *str>'9')){
154 while(*str && (*str>='0' && *str<='9')){
162 int32_t getLength(void){
167 memset(lenstr, 0, 21);
168 cli_getsn_cecho(lenstr, 20);
169 len2 = strstrip(lenstr);
170 if(!strncasecmp_P(len2, PSTR("LEN"), 3)){
171 while(*len2 && *len2!='=')
176 }while(*len2 && !isdigit((uint8_t)*len2));
177 len = my_strtoul(len2);
178 //len=(uint32_t)strtoul(len2, NULL, 10);
182 if(!strncasecmp_P(len2, PSTR("EXIT"), 4)){
189 void shavs_test1(void){ /* KAT tests */
191 int32_t expect_input=0;
194 cli_putstr_P(PSTR("\r\nERROR: select algorithm first!"));
198 uint8_t diggest[pgm_read_word(&(shavs_algo->hashsize_b))/8];
199 shavs_ctx.buffersize_B=pgm_read_word(&(shavs_algo->blocksize_b))/8;
200 uint8_t buffer[shavs_ctx.buffersize_B+5];
201 shavs_ctx.buffer = buffer;
202 cli_putstr_P(PSTR("\r\nbuffer_size = 0x"));
203 cli_hexdump_rev(&(shavs_ctx.buffersize_B), 2);
204 cli_putstr_P(PSTR(" bytes"));
206 shavs_ctx.blocks = 0;
207 memset(buffer, 0, shavs_ctx.buffersize_B);
208 length = getLength();
214 cli_putstr_P(PSTR("\r\nLen == "));
215 cli_hexdump_rev(&length, 4);
220 expect_input=((length + 7) >> 2) & (~1L);
223 cli_putstr_P(PSTR("\r\nexpected_input == "));
224 cli_hexdump_rev(&expect_input, 4);
226 cli_putstr_P(PSTR("\r\nexpected_input == 0 !!!"));
228 shavs_ctx.buffer_idx = 0;
229 shavs_ctx.in_byte = 0;
230 shavs_ctx.blocks = 0;
233 cli_putstr_P(PSTR("\r\n HFAL init"));
234 cli_putstr_P(PSTR("\r\n (2) expected_input == "));
235 cli_hexdump_rev(&expect_input, 4);
237 ret = hfal_hash_init(shavs_algo, &(shavs_ctx.ctx));
239 cli_putstr_P(PSTR("\r\n HFAL init returned with: "));
240 cli_hexdump(&ret, 1);
244 cli_putstr_P(PSTR("\r\n (3) expected_input == "));
245 cli_hexdump_rev(&expect_input, 4);
246 cli_putstr_P(PSTR("\r\n"));
248 while((c=cli_getc_cecho())!='M' && c!='m'){
250 cli_putstr_P(PSTR("\r\nERROR: wrong input (1) [0x"));
252 cli_putstr_P(PSTR("]!\r\n"));
253 hfal_hash_free(&(shavs_ctx.ctx));
257 if((c=cli_getc_cecho())!='s' && c!='S'){
258 cli_putstr_P(PSTR("\r\nERROR: wrong input (2)!\r\n"));
259 hfal_hash_free(&(shavs_ctx.ctx));
262 if((c=cli_getc_cecho())!='g' && c!='G'){
263 cli_putstr_P(PSTR("\r\nERROR: wrong input (3)!\r\n"));
264 hfal_hash_free(&(shavs_ctx.ctx));
267 while((c=cli_getc_cecho())!='='){
269 cli_putstr_P(PSTR("\r\nERROR: wrong input (4)!\r\n"));
270 hfal_hash_free(&(shavs_ctx.ctx));
275 cli_putstr_P(PSTR("\r\nparsing started"));
277 shavs_ctx.buffer_idx = 0;
278 shavs_ctx.in_byte = 0;
279 shavs_ctx.blocks = 0;
280 while(expect_input>0){
283 cli_putstr_P(PSTR("\r\n\t("));
284 cli_hexdump_rev(&expect_input, 4);
285 cli_putstr_P(PSTR(") "));
288 if(buffer_add(c)==0){
291 if(!isblank((uint16_t)c)){
292 cli_putstr_P(PSTR("\r\nERROR: wrong input (5) ("));
294 cli_putstr_P(PSTR(")!\r\n"));
295 hfal_hash_free(&(shavs_ctx.ctx));
301 cli_putstr_P(PSTR("\r\nBuffer-A:"));
302 cli_hexdump_block(buffer, shavs_ctx.buffersize_B, 5, 8);
304 cli_putstr_P(PSTR("\r\n starting finalisation"));
305 cli_putstr_P(PSTR("\r\n\tblocks == "));
306 cli_hexdump_rev(&(shavs_ctx.blocks),4);
307 cli_putstr_P(PSTR("\r\n\tbuffer_idx == "));
308 cli_hexdump_rev(&(shavs_ctx.buffer_idx),2);
309 cli_putstr_P(PSTR("\r\n\tin_byte == "));
310 cli_hexdump_rev(&(shavs_ctx.in_byte),1);
313 cli_putstr_P(PSTR("\r\n starting last block"));
314 cli_putstr_P(PSTR("\r\n\tlength == "));
315 cli_hexdump_rev(&length,4);
316 cli_putstr_P(PSTR("\r\n\tbuffersize_B == "));
317 cli_hexdump_rev(&(shavs_ctx.buffersize_B),2);
318 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
319 cli_putstr_P(PSTR("\r\n\t (temp) == "));
320 cli_hexdump_rev(&temp,2);
322 temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
324 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
326 hfal_hash_lastBlock( &(shavs_ctx.ctx), buffer, /* be aware of freaking compilers!!! */
329 cli_putstr_P(PSTR("\r\n starting ctx2hash"));
332 hfal_hash_ctx2hash(diggest, &(shavs_ctx.ctx));
334 cli_putstr_P(PSTR("\r\n starting hash free"));
336 hfal_hash_free(&(shavs_ctx.ctx));
337 cli_putstr_P(PSTR("\r\n MD = "));
338 cli_hexdump(diggest, pgm_read_word(&(shavs_algo->hashsize_b))/8);
343 void shavs_test2(void){ /* Monte Carlo tests for SHA-1 & SHA-2 */
344 uint16_t expected_input;
350 cli_putstr_P(PSTR("\r\nERROR: select algorithm first!"));
353 uint8_t ml=pgm_read_word(&(shavs_algo->hashsize_b))/8;
356 while((c=cli_getc_cecho())!='S' && c!='s'){
358 cli_putstr_P(PSTR("\r\nERROR: wrong input (1) [0x"));
360 cli_putstr_P(PSTR("]!\r\n"));
364 if((c=cli_getc_cecho())!='e' && c!='e'){
365 cli_putstr_P(PSTR("\r\nERROR: wrong input (2)!\r\n"));
368 if((c=cli_getc_cecho())!='e' && c!='e'){
369 cli_putstr_P(PSTR("\r\nERROR: wrong input (3)!\r\n"));
372 if((c=cli_getc_cecho())!='d' && c!='D'){
373 cli_putstr_P(PSTR("\r\nERROR: wrong input (4)!\r\n"));
376 while((c=cli_getc_cecho())!='='){
378 cli_putstr_P(PSTR("\r\nERROR: wrong input (5)!\r\n"));
382 expected_input = ml*2;
383 memset(m+2*ml, 0, ml);
387 if(c>='0' && c<='9'){
391 if(c>='a' && c<='f'){
406 }while(expected_input);
407 /* so we have the seed */
408 cli_putstr_P(PSTR("\r\nstarting processing"));
410 for(count=0; count<100; ++count){
411 memcpy(m, m+ml*2, ml);
412 memcpy(m+ml, m+ml*2, ml);
413 for(j=0; j<1000; ++j){
414 hfal_hash_mem(shavs_algo, m+ml*3, m, ml*3*8);
415 memmove(m, m+ml, 3*ml);
417 cli_putstr_P(PSTR("\r\n\r\nCOUNT = "));
419 cli_putc(count/10+'0');
421 cli_putc(count%10+'0');
422 cli_putstr_P(PSTR("\r\nMD = "));
423 cli_hexdump(m+ml*2, ml);
428 void shavs_test3(void){ /* Monte Carlo tests for SHA-3 */
429 uint16_t expected_input;
435 cli_putstr_P(PSTR("\r\nERROR: select algorithm first!"));
438 uint8_t ml=pgm_read_word(&(shavs_algo->hashsize_b))/8;
441 while((c=cli_getc_cecho())!='S' && c!='s'){
443 cli_putstr_P(PSTR("\r\nERROR: wrong input (1) [0x"));
445 cli_putstr_P(PSTR("]!\r\n"));
449 if((c=cli_getc_cecho())!='e' && c!='e'){
450 cli_putstr_P(PSTR("\r\nERROR: wrong input (2)!\r\n"));
453 if((c=cli_getc_cecho())!='e' && c!='e'){
454 cli_putstr_P(PSTR("\r\nERROR: wrong input (3)!\r\n"));
457 if((c=cli_getc_cecho())!='d' && c!='D'){
458 cli_putstr_P(PSTR("\r\nERROR: wrong input (4)!\r\n"));
461 while((c=cli_getc_cecho())!='='){
463 cli_putstr_P(PSTR("\r\nERROR: wrong input (5)!\r\n"));
467 expected_input = 1024/4;
468 memset(m+ml, 0, 1024/8);
472 if(c>='0' && c<='9'){
476 if(c>='a' && c<='f'){
491 }while(expected_input);
492 /* so we have the seed */
493 cli_putstr_P(PSTR("\r\nstarting processing"));
495 for(count=0; count<100; ++count){
496 for(j=0; j<1000; ++j){
497 hfal_hash_mem(shavs_algo, m, m+ml, 1024);
498 memmove(m+ml, m, 1024/8);
500 cli_putstr_P(PSTR("\r\n\r\nj = "));
502 cli_putc(count/10+'0');
504 cli_putc(count%10+'0');
505 cli_putstr_P(PSTR("\r\nMD = "));
506 cli_hexdump(m+ml, ml);