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"
33 #include "performance_test.h"
35 const char* algo_name = "RSA-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);
426 bigint_changeendianess(a);
431 uint8_t pre_alloc_key_crt(void){
433 pub_key.modulus = malloc(sizeof(bigint_t));
434 if(!pub_key.modulus){
435 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
438 priv_key.modulus = pub_key.modulus;
440 priv_key.components = malloc(5 * sizeof(bigint_t*));
441 if(!priv_key.components){
442 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
445 pub_key.exponent = malloc(sizeof(bigint_t));
446 if(!pub_key.exponent){
447 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
451 priv_key.components[c] = malloc(sizeof(bigint_t));
452 if(!priv_key.components[c]){
453 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
462 free(pub_key.modulus->wordv);
463 free(pub_key.exponent->wordv);
464 free(pub_key.modulus);
465 pub_key.modulus = priv_key.modulus = NULL;
466 free(pub_key.exponent);
467 pub_key.exponent = NULL;
468 for(c = 0; c < priv_key.n; ++c){
469 free(priv_key.components[c]->wordv);
470 free(priv_key.components[c]);
472 free(priv_key.components);
473 priv_key.components = NULL;
476 uint8_t read_key_crt(void){
478 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
479 r = pre_alloc_key_crt();
481 r = read_bigint(pub_key.modulus,"\r\n = module =");
483 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
485 r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
487 r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
489 r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
491 r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
493 r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
497 uint8_t read_key_conv(void){
499 cli_putstr_P(PSTR("\r\n== reading key (crt) =="));
500 pub_key.modulus = malloc(sizeof(bigint_t));
501 if(!pub_key.modulus){
502 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
505 r = read_bigint(pub_key.modulus,"\r\n = module =");
507 priv_key.modulus = pub_key.modulus;
509 pub_key.exponent = malloc(sizeof(bigint_t));
510 if(!pub_key.exponent){
511 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
514 priv_key.components = malloc(sizeof(bigint_t*));
515 if(!priv_key.components){
516 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
519 priv_key.components[0] = malloc(sizeof(bigint_t));
520 if(!priv_key.components[0]){
521 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
524 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
526 r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
530 void load_priv_conventional(void){
532 epriv = malloc(sizeof(bigint_t));
534 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
537 epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
538 epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t));
540 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
543 memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
544 priv_key.components = malloc(sizeof(bigint_t*));
545 priv_key.components[0] = epriv;
547 bigint_changeendianess(epriv);
548 bigint_adjust(epriv);
552 void load_priv_crt_mono(void){
554 const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
555 uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
557 v = malloc(5 * sizeof(bigint_t));
559 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
562 priv_key.components = malloc(5*sizeof(bigint_t*));
563 if(!priv_key.components){
564 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
569 v[i] = malloc(sizeof(bigint_t));
571 v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
572 v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
574 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
577 memcpy(v[i]->wordv, bv[i], sv[i]);
578 bigint_changeendianess(v[i]);
580 priv_key.components[i] = v[i];
584 uint8_t load_bigint_from_os(bigint_t* a, PGM_VOID_P os, uint16_t length_B){
585 a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
586 a->wordv = malloc(BIGINT_CEIL(length_B));
588 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
591 memset(a->wordv, 0, sizeof(bigint_word_t));
592 memcpy_P((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
594 bigint_changeendianess(a);
599 void load_fix_rsa(void){
605 if(pre_alloc_key_crt()){
606 cli_putstr_P(PSTR("\r\nOOM!\r\n"));
610 load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
611 load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
613 load_bigint_from_os(priv_key.components[0], P, sizeof(P));
614 load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
615 load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
616 load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
617 load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
619 // load_priv_conventional();
620 // load_priv_crt_mono();
623 void quick_test(void){
624 uint8_t *ciphertext, *plaintext, rc;
625 uint8_t seed[sizeof(SEED)];
627 ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
628 plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
629 memcpy_P(plaintext, MSG, sizeof(MSG));
630 memcpy_P(seed, SEED, sizeof(SEED));
631 cli_putstr_P(PSTR("\r\nplaintext:"));
632 cli_hexdump_block(plaintext, sizeof(MSG), 4, 8);
633 cli_putstr_P(PSTR("\r\nencrypting: ..."));
634 rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed);
636 cli_putstr_P(PSTR("\r\nERROR: rsa_encrypt_oaep returned: "));
637 cli_hexdump_byte(rc);
642 cli_putstr_P(PSTR("\r\n\r\nciphertext:"));
643 cli_hexdump_block(ciphertext, clen, 4, 8);
644 if(clen!=sizeof(ENCRYPTED)){
645 cli_putstr_P(PSTR("\r\n>>FAIL (no size match)<<"));
647 if(memcmp_P(ciphertext, ENCRYPTED, clen)){
648 cli_putstr_P(PSTR("\r\n>>FAIL (no content match)<<"));
650 cli_putstr_P(PSTR("\r\n>>OK<<"));
654 cli_putstr_P(PSTR("\r\ndecrypting: ..."));
655 rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL);
657 cli_putstr_P(PSTR("\r\nERROR: rsa_decrypt_oaep returned: "));
658 cli_hexdump_byte(rc);
661 cli_putstr_P(PSTR("\r\n\r\nplaintext:"));
662 cli_hexdump_block(plaintext, plen, 4, 8);
668 void run_seed_test(void){
669 uint8_t *msg, *ciph, *msg_;
670 uint16_t msg_len, ciph_len, msg_len_;
671 uint8_t seed[20], seed_out[20];
672 char read_int_str[18];
673 cli_putstr_P(PSTR("\r\n== test with given seed =="));
674 cli_putstr_P(PSTR("\r\n = message ="));
675 cli_putstr_P(PSTR("\r\n length: "));
676 cli_getsn(read_int_str, 16);
677 msg_len = own_atou(read_int_str);
678 msg = malloc(msg_len);
680 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
683 ciph = malloc(bigint_length_B(pub_key.modulus));
685 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
688 msg_ = malloc(bigint_length_B(pub_key.modulus));
690 cli_putstr_P(PSTR("\r\nERROR: OOM!"));
693 cli_putstr_P(PSTR("\r\n data: "));
694 read_os(msg, msg_len, NULL);
695 cli_putstr_P(PSTR("\r\n seed (20 bytes): "));
696 read_os(seed, 20, NULL);
698 cli_putstr_P(PSTR("\r\n encrypting ..."));
699 rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed);
700 cli_putstr_P(PSTR("\r\n ciphertext:"));
701 cli_hexdump_block(ciph, ciph_len, 4, 16);
702 cli_putstr_P(PSTR("\r\n decrypting ... "));
703 rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, 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, 20)){
725 cli_putstr_P(PSTR("\r\nERROR: wrong decrypted seed:"));
726 cli_hexdump_block(seed_out, 20, 4, 16);
727 cli_putstr_P(PSTR("\r\nreference:"));
728 cli_hexdump_block(seed, 20, 4, 16);
731 cli_putstr_P(PSTR("\r\n >>OK<<"));
738 void reset_prng(void){
742 cli_putstr_P(PSTR("\r\nPRNG reset"));
746 prng_get_byte = random8;
757 void test_dump(void){
760 cli_putstr_P(PSTR("\r\nenter dump length: "));
761 cli_getsn_cecho(lstr, 15);
762 len = own_atou(lstr);
763 cli_putstr_P(PSTR("\r\ndumping 0x"));
764 cli_hexdump_rev(&len, 2);
765 cli_putstr_P(PSTR(" byte:"));
766 cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
769 /*****************************************************************************
771 *****************************************************************************/
773 const char echo_test_str[] PROGMEM = "echo-test";
774 const char reset_prng_str[] PROGMEM = "reset-prng";
775 const char load_key_str[] PROGMEM = "load-key";
776 const char load_fix_key_str[] PROGMEM = "load-fix-key";
777 const char quick_test_str[] PROGMEM = "quick-test";
778 const char seed_test_str[] PROGMEM = "seed-test";
779 const char dump_test_str[] PROGMEM = "dump-test";
780 const char performance_str[] PROGMEM = "performance";
781 const char echo_str[] PROGMEM = "echo";
783 const cmdlist_entry_t cmdlist[] PROGMEM = {
784 { reset_prng_str, NULL, reset_prng },
785 { load_key_str, NULL, load_key },
786 { load_fix_key_str, NULL, load_fix_rsa },
787 { quick_test_str, NULL, quick_test },
788 { seed_test_str, NULL, run_seed_test },
789 { dump_test_str, NULL, test_dump },
790 // { performance_str, NULL, testrun_performance_bigint },
791 { echo_str, (void*)1, (void_fpt)echo_ctrl },
798 cli_putstr_P(PSTR("\r\nstack pointer: ~"));
799 cli_hexdump_rev(&xa, 4);
806 welcome_msg(algo_name);
808 cmd_interface(cmdlist);