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 "rsa_pkcs15.h"
33 #include "performance_test.h"
35 const char* algo_name = "RSA-PKCS15";
37 #define BIGINT_CEIL(x) ((((x) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t))
38 #define BIGINT_OFF(x) ((sizeof(bigint_word_t) - (x) % sizeof(bigint_word_t)) % sizeof(bigint_word_t))
40 /*****************************************************************************
41 * additional validation-functions *
42 *****************************************************************************/
45 const uint8_t modulus[] PROGMEM = {
46 0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4,
47 0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab,
48 0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85,
49 0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72,
50 0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97,
51 0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14,
52 0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24,
53 0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb
56 /* Public exponent: */
57 const uint8_t pub_exponent[] PROGMEM = { 0x01, 0x00, 0x01 };
60 const uint8_t priv_exponent[] PROGMEM = {
61 0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c,
62 0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd,
63 0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b,
64 0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55,
65 0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73,
66 0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf,
67 0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde,
68 0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1
72 const uint8_t p[] PROGMEM = {
73 0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b,
74 0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a,
75 0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1,
76 0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d
80 const uint8_t q[] PROGMEM = {
81 0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7,
82 0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c,
83 0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe,
84 0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77
87 /* Prime exponent 1: */
88 const uint8_t dp[] PROGMEM = {
89 0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04,
90 0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3,
91 0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d,
92 0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1
95 /* Prime exponent 2: */
96 const uint8_t dq[] PROGMEM = {
97 0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc,
98 0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73,
99 0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a,
100 0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83
104 const uint8_t qinv[] PROGMEM = {
105 0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d,
106 0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11,
107 0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81,
108 0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1
111 /* PKCS#1 v1.5 encryption of 0x20, random messages with random s0xee,ds
112 * ---------------------------------------------------------------------------
116 const uint8_t message_x[] PROGMEM = {
117 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23,
118 0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34
122 const uint8_t seed_x[] PROGMEM = {
123 0x01, 0x73, 0x41, 0xae, 0x38, 0x75, 0xd5, 0xf8, 0x71, 0x01, 0xf8, 0xcc, 0x4f, 0xa9, 0xb9, 0xbc,
124 0x15, 0x6b, 0xb0, 0x46, 0x28, 0xfc, 0xcd, 0xb2, 0xf4, 0xf1, 0x1e, 0x90, 0x5b, 0xd3, 0xa1, 0x55,
125 0xd3, 0x76, 0xf5, 0x93, 0xbd, 0x73, 0x04, 0x21, 0x08, 0x74, 0xeb, 0xa0, 0x8a, 0x5e, 0x22, 0xbc,
126 0xcc, 0xb4, 0xc9, 0xd3, 0x88, 0x2a, 0x93, 0xa5, 0x4d, 0xb0, 0x22, 0xf5, 0x03, 0xd1, 0x63, 0x38,
127 0xb6, 0xb7, 0xce, 0x16, 0xdc, 0x7f, 0x4b, 0xbf, 0x9a, 0x96, 0xb5, 0x97, 0x72, 0xd6, 0x60, 0x6e,
128 0x97, 0x47, 0xc7, 0x64, 0x9b, 0xf9, 0xe0, 0x83, 0xdb, 0x98, 0x18, 0x84, 0xa9, 0x54, 0xab, 0x3c,
132 const uint8_t encrypted_x[] PROGMEM = {
133 0x50, 0xb4, 0xc1, 0x41, 0x36, 0xbd, 0x19, 0x8c, 0x2f, 0x3c, 0x3e, 0xd2, 0x43, 0xfc, 0xe0, 0x36,
134 0xe1, 0x68, 0xd5, 0x65, 0x17, 0x98, 0x4a, 0x26, 0x3c, 0xd6, 0x64, 0x92, 0xb8, 0x08, 0x04, 0xf1,
135 0x69, 0xd2, 0x10, 0xf2, 0xb9, 0xbd, 0xfb, 0x48, 0xb1, 0x2f, 0x9e, 0xa0, 0x50, 0x09, 0xc7, 0x7d,
136 0xa2, 0x57, 0xcc, 0x60, 0x0c, 0xce, 0xfe, 0x3a, 0x62, 0x83, 0x78, 0x9d, 0x8e, 0xa0, 0xe6, 0x07,
137 0xac, 0x58, 0xe2, 0x69, 0x0e, 0xc4, 0xeb, 0xc1, 0x01, 0x46, 0xe8, 0xcb, 0xaa, 0x5e, 0xd4, 0xd5,
138 0xcc, 0xe6, 0xfe, 0x7b, 0x0f, 0xf9, 0xef, 0xc1, 0xea, 0xbb, 0x56, 0x4d, 0xbf, 0x49, 0x82, 0x85,
139 0xf4, 0x49, 0xee, 0x61, 0xdd, 0x7b, 0x42, 0xee, 0x5b, 0x58, 0x92, 0xcb, 0x90, 0x60, 0x1f, 0x30,
140 0xcd, 0xa0, 0x7b, 0xf2, 0x64, 0x89, 0x31, 0x0b, 0xcd, 0x23, 0xb5, 0x28, 0xce, 0xab, 0x3c, 0x31
143 uint8_t keys_allocated = 0;
144 rsa_publickey_t pub_key;
145 rsa_privatekey_t priv_key;
148 #define MSG message_x
150 #define ENCRYPTED encrypted_x
151 #define MODULUS modulus
152 #define PUB_EXPONENT pub_exponent
153 #define PRIV_EXPONENT priv_exponent
162 uint8_t convert_nibble(uint8_t c){
163 if(c>='0' && c<='9'){
167 if(c>='a' && c<='f'){
173 const char *block_ignore_string=" \t\r\n,;";
174 #define BUFFER_LIMIT 120
175 uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){
176 uint16_t counter = 0;
178 uint8_t v, tmp = 0, idx = 0;
180 ignore_string = block_ignore_string;
182 while(counter < length){
187 if(strchr(ignore_string, c)){
190 v = convert_nibble(c);
195 ((uint8_t*)dst)[counter++] = (tmp << 4) | v;
197 if(counter % (BUFFER_LIMIT/2) == 0){
208 uint16_t own_atou(const char* str){
210 while(*str && *str >= '0' && *str <= '9'){
217 uint8_t read_bigint(bigint_t* a, char* prompt){
218 uint16_t read_length, actual_length;
221 char read_int_str[18];
223 cli_putstr_P(PSTR("\r\n length: "));
224 cli_getsn(read_int_str, 16);
225 read_length = own_atou(read_int_str);
226 off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
227 buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
229 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
232 cli_putstr_P(PSTR("\r\n data: "));
233 memset(buffer, 0, sizeof(bigint_word_t));
234 actual_length = read_os(buffer + off, read_length, NULL);
235 if(actual_length != read_length){
236 cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!"));
240 a->wordv = (bigint_word_t*)buffer;
241 a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
242 bigint_changeendianess(a);
247 uint8_t pre_alloc_key_crt(void){
249 pub_key.modulus = malloc(sizeof(bigint_t));
250 if(!pub_key.modulus){
251 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
254 priv_key.modulus = pub_key.modulus;
256 priv_key.components = malloc(5 * sizeof(bigint_t*));
257 if(!priv_key.components){
258 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
261 pub_key.exponent = malloc(sizeof(bigint_t));
262 if(!pub_key.exponent){
263 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
267 priv_key.components[c] = malloc(sizeof(bigint_t));
268 if(!priv_key.components[c]){
269 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
278 free(pub_key.modulus->wordv);
279 free(pub_key.exponent->wordv);
280 free(pub_key.modulus);
281 pub_key.modulus = priv_key.modulus = NULL;
282 free(pub_key.exponent);
283 pub_key.exponent = NULL;
284 for(c = 0; c < priv_key.n; ++c){
285 free(priv_key.components[c]->wordv);
286 free(priv_key.components[c]);
288 free(priv_key.components);
289 priv_key.components = NULL;
292 uint8_t read_key_crt(void){
294 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
295 r = pre_alloc_key_crt();
297 r = read_bigint(pub_key.modulus,"\r\n = module =");
299 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
301 r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
303 r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
305 r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
307 r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
309 r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
311 cli_putstr_P(PSTR("\r\nmodulus:"));
312 bigint_print_hex(pub_key.modulus);
313 cli_putstr_P(PSTR("\r\npublic exponent:"));
314 bigint_print_hex(pub_key.exponent);
315 cli_putstr_P(PSTR("\r\np:"));
316 bigint_print_hex(priv_key.components[0]);
317 cli_putstr_P(PSTR("\r\nq:"));
318 bigint_print_hex(priv_key.components[1]);
319 cli_putstr_P(PSTR("\r\ndP:"));
320 bigint_print_hex(priv_key.components[2]);
321 cli_putstr_P(PSTR("\r\ndQ:"));
322 bigint_print_hex(priv_key.components[3]);
323 cli_putstr_P(PSTR("\r\nqInv:"));
324 bigint_print_hex(priv_key.components[4]);
329 uint8_t read_key_conv(void){
331 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
332 pub_key.modulus = malloc(sizeof(bigint_t));
333 if(!pub_key.modulus){
334 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
337 r = read_bigint(pub_key.modulus,"\r\n = module =");
339 priv_key.modulus = pub_key.modulus;
341 pub_key.exponent = malloc(sizeof(bigint_t));
342 if(!pub_key.exponent){
343 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
346 priv_key.components = malloc(sizeof(bigint_t*));
347 if(!priv_key.components){
348 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
351 priv_key.components[0] = malloc(sizeof(bigint_t));
352 if(!priv_key.components[0]){
353 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
356 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
358 r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
362 void load_priv_conventional(void){
364 epriv = malloc(sizeof(bigint_t));
366 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
369 epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
370 epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t));
372 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
375 memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
376 priv_key.components = malloc(sizeof(bigint_t*));
377 priv_key.components[0] = epriv;
379 bigint_changeendianess(epriv);
380 bigint_adjust(epriv);
384 void load_priv_crt_mono(void){
386 const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
387 uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
389 v = malloc(5 * sizeof(bigint_t));
391 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
394 priv_key.components = malloc(5*sizeof(bigint_t*));
395 if(!priv_key.components){
396 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
401 v[i] = malloc(sizeof(bigint_t));
403 v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
404 v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
406 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
409 memcpy(v[i]->wordv, bv[i], sv[i]);
410 bigint_changeendianess(v[i]);
412 priv_key.components[i] = v[i];
416 uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
417 a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
418 a->wordv = malloc(BIGINT_CEIL(length_B));
420 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
423 memset(a->wordv, 0, sizeof(bigint_word_t));
424 memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
426 bigint_changeendianess(a);
431 void load_fix_rsa(void){
437 if(pre_alloc_key_crt()){
438 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
442 load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
443 load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
445 load_bigint_from_os(priv_key.components[0], P, sizeof(P));
446 load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
447 load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
448 load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
449 load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
451 // load_priv_conventional();
452 // load_priv_crt_mono();
455 void quick_test(void){
456 uint8_t *ciphertext, *plaintext, rc;
457 uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)];
462 ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
463 plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
464 memcpy_P(plaintext, MSG, sizeof(MSG));
465 memcpy_P(seed, SEED, sizeof(SEED));
466 cli_putstr_P(PSTR("\r\nplaintext:"));
467 cli_hexdump_block(plaintext, sizeof(MSG), 4, 16);
468 cli_putstr_P(PSTR("\r\nseed:"));
469 cli_hexdump_block(seed, sizeof(SEED), 4, 16);
470 cli_putstr_P(PSTR("\r\nencrypting: ..."));
472 rc = rsa_encrypt_pkcs15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed);
474 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_pkcs15 returned: "));
475 cli_hexdump_byte(rc);
480 cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
481 cli_hexdump_block(ciphertext, clen, 4, 16);
482 if(clen!=sizeof(ENCRYPTED)){
483 cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
485 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
486 cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
488 cli_putstr_P(PSTR("\r\n>>OK<<"));
492 cli_putstr_P(PSTR("\r\ndecrypting: ..."));
493 rc = rsa_decrypt_pkcs15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out);
495 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs15 returned: "));
496 cli_hexdump_byte(rc);
499 cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
500 cli_hexdump_block(plaintext, plen, 4, 16);
501 cli_putstr_P(PSTR("\r\n\r\nseed (out):"));
502 cli_hexdump_block(seed_out, sizeof(SEED), 4, 16);
508 void run_seed_test(void){
509 uint8_t *msg, *ciph, *msg_;
510 uint16_t msg_len, ciph_len, msg_len_;
512 uint8_t *seed, *seed_out;
513 char read_int_str[18];
514 cli_putstr_P(PSTR("\r\n== test with given seed =="));
515 cli_putstr_P(PSTR("\r\n = message ="));
516 cli_putstr_P(PSTR("\r\n length: "));
517 cli_getsn(read_int_str, 16);
518 msg_len = own_atou(read_int_str);
519 seed_len = rsa_pkcs15_compute_padlength_B(pub_key.modulus, msg_len);
520 seed = malloc(seed_len);
522 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
525 seed_out = malloc(seed_len);
527 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
530 msg = malloc(msg_len);
532 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
535 ciph = malloc(bigint_length_B(pub_key.modulus));
537 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
540 msg_ = malloc(bigint_length_B(pub_key.modulus));
542 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
545 cli_putstr_P(PSTR("\r\n data: "));
546 read_os(msg, msg_len, NULL);
547 cli_putstr_P(PSTR("\r\n seed (0x"));
548 cli_hexdump_rev(&seed_len, 2);
549 cli_putstr_P(PSTR(" bytes): "));
550 read_os(seed, seed_len, NULL);
552 cli_putstr_P(PSTR("\r\n encrypting ..."));
554 cli_putstr_P(PSTR("\r\n plaintext:"));
555 cli_hexdump_block(msg, msg_len, 4, 16);
556 cli_putstr_P(PSTR("\r\n seed:"));
557 cli_hexdump_block(seed, seed_len, 4, 16);
559 rsa_encrypt_pkcs15(ciph, &ciph_len, msg, msg_len, &pub_key, seed);
560 cli_putstr_P(PSTR("\r\n ciphertext:"));
561 cli_hexdump_block(ciph, ciph_len, 4, 16);
562 cli_putstr_P(PSTR("\r\n decrypting ... "));
563 rsa_decrypt_pkcs15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out);
564 cli_putstr_P(PSTR("[done]"));
565 if(msg_len != msg_len_){
567 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
568 itoa(msg_len_, tstr, 10);
570 cli_putstr_P(PSTR(" instead of "));
571 itoa(msg_len, tstr, 10);
576 if(memcmp(msg, msg_, msg_len)){
577 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
578 cli_hexdump_block(msg_, msg_len_, 4, 16);
579 cli_putstr_P(PSTR("\r\nreference:"));
580 cli_hexdump_block(msg, msg_len, 4, 16);
584 if(memcmp(seed, seed_out, seed_len)){
585 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
586 cli_hexdump_block(seed_out, seed_len, 4, 16);
587 cli_putstr_P(PSTR("\r\nreference:"));
588 cli_hexdump_block(seed, seed_len, 4, 16);
591 cli_putstr_P(PSTR("\r\n >>OK<<"));
600 void reset_prng(void){
604 cli_putstr_P(PSTR("\r\nPRNG reset"));
608 prng_get_byte = random8;
619 void test_dump(void){
622 cli_putstr_P(PSTR("\r\nenter dump length: "));
623 cli_getsn_cecho(lstr, 15);
624 len = own_atou(lstr);
625 cli_putstr_P(PSTR("\r\ndumping 0x"));
626 cli_hexdump_rev(&len, 2);
627 cli_putstr_P(PSTR(" byte:"));
628 cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
631 /*****************************************************************************
633 *****************************************************************************/
635 const char echo_test_str[] PROGMEM = "echo-test";
636 const char reset_prng_str[] PROGMEM = "reset-prng";
637 const char load_key_str[] PROGMEM = "load-key";
638 const char load_fix_key_str[] PROGMEM = "load-fix-key";
639 const char quick_test_str[] PROGMEM = "quick-test";
640 const char seed_test_str[] PROGMEM = "seed-test";
641 const char dump_test_str[] PROGMEM = "dump-test";
642 const char performance_str[] PROGMEM = "performance";
643 const char echo_str[] PROGMEM = "echo";
645 const cmdlist_entry_t cmdlist[] PROGMEM = {
646 { reset_prng_str, NULL, reset_prng },
647 { load_key_str, NULL, load_key },
648 { load_fix_key_str, NULL, load_fix_rsa },
649 { quick_test_str, NULL, quick_test },
650 { seed_test_str, NULL, run_seed_test },
651 { dump_test_str, NULL, test_dump },
652 // { performance_str, NULL, testrun_performance_bigint },
653 { echo_str, (void*)1, (void_fpt)echo_ctrl },
660 cli_putstr_P(PSTR("\r\nstack pointer: ~"));
661 cli_hexdump_rev(&xa, 4);
668 welcome_msg(algo_name);
670 cmd_interface(cmdlist);