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_W = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
245 bigint_changeendianess(a);
250 uint8_t pre_alloc_key_crt(void){
252 priv_key.components = malloc(5 * sizeof(bigint_t));
253 if(!priv_key.components){
254 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
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);
267 free(priv_key.components);
271 uint8_t read_key_crt(void){
273 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
274 r = pre_alloc_key_crt();
276 r = read_bigint(&pub_key.modulus,"\r\n = module =");
278 memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
279 r = read_bigint(&pub_key.exponent,"\r\n = public exponent =");
281 r = read_bigint(&(priv_key.components[0]),"\r\n = p (first prime) =");
283 r = read_bigint(&(priv_key.components[1]),"\r\n = q (second prime) =");
285 r = read_bigint(&(priv_key.components[2]),"\r\n = dp (p's exponent) =");
287 r = read_bigint(&(priv_key.components[3]),"\r\n = dq (q's exponent) =");
289 r = read_bigint(&(priv_key.components[4]),"\r\n = qInv (q' coefficient) =");
293 uint8_t read_key_conv(void){
295 priv_key.components = malloc(sizeof(bigint_t));
296 if(!priv_key.components){
297 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
300 cli_putstr_P(PSTR("\r\n== reading key (conv) =="));
301 r = read_bigint(&pub_key.modulus,"\r\n = module =");
303 memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
305 r = read_bigint(&pub_key.exponent,"\r\n = public exponent =");
307 r = read_bigint(priv_key.components,"\r\n = private exponent =");
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));
315 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
318 memset(a->wordv, 0, sizeof(bigint_word_t));
319 memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
321 bigint_changeendianess(a);
326 void load_fix_rsa(void){
332 if(pre_alloc_key_crt()){
333 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
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));
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));
350 uint8_t pre_alloc_key_crt(void){
352 pub_key.modulus = malloc(sizeof(bigint_t));
353 if(!pub_key.modulus){
354 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
357 priv_key.modulus = pub_key.modulus;
359 priv_key.components = malloc(5 * sizeof(bigint_t*));
360 if(!priv_key.components){
361 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
364 pub_key.exponent = malloc(sizeof(bigint_t));
365 if(!pub_key.exponent){
366 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
370 priv_key.components[c] = malloc(sizeof(bigint_t));
371 if(!priv_key.components[c]){
372 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
381 for(c = priv_key.n; c > 0 ; --c){
382 free(priv_key.components[c - 1]->wordv);
384 free(pub_key.exponent->wordv);
385 free(pub_key.modulus->wordv);
387 for(c = priv_key.n; c > 0 ; --c){
388 free(priv_key.components[c - 1]);
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;
399 uint8_t read_key_crt(void){
401 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
402 r = pre_alloc_key_crt();
404 r = read_bigint(pub_key.modulus,"\r\n = module =");
406 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
408 r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
410 r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
412 r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
414 r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
416 r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
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]);
437 uint8_t read_key_conv(void){
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!"));
445 r = read_bigint(pub_key.modulus,"\r\n = module =");
447 priv_key.modulus = pub_key.modulus;
449 pub_key.exponent = malloc(sizeof(bigint_t));
450 if(!pub_key.exponent){
451 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
454 priv_key.components = malloc(sizeof(bigint_t*));
455 if(!priv_key.components){
456 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
459 priv_key.components[0] = malloc(sizeof(bigint_t));
460 if(!priv_key.components[0]){
461 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
464 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
466 r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
470 void load_priv_conventional(void){
472 epriv = malloc(sizeof(bigint_t));
474 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
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));
480 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
483 memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
484 priv_key.components = malloc(sizeof(bigint_t*));
485 priv_key.components[0] = epriv;
487 bigint_changeendianess(epriv);
488 bigint_adjust(epriv);
492 void load_priv_crt_mono(void){
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)};
497 v = malloc(5 * sizeof(bigint_t));
499 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
502 priv_key.components = malloc(5*sizeof(bigint_t*));
503 if(!priv_key.components){
504 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
509 v[i] = malloc(sizeof(bigint_t));
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));
514 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
517 memcpy(v[i]->wordv, bv[i], sv[i]);
518 bigint_changeendianess(v[i]);
520 priv_key.components[i] = v[i];
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));
528 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
531 memset(a->wordv, 0, sizeof(bigint_word_t));
532 memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
534 bigint_changeendianess(a);
539 void load_fix_rsa(void){
545 if(pre_alloc_key_crt()){
546 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
550 load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
551 load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
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));
559 // load_priv_conventional();
560 // load_priv_crt_mono();
564 void quick_test(void){
565 uint8_t *ciphertext, *plaintext, rc;
566 uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)];
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: ..."));
581 rc = rsa_encrypt_pkcs1v15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed);
583 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_pkcs1v15 returned: "));
584 cli_hexdump_byte(rc);
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)<<"));
595 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
596 cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
599 cli_putstr_P(PSTR("\r\n>>OK<<"));
603 cli_putstr_P(PSTR("\r\ndecrypting: ..."));
604 rc = rsa_decrypt_pkcs1v15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out);
606 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs1v15 returned: "));
607 cli_hexdump_byte(rc);
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);
619 void run_seed_test(void){
620 uint8_t *msg, *ciph, *msg_;
621 uint16_t ciph_len, msg_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);
634 cli_putstr_P(PSTR("\r\nDBG: @seed: 0x"));
635 cli_hexdump_rev(&seed, 2);
638 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
641 seed_out = malloc(seed_len);
643 cli_putstr_P(PSTR("\r\nDBG: @seed_out: 0x"));
644 cli_hexdump_rev(&seed_out, 2);
647 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
650 msg = malloc(msg_len);
652 cli_putstr_P(PSTR("\r\nDBG: @msg: 0x"));
653 cli_hexdump_rev(&msg, 2);
656 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
659 ciph = malloc(bigint_length_B(&pub_key.modulus));
661 cli_putstr_P(PSTR("\r\nDBG: @ciph: 0x"));
662 cli_hexdump_rev(&ciph, 2);
665 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
668 msg_ = malloc(bigint_length_B(&pub_key.modulus) /* + sizeof(bigint_word_t) */ );
670 cli_putstr_P(PSTR("\r\nDBG: @msg_: 0x"));
671 cli_hexdump_rev(&msg_, 2);
674 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
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);
684 cli_putstr_P(PSTR("\r\n encrypting ..."));
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);
692 cli_putstr_P(PSTR("\r\n first prime:"));
693 bigint_print_hex(&priv_key.components[0]);
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);
699 cli_putstr_P(PSTR("\r\n first prime:"));
700 bigint_print_hex(&priv_key.components[0]);
702 cli_putstr_P(PSTR("\r\n decrypting ... "));
704 rsa_decrypt_pkcs1v15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out);
706 cli_putstr_P(PSTR("[done]"));
707 if(msg_len != msg_len_){
709 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
710 itoa(msg_len_, tstr, 10);
712 cli_putstr_P(PSTR(" instead of "));
713 itoa(msg_len, tstr, 10);
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);
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);
734 cli_putstr_P(PSTR("\r\n >>OK<<"));
743 void reset_prng(void){
747 cli_putstr_P(PSTR("\r\nPRNG reset"));
751 prng_get_byte = random8;
757 cli_putstr_P(PSTR("\r\nDBG: freeing old keys"));
763 cli_putstr_P(PSTR("\r\nERROR: read_key_crt returned 0x"));
768 void test_dump(void){
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);
780 /*****************************************************************************
782 *****************************************************************************/
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";
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 },
809 cli_putstr_P(PSTR("\r\nstack pointer: ~"));
810 cli_hexdump_rev(&xa, 4);
817 welcome_msg(algo_name);
819 cmd_interface(cmdlist);