]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/shavs.c
some adjustments for debugging
[avr-crypto-lib.git] / test_src / shavs.c
1 /* shavs.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2006 2007 2008 2009  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 <avr/pgmspace.h>
28 #include <stdint.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include "hashfunction_descriptor.h"
33 #include "hfal-basic.h"
34 #include "shavs.h"
35 #include "string-extras.h"
36 #include "cli.h"
37
38
39 #ifdef DEBUG
40 #  undef DEBUG
41 #endif
42
43 #define DEBUG 0
44
45 #if DEBUG
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_P(PSTR("\r\nthe following algorithms are available:\r\n"));
59         while(option<='z' && (t=(hfdesc_t*)pgm_read_word(&(shavs_algolist[i])))){
60                 cli_putc('\t');
61                 cli_putc((t==shavs_algo)?'*':' ');
62                 cli_putc(option++);
63                 cli_putstr_P(PSTR(":\t"));
64                 cli_putstr_P((void*)(pgm_read_word(&(t->name))));
65                 cli_putstr_P(PSTR("\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_P(PSTR("\r\nERROR: shavs_algolist not set!"));
77                         return;
78                 }
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!"));
82                                 return;
83                         }
84                 }
85                 shavs_algo=(hfdesc_t*)pgm_read_word(&(shavs_algolist[option]));
86         } else { /* name specifyed */
87                 hfdesc_t* t=NULL;
88                 uint8_t i=0;
89                 while((t=(hfdesc_t*)pgm_read_word(&(shavs_algolist[i]))) &&
90                        strcasecmp_P(param, (void*)pgm_read_word(&(t->name))))
91                         ++i;
92                 if(t){
93                         shavs_algo=t;
94                 }else{
95                         cli_putstr_P(PSTR("\r\nERROR: could not find \""));
96                         cli_putstr(param);
97                         cli_putstr_P(PSTR("\"!"));
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 uint8_t buffer_add(char c){
114         uint8_t v,t;
115         if(shavs_ctx.buffer_idx==shavs_ctx.buffersize_B){
116                 hfal_hash_nextBlock(&(shavs_ctx.ctx), shavs_ctx.buffer);
117                 ++shavs_ctx.blocks;
118                 shavs_ctx.buffer_idx=0;
119                 shavs_ctx.in_byte=0;
120                 cli_putc('.');
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
133         t=shavs_ctx.buffer[shavs_ctx.buffer_idx];
134         if(shavs_ctx.in_byte){
135                 t = (t&0xF0) | v;
136                 shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
137                 shavs_ctx.buffer_idx++;
138         }else{
139                 t = (t&0x0F) | (v<<4);
140                 shavs_ctx.buffer[shavs_ctx.buffer_idx]=t;
141         }
142         shavs_ctx.in_byte ^= 1;
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_cecho(lenstr, 20);
153                 len2 = strstrip(lenstr);
154                 if(!strncasecmp_P(len2, PSTR("LEN"), 3)){
155                         while(*len2 && *len2!='=')
156                                 len2++;
157                         if(*len2=='='){
158                                 do{
159                                         len2++;
160                                 }while(*len2 && !isdigit(*len2));
161                                 len=(uint32_t)strtoul(len2, NULL, 10);
162                                 return len;
163                         }
164                 } else {
165                         if(!strncasecmp_P(len2, PSTR("EXIT"), 4)){
166                                 return -1;
167                         }
168                 }
169         }
170 }
171
172 void shavs_test1(void){
173         uint32_t length=0;
174         int32_t expect_input=0;
175
176         if(!shavs_algo){
177                         cli_putstr_P(PSTR("\r\nERROR: select algorithm first!"));
178                 return;
179         }
180         uint8_t diggest[pgm_read_word(shavs_algo->hashsize_b)/8];
181         shavs_ctx.buffersize_B=pgm_read_word(&(shavs_algo->blocksize_b))/8;
182         uint8_t buffer[shavs_ctx.buffersize_B];
183         shavs_ctx.buffer = buffer;
184         cli_putstr_P(PSTR("\r\nbuffer_size = 0x"));
185         cli_hexdump_rev(&(shavs_ctx.buffersize_B), 2);
186         cli_putstr_P(PSTR(" bytes"));
187         for(;;){
188                 shavs_ctx.blocks = 0;
189                 char c;
190                 length = getLength();
191                 if(length<0){
192                         return;
193                 }
194
195 #if DEBUG
196                 cli_putstr_P(PSTR("\r\nLen == "));
197                 cli_hexdump_rev(&length, 4);
198 #endif
199                 if(length==0){
200                         expect_input=2;
201                 }else{
202                         expect_input=((length+7)>>2)&(~1L);
203                 }
204 #if DEBUG
205                 cli_putstr_P(PSTR("\r\nexpected_input == "));
206                 cli_hexdump_rev(&expect_input, 4);
207                 if(expect_input==0)
208                         cli_putstr_P(PSTR("\r\nexpected_input == 0 !!!"));
209 #endif
210                 shavs_ctx.buffer_idx = 0;
211                 shavs_ctx.in_byte    = 0;
212                 shavs_ctx.blocks     = 0;
213                 uint8_t ret;
214 #if DEBUG
215                 cli_putstr_P(PSTR("\r\n HFAL init"));
216                 cli_putstr_P(PSTR("\r\n (2) expected_input == "));
217                 cli_hexdump_rev(&expect_input, 4);
218 #endif
219                 ret = hfal_hash_init(shavs_algo, &(shavs_ctx.ctx));
220                 //ret=0;
221                 if(ret){
222                         cli_putstr_P(PSTR("\r\n HFAL init returned with: "));
223                         cli_hexdump(&ret, 1);
224                         return;
225                 }
226 #if DEBUG
227                 cli_putstr_P(PSTR("\r\n (3) expected_input == "));
228                 cli_hexdump_rev(&expect_input, 4);
229                 cli_putstr_P(PSTR("\r\n"));
230 #endif
231                 while((c=cli_getc_cecho())!='M' && c!='m'){
232                         if(!isblank(c)){
233                                 cli_putstr_P(PSTR("\r\nERROR: wrong input (1) [0x"));
234                                 cli_hexdump(&c, 1);
235                                 cli_putstr_P(PSTR("]!\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_P(PSTR("\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_P(PSTR("\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(c)){
252                                 cli_putstr_P(PSTR("\r\nERROR: wrong input (4)!\r\n"));
253                                 hfal_hash_free(&(shavs_ctx.ctx));
254                                 return;
255                         }
256                 }
257 #if DEBUG
258                 cli_putstr_P(PSTR("\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_P(PSTR("\r\n\t("));
267                         cli_hexdump_rev(&expect_input, 4);
268                         cli_putstr_P(PSTR(") "));
269                         _delay_ms(500);
270 #endif
271                         if(buffer_add(c)==0){
272                                 --expect_input;
273                         }else{
274                                 if(!isblank((uint16_t)c)){
275                                         cli_putstr_P(PSTR("\r\nERROR: wrong input (5) ("));
276                                         cli_putc(c);
277                                         cli_putstr_P(PSTR(")!\r\n"));
278                                         hfal_hash_free(&(shavs_ctx.ctx));
279                                         return;
280                                 }
281                         }
282                 }
283 #if DEBUG
284                 cli_putstr_P(PSTR("\r\n starting finalisation"));
285                 cli_putstr_P(PSTR("\r\n\tblocks     == "));
286                 cli_hexdump_rev(&(shavs_ctx.blocks),4);
287                 cli_putstr_P(PSTR("\r\n\tbuffer_idx == "));
288                 cli_hexdump_rev(&(shavs_ctx.buffer_idx),2);
289                 cli_putstr_P(PSTR("\r\n\tin_byte    == "));
290                 cli_hexdump_rev(&(shavs_ctx.in_byte),1);
291                 _delay_ms(500);
292
293                 cli_putstr_P(PSTR("\r\n starting last block"));
294                 cli_putstr_P(PSTR("\r\n\tlength       == "));
295                 cli_hexdump_rev(&length,4);
296                 cli_putstr_P(PSTR("\r\n\tbuffersize_B == "));
297                 cli_hexdump_rev(&(shavs_ctx.buffersize_B),2);
298                 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
299                 cli_putstr_P(PSTR("\r\n\t (temp)      == "));
300                 cli_hexdump_rev(&temp,2);
301                 _delay_ms(500);
302 #endif
303 #if !DEBUG
304                 uint16_t temp=length-(shavs_ctx.blocks)*((shavs_ctx.buffersize_B)*8);
305 //              cli_putstr_P(PSTR("\r\n\t (temp)      == "));
306                 cli_hexdump_rev(&temp,2);
307 #endif
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_P(PSTR("\r\n starting ctx2hash"));
313                 _delay_ms(500);
314 #endif
315                 hfal_hash_ctx2hash(diggest, &(shavs_ctx.ctx));
316 #if DEBUG
317                 cli_putstr_P(PSTR("\r\n starting hash free"));
318 #endif
319                 hfal_hash_free(&(shavs_ctx.ctx));
320                 cli_putstr_P(PSTR("\r\n MD = "));
321                 cli_hexdump(diggest, pgm_read_word(&(shavs_algo->hashsize_b))/8);
322
323         }
324 }
325