]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/main-rsaes_pkcs1v15-test.c
efea72c122c0596e4915e822c4dbf9200b3ba1ca
[avr-crypto-lib.git] / test_src / main-rsaes_pkcs1v15-test.c
1 /* main-dsa-test.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 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  * RSA test-suit
21  *
22 */
23 #include "main-test-common.h"
24
25 #include "noekeon.h"
26 #include "noekeon_prng.h"
27 #include "bigint.h"
28 #include "bigint_io.h"
29 #include "random_dummy.h"
30 #include "rsa_basic.h"
31 #include "rsaes_pkcs1v15.h"
32
33 #include "performance_test.h"
34
35 #define DEBUG 0
36
37 const char* algo_name = "RSAES-PKCS1V15";
38
39 #define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) *  sizeof(bigint_word_t))
40 #define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t))
41
42 /*****************************************************************************
43  *  additional validation-functions                                                                                      *
44  *****************************************************************************/
45
46 /* Modulus: */
47 const uint8_t modulus[] PROGMEM = {
48 0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4,
49 0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab,
50 0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85,
51 0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72,
52 0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97,
53 0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14,
54 0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24,
55 0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb
56 };
57
58 /* Public exponent: */
59 const uint8_t pub_exponent[] PROGMEM = { 0x01, 0x00, 0x01 };
60
61 /* Exponent: */
62 const uint8_t priv_exponent[] PROGMEM = {
63 0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c,
64 0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd,
65 0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b,
66 0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55,
67 0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73,
68 0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf,
69 0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde,
70 0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1
71 };
72
73 /* Prime 1: */
74 const uint8_t p[] PROGMEM = {
75 0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b,
76 0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a,
77 0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1,
78 0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d
79 };
80
81 /* Prime 2: */
82 const uint8_t q[] PROGMEM = {
83 0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7,
84 0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c,
85 0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe,
86 0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77
87 };
88
89 /* Prime exponent 1: */
90 const uint8_t dp[] PROGMEM = {
91 0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04,
92 0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3,
93 0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d,
94 0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1
95 };
96
97 /* Prime exponent 2: */
98 const uint8_t dq[] PROGMEM = {
99 0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc,
100 0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73,
101 0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a,
102 0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83
103 };
104
105 /* Coefficient: */
106 const uint8_t qinv[] PROGMEM = {
107 0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d,
108 0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11,
109 0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81,
110 0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1
111 };
112
113 /* PKCS#1 v1.5 encryption of 0x20, random messages with random s0xee,ds
114  *  ---------------------------------------------------------------------------
115  */
116
117 /* Message: */
118 const uint8_t message_x[] PROGMEM = {
119 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23,
120 0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34
121 };
122
123 /* Seed: */
124 const uint8_t seed_x[] PROGMEM = {
125 0x01, 0x73, 0x41, 0xae, 0x38, 0x75, 0xd5, 0xf8, 0x71, 0x01, 0xf8, 0xcc, 0x4f, 0xa9, 0xb9, 0xbc,
126 0x15, 0x6b, 0xb0, 0x46, 0x28, 0xfc, 0xcd, 0xb2, 0xf4, 0xf1, 0x1e, 0x90, 0x5b, 0xd3, 0xa1, 0x55,
127 0xd3, 0x76, 0xf5, 0x93, 0xbd, 0x73, 0x04, 0x21, 0x08, 0x74, 0xeb, 0xa0, 0x8a, 0x5e, 0x22, 0xbc,
128 0xcc, 0xb4, 0xc9, 0xd3, 0x88, 0x2a, 0x93, 0xa5, 0x4d, 0xb0, 0x22, 0xf5, 0x03, 0xd1, 0x63, 0x38,
129 0xb6, 0xb7, 0xce, 0x16, 0xdc, 0x7f, 0x4b, 0xbf, 0x9a, 0x96, 0xb5, 0x97, 0x72, 0xd6, 0x60, 0x6e,
130 0x97, 0x47, 0xc7, 0x64, 0x9b, 0xf9, 0xe0, 0x83, 0xdb, 0x98, 0x18, 0x84, 0xa9, 0x54, 0xab, 0x3c,
131 0x6f };
132
133 /* Encryption: */
134 const uint8_t encrypted_x[] PROGMEM = {
135 0x50, 0xb4, 0xc1, 0x41, 0x36, 0xbd, 0x19, 0x8c, 0x2f, 0x3c, 0x3e, 0xd2, 0x43, 0xfc, 0xe0, 0x36,
136 0xe1, 0x68, 0xd5, 0x65, 0x17, 0x98, 0x4a, 0x26, 0x3c, 0xd6, 0x64, 0x92, 0xb8, 0x08, 0x04, 0xf1,
137 0x69, 0xd2, 0x10, 0xf2, 0xb9, 0xbd, 0xfb, 0x48, 0xb1, 0x2f, 0x9e, 0xa0, 0x50, 0x09, 0xc7, 0x7d,
138 0xa2, 0x57, 0xcc, 0x60, 0x0c, 0xce, 0xfe, 0x3a, 0x62, 0x83, 0x78, 0x9d, 0x8e, 0xa0, 0xe6, 0x07,
139 0xac, 0x58, 0xe2, 0x69, 0x0e, 0xc4, 0xeb, 0xc1, 0x01, 0x46, 0xe8, 0xcb, 0xaa, 0x5e, 0xd4, 0xd5,
140 0xcc, 0xe6, 0xfe, 0x7b, 0x0f, 0xf9, 0xef, 0xc1, 0xea, 0xbb, 0x56, 0x4d, 0xbf, 0x49, 0x82, 0x85,
141 0xf4, 0x49, 0xee, 0x61, 0xdd, 0x7b, 0x42, 0xee, 0x5b, 0x58, 0x92, 0xcb, 0x90, 0x60, 0x1f, 0x30,
142 0xcd, 0xa0, 0x7b, 0xf2, 0x64, 0x89, 0x31, 0x0b, 0xcd, 0x23, 0xb5, 0x28, 0xce, 0xab, 0x3c, 0x31
143 };
144
145 uint8_t keys_allocated = 0;
146 rsa_publickey_t pub_key;
147 rsa_privatekey_t priv_key;
148
149 #if 1
150   #define MSG       message_x
151   #define SEED      seed_x
152   #define ENCRYPTED encrypted_x
153   #define MODULUS modulus
154   #define PUB_EXPONENT pub_exponent
155   #define PRIV_EXPONENT priv_exponent
156   #define P p
157   #define Q q
158   #define DP dp
159   #define DQ dq
160   #define QINV qinv
161 #endif
162
163
164 uint8_t convert_nibble(uint8_t c){
165         if(c>='0' && c<='9'){
166                 return c - '0';
167         }
168         c |= 'A' ^ 'a';
169         if(c>='a' && c<='f'){
170                 return c - 'a' + 10;
171         }
172         return 0xff;
173 }
174
175 const char *block_ignore_string=" \t\r\n,;";
176 #define BUFFER_LIMIT 120
177 uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){
178         uint16_t counter = 0;
179         uint16_t c;
180         uint8_t v, tmp = 0, idx = 0;
181         if(!ignore_string){
182                 ignore_string = block_ignore_string;
183         }
184         while(counter < length){
185                 c = cli_getc();
186                 if(c > 0xff){
187                         return counter;
188                 }
189                 if(strchr(ignore_string, c)){
190                         continue;
191                 }
192                 v = convert_nibble(c);
193                 if(v > 0x0f){
194                         return counter;
195                 }
196                 if(idx){
197                         ((uint8_t*)dst)[counter++] = (tmp << 4) | v;
198                         idx = 0;
199                         if(counter % (BUFFER_LIMIT/2) == 0){
200                                 cli_putc('.');
201                         }
202                 }else{
203                         tmp = v;
204                         idx = 1;
205                 }
206         }
207         return counter;
208 }
209
210 uint16_t own_atou(const char* str){
211         uint16_t r=0;
212         while(*str && *str >= '0' && *str <= '9'){
213                 r *= 10;
214                 r += *str++ - '0';
215         }
216         return r;
217 }
218
219 uint8_t read_bigint(bigint_t* a, char* prompt){
220         uint16_t read_length, actual_length;
221         uint8_t off;
222         uint8_t *buffer;
223         char read_int_str[18];
224         cli_putstr(prompt);
225         cli_putstr_P(PSTR("\r\n  length: "));
226         cli_getsn(read_int_str, 16);
227         read_length = own_atou(read_int_str);
228         off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
229         buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
230         if(!buffer){
231                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
232                 return 2;
233         }
234         cli_putstr_P(PSTR("\r\n  data: "));
235         memset(buffer, 0, sizeof(bigint_word_t));
236         actual_length = read_os(buffer + off, read_length, NULL);
237         if(actual_length != read_length){
238                 cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!"));
239                 free(buffer);
240                 return 1;
241         }
242         a->wordv = (bigint_word_t*)buffer;
243         a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
244         a->info = 0;
245         bigint_changeendianess(a);
246         bigint_adjust(a);
247         return 0;
248 }
249
250 uint8_t pre_alloc_key_crt(void){
251         uint8_t c;
252         pub_key.modulus = malloc(sizeof(bigint_t));
253         if(!pub_key.modulus){
254                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
255                 return 6;
256         }
257         priv_key.modulus = pub_key.modulus;
258         priv_key.n = 5;
259         priv_key.components = malloc(5 * sizeof(bigint_t*));
260         if(!priv_key.components){
261                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
262                 return 3;
263         }
264         pub_key.exponent = malloc(sizeof(bigint_t));
265         if(!pub_key.exponent){
266                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
267                 return 4;
268         }
269         for(c=0; c<5; ++c){
270                 priv_key.components[c] = malloc(sizeof(bigint_t));
271                 if(!priv_key.components[c]){
272                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
273                         return 7+c;
274                 }
275         }
276         return 0;
277 }
278
279 void free_key(void){
280         uint8_t c;
281         for(c = priv_key.n; c > 0 ; --c){
282                 free(priv_key.components[c - 1]->wordv);
283         }
284         free(pub_key.exponent->wordv);
285         free(pub_key.modulus->wordv);
286
287         for(c = priv_key.n; c > 0 ; --c){
288                 free(priv_key.components[c - 1]);
289         }
290         free(pub_key.exponent);
291         pub_key.exponent = NULL;
292         free(priv_key.components);
293         priv_key.components = NULL;
294         free(pub_key.modulus);
295         pub_key.modulus = priv_key.modulus = NULL;
296         keys_allocated = 0;
297 }
298
299 uint8_t read_key_crt(void){
300         uint8_t r;
301         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
302         r = pre_alloc_key_crt();
303         if(r) return r;
304         r = read_bigint(pub_key.modulus,"\r\n = module =");
305         if(r) return r;
306         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
307         if(r) return r;
308         r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
309         if(r) return r;
310         r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
311         if(r) return r;
312         r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
313         if(r) return r;
314         r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
315         if(r) return r;
316         r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
317
318 #if DEBUG
319         cli_putstr_P(PSTR("\r\nmodulus:"));
320         bigint_print_hex(pub_key.modulus);
321         cli_putstr_P(PSTR("\r\npublic exponent:"));
322         bigint_print_hex(pub_key.exponent);
323         cli_putstr_P(PSTR("\r\np:"));
324         bigint_print_hex(priv_key.components[0]);
325         cli_putstr_P(PSTR("\r\nq:"));
326         bigint_print_hex(priv_key.components[1]);
327         cli_putstr_P(PSTR("\r\ndP:"));
328         bigint_print_hex(priv_key.components[2]);
329         cli_putstr_P(PSTR("\r\ndQ:"));
330         bigint_print_hex(priv_key.components[3]);
331         cli_putstr_P(PSTR("\r\nqInv:"));
332         bigint_print_hex(priv_key.components[4]);
333 #endif
334         return r;
335 }
336
337 uint8_t read_key_conv(void){
338         uint8_t r;
339         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
340         pub_key.modulus = malloc(sizeof(bigint_t));
341         if(!pub_key.modulus){
342                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
343                 return 2;
344         }
345         r = read_bigint(pub_key.modulus,"\r\n = module =");
346         if(r) return r;
347         priv_key.modulus = pub_key.modulus;
348         priv_key.n = 1;
349         pub_key.exponent = malloc(sizeof(bigint_t));
350         if(!pub_key.exponent){
351                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
352                 return 2;
353         }
354         priv_key.components = malloc(sizeof(bigint_t*));
355         if(!priv_key.components){
356                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
357                 return 2;
358         }
359         priv_key.components[0] = malloc(sizeof(bigint_t));
360         if(!priv_key.components[0]){
361                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
362                 return 2;
363         }
364         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
365         if(r) return r;
366         r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
367         return r;
368 }
369
370 void load_priv_conventional(void){
371         bigint_t *epriv;
372         epriv = malloc(sizeof(bigint_t));
373         if(!epriv){
374                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
375                 return;
376         }
377         epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
378         epriv->wordv =  malloc(epriv->length_B * sizeof(bigint_word_t));
379         if(!epriv->wordv){
380                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
381                 return;
382         }
383         memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
384         priv_key.components = malloc(sizeof(bigint_t*));
385         priv_key.components[0] = epriv;
386         priv_key.n = 1;
387         bigint_changeendianess(epriv);
388         bigint_adjust(epriv);
389 }
390
391
392 void load_priv_crt_mono(void){
393         bigint_t **v;
394         const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
395         uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
396         uint8_t i;
397         v = malloc(5 * sizeof(bigint_t));
398         if(!v){
399                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
400                 return;
401         }
402         priv_key.components = malloc(5*sizeof(bigint_t*));
403         if(!priv_key.components){
404                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
405                 return;
406         }
407         priv_key.n = 5;
408         for(i=0; i<5; ++i){
409                 v[i] = malloc(sizeof(bigint_t));
410                 v[i]->info = 0;
411                 v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
412                 v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
413                 if(!v[i]->wordv){
414                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
415                         return;
416                 }
417                 memcpy(v[i]->wordv, bv[i], sv[i]);
418                 bigint_changeendianess(v[i]);
419                 bigint_adjust(v[i]);
420                 priv_key.components[i] = v[i];
421         }
422 }
423
424 uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
425         a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
426         a->wordv = malloc(BIGINT_CEIL(length_B));
427         if(!a->wordv){
428                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
429                 return 1;
430         }
431         memset(a->wordv, 0, sizeof(bigint_word_t));
432         memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
433         a->info = 0;
434         bigint_changeendianess(a);
435         bigint_adjust(a);
436         return 0;
437 }
438
439 void load_fix_rsa(void){
440         if(keys_allocated){
441                 free_key();
442         }
443         keys_allocated = 1;
444
445         if(pre_alloc_key_crt()){
446                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
447                 return;
448         }
449
450         load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
451         load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
452         priv_key.n = 5;
453         load_bigint_from_os(priv_key.components[0], P, sizeof(P));
454         load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
455         load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
456         load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
457         load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
458
459 //      load_priv_conventional();
460 //      load_priv_crt_mono();
461 }
462
463 void quick_test(void){
464         uint8_t *ciphertext, *plaintext, rc;
465         uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)];
466         uint16_t clen, plen;
467         if(!keys_allocated){
468                 load_fix_rsa();
469         }
470         ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
471         plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
472         memcpy_P(plaintext, MSG, sizeof(MSG));
473         memcpy_P(seed, SEED, sizeof(SEED));
474         cli_putstr_P(PSTR("\r\nplaintext:"));
475         cli_hexdump_block(plaintext, sizeof(MSG), 4, 16);
476         cli_putstr_P(PSTR("\r\nseed:"));
477         cli_hexdump_block(seed, sizeof(SEED), 4, 16);
478         cli_putstr_P(PSTR("\r\nencrypting: ..."));
479
480         rc = rsa_encrypt_pkcs1v15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed);
481         if(rc){
482                 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_pkcs1v15 returned: "));
483                 cli_hexdump_byte(rc);
484                 return;
485
486         }
487
488         cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
489         cli_hexdump_block(ciphertext, clen, 4, 16);
490         if(clen!=sizeof(ENCRYPTED)){
491                         cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
492         }else{
493                 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
494                         cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
495                 }else{
496                         cli_putstr_P(PSTR("\r\n>>OK<<"));
497                 }
498         }
499
500         cli_putstr_P(PSTR("\r\ndecrypting: ..."));
501         rc = rsa_decrypt_pkcs1v15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out);
502         if(rc){
503                 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs1v15 returned: "));
504                 cli_hexdump_byte(rc);
505                 return;
506         }
507         cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
508         cli_hexdump_block(plaintext, plen, 4, 16);
509         cli_putstr_P(PSTR("\r\n\r\nseed (out):"));
510         cli_hexdump_block(seed_out, sizeof(SEED), 4, 16);
511
512         free(ciphertext);
513         free(plaintext);
514 }
515
516 void run_seed_test(void){
517         uint8_t *msg, *ciph, *msg_;
518         uint16_t ciph_len, msg_len;
519         uint16_t msg_len_;
520         uint16_t seed_len;
521         uint8_t *seed, *seed_out;
522         char read_int_str[18];
523         cli_putstr_P(PSTR("\r\n== test with given seed =="));
524         cli_putstr_P(PSTR("\r\n = message ="));
525         cli_putstr_P(PSTR("\r\n  length: "));
526         cli_getsn(read_int_str, 16);
527         msg_len = own_atou(read_int_str);
528         seed_len = rsa_pkcs1v15_compute_padlength_B(pub_key.modulus, msg_len);
529         seed = malloc(seed_len);
530 #if DEBUG
531         cli_putstr_P(PSTR("\r\nDBG: @seed: 0x"));
532         cli_hexdump_rev(&seed, 2);
533 #endif
534         if(!seed){
535                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
536                 return;
537         }
538         seed_out = malloc(seed_len);
539 #if DEBUG
540         cli_putstr_P(PSTR("\r\nDBG: @seed_out: 0x"));
541         cli_hexdump_rev(&seed_out, 2);
542 #endif
543         if(!seed_out){
544                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
545                 return;
546         }
547         msg = malloc(msg_len);
548 #if DEBUG
549         cli_putstr_P(PSTR("\r\nDBG: @msg: 0x"));
550         cli_hexdump_rev(&msg, 2);
551 #endif
552         if(!msg){
553                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
554                 return;
555         }
556         ciph = malloc(bigint_length_B(pub_key.modulus));
557 #if DEBUG
558         cli_putstr_P(PSTR("\r\nDBG: @ciph: 0x"));
559         cli_hexdump_rev(&ciph, 2);
560 #endif
561         if(!ciph){
562                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
563                 return;
564         }
565         msg_ = malloc(bigint_length_B(pub_key.modulus) + sizeof(bigint_word_t));
566 #if DEBUG
567         cli_putstr_P(PSTR("\r\nDBG: @msg_: 0x"));
568         cli_hexdump_rev(&msg_, 2);
569 #endif
570         if(!msg_){
571                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
572                 return;
573         }
574         cli_putstr_P(PSTR("\r\n  data: "));
575         read_os(msg, msg_len, NULL);
576         cli_putstr_P(PSTR("\r\n  seed (0x"));
577         cli_hexdump_rev(&seed_len, 2);
578         cli_putstr_P(PSTR(" bytes): "));
579         read_os(seed, seed_len, NULL);
580
581         cli_putstr_P(PSTR("\r\n  encrypting ..."));
582 /*
583         cli_putstr_P(PSTR("\r\n plaintext:"));
584         cli_hexdump_block(msg, msg_len, 4, 16);
585         cli_putstr_P(PSTR("\r\n seed:"));
586         cli_hexdump_block(seed, seed_len, 4, 16);
587 */
588 #if DEBUG
589         cli_putstr_P(PSTR("\r\n  first prime:"));
590         bigint_print_hex(priv_key.components[0]);
591 #endif
592         rsa_encrypt_pkcs1v15(ciph, &ciph_len, msg, msg_len, &pub_key, seed);
593         cli_putstr_P(PSTR("\r\n  ciphertext:"));
594         cli_hexdump_block(ciph, ciph_len, 4, 16);
595 #if DEBUG
596         cli_putstr_P(PSTR("\r\n  first prime:"));
597         bigint_print_hex(priv_key.components[0]);
598 #endif
599         cli_putstr_P(PSTR("\r\n  decrypting ... "));
600
601         rsa_decrypt_pkcs1v15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out);
602
603         cli_putstr_P(PSTR("[done]"));
604         if(msg_len != msg_len_){
605                 char tstr[16];
606                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
607                 itoa(msg_len_, tstr, 10);
608                 cli_putstr(tstr);
609                 cli_putstr_P(PSTR(" instead of "));
610                 itoa(msg_len, tstr, 10);
611                 cli_putstr(tstr);
612                 cli_putc(')');
613                 goto end;
614         }
615         if(memcmp(msg, msg_, msg_len)){
616                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
617                 cli_hexdump_block(msg_, msg_len_, 4, 16);
618                 cli_putstr_P(PSTR("\r\nreference:"));
619                 cli_hexdump_block(msg, msg_len, 4, 16);
620                 goto end;
621         }
622
623         if(memcmp(seed, seed_out, seed_len)){
624                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
625                 cli_hexdump_block(seed_out, seed_len, 4, 16);
626                 cli_putstr_P(PSTR("\r\nreference:"));
627                 cli_hexdump_block(seed, seed_len, 4, 16);
628                 goto end;
629         }
630
631         cli_putstr_P(PSTR("\r\n  >>OK<<"));
632 end:
633         free(msg_);
634         free(ciph);
635         free(msg);
636         free(seed_out);
637         free(seed);
638 }
639
640 void reset_prng(void){
641         uint8_t buf[16];
642         memset(buf, 0, 16);
643         random_seed(buf);
644         cli_putstr_P(PSTR("\r\nPRNG reset"));
645 }
646
647 void rsa_init(void){
648         prng_get_byte = random8;
649 }
650
651 void load_key(void){
652         uint8_t r;
653         if(keys_allocated){
654                 cli_putstr_P(PSTR("\r\nDBG: freeing old keys"));
655                 free_key();
656         }
657         keys_allocated = 1;
658         r = read_key_crt();
659         if(r){
660                 cli_putstr_P(PSTR("\r\nERROR: read_key_crt returned 0x"));
661                 cli_hexdump_byte(r);
662         }
663 }
664
665 void test_dump(void){
666         char lstr[16];
667         int len;
668         cli_putstr_P(PSTR("\r\nenter dump length: "));
669         cli_getsn_cecho(lstr, 15);
670         len = own_atou(lstr);
671         cli_putstr_P(PSTR("\r\ndumping 0x"));
672         cli_hexdump_rev(&len, 2);
673         cli_putstr_P(PSTR(" byte:"));
674         cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
675 }
676
677 /*****************************************************************************
678  *  main                                                                                                                                         *
679  *****************************************************************************/
680
681 const char echo_test_str[]    PROGMEM = "echo-test";
682 const char reset_prng_str[]   PROGMEM = "reset-prng";
683 const char load_key_str[]     PROGMEM = "load-key";
684 const char load_fix_key_str[] PROGMEM = "load-fix-key";
685 const char quick_test_str[]   PROGMEM = "quick-test";
686 const char seed_test_str[]    PROGMEM = "seed-test";
687 const char dump_test_str[]    PROGMEM = "dump-test";
688 const char performance_str[]  PROGMEM = "performance";
689 const char echo_str[]         PROGMEM = "echo";
690
691 const cmdlist_entry_t cmdlist[] PROGMEM = {
692         { reset_prng_str,       NULL, reset_prng                    },
693         { load_key_str,         NULL, load_key                      },
694         { load_fix_key_str,     NULL, load_fix_rsa                  },
695         { quick_test_str,       NULL, quick_test                    },
696         { seed_test_str,        NULL, run_seed_test                 },
697         { dump_test_str,        NULL, test_dump                     },
698 //      { performance_str,      NULL, testrun_performance_bigint    },
699         { echo_str,         (void*)1, (void_fpt)echo_ctrl           },
700         { NULL,                 NULL, NULL                          }
701 };
702
703 void dump_sp(void){
704         uint8_t x;
705         uint8_t *xa = &x;
706         cli_putstr_P(PSTR("\r\nstack pointer: ~"));
707         cli_hexdump_rev(&xa, 4);
708 }
709
710 int main (void){
711         main_setup();
712
713         for(;;){
714                 welcome_msg(algo_name);
715                 rsa_init();
716                 cmd_interface(cmdlist);
717         }
718 }