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_oaep.h"
33 #include "performance_test.h"
35 const char* algo_name = "RSAES-OAEP";
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 *****************************************************************************/
44 /* ==================================
45 * Example 1: A 1024-bit RSA Key Pair
46 * ================================== */
48 /* ------------------------------
49 * Components of the RSA Key Pair
50 * ------------------------------ */
53 const uint8_t modulus[] = {
54 0xa8, 0xb3, 0xb2, 0x84, 0xaf, 0x8e, 0xb5, 0x0b, 0x38, 0x70, 0x34, 0xa8, 0x60, 0xf1, 0x46, 0xc4,
55 0x91, 0x9f, 0x31, 0x87, 0x63, 0xcd, 0x6c, 0x55, 0x98, 0xc8, 0xae, 0x48, 0x11, 0xa1, 0xe0, 0xab,
56 0xc4, 0xc7, 0xe0, 0xb0, 0x82, 0xd6, 0x93, 0xa5, 0xe7, 0xfc, 0xed, 0x67, 0x5c, 0xf4, 0x66, 0x85,
57 0x12, 0x77, 0x2c, 0x0c, 0xbc, 0x64, 0xa7, 0x42, 0xc6, 0xc6, 0x30, 0xf5, 0x33, 0xc8, 0xcc, 0x72,
58 0xf6, 0x2a, 0xe8, 0x33, 0xc4, 0x0b, 0xf2, 0x58, 0x42, 0xe9, 0x84, 0xbb, 0x78, 0xbd, 0xbf, 0x97,
59 0xc0, 0x10, 0x7d, 0x55, 0xbd, 0xb6, 0x62, 0xf5, 0xc4, 0xe0, 0xfa, 0xb9, 0x84, 0x5c, 0xb5, 0x14,
60 0x8e, 0xf7, 0x39, 0x2d, 0xd3, 0xaa, 0xff, 0x93, 0xae, 0x1e, 0x6b, 0x66, 0x7b, 0xb3, 0xd4, 0x24,
61 0x76, 0x16, 0xd4, 0xf5, 0xba, 0x10, 0xd4, 0xcf, 0xd2, 0x26, 0xde, 0x88, 0xd3, 0x9f, 0x16, 0xfb
64 /* RSA public exponent e: */
65 const uint8_t public_exponent[] = {
66 0x00, 0x01, 0x00, 0x01
69 /* RSA private exponent d: */
70 const uint8_t private_exponent[] = {
71 0x53, 0x33, 0x9c, 0xfd, 0xb7, 0x9f, 0xc8, 0x46, 0x6a, 0x65, 0x5c, 0x73, 0x16, 0xac, 0xa8, 0x5c,
72 0x55, 0xfd, 0x8f, 0x6d, 0xd8, 0x98, 0xfd, 0xaf, 0x11, 0x95, 0x17, 0xef, 0x4f, 0x52, 0xe8, 0xfd,
73 0x8e, 0x25, 0x8d, 0xf9, 0x3f, 0xee, 0x18, 0x0f, 0xa0, 0xe4, 0xab, 0x29, 0x69, 0x3c, 0xd8, 0x3b,
74 0x15, 0x2a, 0x55, 0x3d, 0x4a, 0xc4, 0xd1, 0x81, 0x2b, 0x8b, 0x9f, 0xa5, 0xaf, 0x0e, 0x7f, 0x55,
75 0xfe, 0x73, 0x04, 0xdf, 0x41, 0x57, 0x09, 0x26, 0xf3, 0x31, 0x1f, 0x15, 0xc4, 0xd6, 0x5a, 0x73,
76 0x2c, 0x48, 0x31, 0x16, 0xee, 0x3d, 0x3d, 0x2d, 0x0a, 0xf3, 0x54, 0x9a, 0xd9, 0xbf, 0x7c, 0xbf,
77 0xb7, 0x8a, 0xd8, 0x84, 0xf8, 0x4d, 0x5b, 0xeb, 0x04, 0x72, 0x4d, 0xc7, 0x36, 0x9b, 0x31, 0xde,
78 0xf3, 0x7d, 0x0c, 0xf5, 0x39, 0xe9, 0xcf, 0xcd, 0xd3, 0xde, 0x65, 0x37, 0x29, 0xea, 0xd5, 0xd1
83 0xd3, 0x27, 0x37, 0xe7, 0x26, 0x7f, 0xfe, 0x13, 0x41, 0xb2, 0xd5, 0xc0, 0xd1, 0x50, 0xa8, 0x1b,
84 0x58, 0x6f, 0xb3, 0x13, 0x2b, 0xed, 0x2f, 0x8d, 0x52, 0x62, 0x86, 0x4a, 0x9c, 0xb9, 0xf3, 0x0a,
85 0xf3, 0x8b, 0xe4, 0x48, 0x59, 0x8d, 0x41, 0x3a, 0x17, 0x2e, 0xfb, 0x80, 0x2c, 0x21, 0xac, 0xf1,
86 0xc1, 0x1c, 0x52, 0x0c, 0x2f, 0x26, 0xa4, 0x71, 0xdc, 0xad, 0x21, 0x2e, 0xac, 0x7c, 0xa3, 0x9d
91 0xcc, 0x88, 0x53, 0xd1, 0xd5, 0x4d, 0xa6, 0x30, 0xfa, 0xc0, 0x04, 0xf4, 0x71, 0xf2, 0x81, 0xc7,
92 0xb8, 0x98, 0x2d, 0x82, 0x24, 0xa4, 0x90, 0xed, 0xbe, 0xb3, 0x3d, 0x3e, 0x3d, 0x5c, 0xc9, 0x3c,
93 0x47, 0x65, 0x70, 0x3d, 0x1d, 0xd7, 0x91, 0x64, 0x2f, 0x1f, 0x11, 0x6a, 0x0d, 0xd8, 0x52, 0xbe,
94 0x24, 0x19, 0xb2, 0xaf, 0x72, 0xbf, 0xe9, 0xa0, 0x30, 0xe8, 0x60, 0xb0, 0x28, 0x8b, 0x5d, 0x77
97 /* p's CRT exponent dP: */
98 const uint8_t dp[] = {
99 0x0e, 0x12, 0xbf, 0x17, 0x18, 0xe9, 0xce, 0xf5, 0x59, 0x9b, 0xa1, 0xc3, 0x88, 0x2f, 0xe8, 0x04,
100 0x6a, 0x90, 0x87, 0x4e, 0xef, 0xce, 0x8f, 0x2c, 0xcc, 0x20, 0xe4, 0xf2, 0x74, 0x1f, 0xb0, 0xa3,
101 0x3a, 0x38, 0x48, 0xae, 0xc9, 0xc9, 0x30, 0x5f, 0xbe, 0xcb, 0xd2, 0xd7, 0x68, 0x19, 0x96, 0x7d,
102 0x46, 0x71, 0xac, 0xc6, 0x43, 0x1e, 0x40, 0x37, 0x96, 0x8d, 0xb3, 0x78, 0x78, 0xe6, 0x95, 0xc1
105 /* q's CRT exponent dQ: */
106 const uint8_t dq[] = {
107 0x95, 0x29, 0x7b, 0x0f, 0x95, 0xa2, 0xfa, 0x67, 0xd0, 0x07, 0x07, 0xd6, 0x09, 0xdf, 0xd4, 0xfc,
108 0x05, 0xc8, 0x9d, 0xaf, 0xc2, 0xef, 0x6d, 0x6e, 0xa5, 0x5b, 0xec, 0x77, 0x1e, 0xa3, 0x33, 0x73,
109 0x4d, 0x92, 0x51, 0xe7, 0x90, 0x82, 0xec, 0xda, 0x86, 0x6e, 0xfe, 0xf1, 0x3c, 0x45, 0x9e, 0x1a,
110 0x63, 0x13, 0x86, 0xb7, 0xe3, 0x54, 0xc8, 0x99, 0xf5, 0xf1, 0x12, 0xca, 0x85, 0xd7, 0x15, 0x83
113 /* CRT coefficient qInv: */
114 const uint8_t qinv[] = {
115 0x4f, 0x45, 0x6c, 0x50, 0x24, 0x93, 0xbd, 0xc0, 0xed, 0x2a, 0xb7, 0x56, 0xa3, 0xa6, 0xed, 0x4d,
116 0x67, 0x35, 0x2a, 0x69, 0x7d, 0x42, 0x16, 0xe9, 0x32, 0x12, 0xb1, 0x27, 0xa6, 0x3d, 0x54, 0x11,
117 0xce, 0x6f, 0xa9, 0x8d, 0x5d, 0xbe, 0xfd, 0x73, 0x26, 0x3e, 0x37, 0x28, 0x14, 0x27, 0x43, 0x81,
118 0x81, 0x66, 0xed, 0x7d, 0xd6, 0x36, 0x87, 0xdd, 0x2a, 0x8c, 0xa1, 0xd2, 0xf4, 0xfb, 0xd8, 0xe1
121 /* ---------------------------------
122 * RSAES-OAEP Encryption Example 1.1
123 * --------------------------------- */
125 /* Message to be, encrypted: */
126 const uint8_t message[] = {
127 0x66, 0x28, 0x19, 0x4e, 0x12, 0x07, 0x3d, 0xb0, 0x3b, 0xa9, 0x4c, 0xda, 0x9e, 0xf9, 0x53, 0x23,
128 0x97, 0xd5, 0x0d, 0xba, 0x79, 0xb9, 0x87, 0x00, 0x4a, 0xfe, 0xfe, 0x34
132 const uint8_t seed[] = {
133 0x18, 0xb7, 0x76, 0xea, 0x21, 0x06, 0x9d, 0x69, 0x77, 0x6a, 0x33, 0xe9, 0x6b, 0xad, 0x48, 0xe1,
134 0xdd, 0xa0, 0xa5, 0xef
138 const uint8_t encrypted[] = {
139 0x35, 0x4f, 0xe6, 0x7b, 0x4a, 0x12, 0x6d, 0x5d, 0x35, 0xfe, 0x36, 0xc7, 0x77, 0x79, 0x1a, 0x3f,
140 0x7b, 0xa1, 0x3d, 0xef, 0x48, 0x4e, 0x2d, 0x39, 0x08, 0xaf, 0xf7, 0x22, 0xfa, 0xd4, 0x68, 0xfb,
141 0x21, 0x69, 0x6d, 0xe9, 0x5d, 0x0b, 0xe9, 0x11, 0xc2, 0xd3, 0x17, 0x4f, 0x8a, 0xfc, 0xc2, 0x01,
142 0x03, 0x5f, 0x7b, 0x6d, 0x8e, 0x69, 0x40, 0x2d, 0xe5, 0x45, 0x16, 0x18, 0xc2, 0x1a, 0x53, 0x5f,
143 0xa9, 0xd7, 0xbf, 0xc5, 0xb8, 0xdd, 0x9f, 0xc2, 0x43, 0xf8, 0xcf, 0x92, 0x7d, 0xb3, 0x13, 0x22,
144 0xd6, 0xe8, 0x81, 0xea, 0xa9, 0x1a, 0x99, 0x61, 0x70, 0xe6, 0x57, 0xa0, 0x5a, 0x26, 0x64, 0x26,
145 0xd9, 0x8c, 0x88, 0x00, 0x3f, 0x84, 0x77, 0xc1, 0x22, 0x70, 0x94, 0xa0, 0xd9, 0xfa, 0x1e, 0x8c,
146 0x40, 0x24, 0x30, 0x9c, 0xe1, 0xec, 0xcc, 0xb5, 0x21, 0x00, 0x35, 0xd4, 0x7a, 0xc7, 0x2e, 0x8a
149 /* Message to be encrypted: */
150 const uint8_t message2[] = {
151 0x75, 0x0c, 0x40, 0x47, 0xf5, 0x47, 0xe8, 0xe4, 0x14, 0x11, 0x85, 0x65, 0x23, 0x29, 0x8a, 0xc9,
152 0xba, 0xe2, 0x45, 0xef, 0xaf, 0x13, 0x97, 0xfb, 0xe5, 0x6f, 0x9d, 0xd5
156 const uint8_t seed2[] = {
157 0x0c, 0xc7, 0x42, 0xce, 0x4a, 0x9b, 0x7f, 0x32, 0xf9, 0x51, 0xbc, 0xb2, 0x51, 0xef, 0xd9, 0x25,
158 0xfe, 0x4f, 0xe3, 0x5f
162 const uint8_t encrypted2[] = {
163 0x64, 0x0d, 0xb1, 0xac, 0xc5, 0x8e, 0x05, 0x68, 0xfe, 0x54, 0x07, 0xe5, 0xf9, 0xb7, 0x01, 0xdf,
164 0xf8, 0xc3, 0xc9, 0x1e, 0x71, 0x6c, 0x53, 0x6f, 0xc7, 0xfc, 0xec, 0x6c, 0xb5, 0xb7, 0x1c, 0x11,
165 0x65, 0x98, 0x8d, 0x4a, 0x27, 0x9e, 0x15, 0x77, 0xd7, 0x30, 0xfc, 0x7a, 0x29, 0x93, 0x2e, 0x3f,
166 0x00, 0xc8, 0x15, 0x15, 0x23, 0x6d, 0x8d, 0x8e, 0x31, 0x01, 0x7a, 0x7a, 0x09, 0xdf, 0x43, 0x52,
167 0xd9, 0x04, 0xcd, 0xeb, 0x79, 0xaa, 0x58, 0x3a, 0xdc, 0xc3, 0x1e, 0xa6, 0x98, 0xa4, 0xc0, 0x52,
168 0x83, 0xda, 0xba, 0x90, 0x89, 0xbe, 0x54, 0x91, 0xf6, 0x7c, 0x1a, 0x4e, 0xe4, 0x8d, 0xc7, 0x4b,
169 0xbb, 0xe6, 0x64, 0x3a, 0xef, 0x84, 0x66, 0x79, 0xb4, 0xcb, 0x39, 0x5a, 0x35, 0x2d, 0x5e, 0xd1,
170 0x15, 0x91, 0x2d, 0xf6, 0x96, 0xff, 0xe0, 0x70, 0x29, 0x32, 0x94, 0x6d, 0x71, 0x49, 0x2b, 0x44
173 /**********************************************************************************************/
174 /* ---------------------------------
175 * RSAES-OAEP Encryption Example 2.1
176 * --------------------------------- */
178 /* Message to be encrypted: */
179 const uint8_t message3[] = {
180 0x8f, 0xf0, 0x0c, 0xaa, 0x60, 0x5c, 0x70, 0x28, 0x30, 0x63, 0x4d, 0x9a, 0x6c, 0x3d, 0x42, 0xc6,
181 0x52, 0xb5, 0x8c, 0xf1, 0xd9, 0x2f, 0xec, 0x57, 0x0b, 0xee, 0xe7
185 const uint8_t seed3[] = {
186 0x8c, 0x40, 0x7b, 0x5e, 0xc2, 0x89, 0x9e, 0x50, 0x99, 0xc5, 0x3e, 0x8c, 0xe7, 0x93, 0xbf, 0x94,
187 0xe7, 0x1b, 0x17, 0x82
191 const uint8_t encrypted3[] = {
192 0x01, 0x81, 0xaf, 0x89, 0x22, 0xb9, 0xfc, 0xb4, 0xd7, 0x9d, 0x92, 0xeb, 0xe1, 0x98, 0x15, 0x99,
193 0x2f, 0xc0, 0xc1, 0x43, 0x9d, 0x8b, 0xcd, 0x49, 0x13, 0x98, 0xa0, 0xf4, 0xad, 0x3a, 0x32, 0x9a,
194 0x5b, 0xd9, 0x38, 0x55, 0x60, 0xdb, 0x53, 0x26, 0x83, 0xc8, 0xb7, 0xda, 0x04, 0xe4, 0xb1, 0x2a,
195 0xed, 0x6a, 0xac, 0xdf, 0x47, 0x1c, 0x34, 0xc9, 0xcd, 0xa8, 0x91, 0xad, 0xdc, 0xc2, 0xdf, 0x34,
196 0x56, 0x65, 0x3a, 0xa6, 0x38, 0x2e, 0x9a, 0xe5, 0x9b, 0x54, 0x45, 0x52, 0x57, 0xeb, 0x09, 0x9d,
197 0x56, 0x2b, 0xbe, 0x10, 0x45, 0x3f, 0x2b, 0x6d, 0x13, 0xc5, 0x9c, 0x02, 0xe1, 0x0f, 0x1f, 0x8a,
198 0xbb, 0x5d, 0xa0, 0xd0, 0x57, 0x09, 0x32, 0xda, 0xcf, 0x2d, 0x09, 0x01, 0xdb, 0x72, 0x9d, 0x0f,
199 0xef, 0xcc, 0x05, 0x4e, 0x70, 0x96, 0x8e, 0xa5, 0x40, 0xc8, 0x1b, 0x04, 0xbc, 0xae, 0xfe, 0x72,
203 /**********************************************************************************************/
205 /* ---------------------------------
206 * RSAES-OAEP Encryption Example 2.4
207 * --------------------------------- */
209 /* Message to be encrypted: */
210 const uint8_t message4[] PROGMEM = {
211 0xa7, 0xeb, 0x2a, 0x50, 0x36, 0x93, 0x1d, 0x27, 0xd4, 0xe8, 0x91, 0x32, 0x6d, 0x99, 0x69, 0x2f,
212 0xfa, 0xdd, 0xa9, 0xbf, 0x7e, 0xfd, 0x3e, 0x34, 0xe6, 0x22, 0xc4, 0xad, 0xc0, 0x85, 0xf7, 0x21,
213 0xdf, 0xe8, 0x85, 0x07, 0x2c, 0x78, 0xa2, 0x03, 0xb1, 0x51, 0x73, 0x9b, 0xe5, 0x40, 0xfa, 0x8c,
214 0x15, 0x3a, 0x10, 0xf0, 0x0a
218 const uint8_t seed4[] PROGMEM = {
219 0x9a, 0x7b, 0x3b, 0x0e, 0x70, 0x8b, 0xd9, 0x6f, 0x81, 0x90, 0xec, 0xab, 0x4f, 0xb9, 0xb2, 0xb3,
220 0x80, 0x5a, 0x81, 0x56
224 const uint8_t encrypted4[] PROGMEM = {
225 /* 0x00,*/ 0xa4, 0x57, 0x8c, 0xbc, 0x17, 0x63, 0x18, 0xa6, 0x38, 0xfb, 0xa7, 0xd0, 0x1d, 0xf1, 0x57,
226 0x46, 0xaf, 0x44, 0xd4, 0xf6, 0xcd, 0x96, 0xd7, 0xe7, 0xc4, 0x95, 0xcb, 0xf4, 0x25, 0xb0, 0x9c,
227 0x64, 0x9d, 0x32, 0xbf, 0x88, 0x6d, 0xa4, 0x8f, 0xba, 0xf9, 0x89, 0xa2, 0x11, 0x71, 0x87, 0xca,
228 0xfb, 0x1f, 0xb5, 0x80, 0x31, 0x76, 0x90, 0xe3, 0xcc, 0xd4, 0x46, 0x92, 0x0b, 0x7a, 0xf8, 0x2b,
229 0x31, 0xdb, 0x58, 0x04, 0xd8, 0x7d, 0x01, 0x51, 0x4a, 0xcb, 0xfa, 0x91, 0x56, 0xe7, 0x82, 0xf8,
230 0x67, 0xf6, 0xbe, 0xd9, 0x44, 0x9e, 0x0e, 0x9a, 0x2c, 0x09, 0xbc, 0xec, 0xc6, 0xaa, 0x08, 0x76,
231 0x36, 0x96, 0x5e, 0x34, 0xb3, 0xec, 0x76, 0x6f, 0x2f, 0xe2, 0xe4, 0x30, 0x18, 0xa2, 0xfd, 0xde,
232 0xb1, 0x40, 0x61, 0x6a, 0x0e, 0x9d, 0x82, 0xe5, 0x33, 0x10, 0x24, 0xee, 0x06, 0x52, 0xfc, 0x76,
236 /**********************************************************************************************/
239 const uint8_t modulus2[] PROGMEM = {
240 0x01, 0x94, 0x7c, 0x7f, 0xce, 0x90, 0x42, 0x5f, 0x47, 0x27, 0x9e, 0x70, 0x85, 0x1f, 0x25, 0xd5,
241 0xe6, 0x23, 0x16, 0xfe, 0x8a, 0x1d, 0xf1, 0x93, 0x71, 0xe3, 0xe6, 0x28, 0xe2, 0x60, 0x54, 0x3e,
242 0x49, 0x01, 0xef, 0x60, 0x81, 0xf6, 0x8c, 0x0b, 0x81, 0x41, 0x19, 0x0d, 0x2a, 0xe8, 0xda, 0xba,
243 0x7d, 0x12, 0x50, 0xec, 0x6d, 0xb6, 0x36, 0xe9, 0x44, 0xec, 0x37, 0x22, 0x87, 0x7c, 0x7c, 0x1d,
244 0x0a, 0x67, 0xf1, 0x4b, 0x16, 0x94, 0xc5, 0xf0, 0x37, 0x94, 0x51, 0xa4, 0x3e, 0x49, 0xa3, 0x2d,
245 0xde, 0x83, 0x67, 0x0b, 0x73, 0xda, 0x91, 0xa1, 0xc9, 0x9b, 0xc2, 0x3b, 0x43, 0x6a, 0x60, 0x05,
246 0x5c, 0x61, 0x0f, 0x0b, 0xaf, 0x99, 0xc1, 0xa0, 0x79, 0x56, 0x5b, 0x95, 0xa3, 0xf1, 0x52, 0x66,
247 0x32, 0xd1, 0xd4, 0xda, 0x60, 0xf2, 0x0e, 0xda, 0x25, 0xe6, 0x53, 0xc4, 0xf0, 0x02, 0x76, 0x6f,
251 /* RSA public exponent e: */
252 const uint8_t public_exponent2[] PROGMEM = {
256 /* RSA private exponent d: */
257 const uint8_t private_exponent2[] PROGMEM = {
258 0x08, 0x23, 0xf2, 0x0f, 0xad, 0xb5, 0xda, 0x89, 0x08, 0x8a, 0x9d, 0x00, 0x89, 0x3e, 0x21, 0xfa,
259 0x4a, 0x1b, 0x11, 0xfb, 0xc9, 0x3c, 0x64, 0xa3, 0xbe, 0x0b, 0xaa, 0xea, 0x97, 0xfb, 0x3b, 0x93,
260 0xc3, 0xff, 0x71, 0x37, 0x04, 0xc1, 0x9c, 0x96, 0x3c, 0x1d, 0x10, 0x7a, 0xae, 0x99, 0x05, 0x47,
261 0x39, 0xf7, 0x9e, 0x02, 0xe1, 0x86, 0xde, 0x86, 0xf8, 0x7a, 0x6d, 0xde, 0xfe, 0xa6, 0xd8, 0xcc,
262 0xd1, 0xd3, 0xc8, 0x1a, 0x47, 0xbf, 0xa7, 0x25, 0x5b, 0xe2, 0x06, 0x01, 0xa4, 0xa4, 0xb2, 0xf0,
263 0x8a, 0x16, 0x7b, 0x5e, 0x27, 0x9d, 0x71, 0x5b, 0x1b, 0x45, 0x5b, 0xdd, 0x7e, 0xab, 0x24, 0x59,
264 0x41, 0xd9, 0x76, 0x8b, 0x9a, 0xce, 0xfb, 0x3c, 0xcd, 0xa5, 0x95, 0x2d, 0xa3, 0xce, 0xe7, 0x25,
265 0x25, 0xb4, 0x50, 0x16, 0x63, 0xa8, 0xee, 0x15, 0xc9, 0xe9, 0x92, 0xd9, 0x24, 0x62, 0xfe, 0x39
269 const uint8_t p2[] PROGMEM = {
270 0x01, 0x59, 0xdb, 0xde, 0x04, 0xa3, 0x3e, 0xf0, 0x6f, 0xb6, 0x08, 0xb8, 0x0b, 0x19, 0x0f, 0x4d,
271 0x3e, 0x22, 0xbc, 0xc1, 0x3a, 0xc8, 0xe4, 0xa0, 0x81, 0x03, 0x3a, 0xbf, 0xa4, 0x16, 0xed, 0xb0,
272 0xb3, 0x38, 0xaa, 0x08, 0xb5, 0x73, 0x09, 0xea, 0x5a, 0x52, 0x40, 0xe7, 0xdc, 0x6e, 0x54, 0x37,
273 0x8c, 0x69, 0x41, 0x4c, 0x31, 0xd9, 0x7d, 0xdb, 0x1f, 0x40, 0x6d, 0xb3, 0x76, 0x9c, 0xc4, 0x1a,
278 const uint8_t q2[] PROGMEM = {
279 0x01, 0x2b, 0x65, 0x2f, 0x30, 0x40, 0x3b, 0x38, 0xb4, 0x09, 0x95, 0xfd, 0x6f, 0xf4, 0x1a, 0x1a,
280 0xcc, 0x8a, 0xda, 0x70, 0x37, 0x32, 0x36, 0xb7, 0x20, 0x2d, 0x39, 0xb2, 0xee, 0x30, 0xcf, 0xb4,
281 0x6d, 0xb0, 0x95, 0x11, 0xf6, 0xf3, 0x07, 0xcc, 0x61, 0xcc, 0x21, 0x60, 0x6c, 0x18, 0xa7, 0x5b,
282 0x8a, 0x62, 0xf8, 0x22, 0xdf, 0x03, 0x1b, 0xa0, 0xdf, 0x0d, 0xaf, 0xd5, 0x50, 0x6f, 0x56, 0x8b,
286 /* p's CRT exponent dP: */
287 const uint8_t dp2[] PROGMEM = {
288 0x43, 0x6e, 0xf5, 0x08, 0xde, 0x73, 0x65, 0x19, 0xc2, 0xda, 0x4c, 0x58, 0x0d, 0x98, 0xc8, 0x2c,
289 0xb7, 0x45, 0x2a, 0x3f, 0xb5, 0xef, 0xad, 0xc3, 0xb9, 0xc7, 0x78, 0x9a, 0x1b, 0xc6, 0x58, 0x4f,
290 0x79, 0x5a, 0xdd, 0xbb, 0xd3, 0x24, 0x39, 0xc7, 0x46, 0x86, 0x55, 0x2e, 0xcb, 0x6c, 0x2c, 0x30,
291 0x7a, 0x4d, 0x3a, 0xf7, 0xf5, 0x39, 0xee, 0xc1, 0x57, 0x24, 0x8c, 0x7b, 0x31, 0xf1, 0xa2, 0x55
294 /* q's CRT exponent dQ: */
295 const uint8_t dq2[] PROGMEM = {
296 0x01, 0x2b, 0x15, 0xa8, 0x9f, 0x3d, 0xfb, 0x2b, 0x39, 0x07, 0x3e, 0x73, 0xf0, 0x2b, 0xdd, 0x0c,
297 0x1a, 0x7b, 0x37, 0x9d, 0xd4, 0x35, 0xf0, 0x5c, 0xdd, 0xe2, 0xef, 0xf9, 0xe4, 0x62, 0x94, 0x8b,
298 0x7c, 0xec, 0x62, 0xee, 0x90, 0x50, 0xd5, 0xe0, 0x81, 0x6e, 0x07, 0x85, 0xa8, 0x56, 0xb4, 0x91,
299 0x08, 0xdc, 0xb7, 0x5f, 0x36, 0x83, 0x87, 0x4d, 0x1c, 0xa6, 0x32, 0x9a, 0x19, 0x01, 0x30, 0x66,
303 /* CRT coefficient qInv: */
304 const uint8_t qinv2[] PROGMEM = {
305 0x02, 0x70, 0xdb, 0x17, 0xd5, 0x91, 0x4b, 0x01, 0x8d, 0x76, 0x11, 0x8b, 0x24, 0x38, 0x9a, 0x73,
306 0x50, 0xec, 0x83, 0x6b, 0x00, 0x63, 0xa2, 0x17, 0x21, 0x23, 0x6f, 0xd8, 0xed, 0xb6, 0xd8, 0x9b,
307 0x51, 0xe7, 0xee, 0xb8, 0x7b, 0x61, 0x1b, 0x71, 0x32, 0xcb, 0x7e, 0xa7, 0x35, 0x6c, 0x23, 0x15,
308 0x1c, 0x1e, 0x77, 0x51, 0x50, 0x7c, 0x78, 0x6d, 0x9e, 0xe1, 0x79, 0x41, 0x70, 0xa8, 0xc8, 0xe8
312 /**********************************************************************************************/
315 uint8_t keys_allocated = 0;
316 rsa_publickey_t pub_key;
317 rsa_privatekey_t priv_key;
322 #define ENCRYPTED encrypted
323 #define MODULUS modulus
324 #define PUB_EXPONENT public_exponent
325 #define PRIV_EXPONENT private_exponent
334 #define ENCRYPTED encrypted4
335 #define MODULUS modulus2
336 #define PUB_EXPONENT public_exponent2
337 #define PRIV_EXPONENT private_exponent2
346 uint8_t convert_nibble(uint8_t c){
347 if(c>='0' && c<='9'){
351 if(c>='a' && c<='f'){
357 const char *block_ignore_string=" \t\r\n,;";
358 #define BUFFER_LIMIT 120
359 uint16_t read_os(void* dst, uint16_t length, const char* ignore_string){
360 uint16_t counter = 0;
362 uint8_t v, tmp = 0, idx = 0;
364 ignore_string = block_ignore_string;
366 while(counter < length){
371 if(strchr(ignore_string, c)){
374 v = convert_nibble(c);
379 ((uint8_t*)dst)[counter++] = (tmp << 4) | v;
381 if(counter % (BUFFER_LIMIT/2) == 0){
392 uint16_t own_atou(const char* str){
394 while(*str && *str >= '0' && *str <= '9'){
401 uint8_t read_bigint(bigint_t* a, char* prompt){
402 uint16_t read_length, actual_length;
405 char read_int_str[18];
407 cli_putstr_P(PSTR("\r\n length: "));
408 cli_getsn(read_int_str, 16);
409 read_length = own_atou(read_int_str);
410 off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
411 buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
413 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
416 cli_putstr_P(PSTR("\r\n data: "));
417 memset(buffer, 0, sizeof(bigint_word_t));
418 actual_length = read_os(buffer + off, read_length, NULL);
419 if(actual_length != read_length){
420 cli_putstr_P(PSTR("\r\nERROR: unexpected end of data!"));
424 a->wordv = (bigint_word_t*)buffer;
425 a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
427 bigint_changeendianess(a);
432 uint8_t pre_alloc_key_crt(void){
434 pub_key.modulus = malloc(sizeof(bigint_t));
435 if(!pub_key.modulus){
436 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
439 priv_key.modulus = pub_key.modulus;
441 priv_key.components = malloc(5 * sizeof(bigint_t*));
442 if(!priv_key.components){
443 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
446 pub_key.exponent = malloc(sizeof(bigint_t));
447 if(!pub_key.exponent){
448 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
452 priv_key.components[c] = malloc(sizeof(bigint_t));
453 if(!priv_key.components[c]){
454 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
463 free(pub_key.modulus->wordv);
464 free(pub_key.exponent->wordv);
465 free(pub_key.modulus);
466 pub_key.modulus = priv_key.modulus = NULL;
467 free(pub_key.exponent);
468 pub_key.exponent = NULL;
469 for(c = 0; c < priv_key.n; ++c){
470 free(priv_key.components[c]->wordv);
471 free(priv_key.components[c]);
473 free(priv_key.components);
474 priv_key.components = NULL;
477 uint8_t read_key_crt(void){
479 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
480 r = pre_alloc_key_crt();
482 r = read_bigint(pub_key.modulus,"\r\n = module =");
484 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
486 r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
488 r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
490 r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
492 r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
494 r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
498 uint8_t read_key_conv(void){
500 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
501 pub_key.modulus = malloc(sizeof(bigint_t));
502 if(!pub_key.modulus){
503 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
506 r = read_bigint(pub_key.modulus,"\r\n = module =");
508 priv_key.modulus = pub_key.modulus;
510 pub_key.exponent = malloc(sizeof(bigint_t));
511 if(!pub_key.exponent){
512 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
515 priv_key.components = malloc(sizeof(bigint_t*));
516 if(!priv_key.components){
517 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
520 priv_key.components[0] = malloc(sizeof(bigint_t));
521 if(!priv_key.components[0]){
522 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
525 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
527 r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
531 void load_priv_conventional(void){
533 epriv = malloc(sizeof(bigint_t));
535 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
538 epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
539 epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t));
541 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
544 memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
545 priv_key.components = malloc(sizeof(bigint_t*));
546 priv_key.components[0] = epriv;
548 bigint_changeendianess(epriv);
549 bigint_adjust(epriv);
553 void load_priv_crt_mono(void){
555 const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
556 uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
558 v = malloc(5 * sizeof(bigint_t));
560 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
563 priv_key.components = malloc(5*sizeof(bigint_t*));
564 if(!priv_key.components){
565 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
570 v[i] = malloc(sizeof(bigint_t));
572 v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
573 v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
575 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
578 memcpy(v[i]->wordv, bv[i], sv[i]);
579 bigint_changeendianess(v[i]);
581 priv_key.components[i] = v[i];
585 uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
586 a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
587 a->wordv = malloc(BIGINT_CEIL(length_B));
589 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
592 memset(a->wordv, 0, sizeof(bigint_word_t));
593 memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
595 bigint_changeendianess(a);
600 void load_fix_rsa(void){
606 if(pre_alloc_key_crt()){
607 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
611 load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
612 load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
614 load_bigint_from_os(priv_key.components[0], P, sizeof(P));
615 load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
616 load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
617 load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
618 load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
620 // load_priv_conventional();
621 // load_priv_crt_mono();
624 void quick_test(void){
625 uint8_t *ciphertext, *plaintext, rc;
626 uint8_t seed[sizeof(SEED)];
628 ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
629 plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
630 memcpy_P(plaintext, MSG, sizeof(MSG));
631 memcpy_P(seed, SEED, sizeof(SEED));
632 cli_putstr_P(PSTR("\r\nplaintext:"));
633 cli_hexdump_block(plaintext, sizeof(MSG), 4, 8);
634 cli_putstr_P(PSTR("\r\nencrypting: ..."));
635 rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed);
637 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: "));
638 cli_hexdump_byte(rc);
643 cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
644 cli_hexdump_block(ciphertext, clen, 4, 8);
645 if(clen!=sizeof(ENCRYPTED)){
646 cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
648 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
649 cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
651 cli_putstr_P(PSTR("\r\n>>OK<<"));
655 cli_putstr_P(PSTR("\r\ndecrypting: ..."));
656 rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL);
658 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: "));
659 cli_hexdump_byte(rc);
662 cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
663 cli_hexdump_block(plaintext, plen, 4, 8);
669 void run_seed_test(void){
670 uint8_t *msg, *ciph, *msg_;
671 uint16_t msg_len, ciph_len, msg_len_;
672 uint8_t seed[20], seed_out[20];
673 char read_int_str[18];
674 cli_putstr_P(PSTR("\r\n== test with given seed =="));
675 cli_putstr_P(PSTR("\r\n = message ="));
676 cli_putstr_P(PSTR("\r\n length: "));
677 cli_getsn(read_int_str, 16);
678 msg_len = own_atou(read_int_str);
679 msg = malloc(msg_len);
681 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
684 ciph = malloc(bigint_length_B(pub_key.modulus));
686 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
689 msg_ = malloc(bigint_length_B(pub_key.modulus) + sizeof(bigint_word_t));
691 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
694 cli_putstr_P(PSTR("\r\n data: "));
695 read_os(msg, msg_len, NULL);
696 cli_putstr_P(PSTR("\r\n seed (20 bytes): "));
697 read_os(seed, 20, NULL);
699 cli_putstr_P(PSTR("\r\n encrypting ..."));
700 rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed);
701 cli_putstr_P(PSTR("\r\n ciphertext:"));
702 cli_hexdump_block(ciph, ciph_len, 4, 16);
703 cli_putstr_P(PSTR("\r\n decrypting ... "));
704 rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out);
705 cli_putstr_P(PSTR("[done]"));
706 if(msg_len != msg_len_){
708 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message length ("));
709 itoa(msg_len_, tstr, 10);
711 cli_putstr_P(PSTR(" instead of "));
712 itoa(msg_len, tstr, 10);
717 if(memcmp(msg, msg_, msg_len)){
718 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted message:"));
719 cli_hexdump_block(msg_, msg_len_, 4, 16);
720 cli_putstr_P(PSTR("\r\nreference:"));
721 cli_hexdump_block(msg, msg_len, 4, 16);
725 if(memcmp(seed, seed_out, 20)){
726 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
727 cli_hexdump_block(seed_out, 20, 4, 16);
728 cli_putstr_P(PSTR("\r\nreference:"));
729 cli_hexdump_block(seed, 20, 4, 16);
732 cli_putstr_P(PSTR("\r\n >>OK<<"));
739 void reset_prng(void){
743 cli_putstr_P(PSTR("\r\nPRNG reset"));
747 prng_get_byte = random8;
758 void test_dump(void){
761 cli_putstr_P(PSTR("\r\nenter dump length: "));
762 cli_getsn_cecho(lstr, 15);
763 len = own_atou(lstr);
764 cli_putstr_P(PSTR("\r\ndumping 0x"));
765 cli_hexdump_rev(&len, 2);
766 cli_putstr_P(PSTR(" byte:"));
767 cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
770 /*****************************************************************************
772 *****************************************************************************/
774 const char echo_test_str[] PROGMEM = "echo-test";
775 const char reset_prng_str[] PROGMEM = "reset-prng";
776 const char load_key_str[] PROGMEM = "load-key";
777 const char load_fix_key_str[] PROGMEM = "load-fix-key";
778 const char quick_test_str[] PROGMEM = "quick-test";
779 const char seed_test_str[] PROGMEM = "seed-test";
780 const char dump_test_str[] PROGMEM = "dump-test";
781 const char performance_str[] PROGMEM = "performance";
782 const char echo_str[] PROGMEM = "echo";
784 const cmdlist_entry_t cmdlist[] PROGMEM = {
785 { reset_prng_str, NULL, reset_prng },
786 { load_key_str, NULL, load_key },
787 { load_fix_key_str, NULL, load_fix_rsa },
788 { quick_test_str, NULL, quick_test },
789 { seed_test_str, NULL, run_seed_test },
790 { dump_test_str, NULL, test_dump },
791 // { performance_str, NULL, testrun_performance_bigint },
792 { echo_str, (void*)1, (void_fpt)echo_ctrl },
799 cli_putstr_P(PSTR("\r\nstack pointer: ~"));
800 cli_hexdump_rev(&xa, 4);
807 welcome_msg(algo_name);
809 cmd_interface(cmdlist);