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;
114 uint8_t buffer_add(char c){
116 if(shavs_ctx.buffer_idx==shavs_ctx.buffersize_B){
117 hfal_hash_nextBlock(&(shavs_ctx.ctx), shavs_ctx.buffer);
119 shavs_ctx.buffer_idx=0;
122 if(c>='0' && c<='9'){
125 c &= (uint8_t)~('a' ^ 'A');
126 if(c>='A' && c<='F'){
132 t=shavs_ctx.buffer[shavs_ctx.buffer_idx];
133 if(shavs_ctx.in_byte){
135 shavs_ctx.buffer[shavs_ctx.buffer_idx] = t;
136 shavs_ctx.buffer_idx++;
137 shavs_ctx.in_byte = 0;
140 shavs_ctx.buffer[shavs_ctx.buffer_idx] = t;
141 shavs_ctx.in_byte = 1;
147 uint32_t my_strtoul(const char* str){
149 while(*str && (*str<'0' || *str>'9')){
155 while(*str && (*str>='0' && *str<='9')){
163 int32_t getLength(void){
168 memset(lenstr, 0, 21);
169 cli_getsn(lenstr, 20);
170 len2 = strstrip(lenstr);
171 if(!strncasecmp(len2, "LEN", 3)){
172 while(*len2 && *len2!='=')
177 }while(*len2 && !isdigit((uint8_t)*len2));
178 len = my_strtoul(len2);
179 //len=(uint32_t)strtoul(len2, NULL, 10);
183 if(!strncasecmp(len2, "EXIT", 4)){
190 void shavs_test1(void){ /* KAT tests */
192 int32_t expect_input=0;
195 cli_putstr("\r\nERROR: select algorithm first!");
199 uint8_t diggest[shavs_algo->hashsize_b/8];
200 shavs_ctx.buffersize_B=shavs_algo->blocksize_b/8;
201 uint8_t buffer[shavs_ctx.buffersize_B+5];
202 shavs_ctx.buffer = buffer;
203 cli_putstr("\r\nbuffer_size = 0x");
204 cli_hexdump_rev(&(shavs_ctx.buffersize_B), 2);
205 cli_putstr(" bytes");
207 shavs_ctx.blocks = 0;
208 memset(buffer, 0, shavs_ctx.buffersize_B);
209 length = getLength();
210 if((int32_t)length<0){
212 cli_putstr("\r\n(x) Len == ");
213 cli_hexdump_rev(&length, 4);
220 cli_putstr("\r\nLen == ");
221 cli_hexdump_rev(&length, 4);
227 expect_input=((length + 7) >> 2) & (~1L);
230 cli_putstr("\r\nexpected_input == ");
231 cli_hexdump_rev(&expect_input, 4);
233 cli_putstr("\r\nexpected_input == 0 !!!");
235 shavs_ctx.buffer_idx = 0;
236 shavs_ctx.in_byte = 0;
237 shavs_ctx.blocks = 0;
240 cli_putstr("\r\n HFAL init");
241 cli_putstr("\r\n (2) expected_input == ");
242 cli_hexdump_rev(&expect_input, 4);
244 ret = hfal_hash_init(shavs_algo, &(shavs_ctx.ctx));
246 cli_putstr("\r\n HFAL init returned with: ");
247 cli_hexdump(&ret, 1);
251 cli_putstr("\r\n (3) expected_input == ");
252 cli_hexdump_rev(&expect_input, 4);
255 while((c=cli_getc_cecho())!='M' && c!='m'){
256 if(!isblank((uint8_t)c)){
257 cli_putstr("\r\nERROR: wrong input (1) [0x");
259 cli_putstr("]!\r\n");
260 hfal_hash_free(&(shavs_ctx.ctx));
264 if((c=cli_getc_cecho())!='s' && c!='S'){
265 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
266 hfal_hash_free(&(shavs_ctx.ctx));
269 if((c=cli_getc_cecho())!='g' && c!='G'){
270 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
271 hfal_hash_free(&(shavs_ctx.ctx));
274 while((c=cli_getc_cecho())!='='){
275 if(!isblank((uint8_t)c)){
276 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
277 hfal_hash_free(&(shavs_ctx.ctx));
282 cli_putstr("\r\nparsing started");
284 shavs_ctx.buffer_idx = 0;
285 shavs_ctx.in_byte = 0;
286 shavs_ctx.blocks = 0;
287 while(expect_input>0){
290 cli_putstr("\r\n\t(");
291 cli_hexdump_rev(&expect_input, 4);
294 if(buffer_add(c)==0){
297 if(!isblank((uint16_t)c)){
298 cli_putstr("\r\nERROR: wrong input (5) (");
300 cli_putstr(")!\r\n");
301 hfal_hash_free(&(shavs_ctx.ctx));
307 cli_putstr("\r\nBuffer-A:");
308 cli_hexdump_block(buffer, shavs_ctx.buffersize_B, 5, 8);
310 cli_putstr("\r\n starting finalization");
311 cli_putstr("\r\n\tblocks == ");
312 cli_hexdump_rev(&(shavs_ctx.blocks),4);
313 cli_putstr("\r\n\tbuffer_idx == ");
314 cli_hexdump_rev(&(shavs_ctx.buffer_idx),2);
315 cli_putstr("\r\n\tin_byte == ");
316 cli_hexdump_rev(&(shavs_ctx.in_byte),1);
318 cli_putstr("\r\n starting last block");
319 cli_putstr("\r\n\tlength == ");
320 cli_hexdump_rev(&length,4);
321 cli_putstr("\r\n\tbuffersize_B == ");
322 cli_hexdump_rev(&(shavs_ctx.buffersize_B),2);
323 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
324 cli_putstr("\r\n\t (temp) == ");
325 cli_hexdump_rev(&temp,2);
327 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
329 hfal_hash_lastBlock( &(shavs_ctx.ctx), buffer, /* be aware of freaking compilers!!! */
332 cli_putstr("\r\n starting ctx2hash");
334 hfal_hash_ctx2hash(diggest, &(shavs_ctx.ctx));
336 cli_putstr("\r\n starting hash free");
338 hfal_hash_free(&(shavs_ctx.ctx));
339 cli_putstr("\r\n MD = ");
340 cli_hexdump(diggest, shavs_algo->hashsize_b/8);
345 void shavs_test2(void){ /* Monte Carlo tests for SHA-1 & SHA-2 */
346 uint16_t expected_input;
352 cli_putstr("\r\nERROR: select algorithm first!");
355 uint8_t ml=shavs_algo->hashsize_b/8;
358 while((c=cli_getc_cecho())!='S' && c!='s'){
359 if(!isblank((uint8_t)c)){
360 cli_putstr("\r\nERROR: wrong input (1) [0x");
362 cli_putstr("]!\r\n");
366 if((c=cli_getc_cecho())!='e' && c!='E'){
367 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
370 if((c=cli_getc_cecho())!='e' && c!='E'){
371 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
374 if((c=cli_getc_cecho())!='d' && c!='D'){
375 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
378 while((c=cli_getc_cecho())!='='){
379 if(!isblank((uint8_t)c)){
380 cli_putstr("\r\nERROR: wrong input (5)!\r\n");
384 expected_input = ml*2;
385 memset(m+2*ml, 0, ml);
389 if(c>='0' && c<='9'){
393 if(c>='a' && c<='f'){
408 }while(expected_input);
409 /* so we have the seed */
410 cli_putstr("\r\nstarting processing");
412 for(count=0; count<100; ++count){
413 memcpy(m, m+ml*2, ml);
414 memcpy(m+ml, m+ml*2, ml);
415 for(j=0; j<1000; ++j){
416 hfal_hash_mem(shavs_algo, m+ml*3, m, ml*3*8);
417 memmove(m, m+ml, 3*ml);
419 cli_putstr("\r\n\r\nCOUNT = ");
421 cli_putc(count/10+'0');
423 cli_putc(count%10+'0');
424 cli_putstr("\r\nMD = ");
425 cli_hexdump(m+ml*2, ml);
430 void shavs_test3(void){ /* Monte Carlo tests for SHA-3 */
431 uint16_t expected_input;
437 cli_putstr("\r\nERROR: select algorithm first!");
440 uint8_t ml=shavs_algo->hashsize_b/8;
443 while((c=cli_getc_cecho())!='S' && c!='s'){
444 if(!isblank((uint8_t)c)){
445 cli_putstr("\r\nERROR: wrong input (1) [0x");
447 cli_putstr("]!\r\n");
451 if((c=cli_getc_cecho())!='e' && c!='E'){
452 cli_putstr("\r\nERROR: wrong input (2)!\r\n");
455 if((c=cli_getc_cecho())!='e' && c!='E'){
456 cli_putstr("\r\nERROR: wrong input (3)!\r\n");
459 if((c=cli_getc_cecho())!='d' && c!='D'){
460 cli_putstr("\r\nERROR: wrong input (4)!\r\n");
463 while((c=cli_getc_cecho())!='='){
464 if(!isblank((uint8_t)c)){
465 cli_putstr("\r\nERROR: wrong input (5)!\r\n");
469 expected_input = 1024/4;
470 memset(m+ml, 0, 1024/8);
474 if(c>='0' && c<='9'){
478 if(c>='a' && c<='f'){
493 }while(expected_input);
494 /* so we have the seed */
495 cli_putstr("\r\nstarting processing");
497 for(count=0; count<100; ++count){
498 for(j=0; j<1000; ++j){
499 hfal_hash_mem(shavs_algo, m, m+ml, 1024);
500 memmove(m+ml, m, 1024/8);
502 cli_putstr("\r\n\r\nj = ");
504 cli_putc(count/10+'0');
506 cli_putc(count%10+'0');
507 cli_putstr("\r\nMD = ");
508 cli_hexdump(m+ml, ml);