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[] = {
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[] = {
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[] = {
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[] = {
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[] = {
256 /* RSA private exponent d: */
257 const uint8_t private_exponent2[] = {
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[] = {
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[] = {
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[] = {
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[] = {
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[] = {
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 char* own_utoa(unsigned value, char* str, uint8_t radix){
402 char *p = str, *b = str;
414 d = div(value, radix);
419 *p++ = 'a' + d.rem - 10;
431 uint8_t read_bigint(bigint_t* a, char* prompt){
432 uint16_t read_length, actual_length;
435 char read_int_str[18];
437 cli_putstr("\r\n length: ");
438 cli_getsn(read_int_str, 16);
439 read_length = own_atou(read_int_str);
440 off = (sizeof(bigint_word_t) - (read_length % sizeof(bigint_word_t))) % sizeof(bigint_word_t);
441 buffer = malloc(((read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t)) * sizeof(bigint_word_t));
443 cli_putstr("\r\nERROR: OOM!");
446 cli_putstr("\r\n data: ");
447 memset(buffer, 0, sizeof(bigint_word_t));
448 actual_length = read_os(buffer + off, read_length, NULL);
449 if(actual_length != read_length){
450 cli_putstr("\r\nERROR: unexpected end of data!");
454 a->wordv = (bigint_word_t*)buffer;
455 a->length_B = (read_length + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
456 bigint_changeendianess(a);
461 uint8_t pre_alloc_key_crt(void){
463 pub_key.modulus = malloc(sizeof(bigint_t));
464 if(!pub_key.modulus){
465 cli_putstr("\r\nERROR: OOM!");
468 priv_key.modulus = pub_key.modulus;
470 priv_key.components = malloc(5 * sizeof(bigint_t*));
471 if(!priv_key.components){
472 cli_putstr("\r\nERROR: OOM!");
475 pub_key.exponent = malloc(sizeof(bigint_t));
476 if(!pub_key.exponent){
477 cli_putstr("\r\nERROR: OOM!");
481 priv_key.components[c] = malloc(sizeof(bigint_t));
482 if(!priv_key.components[c]){
483 cli_putstr("\r\nERROR: OOM!");
492 free(pub_key.modulus->wordv);
493 free(pub_key.exponent->wordv);
494 free(pub_key.modulus);
495 pub_key.modulus = priv_key.modulus = NULL;
496 free(pub_key.exponent);
497 pub_key.exponent = NULL;
498 for(c = 0; c < priv_key.n; ++c){
499 free(priv_key.components[c]->wordv);
500 free(priv_key.components[c]);
502 free(priv_key.components);
503 priv_key.components = NULL;
506 uint8_t read_key_crt(void){
508 cli_putstr("\r\n== reading key (crt) ==");
509 r = pre_alloc_key_crt();
511 r = read_bigint(pub_key.modulus,"\r\n = module =");
513 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
515 r = read_bigint(priv_key.components[0],"\r\n = p (first prime) =");
517 r = read_bigint(priv_key.components[1],"\r\n = q (second prime) =");
519 r = read_bigint(priv_key.components[2],"\r\n = dp (p's exponent) =");
521 r = read_bigint(priv_key.components[3],"\r\n = dq (q's exponent) =");
523 r = read_bigint(priv_key.components[4],"\r\n = qInv (q' coefficient) =");
527 uint8_t read_key_conv(void){
529 cli_putstr("\r\n== reading key (crt) ==");
530 pub_key.modulus = malloc(sizeof(bigint_t));
531 if(!pub_key.modulus){
532 cli_putstr("\r\nERROR: OOM!");
535 r = read_bigint(pub_key.modulus,"\r\n = module =");
537 priv_key.modulus = pub_key.modulus;
539 pub_key.exponent = malloc(sizeof(bigint_t));
540 if(!pub_key.exponent){
541 cli_putstr("\r\nERROR: OOM!");
544 priv_key.components = malloc(sizeof(bigint_t*));
545 if(!priv_key.components){
546 cli_putstr("\r\nERROR: OOM!");
549 priv_key.components[0] = malloc(sizeof(bigint_t));
550 if(!priv_key.components[0]){
551 cli_putstr("\r\nERROR: OOM!");
554 r = read_bigint(pub_key.exponent,"\r\n = public exponent =");
556 r = read_bigint(priv_key.components[0],"\r\n = private exponent =");
560 void load_priv_conventional(void){
562 epriv = malloc(sizeof(bigint_t));
564 cli_putstr("\r\nERROR: OOM!");
567 epriv->length_B = (sizeof(PRIV_EXPONENT) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
568 epriv->wordv = malloc(epriv->length_B * sizeof(bigint_word_t));
570 cli_putstr("\r\nERROR: OOM!");
573 memcpy(epriv->wordv, PRIV_EXPONENT, sizeof(PRIV_EXPONENT));
574 priv_key.components = malloc(sizeof(bigint_t*));
575 priv_key.components[0] = epriv;
577 bigint_changeendianess(epriv);
578 bigint_adjust(epriv);
582 void load_priv_crt_mono(void){
584 const uint8_t *bv[5] = {P,Q,DP,DQ,QINV};
585 uint16_t sv[5] = {sizeof(P), sizeof(Q), sizeof(DP), sizeof(DQ), sizeof(QINV)};
587 v = malloc(5 * sizeof(bigint_t));
589 cli_putstr("\r\nERROR: OOM!");
592 priv_key.components = malloc(5*sizeof(bigint_t*));
593 if(!priv_key.components){
594 cli_putstr("\r\nERROR: OOM!");
599 v[i] = malloc(sizeof(bigint_t));
601 v[i]->length_B = (sv[i] + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
602 v[i]->wordv = calloc(v[i]->length_B , sizeof(bigint_word_t));
604 cli_putstr("\r\nERROR: OOM!");
607 memcpy(v[i]->wordv, bv[i], sv[i]);
608 bigint_changeendianess(v[i]);
610 priv_key.components[i] = v[i];
614 uint8_t load_bigint_from_os(bigint_t* a, const void* os, uint16_t length_B){
615 a->length_B = BIGINT_CEIL(length_B) / sizeof(bigint_word_t);
616 a->wordv = malloc(BIGINT_CEIL(length_B));
618 cli_putstr("\r\nOOM!\r\n");
621 memset(a->wordv, 0, sizeof(bigint_word_t));
622 memcpy((uint8_t*)a->wordv + BIGINT_OFF(length_B), os, length_B);
624 bigint_changeendianess(a);
629 void load_fix_rsa(void){
635 if(pre_alloc_key_crt()){
636 cli_putstr("\r\nOOM!\r\n");
640 load_bigint_from_os(pub_key.modulus, MODULUS, sizeof(MODULUS));
641 load_bigint_from_os(pub_key.exponent, PUB_EXPONENT, sizeof(PUB_EXPONENT));
643 load_bigint_from_os(priv_key.components[0], P, sizeof(P));
644 load_bigint_from_os(priv_key.components[1], Q, sizeof(Q));
645 load_bigint_from_os(priv_key.components[2], DP, sizeof(DP));
646 load_bigint_from_os(priv_key.components[3], DQ, sizeof(DQ));
647 load_bigint_from_os(priv_key.components[4], QINV, sizeof(QINV));
649 // load_priv_conventional();
650 // load_priv_crt_mono();
653 void quick_test(void){
654 uint8_t *ciphertext, *plaintext, rc;
655 uint8_t seed[sizeof(SEED)];
657 ciphertext = malloc(clen = pub_key.modulus->length_B * sizeof(bigint_word_t));
658 plaintext = malloc(pub_key.modulus->length_B * sizeof(bigint_word_t));
659 memcpy(plaintext, MSG, sizeof(MSG));
660 memcpy(seed, SEED, sizeof(SEED));
661 cli_putstr("\r\nplaintext:");
662 cli_hexdump_block(plaintext, sizeof(MSG), 4, 8);
663 cli_putstr("\r\nencrypting: ...");
664 rc = rsa_encrypt_oaep(ciphertext, &clen, plaintext, sizeof(MSG), &pub_key, NULL, NULL, seed);
666 cli_putstr("\r\nERROR: rsa_encrypt_oaep returned: ");
667 cli_hexdump_byte(rc);
672 cli_putstr("\r\n\r\nciphertext:");
673 cli_hexdump_block(ciphertext, clen, 4, 8);
674 if(clen!=sizeof(ENCRYPTED)){
675 cli_putstr("\r\n>>FAIL (no size match)<<");
677 if(memcmp(ciphertext, ENCRYPTED, clen)){
678 cli_putstr("\r\n>>FAIL (no content match)<<");
680 cli_putstr("\r\n>>OK<<");
684 cli_putstr("\r\ndecrypting: ...");
685 rc = rsa_decrypt_oaep(plaintext, &plen, ciphertext, clen, &priv_key, NULL, NULL, NULL);
687 cli_putstr("\r\nERROR: rsa_decrypt_oaep returned: ");
688 cli_hexdump_byte(rc);
691 cli_putstr("\r\n\r\nplaintext:");
692 cli_hexdump_block(plaintext, plen, 4, 8);
698 void run_seed_test(void){
699 uint8_t *msg, *ciph, *msg_;
700 uint16_t msg_len, ciph_len, msg_len_;
701 uint8_t seed[20], seed_out[20];
702 char read_int_str[18];
703 cli_putstr("\r\n== test with given seed ==");
704 cli_putstr("\r\n = message =");
705 cli_putstr("\r\n length: ");
706 cli_getsn(read_int_str, 16);
707 msg_len = own_atou(read_int_str);
708 msg = malloc(msg_len);
710 cli_putstr("\r\nERROR: OOM!");
713 ciph = malloc(bigint_length_B(pub_key.modulus));
715 cli_putstr("\r\nERROR: OOM!");
718 msg_ = malloc(bigint_length_B(pub_key.modulus));
720 cli_putstr("\r\nERROR: OOM!");
723 cli_putstr("\r\n data: ");
724 read_os(msg, msg_len, NULL);
725 cli_putstr("\r\n seed (20 bytes): ");
726 read_os(seed, 20, NULL);
728 cli_putstr("\r\n encrypting ...");
729 rsa_encrypt_oaep(ciph, &ciph_len, msg, msg_len, &pub_key, NULL, NULL, seed);
730 cli_putstr("\r\n ciphertext:");
731 cli_hexdump_block(ciph, ciph_len, 4, 16);
732 cli_putstr("\r\n decrypting ... ");
733 rsa_decrypt_oaep(msg_, &msg_len_, ciph, ciph_len, &priv_key, NULL, NULL, seed_out);
734 cli_putstr("[done]");
735 if(msg_len != msg_len_){
737 cli_putstr("\r\nERROR: wrong decrypted message length (");
739 own_utoa(msg_len_, tstr, 10);
741 cli_putstr(" instead of ");
742 own_utoa(msg_len, tstr, 10);
747 if(memcmp(msg, msg_, msg_len)){
748 cli_putstr("\r\nERROR: wrong decrypted message:");
749 cli_hexdump_block(msg_, msg_len_, 4, 16);
750 cli_putstr("\r\nreference:");
751 cli_hexdump_block(msg, msg_len, 4, 16);
755 if(memcmp(seed, seed_out, 20)){
756 cli_putstr("\r\nERROR: wrong decrypted seed:");
757 cli_hexdump_block(seed_out, 20, 4, 16);
758 cli_putstr("\r\nreference:");
759 cli_hexdump_block(seed, 20, 4, 16);
762 cli_putstr("\r\n >>OK<<");
769 void reset_prng(void){
773 cli_putstr("\r\nPRNG reset");
777 prng_get_byte = random8;
788 void test_dump(void){
791 cli_putstr("\r\nenter dump length: ");
793 len = own_atou(lstr);
794 cli_putstr("\r\ndumping 0x");
795 cli_hexdump_rev(&len, 2);
796 cli_putstr(" byte:");
797 cli_hexdump_block(pub_key.modulus->wordv, len, 4, 8);
800 /*****************************************************************************
802 *****************************************************************************/
804 const char echo_test_str[] = "echo-test";
805 const char reset_prng_str[] = "reset-prng";
806 const char load_key_str[] = "load-key";
807 const char load_fix_key_str[] = "load-fix-key";
808 const char quick_test_str[] = "quick-test";
809 const char seed_test_str[] = "seed-test";
810 const char dump_test_str[] = "dump-test";
811 const char performance_str[] = "performance";
812 const char echo_str[] = "echo";
814 const cmdlist_entry_t cmdlist[] = {
815 { reset_prng_str, NULL, reset_prng },
816 { load_key_str, NULL, load_key },
817 { load_fix_key_str, NULL, load_fix_rsa },
818 { quick_test_str, NULL, quick_test },
819 { seed_test_str, NULL, run_seed_test },
820 { dump_test_str, NULL, test_dump },
821 // { performance_str, NULL, testrun_performance_bigint },
822 { echo_str, (void*)1, (void_fpt)echo_ctrl },
829 cli_putstr("\r\nstack pointer: ~");
830 cli_hexdump_rev(&xa, 4);
837 welcome_msg(algo_name);
839 cmd_interface(cmdlist);