]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/main-rsaes_pkcs1v15-test.c
fixing E-Mail-Address & Copyright
[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) 2006-2015 Daniel Otte (bg@nerilex.org)
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 1
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_W = (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         priv_key.n = 5;
252         priv_key.components = malloc(5 * sizeof(bigint_t));
253         if(!priv_key.components){
254                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
255                 return 2;
256         }
257         return 0;
258 }
259
260 void free_key(void){
261         uint8_t c;
262         free(pub_key.modulus.wordv);
263         free(pub_key.exponent.wordv);
264         for(c = 0; c < priv_key.n; ++c){
265                 free(priv_key.components[c].wordv);
266         }
267         free(priv_key.components);
268         keys_allocated = 0;
269 }
270
271 uint8_t read_key_crt(void){
272         uint8_t r;
273         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
274         r = pre_alloc_key_crt();
275         if(r) return r;
276         r = read_bigint(&pub_key.modulus,"\r\n = module =");
277         if(r) return r;
278         memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
279         r = read_bigint(&pub_key.exponent,"\r\n = public exponent =");
280         if(r) return r;
281         r = read_bigint(&(priv_key.components[0]),"\r\n = p (first prime) =");
282         if(r) return r;
283         r = read_bigint(&(priv_key.components[1]),"\r\n = q (second prime) =");
284         if(r) return r;
285         r = read_bigint(&(priv_key.components[2]),"\r\n = dp (p's exponent) =");
286         if(r) return r;
287         r = read_bigint(&(priv_key.components[3]),"\r\n = dq (q's exponent) =");
288         if(r) return r;
289         r = read_bigint(&(priv_key.components[4]),"\r\n = qInv (q' coefficient) =");
290         return r;
291 }
292
293 uint8_t read_key_conv(void){
294         uint8_t r;
295         priv_key.components = malloc(sizeof(bigint_t));
296         if(!priv_key.components){
297                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
298                 return 2;
299         }
300         cli_putstr_P(PSTR("\r\n== reading key (conv) =="));
301         r = read_bigint(&pub_key.modulus,"\r\n = module =");
302         if(r) return r;
303         memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
304         priv_key.n = 1;
305         r = read_bigint(&pub_key.exponent,"\r\n = public exponent =");
306         if(r) return r;
307         r = read_bigint(priv_key.components,"\r\n = private exponent =");
308         return r;
309 }
310
311 uint8_t load_bigint_from_os(bigint_t *a, PGM_VOID_P os, uint16_t length_B){
312         a->length_W = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
313         a->wordv = malloc(BIGINT_CEIL(length_B));
314         if(!a->wordv){
315                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
316                 return 1;
317         }
318         memset(a->wordv, 0, sizeof(bigint_word_t));
319         memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
320         a->info = 0;
321         bigint_changeendianess(a);
322         bigint_adjust(a);
323         return 0;
324 }
325
326 void load_fix_rsa(void){
327         if(keys_allocated){
328                 free_key();
329         }
330         keys_allocated = 1;
331
332         if(pre_alloc_key_crt()){
333                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
334                 return;
335         }
336
337         load_bigint_from_os(&pub_key.modulus, MODULUS, sizeof(MODULUS));
338         memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
339         load_bigint_from_os(&pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
340         priv_key.n = 5;
341         load_bigint_from_os(&(priv_key.components[0]), P, sizeof(P));
342         load_bigint_from_os(&(priv_key.components[1]), Q, sizeof(Q));
343         load_bigint_from_os(&(priv_key.components[2]), DP, sizeof(DP));
344         load_bigint_from_os(&(priv_key.components[3]), DQ, sizeof(DQ));
345         load_bigint_from_os(&(priv_key.components[4]), QINV, sizeof(QINV));
346 }
347
348 /*
349
350 uint8_t pre_alloc_key_crt(void){
351         uint8_t c;
352         pub_key.modulus = malloc(sizeof(bigint_t));
353         if(!pub_key.modulus){
354                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
355                 return 6;
356         }
357         priv_key.modulus = pub_key.modulus;
358         priv_key.n = 5;
359         priv_key.components = malloc(5 * sizeof(bigint_t*));
360         if(!priv_key.components){
361                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
362                 return 3;
363         }
364         pub_key.exponent = malloc(sizeof(bigint_t));
365         if(!pub_key.exponent){
366                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
367                 return 4;
368         }
369         for(c=0; c<5; ++c){
370                 priv_key.components[c] = malloc(sizeof(bigint_t));
371                 if(!priv_key.components[c]){
372                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
373                         return 7+c;
374                 }
375         }
376         return 0;
377 }
378
379 void free_key(void){
380         uint8_t c;
381         for(c = priv_key.n; c > 0 ; --c){
382                 free(priv_key.components[c - 1]->wordv);
383         }
384         free(pub_key.exponent->wordv);
385         free(pub_key.modulus->wordv);
386
387         for(c = priv_key.n; c > 0 ; --c){
388                 free(priv_key.components[c - 1]);
389         }
390         free(pub_key.exponent);
391         pub_key.exponent = NULL;
392         free(priv_key.components);
393         priv_key.components = NULL;
394         free(pub_key.modulus);
395         pub_key.modulus = priv_key.modulus = NULL;
396         keys_allocated = 0;
397 }
398
399 uint8_t read_key_crt(void){
400         uint8_t r;
401         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
402         r = pre_alloc_key_crt();
403         if(r) return r;
404         r = read_bigint(pub_key.modulus,"\r\n = module =");
405         if(r) return r;
406         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
407         if(r) return r;
408         r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
409         if(r) return r;
410         r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
411         if(r) return r;
412         r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
413         if(r) return r;
414         r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
415         if(r) return r;
416         r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
417
418 #if DEBUG
419         cli_putstr_P(PSTR("\r\nmodulus:"));
420         bigint_print_hex(pub_key.modulus);
421         cli_putstr_P(PSTR("\r\npublic exponent:"));
422         bigint_print_hex(pub_key.exponent);
423         cli_putstr_P(PSTR("\r\np:"));
424         bigint_print_hex(priv_key.components[0]);
425         cli_putstr_P(PSTR("\r\nq:"));
426         bigint_print_hex(priv_key.components[1]);
427         cli_putstr_P(PSTR("\r\ndP:"));
428         bigint_print_hex(priv_key.components[2]);
429         cli_putstr_P(PSTR("\r\ndQ:"));
430         bigint_print_hex(priv_key.components[3]);
431         cli_putstr_P(PSTR("\r\nqInv:"));
432         bigint_print_hex(priv_key.components[4]);
433 #endif
434         return r;
435 }
436
437 uint8_t read_key_conv(void){
438         uint8_t r;
439         cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
440         pub_key.modulus = malloc(sizeof(bigint_t));
441         if(!pub_key.modulus){
442                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
443                 return 2;
444         }
445         r = read_bigint(pub_key.modulus,"\r\n = module =");
446         if(r) return r;
447         priv_key.modulus = pub_key.modulus;
448         priv_key.n = 1;
449         pub_key.exponent = malloc(sizeof(bigint_t));
450         if(!pub_key.exponent){
451                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
452                 return 2;
453         }
454         priv_key.components = malloc(sizeof(bigint_t*));
455         if(!priv_key.components){
456                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
457                 return 2;
458         }
459         priv_key.components[0] = malloc(sizeof(bigint_t));
460         if(!priv_key.components[0]){
461                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
462                 return 2;
463         }
464         r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
465         if(r) return r;
466         r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
467         return r;
468 }
469
470 void load_priv_conventional(void){
471         bigint_t *epriv;
472         epriv = malloc(sizeof(bigint_t));
473         if(!epriv){
474                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
475                 return;
476         }
477         epriv->length_W = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
478         epriv->wordv =  malloc(epriv->length_W * sizeof(bigint_word_t));
479         if(!epriv->wordv){
480                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
481                 return;
482         }
483         memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
484         priv_key.components = malloc(sizeof(bigint_t*));
485         priv_key.components[0] = epriv;
486         priv_key.n = 1;
487         bigint_changeendianess(epriv);
488         bigint_adjust(epriv);
489 }
490
491
492 void load_priv_crt_mono(void){
493         bigint_t **v;
494         const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
495         uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
496         uint8_t i;
497         v = malloc(5 * sizeof(bigint_t));
498         if(!v){
499                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
500                 return;
501         }
502         priv_key.components = malloc(5*sizeof(bigint_t*));
503         if(!priv_key.components){
504                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
505                 return;
506         }
507         priv_key.n = 5;
508         for(i=0; i<5; ++i){
509                 v[i] = malloc(sizeof(bigint_t));
510                 v[i]->info = 0;
511                 v[i]->length_W = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
512                 v[i]->wordv = calloc(v[i]->length_W , sizeof(bigint_word_t));
513                 if(!v[i]->wordv){
514                         cli_putstr_P(PSTR("\r\nERROR: OOM!"));
515                         return;
516                 }
517                 memcpy(v[i]->wordv, bv[i], sv[i]);
518                 bigint_changeendianess(v[i]);
519                 bigint_adjust(v[i]);
520                 priv_key.components[i] = v[i];
521         }
522 }
523
524 uint8_t load_bigint_from_os(bigint_t *a, PGM_VOID_P os, uint16_t length_B){
525         a->length_W = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
526         a->wordv = malloc(BIGINT_CEIL(length_B));
527         if(!a->wordv){
528                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
529                 return 1;
530         }
531         memset(a->wordv, 0, sizeof(bigint_word_t));
532         memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
533         a->info = 0;
534         bigint_changeendianess(a);
535         bigint_adjust(a);
536         return 0;
537 }
538
539 void load_fix_rsa(void){
540         if(keys_allocated){
541                 free_key();
542         }
543         keys_allocated = 1;
544
545         if(pre_alloc_key_crt()){
546                 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
547                 return;
548         }
549
550         load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
551         load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
552         priv_key.n = 5;
553         load_bigint_from_os(priv_key.components[0], P, sizeof(P));
554         load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
555         load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
556         load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
557         load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
558
559 //      load_priv_conventional();
560 //      load_priv_crt_mono();
561 }
562 */
563
564 void quick_test(void){
565         uint8_t *ciphertext, *plaintext, rc;
566         uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)];
567         uint16_t clen, plen;
568         if(!keys_allocated){
569                 load_fix_rsa();
570         }
571         ciphertext = malloc(clen = bigint_length_B(&pub_key.modulus));
572         plaintext = malloc(clen);
573         memcpy_P(plaintext, MSG, sizeof(MSG));
574         memcpy_P(seed, SEED, sizeof(SEED));
575         cli_putstr_P(PSTR("\r\nplaintext:"));
576         cli_hexdump_block(plaintext, sizeof(MSG), 4, 16);
577         cli_putstr_P(PSTR("\r\nseed:"));
578         cli_hexdump_block(seed, sizeof(SEED), 4, 16);
579         cli_putstr_P(PSTR("\r\nencrypting: ..."));
580
581         rc = rsa_encrypt_pkcs1v15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed);
582         if(rc){
583                 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_pkcs1v15 returned: "));
584                 cli_hexdump_byte(rc);
585                 return;
586
587         }
588
589         cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
590         cli_hexdump_block(ciphertext, clen, 4, 16);
591         if(clen != sizeof(ENCRYPTED)){
592                         cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
593                         return;
594         }else{
595                 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
596                         cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
597                         return;
598                 }else{
599                         cli_putstr_P(PSTR("\r\n>>OK<<"));
600                 }
601         }
602
603         cli_putstr_P(PSTR("\r\ndecrypting: ..."));
604         rc = rsa_decrypt_pkcs1v15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out);
605         if(rc){
606                 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs1v15 returned: "));
607                 cli_hexdump_byte(rc);
608                 return;
609         }
610         cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
611         cli_hexdump_block(plaintext, plen, 4, 16);
612         cli_putstr_P(PSTR("\r\n\r\nseed (out):"));
613         cli_hexdump_block(seed_out, sizeof(SEED), 4, 16);
614
615         free(ciphertext);
616         free(plaintext);
617 }
618
619 void run_seed_test(void){
620         uint8_t *msg, *ciph, *msg_;
621         uint16_t ciph_len, msg_len;
622         uint16_t msg_len_;
623         uint16_t seed_len;
624         uint8_t *seed, *seed_out;
625         char read_int_str[18];
626         cli_putstr_P(PSTR("\r\n== test with given seed =="));
627         cli_putstr_P(PSTR("\r\n = message ="));
628         cli_putstr_P(PSTR("\r\n  length: "));
629         cli_getsn(read_int_str, 16);
630         msg_len = own_atou(read_int_str);
631         seed_len = rsa_pkcs1v15_compute_padlength_B(&pub_key.modulus, msg_len);
632         seed = malloc(seed_len);
633 #if DEBUG
634         cli_putstr_P(PSTR("\r\nDBG: @seed: 0x"));
635         cli_hexdump_rev(&seed, 2);
636 #endif
637         if(!seed){
638                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
639                 return;
640         }
641         seed_out = malloc(seed_len);
642 #if DEBUG
643         cli_putstr_P(PSTR("\r\nDBG: @seed_out: 0x"));
644         cli_hexdump_rev(&seed_out, 2);
645 #endif
646         if(!seed_out){
647                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
648                 return;
649         }
650         msg = malloc(msg_len);
651 #if DEBUG
652         cli_putstr_P(PSTR("\r\nDBG: @msg: 0x"));
653         cli_hexdump_rev(&msg, 2);
654 #endif
655         if(!msg){
656                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
657                 return;
658         }
659         ciph = malloc(bigint_length_B(&pub_key.modulus));
660 #if DEBUG
661         cli_putstr_P(PSTR("\r\nDBG: @ciph: 0x"));
662         cli_hexdump_rev(&ciph, 2);
663 #endif
664         if(!ciph){
665                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
666                 return;
667         }
668         msg_ = malloc(bigint_length_B(&pub_key.modulus) /* + sizeof(bigint_word_t) */ );
669 #if DEBUG
670         cli_putstr_P(PSTR("\r\nDBG: @msg_: 0x"));
671         cli_hexdump_rev(&msg_, 2);
672 #endif
673         if(!msg_){
674                 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
675                 return;
676         }
677         cli_putstr_P(PSTR("\r\n  data: "));
678         read_os(msg, msg_len, NULL);
679         cli_putstr_P(PSTR("\r\n  seed (0x"));
680         cli_hexdump_rev(&seed_len, 2);
681         cli_putstr_P(PSTR(" bytes): "));
682         read_os(seed, seed_len, NULL);
683
684         cli_putstr_P(PSTR("\r\n  encrypting ..."));
685 /*
686         cli_putstr_P(PSTR("\r\n plaintext:"));
687         cli_hexdump_block(msg, msg_len, 4, 16);
688         cli_putstr_P(PSTR("\r\n seed:"));
689         cli_hexdump_block(seed, seed_len, 4, 16);
690 */
691 #if DEBUG
692         cli_putstr_P(PSTR("\r\n  first prime:"));
693         bigint_print_hex(&priv_key.components[0]);
694 #endif
695         rsa_encrypt_pkcs1v15(ciph, &ciph_len, msg, msg_len, &pub_key, seed);
696         cli_putstr_P(PSTR("\r\n  ciphertext:"));
697         cli_hexdump_block(ciph, ciph_len, 4, 16);
698 #if DEBUG
699         cli_putstr_P(PSTR("\r\n  first prime:"));
700         bigint_print_hex(&priv_key.components[0]);
701 #endif
702         cli_putstr_P(PSTR("\r\n  decrypting ... "));
703
704         rsa_decrypt_pkcs1v15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out);
705
706         cli_putstr_P(PSTR("[done]"));
707         if(msg_len != msg_len_){
708                 char tstr[16];
709                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
710                 itoa(msg_len_, tstr, 10);
711                 cli_putstr(tstr);
712                 cli_putstr_P(PSTR(" instead of "));
713                 itoa(msg_len, tstr, 10);
714                 cli_putstr(tstr);
715                 cli_putc(')');
716                 goto end;
717         }
718         if(memcmp(msg, msg_, msg_len)){
719                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
720                 cli_hexdump_block(msg_, msg_len_, 4, 16);
721                 cli_putstr_P(PSTR("\r\nreference:"));
722                 cli_hexdump_block(msg, msg_len, 4, 16);
723                 goto end;
724         }
725
726         if(memcmp(seed, seed_out, seed_len)){
727                 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
728                 cli_hexdump_block(seed_out, seed_len, 4, 16);
729                 cli_putstr_P(PSTR("\r\nreference:"));
730                 cli_hexdump_block(seed, seed_len, 4, 16);
731                 goto end;
732         }
733
734         cli_putstr_P(PSTR("\r\n  >>OK<<"));
735 end:
736         free(msg_);
737         free(ciph);
738         free(msg);
739         free(seed_out);
740         free(seed);
741 }
742
743 void reset_prng(void){
744         uint8_t buf[16];
745         memset(buf, 0, 16);
746         random_seed(buf);
747         cli_putstr_P(PSTR("\r\nPRNG reset"));
748 }
749
750 void rsa_init(void){
751         prng_get_byte = random8;
752 }
753
754 void load_key(void){
755         uint8_t r;
756         if(keys_allocated){
757                 cli_putstr_P(PSTR("\r\nDBG: freeing old keys"));
758                 free_key();
759         }
760         keys_allocated = 1;
761         r = read_key_crt();
762         if(r){
763                 cli_putstr_P(PSTR("\r\nERROR: read_key_crt returned 0x"));
764                 cli_hexdump_byte(r);
765         }
766 }
767
768 void test_dump(void){
769         char lstr[16];
770         int len;
771         cli_putstr_P(PSTR("\r\nenter dump length: "));
772         cli_getsn_cecho(lstr, 15);
773         len = own_atou(lstr);
774         cli_putstr_P(PSTR("\r\ndumping 0x"));
775         cli_hexdump_rev(&len, 2);
776         cli_putstr_P(PSTR(" byte:"));
777         cli_hexdump_block(pub_key.modulus.wordv, len, 4, 8);
778 }
779
780 /*****************************************************************************
781  *  main                                                                                                                                         *
782  *****************************************************************************/
783
784 const char echo_test_str[]    PROGMEM = "echo-test";
785 const char reset_prng_str[]   PROGMEM = "reset-prng";
786 const char load_key_str[]     PROGMEM = "load-key";
787 const char load_fix_key_str[] PROGMEM = "load-fix-key";
788 const char quick_test_str[]   PROGMEM = "quick-test";
789 const char seed_test_str[]    PROGMEM = "seed-test";
790 const char dump_test_str[]    PROGMEM = "dump-test";
791 const char performance_str[]  PROGMEM = "performance";
792 const char echo_str[]         PROGMEM = "echo";
793
794 const cmdlist_entry_t cmdlist[] PROGMEM = {
795         { reset_prng_str,       NULL, reset_prng                    },
796         { load_key_str,         NULL, load_key                      },
797         { load_fix_key_str,     NULL, load_fix_rsa                  },
798         { quick_test_str,       NULL, quick_test                    },
799         { seed_test_str,        NULL, run_seed_test                 },
800         { dump_test_str,        NULL, test_dump                     },
801 //      { performance_str,      NULL, testrun_performance_bigint    },
802         { echo_str,         (void*)1, (void_fpt)echo_ctrl           },
803         { NULL,                 NULL, NULL                          }
804 };
805
806 void dump_sp(void){
807         uint8_t x;
808         uint8_t *xa = &x;
809         cli_putstr_P(PSTR("\r\nstack pointer: ~"));
810         cli_hexdump_rev(&xa, 4);
811 }
812
813 int main (void){
814         main_setup();
815
816         for(;;){
817                 welcome_msg(algo_name);
818                 rsa_init();
819                 cmd_interface(cmdlist);
820         }
821 }