blob: e0206eca294409c8debee46058142635b08c96fc [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/rsa.h"
Janos Follath55be79b2024-08-21 13:24:01 +01003#include "bignum_core.h"
Chris Jones66a4cd42021-03-09 16:04:12 +00004#include "rsa_alt_helpers.h"
Valerio Setti8e6093d2024-01-23 15:19:07 +01005#include "rsa_internal.h"
Paul Bakker33b43f12013-08-20 11:48:36 +02006/* END_HEADER */
Paul Bakker42a29bf2009-07-07 20:18:41 +00007
Paul Bakker33b43f12013-08-20 11:48:36 +02008/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02009 * depends_on:MBEDTLS_RSA_C:MBEDTLS_BIGNUM_C:MBEDTLS_GENPRIME
Paul Bakker33b43f12013-08-20 11:48:36 +020010 * END_DEPENDENCIES
11 */
Paul Bakker5690efc2011-05-26 13:16:06 +000012
Paul Bakker33b43f12013-08-20 11:48:36 +020013/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010014void rsa_invalid_param()
Ronald Cronea7631b2021-06-03 18:51:59 +020015{
16 mbedtls_rsa_context ctx;
17 const int invalid_padding = 42;
18 const int invalid_hash_id = 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010019 unsigned char buf[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
20 size_t buf_len = sizeof(buf);
Ronald Cronea7631b2021-06-03 18:51:59 +020021
Gilles Peskine449bd832023-01-11 14:50:10 +010022 mbedtls_rsa_init(&ctx);
Ronald Cronea7631b2021-06-03 18:51:59 +020023
Gilles Peskine449bd832023-01-11 14:50:10 +010024 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
25 invalid_padding,
26 MBEDTLS_MD_NONE),
27 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cronea7631b2021-06-03 18:51:59 +020028
Gilles Peskine449bd832023-01-11 14:50:10 +010029 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
30 MBEDTLS_RSA_PKCS_V21,
31 invalid_hash_id),
32 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cronea7631b2021-06-03 18:51:59 +020033
Gilles Peskine449bd832023-01-11 14:50:10 +010034 TEST_EQUAL(mbedtls_rsa_pkcs1_sign(&ctx, NULL,
35 NULL, MBEDTLS_MD_NONE,
36 buf_len,
37 NULL, buf),
38 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010039
Gilles Peskine449bd832023-01-11 14:50:10 +010040 TEST_EQUAL(mbedtls_rsa_pkcs1_sign(&ctx, NULL,
41 NULL, MBEDTLS_MD_SHA256,
42 0,
43 NULL, buf),
44 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010045
Gilles Peskine449bd832023-01-11 14:50:10 +010046 TEST_EQUAL(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_NONE,
47 buf_len,
48 NULL, buf),
49 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010050
Gilles Peskine449bd832023-01-11 14:50:10 +010051 TEST_EQUAL(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_SHA256,
52 0,
53 NULL, buf),
54 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010055
Ronald Cron3a0375f2021-06-08 10:22:28 +020056#if !defined(MBEDTLS_PKCS1_V15)
Gilles Peskine449bd832023-01-11 14:50:10 +010057 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
58 MBEDTLS_RSA_PKCS_V15,
59 MBEDTLS_MD_NONE),
60 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cron3a0375f2021-06-08 10:22:28 +020061#endif
62
Tuvshinzaya Erdenekhuufe7524d2022-09-01 16:07:18 +010063#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine449bd832023-01-11 14:50:10 +010064 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_sign(&ctx, NULL,
65 NULL, MBEDTLS_MD_NONE,
66 buf_len,
67 NULL, buf),
68 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010069
Gilles Peskine449bd832023-01-11 14:50:10 +010070 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_sign(&ctx, NULL,
71 NULL, MBEDTLS_MD_SHA256,
72 0,
73 NULL, buf),
74 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010075
Gilles Peskine449bd832023-01-11 14:50:10 +010076 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_verify(&ctx, MBEDTLS_MD_NONE,
77 buf_len,
78 NULL, buf),
79 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010080
Gilles Peskine449bd832023-01-11 14:50:10 +010081 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_verify(&ctx, MBEDTLS_MD_SHA256,
82 0,
83 NULL, buf),
84 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010085
86
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010087#endif
88
Ronald Cron3a0375f2021-06-08 10:22:28 +020089#if !defined(MBEDTLS_PKCS1_V21)
Gilles Peskine449bd832023-01-11 14:50:10 +010090 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
91 MBEDTLS_RSA_PKCS_V21,
92 MBEDTLS_MD_NONE),
93 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cron3a0375f2021-06-08 10:22:28 +020094#endif
95
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010096#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine449bd832023-01-11 14:50:10 +010097 TEST_EQUAL(mbedtls_rsa_rsassa_pss_sign_ext(&ctx, NULL, NULL,
98 MBEDTLS_MD_NONE, buf_len,
99 NULL, buf_len,
100 buf),
101 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100102
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 TEST_EQUAL(mbedtls_rsa_rsassa_pss_sign_ext(&ctx, NULL, NULL,
104 MBEDTLS_MD_SHA256, 0,
105 NULL, buf_len,
106 buf),
107 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +0100108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify_ext(&ctx, MBEDTLS_MD_NONE,
110 buf_len, NULL,
111 MBEDTLS_MD_NONE,
112 buf_len, buf),
113 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100114
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify_ext(&ctx, MBEDTLS_MD_SHA256,
116 0, NULL,
117 MBEDTLS_MD_NONE,
118 buf_len, buf),
119 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +0100120
Gilles Peskine449bd832023-01-11 14:50:10 +0100121 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify(&ctx, MBEDTLS_MD_NONE,
122 buf_len,
123 NULL, buf),
124 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100125
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify(&ctx, MBEDTLS_MD_SHA256,
127 0,
128 NULL, buf),
129 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100130#endif
131
Ronald Cronea7631b2021-06-03 18:51:59 +0200132exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 mbedtls_rsa_free(&ctx);
Ronald Cronea7631b2021-06-03 18:51:59 +0200134}
135/* END_CASE */
136
137/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100138void rsa_init_free(int reinit)
Gilles Peskine914afe12021-02-01 17:55:24 +0100139{
140 mbedtls_rsa_context ctx;
141
142 /* Double free is not explicitly documented to work, but we rely on it
143 * even inside the library so that you can call mbedtls_rsa_free()
144 * unconditionally on an error path without checking whether it has
145 * already been called in the success path. */
146
Gilles Peskine449bd832023-01-11 14:50:10 +0100147 mbedtls_rsa_init(&ctx);
148 mbedtls_rsa_free(&ctx);
Gilles Peskine914afe12021-02-01 17:55:24 +0100149
Gilles Peskine449bd832023-01-11 14:50:10 +0100150 if (reinit) {
151 mbedtls_rsa_init(&ctx);
152 }
153 mbedtls_rsa_free(&ctx);
Gilles Peskine914afe12021-02-01 17:55:24 +0100154
155 /* This test case always succeeds, functionally speaking. A plausible
156 * bug might trigger an invalid pointer dereference or a memory leak. */
157 goto exit;
158}
159/* END_CASE */
160
Manuel Pégourié-Gonnard236c4e22022-07-16 08:35:06 +0200161/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100162void mbedtls_rsa_pkcs1_sign(data_t *message_str, int padding_mode,
163 int digest, int mod, char *input_P,
164 char *input_Q, char *input_N, char *input_E,
165 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000166{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200167 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100169 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200170 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000171
Gilles Peskine449bd832023-01-11 14:50:10 +0100172 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
173 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
174 mbedtls_rsa_init(&ctx);
175 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
176 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000177
Gilles Peskine449bd832023-01-11 14:50:10 +0100178 memset(output, 0x00, sizeof(output));
179 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000180
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
182 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
183 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
184 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000185
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100187 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
188 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
190 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192 TEST_ASSERT(mbedtls_rsa_pkcs1_sign(
193 &ctx, &mbedtls_test_rnd_pseudo_rand, &rnd_info,
194 digest, message_str->len, message_str->x,
195 output) == result);
196 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
199 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000200 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000201
Paul Bakkerbd51b262014-07-10 15:26:12 +0200202exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
204 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
205 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000206}
Paul Bakker33b43f12013-08-20 11:48:36 +0200207/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000208
Manuel Pégourié-Gonnard236c4e22022-07-16 08:35:06 +0200209/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100210void mbedtls_rsa_pkcs1_verify(data_t *message_str, int padding_mode,
211 int digest, int mod,
212 char *input_N, char *input_E,
213 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000214{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100216 mbedtls_mpi N, E;
217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
219 mbedtls_rsa_init(&ctx);
220 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
221 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
224 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
225 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100226 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
227 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000229
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 TEST_ASSERT(mbedtls_rsa_pkcs1_verify(&ctx, digest, message_str->len, message_str->x,
231 result_str->x) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100232
Paul Bakkerbd51b262014-07-10 15:26:12 +0200233exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
235 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000236}
Paul Bakker33b43f12013-08-20 11:48:36 +0200237/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000238
Paul Bakker821fb082009-07-12 13:26:42 +0000239
Paul Bakker33b43f12013-08-20 11:48:36 +0200240/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241void rsa_pkcs1_sign_raw(data_t *hash_result,
242 int padding_mode, int mod,
243 char *input_P, char *input_Q,
244 char *input_N, char *input_E,
245 data_t *result_str)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000246{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200247 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100249 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200250 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 mbedtls_rsa_init(&ctx);
253 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
254 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
Paul Bakker821fb082009-07-12 13:26:42 +0000255
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
257 MBEDTLS_MD_NONE) == 0);
Paul Elliotte57dd2d2021-06-25 11:13:24 +0100258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 memset(output, 0x00, sizeof(output));
260 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000261
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
263 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
264 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
265 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000266
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100268 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
269 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
271 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000272
Paul Bakker821fb082009-07-12 13:26:42 +0000273
Gilles Peskine449bd832023-01-11 14:50:10 +0100274 TEST_ASSERT(mbedtls_rsa_pkcs1_sign(&ctx, &mbedtls_test_rnd_pseudo_rand,
275 &rnd_info, MBEDTLS_MD_NONE,
276 hash_result->len,
277 hash_result->x, output) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000278
Paul Bakker821fb082009-07-12 13:26:42 +0000279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
281 ctx.len, result_str->len) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000282
Paul Bakkerbd51b262014-07-10 15:26:12 +0200283exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
285 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000288}
Paul Bakker33b43f12013-08-20 11:48:36 +0200289/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000290
Paul Bakker33b43f12013-08-20 11:48:36 +0200291/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100292void rsa_pkcs1_verify_raw(data_t *hash_result,
293 int padding_mode, int mod,
294 char *input_N, char *input_E,
295 data_t *result_str, int correct)
Paul Bakker821fb082009-07-12 13:26:42 +0000296{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200297 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298 mbedtls_rsa_context ctx;
Paul Bakker821fb082009-07-12 13:26:42 +0000299
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100300 mbedtls_mpi N, E;
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 mbedtls_rsa_init(&ctx);
304 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
305 MBEDTLS_MD_NONE) == 0);
306 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
309 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100312 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
313 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000315
Paul Bakker821fb082009-07-12 13:26:42 +0000316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 TEST_ASSERT(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_NONE, hash_result->len, hash_result->x,
318 result_str->x) == correct);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100319
Paul Bakkerbd51b262014-07-10 15:26:12 +0200320exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
322 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000323}
Paul Bakker33b43f12013-08-20 11:48:36 +0200324/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000325
Paul Bakker33b43f12013-08-20 11:48:36 +0200326/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100327void mbedtls_rsa_pkcs1_encrypt(data_t *message_str, int padding_mode,
328 int mod, char *input_N, char *input_E,
329 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000330{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200331 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 mbedtls_rsa_context ctx;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200333 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker997bbd12011-03-13 15:45:42 +0000334
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100335 mbedtls_mpi N, E;
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker821fb082009-07-12 13:26:42 +0000339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 mbedtls_rsa_init(&ctx);
341 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
342 MBEDTLS_MD_NONE) == 0);
343 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
346 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100349 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
350 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000352
Paul Bakker42a29bf2009-07-07 20:18:41 +0000353
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 TEST_ASSERT(mbedtls_rsa_pkcs1_encrypt(&ctx,
355 &mbedtls_test_rnd_pseudo_rand,
356 &rnd_info, message_str->len,
357 message_str->x,
358 output) == result);
359 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000360
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
362 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000363 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100364
Paul Bakkerbd51b262014-07-10 15:26:12 +0200365exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
367 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000368}
Paul Bakker33b43f12013-08-20 11:48:36 +0200369/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000370
Paul Bakker33b43f12013-08-20 11:48:36 +0200371/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100372void rsa_pkcs1_encrypt_bad_rng(data_t *message_str, int padding_mode,
373 int mod, char *input_N, char *input_E,
374 data_t *result_str, int result)
Paul Bakkera6656852010-07-18 19:47:14 +0000375{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200376 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_rsa_context ctx;
Paul Bakkera6656852010-07-18 19:47:14 +0000378
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100379 mbedtls_mpi N, E;
380
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
382 mbedtls_rsa_init(&ctx);
383 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
384 MBEDTLS_MD_NONE) == 0);
385 memset(output, 0x00, sizeof(output));
Paul Bakkera6656852010-07-18 19:47:14 +0000386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
388 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100391 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
392 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000394
Paul Bakkera6656852010-07-18 19:47:14 +0000395
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 TEST_ASSERT(mbedtls_rsa_pkcs1_encrypt(&ctx, &mbedtls_test_rnd_zero_rand,
397 NULL, message_str->len,
398 message_str->x,
399 output) == result);
400 if (result == 0) {
Paul Bakkera6656852010-07-18 19:47:14 +0000401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
403 ctx.len, result_str->len) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000404 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100405
Paul Bakkerbd51b262014-07-10 15:26:12 +0200406exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
408 mbedtls_rsa_free(&ctx);
Paul Bakkera6656852010-07-18 19:47:14 +0000409}
Paul Bakker33b43f12013-08-20 11:48:36 +0200410/* END_CASE */
Paul Bakkera6656852010-07-18 19:47:14 +0000411
Paul Bakker33b43f12013-08-20 11:48:36 +0200412/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100413void mbedtls_rsa_pkcs1_decrypt(data_t *message_str, int padding_mode,
414 int mod, char *input_P,
415 char *input_Q, char *input_N,
416 char *input_E, int max_output,
417 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000418{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200419 unsigned char output[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 mbedtls_rsa_context ctx;
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000421 size_t output_len;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200422 mbedtls_test_rnd_pseudo_info rnd_info;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100423 mbedtls_mpi N, P, Q, E;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
426 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100427
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 mbedtls_rsa_init(&ctx);
429 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
430 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 memset(output, 0x00, sizeof(output));
433 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000434
Paul Bakker42a29bf2009-07-07 20:18:41 +0000435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
437 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
438 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
439 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100442 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
443 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
445 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000446
Paul Bakker69998dd2009-07-11 19:15:20 +0000447 output_len = 0;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 TEST_ASSERT(mbedtls_rsa_pkcs1_decrypt(&ctx, mbedtls_test_rnd_pseudo_rand,
450 &rnd_info,
451 &output_len, message_str->x, output,
452 max_output) == result);
453 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
456 output_len,
457 result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000458 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000459
Paul Bakkerbd51b262014-07-10 15:26:12 +0200460exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
462 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
463 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000464}
Paul Bakker33b43f12013-08-20 11:48:36 +0200465/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000466
Paul Bakker33b43f12013-08-20 11:48:36 +0200467/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100468void mbedtls_rsa_public(data_t *message_str, int mod,
469 char *input_N, char *input_E,
470 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000471{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200472 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
Paul Bakker821fb082009-07-12 13:26:42 +0000474
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100475 mbedtls_mpi N, E;
476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
478 mbedtls_rsa_init(&ctx);
479 mbedtls_rsa_init(&ctx2);
480 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000481
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
483 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine058d0092021-06-09 16:24:35 +0200486
487 /* Check test data consistency */
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100488 TEST_EQUAL(message_str->len, (size_t) ((mod + 7) / 8));
489 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
490 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000492
Janos Follath55be79b2024-08-21 13:24:01 +0100493#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
494 mbedtls_mpi_optionally_safe_codepath_reset();
495#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 TEST_ASSERT(mbedtls_rsa_public(&ctx, message_str->x, output) == result);
Janos Follath55be79b2024-08-21 13:24:01 +0100497#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
498 TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_PUBLIC);
499#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 if (result == 0) {
Paul Bakker821fb082009-07-12 13:26:42 +0000501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
503 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000504 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100505
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100506 /* And now with the copy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 TEST_ASSERT(mbedtls_rsa_copy(&ctx2, &ctx) == 0);
Paul Bakkerbd51b262014-07-10 15:26:12 +0200508 /* clear the original to be sure */
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 mbedtls_rsa_free(&ctx);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx2) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 memset(output, 0x00, sizeof(output));
514 TEST_ASSERT(mbedtls_rsa_public(&ctx2, message_str->x, output) == result);
515 if (result == 0) {
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
518 ctx.len, result_str->len) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100519 }
520
Paul Bakkerbd51b262014-07-10 15:26:12 +0200521exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
523 mbedtls_rsa_free(&ctx);
524 mbedtls_rsa_free(&ctx2);
Paul Bakker821fb082009-07-12 13:26:42 +0000525}
Paul Bakker33b43f12013-08-20 11:48:36 +0200526/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000527
Paul Bakker33b43f12013-08-20 11:48:36 +0200528/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100529void mbedtls_rsa_private(data_t *message_str, int mod,
530 char *input_P, char *input_Q,
531 char *input_N, char *input_E,
532 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000533{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200534 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200535 mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100536 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200537 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200538 int i;
Paul Bakker821fb082009-07-12 13:26:42 +0000539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
541 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
542 mbedtls_rsa_init(&ctx);
543 mbedtls_rsa_init(&ctx2);
Paul Bakker821fb082009-07-12 13:26:42 +0000544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker821fb082009-07-12 13:26:42 +0000546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
548 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
549 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
550 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine058d0092021-06-09 16:24:35 +0200553
554 /* Check test data consistency */
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100555 TEST_EQUAL(message_str->len, (size_t) ((mod + 7) / 8));
556 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
557 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
559 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000560
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200561 /* repeat three times to test updating of blinding values */
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 for (i = 0; i < 3; i++) {
563 memset(output, 0x00, sizeof(output));
Janos Follath55be79b2024-08-21 13:24:01 +0100564#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
565 mbedtls_mpi_optionally_safe_codepath_reset();
566#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_pseudo_rand,
568 &rnd_info, message_str->x,
569 output) == result);
Janos Follath55be79b2024-08-21 13:24:01 +0100570#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
571 TEST_EQUAL(mbedtls_mpi_optionally_safe_codepath, MBEDTLS_MPI_IS_SECRET);
572#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 if (result == 0) {
Paul Bakker821fb082009-07-12 13:26:42 +0000574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
576 ctx.len,
577 result_str->len) == 0);
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200578 }
Paul Bakker821fb082009-07-12 13:26:42 +0000579 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000580
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100581 /* And now one more time with the copy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 TEST_ASSERT(mbedtls_rsa_copy(&ctx2, &ctx) == 0);
Paul Bakkerbd51b262014-07-10 15:26:12 +0200583 /* clear the original to be sure */
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 mbedtls_rsa_free(&ctx);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100585
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx2) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 memset(output, 0x00, sizeof(output));
589 TEST_ASSERT(mbedtls_rsa_private(&ctx2, mbedtls_test_rnd_pseudo_rand,
590 &rnd_info, message_str->x,
591 output) == result);
592 if (result == 0) {
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
595 ctx2.len,
596 result_str->len) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100597 }
598
Paul Bakkerbd51b262014-07-10 15:26:12 +0200599exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
601 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 mbedtls_rsa_free(&ctx); mbedtls_rsa_free(&ctx2);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000604}
Paul Bakker33b43f12013-08-20 11:48:36 +0200605/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000606
Paul Bakker33b43f12013-08-20 11:48:36 +0200607/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100608void rsa_check_privkey_null()
Paul Bakker37940d9f2009-07-10 22:38:58 +0000609{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 mbedtls_rsa_context ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 memset(&ctx, 0x00, sizeof(mbedtls_rsa_context));
Paul Bakker37940d9f2009-07-10 22:38:58 +0000612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED);
Paul Bakker37940d9f2009-07-10 22:38:58 +0000614}
Paul Bakker33b43f12013-08-20 11:48:36 +0200615/* END_CASE */
Paul Bakker37940d9f2009-07-10 22:38:58 +0000616
Paul Bakker33b43f12013-08-20 11:48:36 +0200617/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100618void mbedtls_rsa_check_pubkey(char *input_N, char *input_E, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000619{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200620 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100621 mbedtls_mpi N, E;
Paul Bakker821fb082009-07-12 13:26:42 +0000622
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
624 mbedtls_rsa_init(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 if (strlen(input_N)) {
627 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000628 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 if (strlen(input_E)) {
630 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000631 }
632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
634 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100635
Paul Bakkerbd51b262014-07-10 15:26:12 +0200636exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
638 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000639}
Paul Bakker33b43f12013-08-20 11:48:36 +0200640/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000641
Paul Bakker33b43f12013-08-20 11:48:36 +0200642/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100643void mbedtls_rsa_check_privkey(int mod, char *input_P, char *input_Q,
644 char *input_N, char *input_E, char *input_D,
645 char *input_DP, char *input_DQ, char *input_QP,
646 int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000647{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_rsa_context ctx;
Paul Bakker821fb082009-07-12 13:26:42 +0000649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 mbedtls_rsa_init(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000651
Paul Bakker33b43f12013-08-20 11:48:36 +0200652 ctx.len = mod / 8;
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 if (strlen(input_P)) {
654 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.P, input_P) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000655 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 if (strlen(input_Q)) {
657 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.Q, input_Q) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000658 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 if (strlen(input_N)) {
660 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.N, input_N) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000661 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if (strlen(input_E)) {
663 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000664 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 if (strlen(input_D)) {
666 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.D, input_D) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000667 }
Hanno Becker131134f2017-08-23 08:31:07 +0100668#if !defined(MBEDTLS_RSA_NO_CRT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 if (strlen(input_DP)) {
670 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.DP, input_DP) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000671 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 if (strlen(input_DQ)) {
673 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.DQ, input_DQ) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000674 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if (strlen(input_QP)) {
676 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.QP, input_QP) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000677 }
Hanno Becker131134f2017-08-23 08:31:07 +0100678#else
Werner Lewisf65a3272022-07-07 11:38:44 +0100679 ((void) input_DP);
680 ((void) input_DQ);
681 ((void) input_QP);
Hanno Becker131134f2017-08-23 08:31:07 +0100682#endif
Paul Bakker821fb082009-07-12 13:26:42 +0000683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100685
Paul Bakkerbd51b262014-07-10 15:26:12 +0200686exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000688}
Paul Bakker33b43f12013-08-20 11:48:36 +0200689/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000690
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100691/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100692void rsa_check_pubpriv(int mod, char *input_Npub, char *input_Epub,
693 char *input_P, char *input_Q, char *input_N,
694 char *input_E, char *input_D, char *input_DP,
695 char *input_DQ, char *input_QP, int result)
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100696{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 mbedtls_rsa_context pub, prv;
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 mbedtls_rsa_init(&pub);
700 mbedtls_rsa_init(&prv);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100701
702 pub.len = mod / 8;
703 prv.len = mod / 8;
704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 if (strlen(input_Npub)) {
706 TEST_ASSERT(mbedtls_test_read_mpi(&pub.N, input_Npub) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100707 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 if (strlen(input_Epub)) {
709 TEST_ASSERT(mbedtls_test_read_mpi(&pub.E, input_Epub) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100710 }
711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if (strlen(input_P)) {
713 TEST_ASSERT(mbedtls_test_read_mpi(&prv.P, input_P) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100714 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 if (strlen(input_Q)) {
716 TEST_ASSERT(mbedtls_test_read_mpi(&prv.Q, input_Q) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100717 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 if (strlen(input_N)) {
719 TEST_ASSERT(mbedtls_test_read_mpi(&prv.N, input_N) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100720 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 if (strlen(input_E)) {
722 TEST_ASSERT(mbedtls_test_read_mpi(&prv.E, input_E) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100723 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 if (strlen(input_D)) {
725 TEST_ASSERT(mbedtls_test_read_mpi(&prv.D, input_D) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100726 }
Hanno Becker131134f2017-08-23 08:31:07 +0100727#if !defined(MBEDTLS_RSA_NO_CRT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 if (strlen(input_DP)) {
729 TEST_ASSERT(mbedtls_test_read_mpi(&prv.DP, input_DP) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100730 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 if (strlen(input_DQ)) {
732 TEST_ASSERT(mbedtls_test_read_mpi(&prv.DQ, input_DQ) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100733 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 if (strlen(input_QP)) {
735 TEST_ASSERT(mbedtls_test_read_mpi(&prv.QP, input_QP) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100736 }
Hanno Becker131134f2017-08-23 08:31:07 +0100737#else
Werner Lewisf65a3272022-07-07 11:38:44 +0100738 ((void) input_DP);
739 ((void) input_DQ);
740 ((void) input_QP);
Hanno Becker131134f2017-08-23 08:31:07 +0100741#endif
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 TEST_ASSERT(mbedtls_rsa_check_pub_priv(&pub, &prv) == result);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100744
745exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 mbedtls_rsa_free(&pub);
747 mbedtls_rsa_free(&prv);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100748}
749/* END_CASE */
750
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200751/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100752void mbedtls_rsa_gen_key(int nrbits, int exponent, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000753{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 mbedtls_rsa_context ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 mbedtls_rsa_init(&ctx);
Paul Bakkerc0a1a312011-12-04 17:12:15 +0000756
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200757 /* This test uses an insecure RNG, suitable only for testing.
758 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 TEST_ASSERT(mbedtls_rsa_gen_key(&ctx, mbedtls_test_rnd_std_rand, NULL, nrbits,
760 exponent) == result);
761 if (result == 0) {
762 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
763 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&ctx.P, &ctx.Q) > 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000764 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100765
Paul Bakkerbd51b262014-07-10 15:26:12 +0200766exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000768}
Paul Bakker33b43f12013-08-20 11:48:36 +0200769/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000770
Manuel Pégourié-Gonnard1d1174a2022-07-16 08:41:34 +0200771/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100772void mbedtls_rsa_deduce_primes(char *input_N,
773 char *input_D,
774 char *input_E,
775 char *output_P,
776 char *output_Q,
777 int corrupt, int result)
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100778{
779 mbedtls_mpi N, P, Pp, Q, Qp, D, E;
780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 mbedtls_mpi_init(&N);
782 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
783 mbedtls_mpi_init(&Pp); mbedtls_mpi_init(&Qp);
784 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100785
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
787 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
788 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
789 TEST_ASSERT(mbedtls_test_read_mpi(&Qp, output_P) == 0);
790 TEST_ASSERT(mbedtls_test_read_mpi(&Pp, output_Q) == 0);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 if (corrupt) {
793 TEST_ASSERT(mbedtls_mpi_add_int(&D, &D, 2) == 0);
794 }
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100795
796 /* Try to deduce P, Q from N, D, E only. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 TEST_ASSERT(mbedtls_rsa_deduce_primes(&N, &D, &E, &P, &Q) == result);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 if (!corrupt) {
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100800 /* Check if (P,Q) = (Pp, Qp) or (P,Q) = (Qp, Pp) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 TEST_ASSERT((mbedtls_mpi_cmp_mpi(&P, &Pp) == 0 && mbedtls_mpi_cmp_mpi(&Q, &Qp) == 0) ||
802 (mbedtls_mpi_cmp_mpi(&P, &Qp) == 0 && mbedtls_mpi_cmp_mpi(&Q, &Pp) == 0));
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100803 }
804
805exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 mbedtls_mpi_free(&N);
807 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
808 mbedtls_mpi_free(&Pp); mbedtls_mpi_free(&Qp);
809 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100810}
811/* END_CASE */
812
Hanno Becker6b4ce492017-08-23 11:00:21 +0100813/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100814void mbedtls_rsa_deduce_private_exponent(char *input_P,
815 char *input_Q,
816 char *input_E,
817 char *output_D,
818 int corrupt, int result)
Hanno Becker6b4ce492017-08-23 11:00:21 +0100819{
820 mbedtls_mpi P, Q, D, Dp, E, R, Rp;
821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
823 mbedtls_mpi_init(&D); mbedtls_mpi_init(&Dp);
824 mbedtls_mpi_init(&E);
825 mbedtls_mpi_init(&R); mbedtls_mpi_init(&Rp);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
828 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
829 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
830 TEST_ASSERT(mbedtls_test_read_mpi(&Dp, output_D) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 if (corrupt) {
Hanno Becker6b4ce492017-08-23 11:00:21 +0100833 /* Make E even */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 0) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100835 }
836
837 /* Try to deduce D from N, P, Q, E. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 TEST_ASSERT(mbedtls_rsa_deduce_private_exponent(&P, &Q,
839 &E, &D) == result);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100840
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 if (!corrupt) {
Hanno Becker6b4ce492017-08-23 11:00:21 +0100842 /*
843 * Check that D and Dp agree modulo LCM(P-1, Q-1).
844 */
845
846 /* Replace P,Q by P-1, Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 TEST_ASSERT(mbedtls_mpi_sub_int(&P, &P, 1) == 0);
848 TEST_ASSERT(mbedtls_mpi_sub_int(&Q, &Q, 1) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100849
850 /* Check D == Dp modulo P-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &D, &P) == 0);
852 TEST_ASSERT(mbedtls_mpi_mod_mpi(&Rp, &Dp, &P) == 0);
853 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &Rp) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100854
855 /* Check D == Dp modulo Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &D, &Q) == 0);
857 TEST_ASSERT(mbedtls_mpi_mod_mpi(&Rp, &Dp, &Q) == 0);
858 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &Rp) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100859 }
860
861exit:
862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
864 mbedtls_mpi_free(&D); mbedtls_mpi_free(&Dp);
865 mbedtls_mpi_free(&E);
866 mbedtls_mpi_free(&R); mbedtls_mpi_free(&Rp);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100867}
868/* END_CASE */
869
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200870/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100871void mbedtls_rsa_import(char *input_N,
872 char *input_P,
873 char *input_Q,
874 char *input_D,
875 char *input_E,
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100876 int bitlen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 int successive,
878 int is_priv,
879 int res_check,
880 int res_complete)
Hanno Beckerc77ab892017-08-23 11:01:06 +0100881{
882 mbedtls_mpi N, P, Q, D, E;
883 mbedtls_rsa_context ctx;
884
Hanno Beckere1582a82017-09-29 11:51:05 +0100885 /* Buffers used for encryption-decryption test */
886 unsigned char *buf_orig = NULL;
887 unsigned char *buf_enc = NULL;
888 unsigned char *buf_dec = NULL;
889
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 const int have_N = (strlen(input_N) > 0);
891 const int have_P = (strlen(input_P) > 0);
892 const int have_Q = (strlen(input_Q) > 0);
893 const int have_D = (strlen(input_D) > 0);
894 const int have_E = (strlen(input_E) > 0);
Hanno Becker4d6e8342017-09-29 11:50:18 +0100895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 mbedtls_rsa_init(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 mbedtls_mpi_init(&N);
899 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
900 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 if (have_N) {
903 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100904 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100905
906 if (have_P) {
907 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
908 }
909
910 if (have_Q) {
911 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
912 }
913
914 if (have_D) {
915 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
916 }
917
918 if (have_E) {
919 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
920 }
921
922 if (!successive) {
923 TEST_ASSERT(mbedtls_rsa_import(&ctx,
924 have_N ? &N : NULL,
925 have_P ? &P : NULL,
926 have_Q ? &Q : NULL,
927 have_D ? &D : NULL,
928 have_E ? &E : NULL) == 0);
929 } else {
Hanno Beckerc77ab892017-08-23 11:01:06 +0100930 /* Import N, P, Q, D, E separately.
931 * This should make no functional difference. */
932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 TEST_ASSERT(mbedtls_rsa_import(&ctx,
934 have_N ? &N : NULL,
935 NULL, NULL, NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 TEST_ASSERT(mbedtls_rsa_import(&ctx,
938 NULL,
939 have_P ? &P : NULL,
940 NULL, NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 TEST_ASSERT(mbedtls_rsa_import(&ctx,
943 NULL, NULL,
944 have_Q ? &Q : NULL,
945 NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 TEST_ASSERT(mbedtls_rsa_import(&ctx,
948 NULL, NULL, NULL,
949 have_D ? &D : NULL,
950 NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 TEST_ASSERT(mbedtls_rsa_import(&ctx,
953 NULL, NULL, NULL, NULL,
954 have_E ? &E : NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100955 }
956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == res_complete);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100958
Hanno Beckere1582a82017-09-29 11:51:05 +0100959 /* On expected success, perform some public and private
960 * key operations to check if the key is working properly. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 if (res_complete == 0) {
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100962 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), bitlen);
963 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (bitlen + 7) / 8);
964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 if (is_priv) {
966 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == res_check);
967 } else {
968 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == res_check);
969 }
Hanno Becker04877a42017-10-11 10:01:33 +0100970
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 if (res_check != 0) {
Hanno Becker04877a42017-10-11 10:01:33 +0100972 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 }
Hanno Beckere1582a82017-09-29 11:51:05 +0100974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 buf_orig = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
976 buf_enc = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
977 buf_dec = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
978 if (buf_orig == NULL || buf_enc == NULL || buf_dec == NULL) {
Hanno Beckere1582a82017-09-29 11:51:05 +0100979 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 }
Hanno Beckere1582a82017-09-29 11:51:05 +0100981
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200982 /* This test uses an insecure RNG, suitable only for testing.
983 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 TEST_ASSERT(mbedtls_test_rnd_std_rand(NULL,
985 buf_orig, mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100986
987 /* Make sure the number we're generating is smaller than the modulus */
988 buf_orig[0] = 0x00;
989
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 TEST_ASSERT(mbedtls_rsa_public(&ctx, buf_orig, buf_enc) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100991
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 if (is_priv) {
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200993 /* This test uses an insecure RNG, suitable only for testing.
994 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_std_rand,
996 NULL, buf_enc,
997 buf_dec) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 TEST_ASSERT(memcmp(buf_orig, buf_dec,
1000 mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001001 }
1002 }
1003
Hanno Beckerc77ab892017-08-23 11:01:06 +01001004exit:
1005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 mbedtls_free(buf_orig);
1007 mbedtls_free(buf_enc);
1008 mbedtls_free(buf_dec);
Hanno Beckere1582a82017-09-29 11:51:05 +01001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 mbedtls_rsa_free(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 mbedtls_mpi_free(&N);
1013 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1014 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001015}
1016/* END_CASE */
1017
Hanno Becker417f2d62017-08-23 11:44:51 +01001018/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001019void mbedtls_rsa_export(char *input_N,
1020 char *input_P,
1021 char *input_Q,
1022 char *input_D,
1023 char *input_E,
1024 int is_priv,
1025 int successive)
Hanno Becker417f2d62017-08-23 11:44:51 +01001026{
1027 /* Original MPI's with which we set up the RSA context */
1028 mbedtls_mpi N, P, Q, D, E;
1029
1030 /* Exported MPI's */
1031 mbedtls_mpi Ne, Pe, Qe, De, Ee;
1032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 const int have_N = (strlen(input_N) > 0);
1034 const int have_P = (strlen(input_P) > 0);
1035 const int have_Q = (strlen(input_Q) > 0);
1036 const int have_D = (strlen(input_D) > 0);
1037 const int have_E = (strlen(input_E) > 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001038
Hanno Becker417f2d62017-08-23 11:44:51 +01001039 mbedtls_rsa_context ctx;
1040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 mbedtls_rsa_init(&ctx);
Hanno Becker417f2d62017-08-23 11:44:51 +01001042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 mbedtls_mpi_init(&N);
1044 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
1045 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Becker417f2d62017-08-23 11:44:51 +01001046
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 mbedtls_mpi_init(&Ne);
1048 mbedtls_mpi_init(&Pe); mbedtls_mpi_init(&Qe);
1049 mbedtls_mpi_init(&De); mbedtls_mpi_init(&Ee);
Hanno Becker417f2d62017-08-23 11:44:51 +01001050
1051 /* Setup RSA context */
1052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if (have_N) {
1054 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1055 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 if (have_P) {
1058 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
1059 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001060
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 if (have_Q) {
1062 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
1063 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001064
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 if (have_D) {
1066 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
1067 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001068
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 if (have_E) {
1070 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1071 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001072
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 TEST_ASSERT(mbedtls_rsa_import(&ctx,
1074 strlen(input_N) ? &N : NULL,
1075 strlen(input_P) ? &P : NULL,
1076 strlen(input_Q) ? &Q : NULL,
1077 strlen(input_D) ? &D : NULL,
1078 strlen(input_E) ? &E : NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001081
1082 /*
1083 * Export parameters and compare to original ones.
1084 */
1085
1086 /* N and E must always be present. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (!successive) {
1088 TEST_ASSERT(mbedtls_rsa_export(&ctx, &Ne, NULL, NULL, NULL, &Ee) == 0);
1089 } else {
1090 TEST_ASSERT(mbedtls_rsa_export(&ctx, &Ne, NULL, NULL, NULL, NULL) == 0);
1091 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, NULL, NULL, &Ee) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001092 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &Ne) == 0);
1094 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&E, &Ee) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001095
1096 /* If we were providing enough information to setup a complete private context,
1097 * we expect to be able to export all core parameters. */
1098
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 if (is_priv) {
1100 if (!successive) {
1101 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, &Pe, &Qe,
1102 &De, NULL) == 0);
1103 } else {
1104 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, &Pe, NULL,
1105 NULL, NULL) == 0);
1106 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, &Qe,
1107 NULL, NULL) == 0);
1108 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, NULL,
1109 &De, NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001110 }
1111
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 if (have_P) {
1113 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P, &Pe) == 0);
1114 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 if (have_Q) {
1117 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &Qe) == 0);
1118 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 if (have_D) {
1121 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&D, &De) == 0);
1122 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001123
1124 /* While at it, perform a sanity check */
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 TEST_ASSERT(mbedtls_rsa_validate_params(&Ne, &Pe, &Qe, &De, &Ee,
1126 NULL, NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001127 }
1128
1129exit:
1130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 mbedtls_rsa_free(&ctx);
Hanno Becker417f2d62017-08-23 11:44:51 +01001132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 mbedtls_mpi_free(&N);
1134 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1135 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Becker417f2d62017-08-23 11:44:51 +01001136
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 mbedtls_mpi_free(&Ne);
1138 mbedtls_mpi_free(&Pe); mbedtls_mpi_free(&Qe);
1139 mbedtls_mpi_free(&De); mbedtls_mpi_free(&Ee);
Hanno Becker417f2d62017-08-23 11:44:51 +01001140}
1141/* END_CASE */
1142
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001143/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001144void mbedtls_rsa_validate_params(char *input_N,
1145 char *input_P,
1146 char *input_Q,
1147 char *input_D,
1148 char *input_E,
1149 int prng, int result)
Hanno Beckerce002632017-08-23 13:22:36 +01001150{
1151 /* Original MPI's with which we set up the RSA context */
1152 mbedtls_mpi N, P, Q, D, E;
1153
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 const int have_N = (strlen(input_N) > 0);
1155 const int have_P = (strlen(input_P) > 0);
1156 const int have_Q = (strlen(input_Q) > 0);
1157 const int have_D = (strlen(input_D) > 0);
1158 const int have_E = (strlen(input_E) > 0);
Hanno Beckerce002632017-08-23 13:22:36 +01001159
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 mbedtls_mpi_init(&N);
1161 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
1162 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckerce002632017-08-23 13:22:36 +01001163
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 if (have_N) {
1165 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1166 }
Hanno Beckerce002632017-08-23 13:22:36 +01001167
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 if (have_P) {
1169 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
1170 }
Hanno Beckerce002632017-08-23 13:22:36 +01001171
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 if (have_Q) {
1173 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
1174 }
Hanno Beckerce002632017-08-23 13:22:36 +01001175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 if (have_D) {
1177 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
1178 }
Hanno Beckerce002632017-08-23 13:22:36 +01001179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 if (have_E) {
1181 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1182 }
Hanno Beckerce002632017-08-23 13:22:36 +01001183
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001184 /* This test uses an insecure RNG, suitable only for testing.
1185 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 TEST_ASSERT(mbedtls_rsa_validate_params(have_N ? &N : NULL,
1187 have_P ? &P : NULL,
1188 have_Q ? &Q : NULL,
1189 have_D ? &D : NULL,
1190 have_E ? &E : NULL,
1191 prng ? mbedtls_test_rnd_std_rand : NULL,
1192 prng ? NULL : NULL) == result);
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001193
Hanno Beckerce002632017-08-23 13:22:36 +01001194exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001195 mbedtls_mpi_free(&N);
1196 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1197 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckerce002632017-08-23 13:22:36 +01001198}
1199/* END_CASE */
1200
Manuel Pégourié-Gonnard1d1174a2022-07-16 08:41:34 +02001201/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001202void mbedtls_rsa_export_raw(data_t *input_N, data_t *input_P,
1203 data_t *input_Q, data_t *input_D,
1204 data_t *input_E, int is_priv,
1205 int successive)
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001206{
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001207 /* Exported buffers */
Ron Eldorfdc15bd2018-11-22 15:47:51 +02001208 unsigned char bufNe[256];
1209 unsigned char bufPe[128];
1210 unsigned char bufQe[128];
1211 unsigned char bufDe[256];
1212 unsigned char bufEe[1];
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001213
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001214 mbedtls_rsa_context ctx;
1215
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 mbedtls_rsa_init(&ctx);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001217
1218 /* Setup RSA context */
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1220 input_N->len ? input_N->x : NULL, input_N->len,
1221 input_P->len ? input_P->x : NULL, input_P->len,
1222 input_Q->len ? input_Q->x : NULL, input_Q->len,
1223 input_D->len ? input_D->x : NULL, input_D->len,
1224 input_E->len ? input_E->x : NULL, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001225
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001227
1228 /*
1229 * Export parameters and compare to original ones.
1230 */
1231
1232 /* N and E must always be present. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 if (!successive) {
1234 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, bufNe, input_N->len,
1235 NULL, 0, NULL, 0, NULL, 0,
1236 bufEe, input_E->len) == 0);
1237 } else {
1238 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, bufNe, input_N->len,
1239 NULL, 0, NULL, 0, NULL, 0,
1240 NULL, 0) == 0);
1241 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1242 NULL, 0, NULL, 0, NULL, 0,
1243 bufEe, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001244 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 TEST_ASSERT(memcmp(input_N->x, bufNe, input_N->len) == 0);
1246 TEST_ASSERT(memcmp(input_E->x, bufEe, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001247
1248 /* If we were providing enough information to setup a complete private context,
1249 * we expect to be able to export all core parameters. */
1250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 if (is_priv) {
1252 if (!successive) {
1253 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1254 bufPe, input_P->len ? input_P->len : sizeof(bufPe),
1255 bufQe, input_Q->len ? input_Q->len : sizeof(bufQe),
1256 bufDe, input_D->len ? input_D->len : sizeof(bufDe),
1257 NULL, 0) == 0);
1258 } else {
1259 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1260 bufPe, input_P->len ? input_P->len : sizeof(bufPe),
1261 NULL, 0, NULL, 0,
1262 NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001263
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0, NULL, 0,
1265 bufQe, input_Q->len ? input_Q->len : sizeof(bufQe),
1266 NULL, 0, NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001267
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0, NULL, 0, NULL, 0,
1269 bufDe, input_D->len ? input_D->len : sizeof(bufDe),
1270 NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001271 }
1272
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 if (input_P->len) {
1274 TEST_ASSERT(memcmp(input_P->x, bufPe, input_P->len) == 0);
1275 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001276
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 if (input_Q->len) {
1278 TEST_ASSERT(memcmp(input_Q->x, bufQe, input_Q->len) == 0);
1279 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001280
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 if (input_D->len) {
1282 TEST_ASSERT(memcmp(input_D->x, bufDe, input_D->len) == 0);
1283 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001284
1285 }
1286
1287exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 mbedtls_rsa_free(&ctx);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001289}
1290/* END_CASE */
1291
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001292/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001293void mbedtls_rsa_import_raw(data_t *input_N,
1294 data_t *input_P, data_t *input_Q,
1295 data_t *input_D, data_t *input_E,
1296 int successive,
1297 int is_priv,
1298 int res_check,
1299 int res_complete)
Hanno Beckerc77ab892017-08-23 11:01:06 +01001300{
Hanno Beckere1582a82017-09-29 11:51:05 +01001301 /* Buffers used for encryption-decryption test */
1302 unsigned char *buf_orig = NULL;
1303 unsigned char *buf_enc = NULL;
1304 unsigned char *buf_dec = NULL;
1305
Hanno Beckerc77ab892017-08-23 11:01:06 +01001306 mbedtls_rsa_context ctx;
Hanno Becker3f3ae852017-10-02 10:08:39 +01001307
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 mbedtls_rsa_init(&ctx);
Hanno Becker3f3ae852017-10-02 10:08:39 +01001309
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 if (!successive) {
1311 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1312 (input_N->len > 0) ? input_N->x : NULL, input_N->len,
1313 (input_P->len > 0) ? input_P->x : NULL, input_P->len,
1314 (input_Q->len > 0) ? input_Q->x : NULL, input_Q->len,
1315 (input_D->len > 0) ? input_D->x : NULL, input_D->len,
1316 (input_E->len > 0) ? input_E->x : NULL,
1317 input_E->len) == 0);
1318 } else {
Hanno Beckerc77ab892017-08-23 11:01:06 +01001319 /* Import N, P, Q, D, E separately.
1320 * This should make no functional difference. */
1321
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1323 (input_N->len > 0) ? input_N->x : NULL, input_N->len,
1324 NULL, 0, NULL, 0, NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001325
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1327 NULL, 0,
1328 (input_P->len > 0) ? input_P->x : NULL, input_P->len,
1329 NULL, 0, NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001330
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1332 NULL, 0, NULL, 0,
1333 (input_Q->len > 0) ? input_Q->x : NULL, input_Q->len,
1334 NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001335
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1337 NULL, 0, NULL, 0, NULL, 0,
1338 (input_D->len > 0) ? input_D->x : NULL, input_D->len,
1339 NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001340
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1342 NULL, 0, NULL, 0, NULL, 0, NULL, 0,
1343 (input_E->len > 0) ? input_E->x : NULL,
1344 input_E->len) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001345 }
1346
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == res_complete);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001348
Hanno Beckere1582a82017-09-29 11:51:05 +01001349 /* On expected success, perform some public and private
1350 * key operations to check if the key is working properly. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001351 if (res_complete == 0) {
1352 if (is_priv) {
1353 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == res_check);
1354 } else {
1355 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == res_check);
1356 }
Hanno Becker04877a42017-10-11 10:01:33 +01001357
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 if (res_check != 0) {
Hanno Becker04877a42017-10-11 10:01:33 +01001359 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 }
Hanno Beckere1582a82017-09-29 11:51:05 +01001361
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 buf_orig = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1363 buf_enc = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1364 buf_dec = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1365 if (buf_orig == NULL || buf_enc == NULL || buf_dec == NULL) {
Hanno Beckere1582a82017-09-29 11:51:05 +01001366 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 }
Hanno Beckere1582a82017-09-29 11:51:05 +01001368
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001369 /* This test uses an insecure RNG, suitable only for testing.
1370 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 TEST_ASSERT(mbedtls_test_rnd_std_rand(NULL,
1372 buf_orig, mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001373
1374 /* Make sure the number we're generating is smaller than the modulus */
1375 buf_orig[0] = 0x00;
1376
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 TEST_ASSERT(mbedtls_rsa_public(&ctx, buf_orig, buf_enc) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001378
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 if (is_priv) {
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001380 /* This test uses an insecure RNG, suitable only for testing.
1381 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_std_rand,
1383 NULL, buf_enc,
1384 buf_dec) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001385
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 TEST_ASSERT(memcmp(buf_orig, buf_dec,
1387 mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001388 }
1389 }
1390
Hanno Beckerc77ab892017-08-23 11:01:06 +01001391exit:
1392
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 mbedtls_free(buf_orig);
1394 mbedtls_free(buf_enc);
1395 mbedtls_free(buf_dec);
Hanno Becker3f3ae852017-10-02 10:08:39 +01001396
Gilles Peskine449bd832023-01-11 14:50:10 +01001397 mbedtls_rsa_free(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001398}
1399/* END_CASE */
1400
Valerio Setti8e6093d2024-01-23 15:19:07 +01001401/* BEGIN_CASE */
Valerio Setti6d597f12024-01-24 13:44:41 +01001402void rsa_parse_pkcs1_key(int is_public, data_t *input, int exp_ret_val)
Valerio Setti6def24c2024-01-24 12:33:04 +01001403{
1404 mbedtls_rsa_context rsa_ctx;
Valerio Setti6d597f12024-01-24 13:44:41 +01001405
Valerio Setti6def24c2024-01-24 12:33:04 +01001406 mbedtls_rsa_init(&rsa_ctx);
1407
Valerio Setti6d597f12024-01-24 13:44:41 +01001408 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001409 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), exp_ret_val);
Valerio Setti6d597f12024-01-24 13:44:41 +01001410 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001411 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), exp_ret_val);
Valerio Setti6d597f12024-01-24 13:44:41 +01001412 }
Valerio Setti6def24c2024-01-24 12:33:04 +01001413
1414exit:
1415 mbedtls_rsa_free(&rsa_ctx);
1416}
1417/* END_CASE */
1418
1419/* BEGIN_CASE */
Valerio Setti1533c3f2024-01-24 11:24:20 +01001420void rsa_parse_write_pkcs1_key(int is_public, data_t *input)
Valerio Setti8e6093d2024-01-23 15:19:07 +01001421{
1422 mbedtls_rsa_context rsa_ctx;
Valerio Setti8e6093d2024-01-23 15:19:07 +01001423 unsigned char *output_buf = NULL;
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001424 unsigned char *output_end, *output_p;
1425 size_t output_len;
Valerio Setti8e6093d2024-01-23 15:19:07 +01001426
1427 mbedtls_rsa_init(&rsa_ctx);
1428
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001429 TEST_CALLOC(output_buf, input->len);
1430 output_end = output_buf + input->len;
1431 output_p = output_end;
1432
Valerio Setti1533c3f2024-01-24 11:24:20 +01001433 /* Parse the key and write it back to output_buf. */
Valerio Setti8e6093d2024-01-23 15:19:07 +01001434 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001435 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001436 TEST_EQUAL(mbedtls_rsa_write_pubkey(&rsa_ctx, output_buf, &output_p), input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001437 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001438 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001439 TEST_EQUAL(mbedtls_rsa_write_key(&rsa_ctx, output_buf, &output_p), input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001440 }
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001441 output_len = output_end - output_p;
Valerio Setti1533c3f2024-01-24 11:24:20 +01001442
1443 /* Check that the written key matches with the one provided in input. */
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001444 TEST_MEMORY_COMPARE(output_p, output_len, input->x, input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001445
1446exit:
1447 mbedtls_free(output_buf);
1448 mbedtls_rsa_free(&rsa_ctx);
1449}
1450/* END_CASE */
1451
Valerio Settia8886452024-01-30 17:35:49 +01001452/* BEGIN_CASE */
1453void rsa_key_write_incremental(int is_public, data_t *input)
1454{
1455 mbedtls_rsa_context rsa_ctx;
Valerio Settic701cb22024-02-02 11:09:37 +01001456 unsigned char *buf = NULL, *end, *p;
1457 size_t i, written_data;
Valerio Settia8886452024-01-30 17:35:49 +01001458
1459 mbedtls_rsa_init(&rsa_ctx);
1460
1461 /* This is supposed to succeed as the real target of this test are the
1462 * write attempt below. */
1463 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001464 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
Valerio Settia8886452024-01-30 17:35:49 +01001465 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001466 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
Valerio Settia8886452024-01-30 17:35:49 +01001467 }
1468
Valerio Settic701cb22024-02-02 11:09:37 +01001469 /* Test with an output buffer smaller than required. */
Valerio Settia8886452024-01-30 17:35:49 +01001470 for (i = 1; i < input->len; i++) {
1471 TEST_CALLOC(buf, i);
1472 end = buf + i;
Valerio Settic701cb22024-02-02 11:09:37 +01001473 p = end;
Valerio Settia8886452024-01-30 17:35:49 +01001474 /* We don't care much about the return value as long as it fails. */
1475 if (is_public) {
Valerio Settic701cb22024-02-02 11:09:37 +01001476 TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) != 0);
Valerio Settia8886452024-01-30 17:35:49 +01001477 } else {
Valerio Settic701cb22024-02-02 11:09:37 +01001478 TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) != 0);
Valerio Settia8886452024-01-30 17:35:49 +01001479 }
1480 mbedtls_free(buf);
1481 buf = NULL;
1482 }
1483
Valerio Settic701cb22024-02-02 11:09:37 +01001484 /* Test with an output buffer equal or larger than what it is strictly required. */
1485 for (i = input->len; i < (2 * input->len); i++) {
1486 TEST_CALLOC(buf, i);
1487 end = buf + i;
1488 p = end;
1489 /* This time all write functions must succeed. */
1490 if (is_public) {
1491 TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) > 0);
1492 } else {
1493 TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) > 0);
1494 }
1495 written_data = (end - p);
1496 TEST_MEMORY_COMPARE(p, written_data, input->x, input->len);
1497 mbedtls_free(buf);
1498 buf = NULL;
Valerio Settia8886452024-01-30 17:35:49 +01001499 }
1500
1501exit:
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001502 mbedtls_free(buf);
Valerio Settia8886452024-01-30 17:35:49 +01001503 mbedtls_rsa_free(&rsa_ctx);
1504}
1505/* END_CASE */
1506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001507/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001508void rsa_selftest()
Paul Bakker42a29bf2009-07-07 20:18:41 +00001509{
Manuel Pégourié-Gonnardfb8d90a2023-03-16 10:47:59 +01001510 MD_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 TEST_ASSERT(mbedtls_rsa_self_test(1) == 0);
Manuel Pégourié-Gonnardfb8d90a2023-03-16 10:47:59 +01001512
1513exit:
1514 MD_PSA_DONE();
Paul Bakker42a29bf2009-07-07 20:18:41 +00001515}
Paul Bakker33b43f12013-08-20 11:48:36 +02001516/* END_CASE */