3 This file is part of the ARM-Crypto-Lib.
4 Copyright (C) 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 #include "main-test-common.h"
26 #include "noekeon_prng.h"
28 #include "bigint_io.h"
29 #include "random_dummy.h"
30 #include "rsa_basic.h"
31 #include "rsaes_pkcs1v15.h"
33 #include "performance_test.h"
37 const char* algo_name = "RSAES-PKCS1V15";
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))
42 /*****************************************************************************
43 * additional validation-functions *
44 *****************************************************************************/
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
58 /* Public exponent: */
59 const uint8_t pub_exponent[] PROGMEM = { 0x01, 0x00, 0x01 };
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
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
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
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
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
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
113 /* PKCS#1 v1.5 encryption of 0x20, random messages with random s0xee,ds
114 * ---------------------------------------------------------------------------
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
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,
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
145 uint8_t keys_allocated = 0;
146 rsa_publickey_t pub_key;
147 rsa_privatekey_t priv_key;
150 #define MSG message_x
152 #define ENCRYPTED encrypted_x
153 #define MODULUS modulus
154 #define PUB_EXPONENT pub_exponent
155 #define PRIV_EXPONENT priv_exponent
164 uint8_t convert_nibble(uint8_t c){
165 if(c>='0' && c<='9'){
169 if(c>='a' && c<='f'){
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;
180 uint8_t v, tmp = 0, idx = 0;
182 ignore_string = block_ignore_string;
184 while(counter < length){
189 if(strchr(ignore_string, c)){
192 v = convert_nibble(c);
197 ((uint8_t*)dst)[counter++] = (tmp << 4) | v;
199 if(counter % (BUFFER_LIMIT/2) == 0){
210 uint16_t own_atou(const char* str){
212 while(*str && *str >= '0' && *str <= '9'){
219 uint8_t read_bigint(bigint_t* a, char* prompt){
220 uint16_t read_length, actual_length;
223 char read_int_str[18];
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));
231 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
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!"));
242 a->wordv = (bigint_word_t*)buffer;
243 a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
245 bigint_changeendianess(a);
250 uint8_t pre_alloc_key_crt(void){
252 pub_key.modulus = malloc(sizeof(bigint_t));
253 if(!pub_key.modulus){
254 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
257 priv_key.modulus = pub_key.modulus;
259 priv_key.components = malloc(5 * sizeof(bigint_t*));
260 if(!priv_key.components){
261 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
264 pub_key.exponent = malloc(sizeof(bigint_t));
265 if(!pub_key.exponent){
266 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
270 priv_key.components[c] = malloc(sizeof(bigint_t));
271 if(!priv_key.components[c]){
272 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
281 for(c = priv_key.n; c > 0 ; --c){
282 free(priv_key.components[c - 1]->wordv);
284 free(pub_key.exponent->wordv);
285 free(pub_key.modulus->wordv);
287 for(c = priv_key.n; c > 0 ; --c){
288 free(priv_key.components[c - 1]);
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;
299 uint8_t read_key_crt(void){
301 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
302 r = pre_alloc_key_crt();
304 r = read_bigint(pub_key.modulus,"\r\n = module =");
306 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
308 r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
310 r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
312 r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
314 r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
316 r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
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]);
337 uint8_t read_key_conv(void){
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!"));
345 r = read_bigint(pub_key.modulus,"\r\n = module =");
347 priv_key.modulus = pub_key.modulus;
349 pub_key.exponent = malloc(sizeof(bigint_t));
350 if(!pub_key.exponent){
351 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
354 priv_key.components = malloc(sizeof(bigint_t*));
355 if(!priv_key.components){
356 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
359 priv_key.components[0] = malloc(sizeof(bigint_t));
360 if(!priv_key.components[0]){
361 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
364 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
366 r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
370 void load_priv_conventional(void){
372 epriv = malloc(sizeof(bigint_t));
374 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
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));
380 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
383 memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
384 priv_key.components = malloc(sizeof(bigint_t*));
385 priv_key.components[0] = epriv;
387 bigint_changeendianess(epriv);
388 bigint_adjust(epriv);
392 void load_priv_crt_mono(void){
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)};
397 v = malloc(5 * sizeof(bigint_t));
399 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
402 priv_key.components = malloc(5*sizeof(bigint_t*));
403 if(!priv_key.components){
404 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
409 v[i] = malloc(sizeof(bigint_t));
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));
414 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
417 memcpy(v[i]->wordv, bv[i], sv[i]);
418 bigint_changeendianess(v[i]);
420 priv_key.components[i] = v[i];
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));
428 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
431 memset(a->wordv, 0, sizeof(bigint_word_t));
432 memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
434 bigint_changeendianess(a);
439 void load_fix_rsa(void){
445 if(pre_alloc_key_crt()){
446 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
450 load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
451 load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
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));
459 // load_priv_conventional();
460 // load_priv_crt_mono();
463 void quick_test(void){
464 uint8_t *ciphertext, *plaintext, rc;
465 uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)];
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: ..."));
480 rc = rsa_encrypt_pkcs1v15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed);
482 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_pkcs1v15 returned: "));
483 cli_hexdump_byte(rc);
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)<<"));
493 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
494 cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
496 cli_putstr_P(PSTR("\r\n>>OK<<"));
500 cli_putstr_P(PSTR("\r\ndecrypting: ..."));
501 rc = rsa_decrypt_pkcs1v15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out);
503 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs1v15 returned: "));
504 cli_hexdump_byte(rc);
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);
516 void run_seed_test(void){
517 uint8_t *msg, *ciph, *msg_;
518 uint16_t ciph_len, msg_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);
531 cli_putstr_P(PSTR("\r\nDBG: @seed: 0x"));
532 cli_hexdump_rev(&seed, 2);
535 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
538 seed_out = malloc(seed_len);
540 cli_putstr_P(PSTR("\r\nDBG: @seed_out: 0x"));
541 cli_hexdump_rev(&seed_out, 2);
544 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
547 msg = malloc(msg_len);
549 cli_putstr_P(PSTR("\r\nDBG: @msg: 0x"));
550 cli_hexdump_rev(&msg, 2);
553 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
556 ciph = malloc(bigint_length_B(pub_key.modulus));
558 cli_putstr_P(PSTR("\r\nDBG: @ciph: 0x"));
559 cli_hexdump_rev(&ciph, 2);
562 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
565 msg_ = malloc(bigint_length_B(pub_key.modulus) + sizeof(bigint_word_t));
567 cli_putstr_P(PSTR("\r\nDBG: @msg_: 0x"));
568 cli_hexdump_rev(&msg_, 2);
571 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
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);
581 cli_putstr_P(PSTR("\r\n encrypting ..."));
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);
589 cli_putstr_P(PSTR("\r\n first prime:"));
590 bigint_print_hex(priv_key.components[0]);
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);
596 cli_putstr_P(PSTR("\r\n first prime:"));
597 bigint_print_hex(priv_key.components[0]);
599 cli_putstr_P(PSTR("\r\n decrypting ... "));
601 rsa_decrypt_pkcs1v15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out);
603 cli_putstr_P(PSTR("[done]"));
604 if(msg_len != msg_len_){
606 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
607 itoa(msg_len_, tstr, 10);
609 cli_putstr_P(PSTR(" instead of "));
610 itoa(msg_len, tstr, 10);
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);
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);
631 cli_putstr_P(PSTR("\r\n >>OK<<"));
640 void reset_prng(void){
644 cli_putstr_P(PSTR("\r\nPRNG reset"));
648 prng_get_byte = random8;
654 cli_putstr_P(PSTR("\r\nDBG: freeing old keys"));
660 cli_putstr_P(PSTR("\r\nERROR: read_key_crt returned 0x"));
665 void test_dump(void){
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);
677 /*****************************************************************************
679 *****************************************************************************/
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";
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 },
706 cli_putstr_P(PSTR("\r\nstack pointer: ~"));
707 cli_hexdump_rev(&xa, 4);
714 welcome_msg(algo_name);
716 cmd_interface(cmdlist);