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)<<"));
594 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
595 cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
597 cli_putstr_P(PSTR("\r\n>>OK<<"));
601 cli_putstr_P(PSTR("\r\ndecrypting: ..."));
602 rc = rsa_decrypt_pkcs1v15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out);
604 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_pkcs1v15 returned: "));
605 cli_hexdump_byte(rc);
608 cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
609 cli_hexdump_block(plaintext, plen, 4, 16);
610 cli_putstr_P(PSTR("\r\n\r\nseed (out):"));
611 cli_hexdump_block(seed_out, sizeof(SEED), 4, 16);
617 void run_seed_test(void){
618 uint8_t *msg, *ciph, *msg_;
619 uint16_t ciph_len, msg_len;
622 uint8_t *seed, *seed_out;
623 char read_int_str[18];
624 cli_putstr_P(PSTR("\r\n== test with given seed =="));
625 cli_putstr_P(PSTR("\r\n = message ="));
626 cli_putstr_P(PSTR("\r\n length: "));
627 cli_getsn(read_int_str, 16);
628 msg_len = own_atou(read_int_str);
629 seed_len = rsa_pkcs1v15_compute_padlength_B(&pub_key.modulus, msg_len);
630 seed = malloc(seed_len);
632 cli_putstr_P(PSTR("\r\nDBG: @seed: 0x"));
633 cli_hexdump_rev(&seed, 2);
636 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
639 seed_out = malloc(seed_len);
641 cli_putstr_P(PSTR("\r\nDBG: @seed_out: 0x"));
642 cli_hexdump_rev(&seed_out, 2);
645 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
648 msg = malloc(msg_len);
650 cli_putstr_P(PSTR("\r\nDBG: @msg: 0x"));
651 cli_hexdump_rev(&msg, 2);
654 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
657 ciph = malloc(bigint_length_B(&pub_key.modulus));
659 cli_putstr_P(PSTR("\r\nDBG: @ciph: 0x"));
660 cli_hexdump_rev(&ciph, 2);
663 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
666 msg_ = malloc(bigint_length_B(&pub_key.modulus) /* + sizeof(bigint_word_t) */ );
668 cli_putstr_P(PSTR("\r\nDBG: @msg_: 0x"));
669 cli_hexdump_rev(&msg_, 2);
672 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
675 cli_putstr_P(PSTR("\r\n data: "));
676 read_os(msg, msg_len, NULL);
677 cli_putstr_P(PSTR("\r\n seed (0x"));
678 cli_hexdump_rev(&seed_len, 2);
679 cli_putstr_P(PSTR(" bytes): "));
680 read_os(seed, seed_len, NULL);
682 cli_putstr_P(PSTR("\r\n encrypting ..."));
684 cli_putstr_P(PSTR("\r\n plaintext:"));
685 cli_hexdump_block(msg, msg_len, 4, 16);
686 cli_putstr_P(PSTR("\r\n seed:"));
687 cli_hexdump_block(seed, seed_len, 4, 16);
690 cli_putstr_P(PSTR("\r\n first prime:"));
691 bigint_print_hex(&priv_key.components[0]);
693 rsa_encrypt_pkcs1v15(ciph, &ciph_len, msg, msg_len, &pub_key, seed);
694 cli_putstr_P(PSTR("\r\n ciphertext:"));
695 cli_hexdump_block(ciph, ciph_len, 4, 16);
697 cli_putstr_P(PSTR("\r\n first prime:"));
698 bigint_print_hex(&priv_key.components[0]);
700 cli_putstr_P(PSTR("\r\n decrypting ... "));
702 rsa_decrypt_pkcs1v15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out);
704 cli_putstr_P(PSTR("[done]"));
705 if(msg_len != msg_len_){
707 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
708 itoa(msg_len_, tstr, 10);
710 cli_putstr_P(PSTR(" instead of "));
711 itoa(msg_len, tstr, 10);
716 if(memcmp(msg, msg_, msg_len)){
717 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
718 cli_hexdump_block(msg_, msg_len_, 4, 16);
719 cli_putstr_P(PSTR("\r\nreference:"));
720 cli_hexdump_block(msg, msg_len, 4, 16);
724 if(memcmp(seed, seed_out, seed_len)){
725 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
726 cli_hexdump_block(seed_out, seed_len, 4, 16);
727 cli_putstr_P(PSTR("\r\nreference:"));
728 cli_hexdump_block(seed, seed_len, 4, 16);
732 cli_putstr_P(PSTR("\r\n >>OK<<"));
741 void reset_prng(void){
745 cli_putstr_P(PSTR("\r\nPRNG reset"));
749 prng_get_byte = random8;
755 cli_putstr_P(PSTR("\r\nDBG: freeing old keys"));
761 cli_putstr_P(PSTR("\r\nERROR: read_key_crt returned 0x"));
766 void test_dump(void){
769 cli_putstr_P(PSTR("\r\nenter dump length: "));
770 cli_getsn_cecho(lstr, 15);
771 len = own_atou(lstr);
772 cli_putstr_P(PSTR("\r\ndumping 0x"));
773 cli_hexdump_rev(&len, 2);
774 cli_putstr_P(PSTR(" byte:"));
775 cli_hexdump_block(pub_key.modulus.wordv, len, 4, 8);
778 /*****************************************************************************
780 *****************************************************************************/
782 const char echo_test_str[] PROGMEM = "echo-test";
783 const char reset_prng_str[] PROGMEM = "reset-prng";
784 const char load_key_str[] PROGMEM = "load-key";
785 const char load_fix_key_str[] PROGMEM = "load-fix-key";
786 const char quick_test_str[] PROGMEM = "quick-test";
787 const char seed_test_str[] PROGMEM = "seed-test";
788 const char dump_test_str[] PROGMEM = "dump-test";
789 const char performance_str[] PROGMEM = "performance";
790 const char echo_str[] PROGMEM = "echo";
792 const cmdlist_entry_t cmdlist[] PROGMEM = {
793 { reset_prng_str, NULL, reset_prng },
794 { load_key_str, NULL, load_key },
795 { load_fix_key_str, NULL, load_fix_rsa },
796 { quick_test_str, NULL, quick_test },
797 { seed_test_str, NULL, run_seed_test },
798 { dump_test_str, NULL, test_dump },
799 // { performance_str, NULL, testrun_performance_bigint },
800 { echo_str, (void*)1, (void_fpt)echo_ctrl },
807 cli_putstr_P(PSTR("\r\nstack pointer: ~"));
808 cli_hexdump_rev(&xa, 4);
815 welcome_msg(algo_name);
817 cmd_interface(cmdlist);