]> git.cryptolib.org Git - arm-crypto-lib.git/blob - test_src/main-rsaes_pkcs1v15-test.c
c0ccd6c1ad520d30f230f26befc534fc8edfade4
[arm-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) 2010 Daniel Otte (daniel.otte@rub.de)
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 const char* algo_name = "RSAES-PKCS15";
36
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))
39
40 /*****************************************************************************
41  *  additional validation-functions                                                                                      *
42  *****************************************************************************/
43
44 /* Modulus: */
45 const uint8_t modulus[]  = {
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
54 };
55
56 /* Public exponent: */
57 const uint8_t pub_exponent[]  = { 0x01, 0x00, 0x01 };
58
59 /* Exponent: */
60 const uint8_t priv_exponent[]  = {
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
69 };
70
71 /* Prime 1: */
72 const uint8_t p[]  = {
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
77 };
78
79 /* Prime 2: */
80 const uint8_t q[]  = {
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
85 };
86
87 /* Prime exponent 1: */
88 const uint8_t dp[]  = {
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
93 };
94
95 /* Prime exponent 2: */
96 const uint8_t dq[]  = {
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
101 };
102
103 /* Coefficient: */
104 const uint8_t qinv[]  = {
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
109 };
110
111 /*
112  * Example 2: A 1024-bit RSA key pair
113  * ---------------------------------------------------
114  */
115
116 /* Modulus: */
117 const uint8_t modulus2[] = {
118 0x98,  0xb7,  0x05,  0x82,  0xca,  0x80,  0x8f,  0xd1,  0xd3,  0x50,  0x95,  0x62,  0xa0,  0xef,  0x30,  0x5a,
119 0xf6,  0xd9,  0x87,  0x54,  0x43,  0xb3,  0x5b,  0xdf,  0x24,  0xd5,  0x36,  0x35,  0x3e,  0x3f,  0x12,  0x28,
120 0xdc,  0xd1,  0x2a,  0x78,  0x56,  0x83,  0x56,  0xc6,  0xff,  0x32,  0x3a,  0xbf,  0x72,  0xac,  0x1c,  0xdb,
121 0xfe,  0x71,  0x2f,  0xb4,  0x9f,  0xe5,  0x94,  0xa5,  0xa2,  0x17,  0x5d,  0x48,  0xb6,  0x73,  0x25,  0x38,
122 0xd8,  0xdf,  0x37,  0xcb,  0x97,  0x0b,  0xe4,  0xa5,  0xb5,  0x62,  0xc3,  0xf2,  0x98,  0xdb,  0x9d,  0xdf,
123 0x75,  0x60,  0x78,  0x77,  0x91,  0x8c,  0xce,  0xd1,  0xd0,  0xd1,  0xf3,  0x77,  0x33,  0x8c,  0x0d,  0x3d,
124 0x32,  0x07,  0x79,  0x7e,  0x86,  0x2c,  0x65,  0xd1,  0x14,  0x39,  0xe5,  0x88,  0x17,  0x75,  0x27,  0xa7,
125 0xde,  0xd9,  0x19,  0x71,  0xad,  0xcf,  0x91,  0xe2,  0xe8,  0x34,  0xe3,  0x7f,  0x05,  0xa7,  0x36,  0x55
126 };
127
128 /* Public exponent: */
129 const uint8_t pub_exponent2[] = {0x01,  0x00,  0x01 };
130
131 /* Exponent: */
132 const uint8_t priv_exponent2[] = {
133 0x06,  0x14,  0xa7,  0x86,  0x05,  0x2d,  0x28,  0x4c,  0xd9,  0x06,  0xa8,  0xe4,  0x13,  0xf7,  0x62,  0x2c,
134 0x05,  0x0f,  0x35,  0x49,  0xc0,  0x26,  0x58,  0x9e,  0xa2,  0x77,  0x50,  0xe0,  0xbe,  0xd9,  0x41,  0x0e,
135 0x5a,  0x78,  0x83,  0xa1,  0xe6,  0x03,  0xf5,  0xc5,  0x17,  0xad,  0x36,  0xd4,  0x9f,  0xaa,  0xc5,  0xbd,
136 0x66,  0xbc,  0xb8,  0x03,  0x0f,  0xa8,  0xd3,  0x09,  0xe3,  0x51,  0xdd,  0xd7,  0x82,  0xd8,  0x43,  0xdf,
137 0x97,  0x56,  0x80,  0xae,  0x73,  0xee,  0xa9,  0xaa,  0xb2,  0x89,  0xb7,  0x57,  0x20,  0x5d,  0xad,  0xb8,
138 0xfd,  0xfb,  0x98,  0x9e,  0xc8,  0xdb,  0x8e,  0x70,  0x95,  0xf5,  0x1f,  0x24,  0x52,  0x9f,  0x56,  0x37,
139 0xaa,  0x66,  0x93,  0x31,  0xe2,  0x56,  0x9f,  0x8b,  0x85,  0x4a,  0xbe,  0xce,  0xc9,  0x9a,  0xa2,  0x64,
140 0xc3,  0xda,  0x7c,  0xc6,  0x86,  0x6f,  0x0c,  0x0e,  0x1f,  0xb8,  0x46,  0x98,  0x48,  0x58,  0x1c,  0x73
141 };
142
143 /* Prime 1: */
144 const uint8_t p2[] = {
145 0xcb,  0x61,  0xa8,  0x8c,  0x8c,  0x30,  0x5a,  0xd9,  0xa8,  0xfb,  0xec,  0x2b,  0xa4,  0xc8,  0x6c,  0xcc,
146 0xc2,  0x02,  0x80,  0x24,  0xaa,  0x16,  0x90,  0xc2,  0x9b,  0xc8,  0x26,  0x4d,  0x2f,  0xeb,  0xe8,  0x7e,
147 0x4f,  0x86,  0xe9,  0x12,  0xef,  0x0f,  0x5c,  0x18,  0x53,  0xd7,  0x1c,  0xbc,  0x9b,  0x14,  0xba,  0xed,
148 0x3c,  0x37,  0xce,  0xf6,  0xc7,  0xa3,  0x59,  0x8b,  0x6f,  0xbe,  0x06,  0x48,  0x10,  0x90,  0x5b,  0x57
149 };
150
151 /* Prime 2: */
152 const uint8_t q2[] = {
153 0xc0,  0x39,  0x9f,  0x0b,  0x93,  0x80,  0xfa,  0xba,  0x38,  0xff,  0x80,  0xd2,  0xff,  0xf6,  0xed,  0xe7,
154 0x9c,  0xfd,  0xab,  0xf6,  0x58,  0x97,  0x20,  0x77,  0xa5,  0xe2,  0xb2,  0x95,  0x69,  0x3e,  0xa5,  0x10,
155 0x72,  0x26,  0x8b,  0x91,  0x74,  0x6e,  0xea,  0x9b,  0xe0,  0x4a,  0xd6,  0x61,  0x00,  0xeb,  0xed,  0x73,
156 0x3d,  0xb4,  0xcd,  0x01,  0x47,  0xa1,  0x8d,  0x6d,  0xe8,  0xc0,  0xcd,  0x8f,  0xbf,  0x24,  0x9c,  0x33
157 };
158
159 /* Prime exponent 1: */
160 const uint8_t dp2[] = {
161 0x94,  0x4c,  0x3a,  0x65,  0x79,  0x57,  0x4c,  0xf7,  0x87,  0x33,  0x62,  0xab,  0x14,  0x35,  0x9c,  0xb7,
162 0xd5,  0x03,  0x93,  0xc2,  0xa8,  0x4f,  0x59,  0xf0,  0xbd,  0x3c,  0xbd,  0x48,  0xed,  0x17,  0x7c,  0x68,
163 0x95,  0xbe,  0x8e,  0xb6,  0xe2,  0x9f,  0xf5,  0x8c,  0x3b,  0x9e,  0x0f,  0xf3,  0x2a,  0xb5,  0x7b,  0xf3,
164 0xbe,  0x44,  0x07,  0x62,  0x84,  0x81,  0x84,  0xaa,  0x9a,  0xa9,  0x19,  0xd5,  0x74,  0x56,  0x7e,  0x73
165 };
166
167 /* Prime exponent 2: */
168 const uint8_t dq2[] = {
169 0x45,  0xeb,  0xef,  0xd5,  0x87,  0x27,  0x30,  0x8c,  0xd2,  0xb4,  0xe6,  0x08,  0x5a,  0x81,  0x58,  0xd2,
170 0x9a,  0x41,  0x8f,  0xee,  0xc1,  0x14,  0xe0,  0x03,  0x85,  0xbc,  0xeb,  0x96,  0xfb,  0xbc,  0x84,  0xd0,
171 0x71,  0xa5,  0x61,  0xb9,  0x5c,  0x30,  0x08,  0x79,  0x00,  0xe2,  0x58,  0x0e,  0xdb,  0x05,  0xf6,  0xce,
172 0xa7,  0x90,  0x7f,  0xcd,  0xca,  0x5f,  0x92,  0x91,  0x7b,  0x4b,  0xbe,  0xba,  0x5e,  0x1e,  0x14,  0x0f
173 };
174
175 /* Coefficient: */
176 const uint8_t qinv2[] = {
177 0xc5,  0x24,  0x68,  0xc8,  0xfd,  0x15,  0xe5,  0xda,  0x2f,  0x6c,  0x8e,  0xba,  0x4e,  0x97,  0xba,  0xeb,
178 0xe9,  0x95,  0xb6,  0x7a,  0x1a,  0x7a,  0xd7,  0x19,  0xdd,  0x9f,  0xff,  0x36,  0x6b,  0x18,  0x4d,  0x5a,
179 0xb4,  0x55,  0x07,  0x59,  0x09,  0x29,  0x20,  0x44,  0xec,  0xb3,  0x45,  0xcf,  0x2c,  0xdd,  0x26,  0x22,
180 0x8e,  0x21,  0xf8,  0x51,  0x83,  0x25,  0x5f,  0x4a,  0x9e,  0x69,  0xf4,  0xc7,  0x15,  0x2e,  0xbb,  0x0f
181 };
182
183
184 /* PKCS#1 v1.5 encryption of 0x20, random messages with random s0xee,ds
185  *  ---------------------------------------------------------------------------
186  */
187
188 /* Message: */
189 const uint8_t message_x[]  = {
190 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23,
191 0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34
192 };
193
194 /* Seed: */
195 const uint8_t seed_x[]  = {
196 0x01, 0x73, 0x41, 0xae, 0x38, 0x75, 0xd5, 0xf8, 0x71, 0x01, 0xf8, 0xcc, 0x4f, 0xa9, 0xb9, 0xbc,
197 0x15, 0x6b, 0xb0, 0x46, 0x28, 0xfc, 0xcd, 0xb2, 0xf4, 0xf1, 0x1e, 0x90, 0x5b, 0xd3, 0xa1, 0x55,
198 0xd3, 0x76, 0xf5, 0x93, 0xbd, 0x73, 0x04, 0x21, 0x08, 0x74, 0xeb, 0xa0, 0x8a, 0x5e, 0x22, 0xbc,
199 0xcc, 0xb4, 0xc9, 0xd3, 0x88, 0x2a, 0x93, 0xa5, 0x4d, 0xb0, 0x22, 0xf5, 0x03, 0xd1, 0x63, 0x38,
200 0xb6, 0xb7, 0xce, 0x16, 0xdc, 0x7f, 0x4b, 0xbf, 0x9a, 0x96, 0xb5, 0x97, 0x72, 0xd6, 0x60, 0x6e,
201 0x97, 0x47, 0xc7, 0x64, 0x9b, 0xf9, 0xe0, 0x83, 0xdb, 0x98, 0x18, 0x84, 0xa9, 0x54, 0xab, 0x3c,
202 0x6f };
203
204 /* Encryption: */
205 const uint8_t encrypted_x[]  = {
206 0x50, 0xb4, 0xc1, 0x41, 0x36, 0xbd, 0x19, 0x8c, 0x2f, 0x3c, 0x3e, 0xd2, 0x43, 0xfc, 0xe0, 0x36,
207 0xe1, 0x68, 0xd5, 0x65, 0x17, 0x98, 0x4a, 0x26, 0x3c, 0xd6, 0x64, 0x92, 0xb8, 0x08, 0x04, 0xf1,
208 0x69, 0xd2, 0x10, 0xf2, 0xb9, 0xbd, 0xfb, 0x48, 0xb1, 0x2f, 0x9e, 0xa0, 0x50, 0x09, 0xc7, 0x7d,
209 0xa2, 0x57, 0xcc, 0x60, 0x0c, 0xce, 0xfe, 0x3a, 0x62, 0x83, 0x78, 0x9d, 0x8e, 0xa0, 0xe6, 0x07,
210 0xac, 0x58, 0xe2, 0x69, 0x0e, 0xc4, 0xeb, 0xc1, 0x01, 0x46, 0xe8, 0xcb, 0xaa, 0x5e, 0xd4, 0xd5,
211 0xcc, 0xe6, 0xfe, 0x7b, 0x0f, 0xf9, 0xef, 0xc1, 0xea, 0xbb, 0x56, 0x4d, 0xbf, 0x49, 0x82, 0x85,
212 0xf4, 0x49, 0xee, 0x61, 0xdd, 0x7b, 0x42, 0xee, 0x5b, 0x58, 0x92, 0xcb, 0x90, 0x60, 0x1f, 0x30,
213 0xcd, 0xa0, 0x7b, 0xf2, 0x64, 0x89, 0x31, 0x0b, 0xcd, 0x23, 0xb5, 0x28, 0xce, 0xab, 0x3c, 0x31
214 };
215
216 /*
217  * PKCS#1 v1.5 Encryption Example 2.15
218  * ----------------------------------
219  */
220 /* Message: */
221 const uint8_t message_2_15[] = {
222 0xa6,  0xd0,  0xe8,  0xc1,  0xea,  0x4a,  0xb4,  0xec,  0xc8,  0x95,  0x7d,  0x62,  0x28,  0x15,  0x79,  0x67,
223 0x5a,  0x64,  0x8d,  0x62,  0xb7,  0xf2,  0x2b,  0x2b,  0x08,  0xd1,  0x31,  0x3f,  0x40,  0x6f,  0x13,  0x7e,
224 0x99,  0x42,  0x67,  0x35,  0xcd,  0xb9,  0x37,  0x2f,  0xec,  0xa1,  0xee,  0x78,  0x46,  0x3f,  0xa5,  0xde,
225 0x9c,  0xdd,  0x84,  0x75,  0x6c,  0x68,  0xbd,  0x1d,  0x92,  0xba,  0x96,  0x5f,  0x50,  0x64,  0x10,  0xb1
226 };
227
228 /* Seed: */
229 const uint8_t seed_2_15[] = {
230 0x1c,  0x25,  0xc9,  0xb8,  0x32,  0x16,  0x9a,  0x1f,  0xdb,  0x6c,  0x14,  0x8e,  0x47,  0xe6,  0x6c,  0x3c,
231 0xc8,  0x21,  0x41,  0xe6,  0x11,  0xa6,  0xf3,  0x0c,  0xc9,  0x0c,  0x50,  0x49,  0xe8,  0xc5,  0x02,  0xb3,
232 0x1c,  0xad,  0xc7,  0x62,  0x39,  0xb7,  0xbd,  0xaf,  0x93,  0xfa,  0x97,  0x34,  0x3e,  0x7e,  0xe5,  0x51,
233 0xbc,  0x52,  0xfd,  0xb5,  0xec,  0x9e,  0x40,  0x0a,  0xf0,  0x5d,  0xbe,  0xac,  0xda
234 };
235
236 /* Encryption: */
237 const uint8_t encrypted_2_15[] = {
238 0xe8,  0xb2,  0xfc,  0x76,  0xdf,  0xb4,  0xa6,  0xcc,  0x43,  0x64,  0xde,  0x8f,  0x68,  0x3c,  0x3f,
239 0xcd,  0x0a,  0x9e,  0xcf,  0xbd,  0x4a,  0x5a,  0x72,  0x24,  0xf4,  0x9a,  0xe9,  0xb4,  0xf3,  0xb5,  0xcd,
240 0xc7,  0x1c,  0xbb,  0x8c,  0x66,  0xfd,  0x35,  0xf3,  0xd1,  0x8e,  0xca,  0x98,  0x96,  0x7b,  0xd4,  0x00,
241 0x5d,  0xf7,  0x91,  0x52,  0x41,  0x6f,  0xd4,  0x7e,  0x56,  0x2c,  0x55,  0xed,  0xc6,  0xd6,  0x12,  0x12,
242 0x28,  0x6e,  0xf9,  0x75,  0xbc,  0xc8,  0x02,  0x69,  0x25,  0x92,  0x65,  0x39,  0x00,  0x97,  0x3c,  0x72,
243 0xe0,  0x1a,  0x69,  0x3b,  0x05,  0xfc,  0x2d,  0x58,  0x56,  0xea,  0xef,  0x7a,  0xc0,  0x8f,  0xf5,  0xec,
244 0xd5,  0x31,  0xe2,  0xc2,  0xce,  0x92,  0x77,  0x45,  0xa1,  0x16,  0x5a,  0x51,  0xaa,  0x66,  0x98,  0xa1,
245 0xff,  0xcb,  0x87,  0xf8,  0x1e,  0xf6,  0x51,  0x0b,  0xca,  0xf9,  0xcb,  0x76,  0x1e,  0x9e,  0x1f,  0x0f
246 };
247
248 uint8_t keys_allocated = 0;
249 rsa_publickey_t pub_key;
250 rsa_privatekey_t priv_key;
251
252 #if 1
253   #define MSG       message_2_15
254   #define SEED      seed_2_15
255   #define ENCRYPTED encrypted_2_15
256   #define MODULUS modulus2
257   #define PUB_EXPONENT pub_exponent2
258   #define PRIV_EXPONENT priv_exponent2
259   #define P p2
260   #define Q q2
261   #define DP dp2
262   #define DQ dq2
263   #define QINV qinv2
264 #endif
265
266
267 uint8_t convert_nibble(uint8_t c){
268         if(c>='0' && c<='9'){
269                 return c - '0';
270         }
271         c |= 'A' ^ 'a';
272         if(c>='a' && c<='f'){
273                 return c - 'a' + 10;
274         }
275         return 0xff;
276 }
277
278 const char *block_ignore_string=" \t\r\n,;";
279 #define BUFFER_LIMIT 120
280 uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){
281         uint16_t counter = 0;
282         uint16_t c;
283         uint8_t v, tmp = 0, idx = 0;
284         if(!ignore_string){
285                 ignore_string = block_ignore_string;
286         }
287         while(counter < length){
288                 c = cli_getc();
289                 if(c > 0xff){
290                         return counter;
291                 }
292                 if(strchr(ignore_string, c)){
293                         continue;
294                 }
295                 v = convert_nibble(c);
296                 if(v > 0x0f){
297                         return counter;
298                 }
299                 if(idx){
300                         ((uint8_t*)dst)[counter++] = (tmp << 4) | v;
301                         idx = 0;
302                         if(counter % (BUFFER_LIMIT/2) == 0){
303                                 cli_putc('.');
304                         }
305                 }else{
306                         tmp = v;
307                         idx = 1;
308                 }
309         }
310         return counter;
311 }
312
313 uint16_t own_atou(const char* str){
314         uint16_t r=0;
315         while(*str && *str >= '0' && *str <= '9'){
316                 r *= 10;
317                 r += *str++ - '0';
318         }
319         return r;
320 }
321
322 uint8_t read_bigint(bigint_t* a, char* prompt){
323         uint16_t read_length, actual_length;
324         uint8_t off;
325         uint8_t *buffer;
326         char read_int_str[18];
327         cli_putstr(prompt);
328         cli_putstr("\r\n  length: ");
329         cli_getsn(read_int_str, 16);
330         read_length = own_atou(read_int_str);
331         off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
332         buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
333         if(!buffer){
334                 cli_putstr("\r\nERROR: OOM!");
335                 return 2;
336         }
337         cli_putstr("\r\n  data: ");
338         memset(buffer, 0, sizeof(bigint_word_t));
339         actual_length = read_os(buffer + off, read_length, NULL);
340         if(actual_length != read_length){
341                 cli_putstr("\r\nERROR: unexpected end of data!");
342                 free(buffer);
343                 return 1;
344         }
345         a->wordv = (bigint_word_t*)buffer;
346         a->length_W = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
347         a->info = 0;
348         bigint_changeendianess(a);
349         bigint_adjust(a);
350         return 0;
351 }
352
353 uint8_t pre_alloc_key_crt(void){
354         priv_key.n = 5;
355         priv_key.components = malloc(5 * sizeof(bigint_t));
356         if(!priv_key.components){
357                 cli_putstr("\r\nERROR: OOM!");
358                 return 2;
359         }
360         return 0;
361 }
362
363 void free_key(void){
364         uint8_t c;
365         free(pub_key.modulus.wordv);
366         free(pub_key.exponent.wordv);
367         pub_key.modulus.wordv = priv_key.modulus.wordv = NULL;
368         for(c = 0; c < priv_key.n; ++c){
369                 free(priv_key.components[c].wordv);
370         }
371         free(priv_key.components);
372 }
373
374 uint8_t read_key_crt(void){
375         uint8_t r;
376         cli_putstr("\r\n== reading key (crt) ==");
377         r = pre_alloc_key_crt();
378         if(r) return r;
379         r = read_bigint(&pub_key.modulus, "\r\n = module =");
380         memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
381         if(r) return r;
382         r = read_bigint(&pub_key.exponent, "\r\n = public exponent =");
383         if(r) return r;
384         r = read_bigint(&priv_key.components[0], "\r\n = p (first prime) =");
385         if(r) return r;
386         r = read_bigint(&priv_key.components[1], "\r\n = q (second prime) =");
387         if(r) return r;
388         r = read_bigint(&priv_key.components[2], "\r\n = dp (p's exponent) =");
389         if(r) return r;
390         r = read_bigint(&priv_key.components[3], "\r\n = dq (q's exponent) =");
391         if(r) return r;
392         r = read_bigint(&priv_key.components[4], "\r\n = qInv (q' coefficient) =");
393         return r;
394 }
395
396 uint8_t read_key_conv(void){
397         uint8_t r;
398         cli_putstr("\r\n== reading key (crt) ==");
399         r = read_bigint(&pub_key.modulus,"\r\n = module =");
400         if(r) return r;
401         memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
402         priv_key.n = 1;
403         priv_key.components = malloc(sizeof(bigint_t));
404         if(!priv_key.components){
405                 cli_putstr("\r\nERROR: OOM!");
406                 return 2;
407         }
408         r = read_bigint(&pub_key.exponent, "\r\n = public exponent =");
409         if(r) return r;
410         r = read_bigint(&priv_key.components[0], "\r\n = private exponent =");
411         return r;
412 }
413
414 void load_priv_conventional(void){
415         priv_key.components = malloc(sizeof(bigint_t));
416         priv_key.components[0].length_W = (sizeof(PRIV_EXPONENT) +
417                         sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
418         priv_key.components[0].wordv =  malloc(priv_key.components[0].length_W *
419                         sizeof(bigint_word_t));
420         if(!priv_key.components[0].wordv){
421                 cli_putstr("\r\nERROR: OOM!");
422                 return;
423         }
424         memcpy(priv_key.components[0].wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
425         priv_key.n = 1;
426         bigint_changeendianess(&priv_key.components[0]);
427         bigint_adjust(&priv_key.components[0]);
428 }
429
430
431 void load_priv_crt_mono(void){
432         bigint_t *v;
433         const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
434         uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
435         uint8_t i;
436         v = malloc(5 * sizeof(bigint_t));
437         if(!v){
438                 cli_putstr("\r\nERROR: OOM!");
439                 return;
440         }
441         priv_key.components = v;
442         priv_key.n = 5;
443         for(i=0; i<5; ++i){
444                 v[i].info = 0;
445                 v[i].length_W = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
446                 v[i].wordv = calloc(v[i].length_W , sizeof(bigint_word_t));
447                 if(!v[i].wordv){
448                         cli_putstr("\r\nERROR: OOM!");
449                         return;
450                 }
451                 memcpy(v[i].wordv, bv[i], sv[i]);
452                 bigint_changeendianess(&v[i]);
453                 bigint_adjust(&v[i]);
454         }
455 }
456
457 uint8_t load_bigint_from_os(bigint_t* a, const void* os, uint16_t length_B){
458         a->length_W = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
459         a->wordv = malloc(BIGINT_CEIL(length_B));
460         if(!a->wordv){
461                 cli_putstr("\r\nOOM!\r\n");
462                 return 1;
463         }
464         memset(a->wordv, 0, sizeof(bigint_word_t));
465         memcpy((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
466         a->info = 0;
467         bigint_changeendianess(a);
468         bigint_adjust(a);
469         return 0;
470 }
471
472 void load_fix_rsa(void){
473         if(keys_allocated){
474                 free_key();
475         }
476         keys_allocated = 1;
477
478         if(pre_alloc_key_crt()){
479                 cli_putstr("\r\nOOM!\r\n");
480                 return;
481         }
482
483         load_bigint_from_os(&pub_key.modulus, MODULUS, sizeof(MODULUS));
484         load_bigint_from_os(&pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
485         priv_key.n = 5;
486         memcpy(&priv_key.modulus, &pub_key.modulus, sizeof(bigint_t));
487         load_bigint_from_os(&priv_key.components[0], P, sizeof(P));
488         load_bigint_from_os(&priv_key.components[1], Q, sizeof(Q));
489         load_bigint_from_os(&priv_key.components[2], DP, sizeof(DP));
490         load_bigint_from_os(&priv_key.components[3], DQ, sizeof(DQ));
491         load_bigint_from_os(&priv_key.components[4], QINV, sizeof(QINV));
492
493 //      load_priv_conventional();
494 //      load_priv_crt_mono();
495 }
496
497 void quick_test(void){
498         uint8_t *ciphertext, *plaintext, rc;
499         uint8_t seed[sizeof(SEED)], seed_out[sizeof(SEED)];
500         uint16_t clen, plen;
501         if(!keys_allocated){
502                 load_fix_rsa();
503         }
504         ciphertext = malloc(clen = pub_key.modulus.length_W * sizeof(bigint_word_t));
505         plaintext = malloc(pub_key.modulus.length_W * sizeof(bigint_word_t));
506         memcpy(plaintext, MSG, sizeof(MSG));
507         memcpy(seed, SEED, sizeof(SEED));
508         cli_putstr("\r\nplaintext:");
509         cli_hexdump_block(plaintext, sizeof(MSG), 4, 16);
510         cli_putstr("\r\nseed:");
511         cli_hexdump_block(seed, sizeof(SEED), 4, 16);
512         cli_putstr("\r\nencrypting: ...");
513
514         rc = rsa_encrypt_pkcs1v15(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, seed);
515         if(rc){
516                 cli_putstr("\r\nERROR: rsa_encrypt_pkcs1v15 returned: ");
517                 cli_hexdump_byte(rc);
518                 return;
519
520         }
521
522         cli_putstr("\r\n\r\nciphertext:");
523         cli_hexdump_block(ciphertext, clen, 4, 16);
524         if(clen!=sizeof(ENCRYPTED)){
525                         cli_putstr("\r\n>>FAIL (no size match)<<");
526         }else{
527                 if(memcmp(ciphertext, ENCRYPTED, clen)){
528                         cli_putstr("\r\n>>FAIL (no content match)<<");
529                 }else{
530                         cli_putstr("\r\n>>OK<<");
531                 }
532         }
533
534         cli_putstr("\r\ndecrypting: ...");
535         rc = rsa_decrypt_pkcs1v15(plaintext, &plen, ciphertext, clen, &priv_key, seed_out);
536         if(rc){
537                 cli_putstr("\r\nERROR: rsa_decrypt_pkcs1v15 returned: ");
538                 cli_hexdump_byte(rc);
539                 return;
540         }
541         cli_putstr("\r\n\r\nplaintext:");
542         cli_hexdump_block(plaintext, plen, 4, 16);
543         cli_putstr("\r\n\r\nseed (out):");
544         cli_hexdump_block(seed_out, sizeof(SEED), 4, 16);
545
546         free(ciphertext);
547         free(plaintext);
548 }
549
550 void run_seed_test(void){
551         uint8_t *msg, *ciph, *msg_;
552         uint16_t msg_len, ciph_len, msg_len_;
553         uint16_t seed_len;
554         uint8_t *seed, *seed_out;
555         char read_int_str[18];
556         cli_putstr("\r\n== test with given seed ==");
557         cli_putstr("\r\n = message =");
558         cli_putstr("\r\n  length: ");
559         cli_getsn(read_int_str, 16);
560         msg_len = own_atou(read_int_str);
561         seed_len = rsa_pkcs1v15_compute_padlength_B(&pub_key.modulus, msg_len);
562         seed = malloc(seed_len);
563         if(!seed){
564                 cli_putstr("\r\nERROR: OOM!");
565                 return;
566         }
567         seed_out = malloc(seed_len);
568         if(!seed_out){
569                 cli_putstr("\r\nERROR: OOM!");
570                 return;
571         }
572         msg = malloc(msg_len);
573         if(!msg){
574                 cli_putstr("\r\nERROR: OOM!");
575                 return;
576         }
577         ciph = malloc(bigint_length_B(&pub_key.modulus));
578         if(!ciph){
579                 cli_putstr("\r\nERROR: OOM!");
580                 return;
581         }
582         msg_ = malloc(bigint_length_B(&pub_key.modulus));
583         if(!msg_){
584                 cli_putstr("\r\nERROR: OOM!");
585                 return;
586         }
587         cli_putstr("\r\n  data: ");
588         read_os(msg, msg_len, NULL);
589         cli_putstr("\r\n  seed (0x");
590         cli_hexdump_rev(&seed_len, 2);
591         cli_putstr(" bytes): ");
592         read_os(seed, seed_len, NULL);
593
594         cli_putstr("\r\n  encrypting ...");
595 /*
596         cli_putstr("\r\n plaintext:");
597         cli_hexdump_block(msg, msg_len, 4, 16);
598         cli_putstr("\r\n seed:");
599         cli_hexdump_block(seed, seed_len, 4, 16);
600 */
601         rsa_encrypt_pkcs1v15(ciph, &ciph_len, msg, msg_len, &pub_key, seed);
602         cli_putstr("\r\n  ciphertext:");
603         cli_hexdump_block(ciph, ciph_len, 4, 16);
604         cli_putstr("\r\n  decrypting ... ");
605         rsa_decrypt_pkcs1v15(msg_, &msg_len_, ciph, ciph_len, &priv_key, seed_out);
606         cli_putstr("[done]");
607         if(msg_len != msg_len_){
608                 char tstr[16];
609                 cli_putstr("\r\nERROR: wrong decrypted message length (");
610                 ultoa(msg_len_, tstr, 10);
611                 cli_putstr(tstr);
612                 cli_putstr(" instead of ");
613                 ultoa(msg_len, tstr, 10);
614                 cli_putstr(tstr);
615                 cli_putc(')');
616                 goto end;
617         }
618         if(memcmp(msg, msg_, msg_len)){
619                 cli_putstr("\r\nERROR: wrong decrypted message:");
620                 cli_hexdump_block(msg_, msg_len_, 4, 16);
621                 cli_putstr("\r\nreference:");
622                 cli_hexdump_block(msg, msg_len, 4, 16);
623                 goto end;
624         }
625
626         if(memcmp(seed, seed_out, seed_len)){
627                 cli_putstr("\r\nERROR: wrong decrypted seed:");
628                 cli_hexdump_block(seed_out, seed_len, 4, 16);
629                 cli_putstr("\r\nreference:");
630                 cli_hexdump_block(seed, seed_len, 4, 16);
631                 goto end;
632         }
633         cli_putstr("\r\n  >>OK<<");
634 end:
635         free(ciph);
636         free(msg_);
637         free(msg);
638         free(seed_out);
639         free(seed);
640 }
641
642 void reset_prng(void){
643         uint8_t buf[16];
644         memset(buf, 0, 16);
645         random_seed(buf);
646         cli_putstr("\r\nPRNG reset");
647 }
648
649 void rsa_init(void){
650         prng_get_byte = random8;
651 }
652
653 void load_key(void){
654         if(keys_allocated){
655                 free_key();
656         }
657         keys_allocated = 1;
658         read_key_crt();
659 }
660
661 void test_dump(void){
662         char lstr[16];
663         int len;
664         cli_putstr("\r\nenter dump length: ");
665         cli_getsn(lstr, 15);
666         len = own_atou(lstr);
667         cli_putstr("\r\ndumping 0x");
668         cli_hexdump_rev(&len, 2);
669         cli_putstr(" byte:");
670         cli_hexdump_block(pub_key.modulus.wordv, len, 4, 8);
671 }
672
673 /*****************************************************************************
674  *  main                                                                                                                                         *
675  *****************************************************************************/
676
677 const char echo_test_str[]     = "echo-test";
678 const char reset_prng_str[]    = "reset-prng";
679 const char load_key_str[]      = "load-key";
680 const char load_fix_key_str[]  = "load-fix-key";
681 const char quick_test_str[]    = "quick-test";
682 const char seed_test_str[]     = "seed-test";
683 const char dump_test_str[]     = "dump-test";
684 const char performance_str[]   = "performance";
685 const char echo_str[]          = "echo";
686
687 const cmdlist_entry_t cmdlist[]  = {
688         { reset_prng_str,       NULL, reset_prng                    },
689         { load_key_str,         NULL, load_key                      },
690         { load_fix_key_str,     NULL, load_fix_rsa                  },
691         { quick_test_str,       NULL, quick_test                    },
692         { seed_test_str,        NULL, run_seed_test                 },
693         { dump_test_str,        NULL, test_dump                     },
694 //      { performance_str,      NULL, testrun_performance_bigint    },
695         { echo_str,         (void*)1, (void_fpt)echo_ctrl           },
696         { NULL,                 NULL, NULL                          }
697 };
698
699 void dump_sp(void){
700         uint8_t x;
701         uint8_t *xa = &x;
702         cli_putstr("\r\nstack pointer: ~");
703         cli_hexdump_rev(&xa, 4);
704 }
705
706 int main (void){
707         main_setup();
708
709         for(;;){
710                 welcome_msg(algo_name);
711                 rsa_init();
712                 cmd_interface(cmdlist);
713         }
714 }