blob: 98ea9efb1c365f86bddd0dab5e37f6a29c628d4b [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"
Janos Follath96cfd7a2024-08-22 18:30:06 +01006#include "test/bignum_codepath_check.h"
Paul Bakker33b43f12013-08-20 11:48:36 +02007/* END_HEADER */
Paul Bakker42a29bf2009-07-07 20:18:41 +00008
Paul Bakker33b43f12013-08-20 11:48:36 +02009/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020010 * depends_on:MBEDTLS_RSA_C:MBEDTLS_BIGNUM_C:MBEDTLS_GENPRIME
Paul Bakker33b43f12013-08-20 11:48:36 +020011 * END_DEPENDENCIES
12 */
Paul Bakker5690efc2011-05-26 13:16:06 +000013
Paul Bakker33b43f12013-08-20 11:48:36 +020014/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010015void rsa_invalid_param()
Ronald Cronea7631b2021-06-03 18:51:59 +020016{
17 mbedtls_rsa_context ctx;
18 const int invalid_padding = 42;
19 const int invalid_hash_id = 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010020 unsigned char buf[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
21 size_t buf_len = sizeof(buf);
Ronald Cronea7631b2021-06-03 18:51:59 +020022
Gilles Peskine449bd832023-01-11 14:50:10 +010023 mbedtls_rsa_init(&ctx);
Ronald Cronea7631b2021-06-03 18:51:59 +020024
Gilles Peskine449bd832023-01-11 14:50:10 +010025 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
26 invalid_padding,
27 MBEDTLS_MD_NONE),
28 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cronea7631b2021-06-03 18:51:59 +020029
Gilles Peskine449bd832023-01-11 14:50:10 +010030 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
31 MBEDTLS_RSA_PKCS_V21,
32 invalid_hash_id),
33 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cronea7631b2021-06-03 18:51:59 +020034
Gilles Peskine449bd832023-01-11 14:50:10 +010035 TEST_EQUAL(mbedtls_rsa_pkcs1_sign(&ctx, NULL,
36 NULL, MBEDTLS_MD_NONE,
37 buf_len,
38 NULL, buf),
39 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010040
Gilles Peskine449bd832023-01-11 14:50:10 +010041 TEST_EQUAL(mbedtls_rsa_pkcs1_sign(&ctx, NULL,
42 NULL, MBEDTLS_MD_SHA256,
43 0,
44 NULL, buf),
45 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010046
Gilles Peskine449bd832023-01-11 14:50:10 +010047 TEST_EQUAL(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_NONE,
48 buf_len,
49 NULL, buf),
50 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010051
Gilles Peskine449bd832023-01-11 14:50:10 +010052 TEST_EQUAL(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_SHA256,
53 0,
54 NULL, buf),
55 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010056
Ronald Cron3a0375f2021-06-08 10:22:28 +020057#if !defined(MBEDTLS_PKCS1_V15)
Gilles Peskine449bd832023-01-11 14:50:10 +010058 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
59 MBEDTLS_RSA_PKCS_V15,
60 MBEDTLS_MD_NONE),
61 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cron3a0375f2021-06-08 10:22:28 +020062#endif
63
Tuvshinzaya Erdenekhuufe7524d2022-09-01 16:07:18 +010064#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine449bd832023-01-11 14:50:10 +010065 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_sign(&ctx, NULL,
66 NULL, MBEDTLS_MD_NONE,
67 buf_len,
68 NULL, buf),
69 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010070
Gilles Peskine449bd832023-01-11 14:50:10 +010071 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_sign(&ctx, NULL,
72 NULL, MBEDTLS_MD_SHA256,
73 0,
74 NULL, buf),
75 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010076
Gilles Peskine449bd832023-01-11 14:50:10 +010077 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_verify(&ctx, MBEDTLS_MD_NONE,
78 buf_len,
79 NULL, buf),
80 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010081
Gilles Peskine449bd832023-01-11 14:50:10 +010082 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_verify(&ctx, MBEDTLS_MD_SHA256,
83 0,
84 NULL, buf),
85 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010086
87
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010088#endif
89
Ronald Cron3a0375f2021-06-08 10:22:28 +020090#if !defined(MBEDTLS_PKCS1_V21)
Gilles Peskine449bd832023-01-11 14:50:10 +010091 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
92 MBEDTLS_RSA_PKCS_V21,
93 MBEDTLS_MD_NONE),
94 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cron3a0375f2021-06-08 10:22:28 +020095#endif
96
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010097#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine449bd832023-01-11 14:50:10 +010098 TEST_EQUAL(mbedtls_rsa_rsassa_pss_sign_ext(&ctx, NULL, NULL,
99 MBEDTLS_MD_NONE, buf_len,
100 NULL, buf_len,
101 buf),
102 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100103
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 TEST_EQUAL(mbedtls_rsa_rsassa_pss_sign_ext(&ctx, NULL, NULL,
105 MBEDTLS_MD_SHA256, 0,
106 NULL, buf_len,
107 buf),
108 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +0100109
Gilles Peskine449bd832023-01-11 14:50:10 +0100110 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify_ext(&ctx, MBEDTLS_MD_NONE,
111 buf_len, NULL,
112 MBEDTLS_MD_NONE,
113 buf_len, buf),
114 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100115
Gilles Peskine449bd832023-01-11 14:50:10 +0100116 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify_ext(&ctx, MBEDTLS_MD_SHA256,
117 0, NULL,
118 MBEDTLS_MD_NONE,
119 buf_len, buf),
120 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +0100121
Gilles Peskine449bd832023-01-11 14:50:10 +0100122 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify(&ctx, MBEDTLS_MD_NONE,
123 buf_len,
124 NULL, buf),
125 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify(&ctx, MBEDTLS_MD_SHA256,
128 0,
129 NULL, buf),
130 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100131#endif
132
Ronald Cronea7631b2021-06-03 18:51:59 +0200133exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 mbedtls_rsa_free(&ctx);
Ronald Cronea7631b2021-06-03 18:51:59 +0200135}
136/* END_CASE */
137
138/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100139void rsa_init_free(int reinit)
Gilles Peskine914afe12021-02-01 17:55:24 +0100140{
141 mbedtls_rsa_context ctx;
142
143 /* Double free is not explicitly documented to work, but we rely on it
144 * even inside the library so that you can call mbedtls_rsa_free()
145 * unconditionally on an error path without checking whether it has
146 * already been called in the success path. */
147
Gilles Peskine449bd832023-01-11 14:50:10 +0100148 mbedtls_rsa_init(&ctx);
149 mbedtls_rsa_free(&ctx);
Gilles Peskine914afe12021-02-01 17:55:24 +0100150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 if (reinit) {
152 mbedtls_rsa_init(&ctx);
153 }
154 mbedtls_rsa_free(&ctx);
Gilles Peskine914afe12021-02-01 17:55:24 +0100155
156 /* This test case always succeeds, functionally speaking. A plausible
157 * bug might trigger an invalid pointer dereference or a memory leak. */
158 goto exit;
159}
160/* END_CASE */
161
Manuel Pégourié-Gonnard236c4e22022-07-16 08:35:06 +0200162/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100163void mbedtls_rsa_pkcs1_sign(data_t *message_str, int padding_mode,
164 int digest, int mod, char *input_P,
165 char *input_Q, char *input_N, char *input_E,
166 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000167{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200168 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100170 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200171 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
174 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
175 mbedtls_rsa_init(&ctx);
176 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
177 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 memset(output, 0x00, sizeof(output));
180 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000181
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
183 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
184 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
185 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100188 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
189 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100190 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
191 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 TEST_ASSERT(mbedtls_rsa_pkcs1_sign(
194 &ctx, &mbedtls_test_rnd_pseudo_rand, &rnd_info,
195 digest, message_str->len, message_str->x,
196 output) == result);
197 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
200 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000201 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000202
Paul Bakkerbd51b262014-07-10 15:26:12 +0200203exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
205 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
206 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000207}
Paul Bakker33b43f12013-08-20 11:48:36 +0200208/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000209
Manuel Pégourié-Gonnard236c4e22022-07-16 08:35:06 +0200210/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100211void mbedtls_rsa_pkcs1_verify(data_t *message_str, int padding_mode,
212 int digest, int mod,
213 char *input_N, char *input_E,
214 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000215{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100217 mbedtls_mpi N, E;
218
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
220 mbedtls_rsa_init(&ctx);
221 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
222 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
225 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
226 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100227 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
228 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 TEST_ASSERT(mbedtls_rsa_pkcs1_verify(&ctx, digest, message_str->len, message_str->x,
232 result_str->x) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100233
Paul Bakkerbd51b262014-07-10 15:26:12 +0200234exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100235 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
236 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000237}
Paul Bakker33b43f12013-08-20 11:48:36 +0200238/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000239
Paul Bakker821fb082009-07-12 13:26:42 +0000240
Paul Bakker33b43f12013-08-20 11:48:36 +0200241/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100242void rsa_pkcs1_sign_raw(data_t *hash_result,
243 int padding_mode, int mod,
244 char *input_P, char *input_Q,
245 char *input_N, char *input_E,
246 data_t *result_str)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000247{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200248 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200249 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100250 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200251 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 mbedtls_rsa_init(&ctx);
254 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
255 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
Paul Bakker821fb082009-07-12 13:26:42 +0000256
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
258 MBEDTLS_MD_NONE) == 0);
Paul Elliotte57dd2d2021-06-25 11:13:24 +0100259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 memset(output, 0x00, sizeof(output));
261 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
264 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
265 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
266 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000267
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100269 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
270 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
272 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000273
Paul Bakker821fb082009-07-12 13:26:42 +0000274
Gilles Peskine449bd832023-01-11 14:50:10 +0100275 TEST_ASSERT(mbedtls_rsa_pkcs1_sign(&ctx, &mbedtls_test_rnd_pseudo_rand,
276 &rnd_info, MBEDTLS_MD_NONE,
277 hash_result->len,
278 hash_result->x, output) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000279
Paul Bakker821fb082009-07-12 13:26:42 +0000280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
282 ctx.len, result_str->len) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000283
Paul Bakkerbd51b262014-07-10 15:26:12 +0200284exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
286 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000289}
Paul Bakker33b43f12013-08-20 11:48:36 +0200290/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000291
Paul Bakker33b43f12013-08-20 11:48:36 +0200292/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100293void rsa_pkcs1_verify_raw(data_t *hash_result,
294 int padding_mode, int mod,
295 char *input_N, char *input_E,
296 data_t *result_str, int correct)
Paul Bakker821fb082009-07-12 13:26:42 +0000297{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200298 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 mbedtls_rsa_context ctx;
Paul Bakker821fb082009-07-12 13:26:42 +0000300
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100301 mbedtls_mpi N, E;
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100303
Gilles Peskine449bd832023-01-11 14:50:10 +0100304 mbedtls_rsa_init(&ctx);
305 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
306 MBEDTLS_MD_NONE) == 0);
307 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
310 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100313 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
314 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000316
Paul Bakker821fb082009-07-12 13:26:42 +0000317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 TEST_ASSERT(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_NONE, hash_result->len, hash_result->x,
319 result_str->x) == correct);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100320
Paul Bakkerbd51b262014-07-10 15:26:12 +0200321exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
323 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000324}
Paul Bakker33b43f12013-08-20 11:48:36 +0200325/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000326
Paul Bakker33b43f12013-08-20 11:48:36 +0200327/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100328void mbedtls_rsa_pkcs1_encrypt(data_t *message_str, int padding_mode,
329 int mod, char *input_N, char *input_E,
330 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000331{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200332 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_rsa_context ctx;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200334 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker997bbd12011-03-13 15:45:42 +0000335
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100336 mbedtls_mpi N, E;
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker821fb082009-07-12 13:26:42 +0000340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 mbedtls_rsa_init(&ctx);
342 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
343 MBEDTLS_MD_NONE) == 0);
344 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000345
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
347 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100350 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
351 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000353
Paul Bakker42a29bf2009-07-07 20:18:41 +0000354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 TEST_ASSERT(mbedtls_rsa_pkcs1_encrypt(&ctx,
356 &mbedtls_test_rnd_pseudo_rand,
357 &rnd_info, message_str->len,
358 message_str->x,
359 output) == result);
360 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000361
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
363 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000364 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100365
Paul Bakkerbd51b262014-07-10 15:26:12 +0200366exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100367 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
368 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000369}
Paul Bakker33b43f12013-08-20 11:48:36 +0200370/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000371
Paul Bakker33b43f12013-08-20 11:48:36 +0200372/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100373void rsa_pkcs1_encrypt_bad_rng(data_t *message_str, int padding_mode,
374 int mod, char *input_N, char *input_E,
375 data_t *result_str, int result)
Paul Bakkera6656852010-07-18 19:47:14 +0000376{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200377 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 mbedtls_rsa_context ctx;
Paul Bakkera6656852010-07-18 19:47:14 +0000379
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100380 mbedtls_mpi N, E;
381
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
383 mbedtls_rsa_init(&ctx);
384 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
385 MBEDTLS_MD_NONE) == 0);
386 memset(output, 0x00, sizeof(output));
Paul Bakkera6656852010-07-18 19:47:14 +0000387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
389 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100392 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
393 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000395
Paul Bakkera6656852010-07-18 19:47:14 +0000396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 TEST_ASSERT(mbedtls_rsa_pkcs1_encrypt(&ctx, &mbedtls_test_rnd_zero_rand,
398 NULL, message_str->len,
399 message_str->x,
400 output) == result);
401 if (result == 0) {
Paul Bakkera6656852010-07-18 19:47:14 +0000402
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
404 ctx.len, result_str->len) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000405 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100406
Paul Bakkerbd51b262014-07-10 15:26:12 +0200407exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100408 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
409 mbedtls_rsa_free(&ctx);
Paul Bakkera6656852010-07-18 19:47:14 +0000410}
Paul Bakker33b43f12013-08-20 11:48:36 +0200411/* END_CASE */
Paul Bakkera6656852010-07-18 19:47:14 +0000412
Paul Bakker33b43f12013-08-20 11:48:36 +0200413/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100414void mbedtls_rsa_pkcs1_decrypt(data_t *message_str, int padding_mode,
415 int mod, char *input_P,
416 char *input_Q, char *input_N,
417 char *input_E, int max_output,
418 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000419{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200420 unsigned char output[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_rsa_context ctx;
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000422 size_t output_len;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200423 mbedtls_test_rnd_pseudo_info rnd_info;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100424 mbedtls_mpi N, P, Q, E;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
427 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 mbedtls_rsa_init(&ctx);
430 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
431 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 memset(output, 0x00, sizeof(output));
434 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000435
Paul Bakker42a29bf2009-07-07 20:18:41 +0000436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
438 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
439 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
440 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100443 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
444 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
446 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000447
Paul Bakker69998dd2009-07-11 19:15:20 +0000448 output_len = 0;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000449
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 TEST_ASSERT(mbedtls_rsa_pkcs1_decrypt(&ctx, mbedtls_test_rnd_pseudo_rand,
451 &rnd_info,
452 &output_len, message_str->x, output,
453 max_output) == result);
454 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
457 output_len,
458 result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000459 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000460
Paul Bakkerbd51b262014-07-10 15:26:12 +0200461exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
463 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
464 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000465}
Paul Bakker33b43f12013-08-20 11:48:36 +0200466/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000467
Paul Bakker33b43f12013-08-20 11:48:36 +0200468/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100469void mbedtls_rsa_public(data_t *message_str, int mod,
470 char *input_N, char *input_E,
471 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000472{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200473 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
Paul Bakker821fb082009-07-12 13:26:42 +0000475
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100476 mbedtls_mpi N, E;
477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
479 mbedtls_rsa_init(&ctx);
480 mbedtls_rsa_init(&ctx2);
481 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000482
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
484 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine058d0092021-06-09 16:24:35 +0200487
488 /* Check test data consistency */
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100489 TEST_EQUAL(message_str->len, (size_t) ((mod + 7) / 8));
490 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
491 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000493
Janos Follath55be79b2024-08-21 13:24:01 +0100494#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +0100495 mbedtls_codepath_reset();
Janos Follath55be79b2024-08-21 13:24:01 +0100496#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 TEST_ASSERT(mbedtls_rsa_public(&ctx, message_str->x, output) == result);
Janos Follath55be79b2024-08-21 13:24:01 +0100498#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +0100499 ASSERT_RSA_CODEPATH(MBEDTLS_MPI_IS_PUBLIC, result);
Janos Follath55be79b2024-08-21 13:24:01 +0100500#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 if (result == 0) {
Paul Bakker821fb082009-07-12 13:26:42 +0000502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
504 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000505 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100506
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100507 /* And now with the copy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 TEST_ASSERT(mbedtls_rsa_copy(&ctx2, &ctx) == 0);
Paul Bakkerbd51b262014-07-10 15:26:12 +0200509 /* clear the original to be sure */
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 mbedtls_rsa_free(&ctx);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx2) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100513
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 memset(output, 0x00, sizeof(output));
515 TEST_ASSERT(mbedtls_rsa_public(&ctx2, message_str->x, output) == result);
516 if (result == 0) {
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
519 ctx.len, result_str->len) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100520 }
521
Paul Bakkerbd51b262014-07-10 15:26:12 +0200522exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
524 mbedtls_rsa_free(&ctx);
525 mbedtls_rsa_free(&ctx2);
Paul Bakker821fb082009-07-12 13:26:42 +0000526}
Paul Bakker33b43f12013-08-20 11:48:36 +0200527/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000528
Paul Bakker33b43f12013-08-20 11:48:36 +0200529/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100530void mbedtls_rsa_private(data_t *message_str, int mod,
531 char *input_P, char *input_Q,
532 char *input_N, char *input_E,
533 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000534{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200535 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100537 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200538 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200539 int i;
Paul Bakker821fb082009-07-12 13:26:42 +0000540
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
542 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
543 mbedtls_rsa_init(&ctx);
544 mbedtls_rsa_init(&ctx2);
Paul Bakker821fb082009-07-12 13:26:42 +0000545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker821fb082009-07-12 13:26:42 +0000547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
549 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
550 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
551 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine058d0092021-06-09 16:24:35 +0200554
555 /* Check test data consistency */
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100556 TEST_EQUAL(message_str->len, (size_t) ((mod + 7) / 8));
557 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
558 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
560 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000561
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200562 /* repeat three times to test updating of blinding values */
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 for (i = 0; i < 3; i++) {
564 memset(output, 0x00, sizeof(output));
Janos Follath55be79b2024-08-21 13:24:01 +0100565#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +0100566 mbedtls_codepath_reset();
Janos Follath55be79b2024-08-21 13:24:01 +0100567#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_pseudo_rand,
569 &rnd_info, message_str->x,
570 output) == result);
Janos Follath55be79b2024-08-21 13:24:01 +0100571#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +0100572 ASSERT_RSA_CODEPATH(MBEDTLS_MPI_IS_SECRET, result);
Janos Follath55be79b2024-08-21 13:24:01 +0100573#endif
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 if (result == 0) {
Paul Bakker821fb082009-07-12 13:26:42 +0000575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
577 ctx.len,
578 result_str->len) == 0);
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200579 }
Paul Bakker821fb082009-07-12 13:26:42 +0000580 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000581
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100582 /* And now one more time with the copy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 TEST_ASSERT(mbedtls_rsa_copy(&ctx2, &ctx) == 0);
Paul Bakkerbd51b262014-07-10 15:26:12 +0200584 /* clear the original to be sure */
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 mbedtls_rsa_free(&ctx);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100586
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx2) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 memset(output, 0x00, sizeof(output));
590 TEST_ASSERT(mbedtls_rsa_private(&ctx2, mbedtls_test_rnd_pseudo_rand,
591 &rnd_info, message_str->x,
592 output) == result);
593 if (result == 0) {
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
596 ctx2.len,
597 result_str->len) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100598 }
599
Paul Bakkerbd51b262014-07-10 15:26:12 +0200600exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
602 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100603
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 mbedtls_rsa_free(&ctx); mbedtls_rsa_free(&ctx2);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000605}
Paul Bakker33b43f12013-08-20 11:48:36 +0200606/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000607
Paul Bakker33b43f12013-08-20 11:48:36 +0200608/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100609void rsa_check_privkey_null()
Paul Bakker37940d9f2009-07-10 22:38:58 +0000610{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_rsa_context ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 memset(&ctx, 0x00, sizeof(mbedtls_rsa_context));
Paul Bakker37940d9f2009-07-10 22:38:58 +0000613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED);
Paul Bakker37940d9f2009-07-10 22:38:58 +0000615}
Paul Bakker33b43f12013-08-20 11:48:36 +0200616/* END_CASE */
Paul Bakker37940d9f2009-07-10 22:38:58 +0000617
Paul Bakker33b43f12013-08-20 11:48:36 +0200618/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100619void mbedtls_rsa_check_pubkey(char *input_N, char *input_E, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000620{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100622 mbedtls_mpi N, E;
Paul Bakker821fb082009-07-12 13:26:42 +0000623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
625 mbedtls_rsa_init(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 if (strlen(input_N)) {
628 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000629 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (strlen(input_E)) {
631 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000632 }
633
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
635 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100636
Paul Bakkerbd51b262014-07-10 15:26:12 +0200637exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
639 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000640}
Paul Bakker33b43f12013-08-20 11:48:36 +0200641/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000642
Paul Bakker33b43f12013-08-20 11:48:36 +0200643/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100644void mbedtls_rsa_check_privkey(int mod, char *input_P, char *input_Q,
645 char *input_N, char *input_E, char *input_D,
646 char *input_DP, char *input_DQ, char *input_QP,
647 int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000648{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_rsa_context ctx;
Paul Bakker821fb082009-07-12 13:26:42 +0000650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 mbedtls_rsa_init(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000652
Paul Bakker33b43f12013-08-20 11:48:36 +0200653 ctx.len = mod / 8;
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 if (strlen(input_P)) {
655 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.P, input_P) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000656 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 if (strlen(input_Q)) {
658 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.Q, input_Q) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000659 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 if (strlen(input_N)) {
661 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.N, input_N) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000662 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 if (strlen(input_E)) {
664 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000665 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 if (strlen(input_D)) {
667 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.D, input_D) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000668 }
Hanno Becker131134f2017-08-23 08:31:07 +0100669#if !defined(MBEDTLS_RSA_NO_CRT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 if (strlen(input_DP)) {
671 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.DP, input_DP) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000672 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 if (strlen(input_DQ)) {
674 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.DQ, input_DQ) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000675 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 if (strlen(input_QP)) {
677 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.QP, input_QP) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000678 }
Hanno Becker131134f2017-08-23 08:31:07 +0100679#else
Werner Lewisf65a3272022-07-07 11:38:44 +0100680 ((void) input_DP);
681 ((void) input_DQ);
682 ((void) input_QP);
Hanno Becker131134f2017-08-23 08:31:07 +0100683#endif
Paul Bakker821fb082009-07-12 13:26:42 +0000684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100686
Paul Bakkerbd51b262014-07-10 15:26:12 +0200687exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000689}
Paul Bakker33b43f12013-08-20 11:48:36 +0200690/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000691
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100692/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100693void rsa_check_pubpriv(int mod, char *input_Npub, char *input_Epub,
694 char *input_P, char *input_Q, char *input_N,
695 char *input_E, char *input_D, char *input_DP,
696 char *input_DQ, char *input_QP, int result)
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100697{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698 mbedtls_rsa_context pub, prv;
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 mbedtls_rsa_init(&pub);
701 mbedtls_rsa_init(&prv);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100702
703 pub.len = mod / 8;
704 prv.len = mod / 8;
705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 if (strlen(input_Npub)) {
707 TEST_ASSERT(mbedtls_test_read_mpi(&pub.N, input_Npub) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100708 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 if (strlen(input_Epub)) {
710 TEST_ASSERT(mbedtls_test_read_mpi(&pub.E, input_Epub) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100711 }
712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 if (strlen(input_P)) {
714 TEST_ASSERT(mbedtls_test_read_mpi(&prv.P, input_P) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100715 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 if (strlen(input_Q)) {
717 TEST_ASSERT(mbedtls_test_read_mpi(&prv.Q, input_Q) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100718 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if (strlen(input_N)) {
720 TEST_ASSERT(mbedtls_test_read_mpi(&prv.N, input_N) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100721 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if (strlen(input_E)) {
723 TEST_ASSERT(mbedtls_test_read_mpi(&prv.E, input_E) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100724 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 if (strlen(input_D)) {
726 TEST_ASSERT(mbedtls_test_read_mpi(&prv.D, input_D) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100727 }
Hanno Becker131134f2017-08-23 08:31:07 +0100728#if !defined(MBEDTLS_RSA_NO_CRT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 if (strlen(input_DP)) {
730 TEST_ASSERT(mbedtls_test_read_mpi(&prv.DP, input_DP) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100731 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 if (strlen(input_DQ)) {
733 TEST_ASSERT(mbedtls_test_read_mpi(&prv.DQ, input_DQ) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100734 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 if (strlen(input_QP)) {
736 TEST_ASSERT(mbedtls_test_read_mpi(&prv.QP, input_QP) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100737 }
Hanno Becker131134f2017-08-23 08:31:07 +0100738#else
Werner Lewisf65a3272022-07-07 11:38:44 +0100739 ((void) input_DP);
740 ((void) input_DQ);
741 ((void) input_QP);
Hanno Becker131134f2017-08-23 08:31:07 +0100742#endif
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 TEST_ASSERT(mbedtls_rsa_check_pub_priv(&pub, &prv) == result);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100745
746exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 mbedtls_rsa_free(&pub);
748 mbedtls_rsa_free(&prv);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100749}
750/* END_CASE */
751
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200752/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100753void mbedtls_rsa_gen_key(int nrbits, int exponent, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000754{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755 mbedtls_rsa_context ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 mbedtls_rsa_init(&ctx);
Paul Bakkerc0a1a312011-12-04 17:12:15 +0000757
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200758 /* This test uses an insecure RNG, suitable only for testing.
759 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 TEST_ASSERT(mbedtls_rsa_gen_key(&ctx, mbedtls_test_rnd_std_rand, NULL, nrbits,
761 exponent) == result);
762 if (result == 0) {
763 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
764 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&ctx.P, &ctx.Q) > 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000765 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100766
Paul Bakkerbd51b262014-07-10 15:26:12 +0200767exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000769}
Paul Bakker33b43f12013-08-20 11:48:36 +0200770/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000771
Manuel Pégourié-Gonnard1d1174a2022-07-16 08:41:34 +0200772/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100773void mbedtls_rsa_deduce_primes(char *input_N,
774 char *input_D,
775 char *input_E,
776 char *output_P,
777 char *output_Q,
778 int corrupt, int result)
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100779{
780 mbedtls_mpi N, P, Pp, Q, Qp, D, E;
781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 mbedtls_mpi_init(&N);
783 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
784 mbedtls_mpi_init(&Pp); mbedtls_mpi_init(&Qp);
785 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100786
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
788 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
789 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
790 TEST_ASSERT(mbedtls_test_read_mpi(&Qp, output_P) == 0);
791 TEST_ASSERT(mbedtls_test_read_mpi(&Pp, output_Q) == 0);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 if (corrupt) {
794 TEST_ASSERT(mbedtls_mpi_add_int(&D, &D, 2) == 0);
795 }
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100796
797 /* Try to deduce P, Q from N, D, E only. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 TEST_ASSERT(mbedtls_rsa_deduce_primes(&N, &D, &E, &P, &Q) == result);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 if (!corrupt) {
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100801 /* Check if (P,Q) = (Pp, Qp) or (P,Q) = (Qp, Pp) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 TEST_ASSERT((mbedtls_mpi_cmp_mpi(&P, &Pp) == 0 && mbedtls_mpi_cmp_mpi(&Q, &Qp) == 0) ||
803 (mbedtls_mpi_cmp_mpi(&P, &Qp) == 0 && mbedtls_mpi_cmp_mpi(&Q, &Pp) == 0));
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100804 }
805
806exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 mbedtls_mpi_free(&N);
808 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
809 mbedtls_mpi_free(&Pp); mbedtls_mpi_free(&Qp);
810 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100811}
812/* END_CASE */
813
Hanno Becker6b4ce492017-08-23 11:00:21 +0100814/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100815void mbedtls_rsa_deduce_private_exponent(char *input_P,
816 char *input_Q,
817 char *input_E,
818 char *output_D,
819 int corrupt, int result)
Hanno Becker6b4ce492017-08-23 11:00:21 +0100820{
821 mbedtls_mpi P, Q, D, Dp, E, R, Rp;
822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
824 mbedtls_mpi_init(&D); mbedtls_mpi_init(&Dp);
825 mbedtls_mpi_init(&E);
826 mbedtls_mpi_init(&R); mbedtls_mpi_init(&Rp);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
829 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
830 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
831 TEST_ASSERT(mbedtls_test_read_mpi(&Dp, output_D) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 if (corrupt) {
Hanno Becker6b4ce492017-08-23 11:00:21 +0100834 /* Make E even */
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 0) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100836 }
837
838 /* Try to deduce D from N, P, Q, E. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 TEST_ASSERT(mbedtls_rsa_deduce_private_exponent(&P, &Q,
840 &E, &D) == result);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 if (!corrupt) {
Hanno Becker6b4ce492017-08-23 11:00:21 +0100843 /*
844 * Check that D and Dp agree modulo LCM(P-1, Q-1).
845 */
846
847 /* Replace P,Q by P-1, Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 TEST_ASSERT(mbedtls_mpi_sub_int(&P, &P, 1) == 0);
849 TEST_ASSERT(mbedtls_mpi_sub_int(&Q, &Q, 1) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100850
851 /* Check D == Dp modulo P-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &D, &P) == 0);
853 TEST_ASSERT(mbedtls_mpi_mod_mpi(&Rp, &Dp, &P) == 0);
854 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &Rp) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100855
856 /* Check D == Dp modulo Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &D, &Q) == 0);
858 TEST_ASSERT(mbedtls_mpi_mod_mpi(&Rp, &Dp, &Q) == 0);
859 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &Rp) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100860 }
861
862exit:
863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
865 mbedtls_mpi_free(&D); mbedtls_mpi_free(&Dp);
866 mbedtls_mpi_free(&E);
867 mbedtls_mpi_free(&R); mbedtls_mpi_free(&Rp);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100868}
869/* END_CASE */
870
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200871/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100872void mbedtls_rsa_import(char *input_N,
873 char *input_P,
874 char *input_Q,
875 char *input_D,
876 char *input_E,
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100877 int bitlen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 int successive,
879 int is_priv,
880 int res_check,
881 int res_complete)
Hanno Beckerc77ab892017-08-23 11:01:06 +0100882{
883 mbedtls_mpi N, P, Q, D, E;
884 mbedtls_rsa_context ctx;
885
Hanno Beckere1582a82017-09-29 11:51:05 +0100886 /* Buffers used for encryption-decryption test */
887 unsigned char *buf_orig = NULL;
888 unsigned char *buf_enc = NULL;
889 unsigned char *buf_dec = NULL;
890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 const int have_N = (strlen(input_N) > 0);
892 const int have_P = (strlen(input_P) > 0);
893 const int have_Q = (strlen(input_Q) > 0);
894 const int have_D = (strlen(input_D) > 0);
895 const int have_E = (strlen(input_E) > 0);
Hanno Becker4d6e8342017-09-29 11:50:18 +0100896
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 mbedtls_rsa_init(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 mbedtls_mpi_init(&N);
900 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
901 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 if (have_N) {
904 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100905 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100906
907 if (have_P) {
908 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
909 }
910
911 if (have_Q) {
912 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
913 }
914
915 if (have_D) {
916 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
917 }
918
919 if (have_E) {
920 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
921 }
922
923 if (!successive) {
924 TEST_ASSERT(mbedtls_rsa_import(&ctx,
925 have_N ? &N : NULL,
926 have_P ? &P : NULL,
927 have_Q ? &Q : NULL,
928 have_D ? &D : NULL,
929 have_E ? &E : NULL) == 0);
930 } else {
Hanno Beckerc77ab892017-08-23 11:01:06 +0100931 /* Import N, P, Q, D, E separately.
932 * This should make no functional difference. */
933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 TEST_ASSERT(mbedtls_rsa_import(&ctx,
935 have_N ? &N : NULL,
936 NULL, NULL, NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100937
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 TEST_ASSERT(mbedtls_rsa_import(&ctx,
939 NULL,
940 have_P ? &P : NULL,
941 NULL, NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 TEST_ASSERT(mbedtls_rsa_import(&ctx,
944 NULL, NULL,
945 have_Q ? &Q : NULL,
946 NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 TEST_ASSERT(mbedtls_rsa_import(&ctx,
949 NULL, NULL, NULL,
950 have_D ? &D : NULL,
951 NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 TEST_ASSERT(mbedtls_rsa_import(&ctx,
954 NULL, NULL, NULL, NULL,
955 have_E ? &E : NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100956 }
957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == res_complete);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100959
Hanno Beckere1582a82017-09-29 11:51:05 +0100960 /* On expected success, perform some public and private
961 * key operations to check if the key is working properly. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 if (res_complete == 0) {
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100963 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), bitlen);
964 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (bitlen + 7) / 8);
965
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 if (is_priv) {
967 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == res_check);
968 } else {
969 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == res_check);
970 }
Hanno Becker04877a42017-10-11 10:01:33 +0100971
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 if (res_check != 0) {
Hanno Becker04877a42017-10-11 10:01:33 +0100973 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 }
Hanno Beckere1582a82017-09-29 11:51:05 +0100975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 buf_orig = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
977 buf_enc = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
978 buf_dec = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
979 if (buf_orig == NULL || buf_enc == NULL || buf_dec == NULL) {
Hanno Beckere1582a82017-09-29 11:51:05 +0100980 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 }
Hanno Beckere1582a82017-09-29 11:51:05 +0100982
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200983 /* This test uses an insecure RNG, suitable only for testing.
984 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 TEST_ASSERT(mbedtls_test_rnd_std_rand(NULL,
986 buf_orig, mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100987
988 /* Make sure the number we're generating is smaller than the modulus */
989 buf_orig[0] = 0x00;
990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 TEST_ASSERT(mbedtls_rsa_public(&ctx, buf_orig, buf_enc) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 if (is_priv) {
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200994 /* This test uses an insecure RNG, suitable only for testing.
995 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_std_rand,
997 NULL, buf_enc,
998 buf_dec) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 TEST_ASSERT(memcmp(buf_orig, buf_dec,
1001 mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001002 }
1003 }
1004
Hanno Beckerc77ab892017-08-23 11:01:06 +01001005exit:
1006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 mbedtls_free(buf_orig);
1008 mbedtls_free(buf_enc);
1009 mbedtls_free(buf_dec);
Hanno Beckere1582a82017-09-29 11:51:05 +01001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 mbedtls_rsa_free(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 mbedtls_mpi_free(&N);
1014 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1015 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001016}
1017/* END_CASE */
1018
Hanno Becker417f2d62017-08-23 11:44:51 +01001019/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001020void mbedtls_rsa_export(char *input_N,
1021 char *input_P,
1022 char *input_Q,
1023 char *input_D,
1024 char *input_E,
1025 int is_priv,
1026 int successive)
Hanno Becker417f2d62017-08-23 11:44:51 +01001027{
1028 /* Original MPI's with which we set up the RSA context */
1029 mbedtls_mpi N, P, Q, D, E;
1030
1031 /* Exported MPI's */
1032 mbedtls_mpi Ne, Pe, Qe, De, Ee;
1033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 const int have_N = (strlen(input_N) > 0);
1035 const int have_P = (strlen(input_P) > 0);
1036 const int have_Q = (strlen(input_Q) > 0);
1037 const int have_D = (strlen(input_D) > 0);
1038 const int have_E = (strlen(input_E) > 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001039
Hanno Becker417f2d62017-08-23 11:44:51 +01001040 mbedtls_rsa_context ctx;
1041
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 mbedtls_rsa_init(&ctx);
Hanno Becker417f2d62017-08-23 11:44:51 +01001043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 mbedtls_mpi_init(&N);
1045 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
1046 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Becker417f2d62017-08-23 11:44:51 +01001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 mbedtls_mpi_init(&Ne);
1049 mbedtls_mpi_init(&Pe); mbedtls_mpi_init(&Qe);
1050 mbedtls_mpi_init(&De); mbedtls_mpi_init(&Ee);
Hanno Becker417f2d62017-08-23 11:44:51 +01001051
1052 /* Setup RSA context */
1053
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 if (have_N) {
1055 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1056 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 if (have_P) {
1059 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
1060 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001061
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 if (have_Q) {
1063 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
1064 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (have_D) {
1067 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
1068 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 if (have_E) {
1071 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1072 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 TEST_ASSERT(mbedtls_rsa_import(&ctx,
1075 strlen(input_N) ? &N : NULL,
1076 strlen(input_P) ? &P : NULL,
1077 strlen(input_Q) ? &Q : NULL,
1078 strlen(input_D) ? &D : NULL,
1079 strlen(input_E) ? &E : NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001080
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001082
1083 /*
1084 * Export parameters and compare to original ones.
1085 */
1086
1087 /* N and E must always be present. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 if (!successive) {
1089 TEST_ASSERT(mbedtls_rsa_export(&ctx, &Ne, NULL, NULL, NULL, &Ee) == 0);
1090 } else {
1091 TEST_ASSERT(mbedtls_rsa_export(&ctx, &Ne, NULL, NULL, NULL, NULL) == 0);
1092 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, NULL, NULL, &Ee) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001093 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &Ne) == 0);
1095 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&E, &Ee) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001096
1097 /* If we were providing enough information to setup a complete private context,
1098 * we expect to be able to export all core parameters. */
1099
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 if (is_priv) {
1101 if (!successive) {
1102 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, &Pe, &Qe,
1103 &De, NULL) == 0);
1104 } else {
1105 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, &Pe, NULL,
1106 NULL, NULL) == 0);
1107 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, &Qe,
1108 NULL, NULL) == 0);
1109 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, NULL,
1110 &De, NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001111 }
1112
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 if (have_P) {
1114 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P, &Pe) == 0);
1115 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001116
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 if (have_Q) {
1118 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &Qe) == 0);
1119 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 if (have_D) {
1122 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&D, &De) == 0);
1123 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001124
1125 /* While at it, perform a sanity check */
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 TEST_ASSERT(mbedtls_rsa_validate_params(&Ne, &Pe, &Qe, &De, &Ee,
1127 NULL, NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001128 }
1129
1130exit:
1131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 mbedtls_rsa_free(&ctx);
Hanno Becker417f2d62017-08-23 11:44:51 +01001133
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 mbedtls_mpi_free(&N);
1135 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1136 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Becker417f2d62017-08-23 11:44:51 +01001137
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 mbedtls_mpi_free(&Ne);
1139 mbedtls_mpi_free(&Pe); mbedtls_mpi_free(&Qe);
1140 mbedtls_mpi_free(&De); mbedtls_mpi_free(&Ee);
Hanno Becker417f2d62017-08-23 11:44:51 +01001141}
1142/* END_CASE */
1143
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001144/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001145void mbedtls_rsa_validate_params(char *input_N,
1146 char *input_P,
1147 char *input_Q,
1148 char *input_D,
1149 char *input_E,
1150 int prng, int result)
Hanno Beckerce002632017-08-23 13:22:36 +01001151{
1152 /* Original MPI's with which we set up the RSA context */
1153 mbedtls_mpi N, P, Q, D, E;
1154
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 const int have_N = (strlen(input_N) > 0);
1156 const int have_P = (strlen(input_P) > 0);
1157 const int have_Q = (strlen(input_Q) > 0);
1158 const int have_D = (strlen(input_D) > 0);
1159 const int have_E = (strlen(input_E) > 0);
Hanno Beckerce002632017-08-23 13:22:36 +01001160
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 mbedtls_mpi_init(&N);
1162 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
1163 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckerce002632017-08-23 13:22:36 +01001164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 if (have_N) {
1166 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1167 }
Hanno Beckerce002632017-08-23 13:22:36 +01001168
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 if (have_P) {
1170 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
1171 }
Hanno Beckerce002632017-08-23 13:22:36 +01001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 if (have_Q) {
1174 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
1175 }
Hanno Beckerce002632017-08-23 13:22:36 +01001176
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 if (have_D) {
1178 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
1179 }
Hanno Beckerce002632017-08-23 13:22:36 +01001180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 if (have_E) {
1182 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1183 }
Hanno Beckerce002632017-08-23 13:22:36 +01001184
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001185 /* This test uses an insecure RNG, suitable only for testing.
1186 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 TEST_ASSERT(mbedtls_rsa_validate_params(have_N ? &N : NULL,
1188 have_P ? &P : NULL,
1189 have_Q ? &Q : NULL,
1190 have_D ? &D : NULL,
1191 have_E ? &E : NULL,
1192 prng ? mbedtls_test_rnd_std_rand : NULL,
1193 prng ? NULL : NULL) == result);
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001194
Hanno Beckerce002632017-08-23 13:22:36 +01001195exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001196 mbedtls_mpi_free(&N);
1197 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1198 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckerce002632017-08-23 13:22:36 +01001199}
1200/* END_CASE */
1201
Manuel Pégourié-Gonnard1d1174a2022-07-16 08:41:34 +02001202/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001203void mbedtls_rsa_export_raw(data_t *input_N, data_t *input_P,
1204 data_t *input_Q, data_t *input_D,
1205 data_t *input_E, int is_priv,
1206 int successive)
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001207{
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001208 /* Exported buffers */
Ron Eldorfdc15bd2018-11-22 15:47:51 +02001209 unsigned char bufNe[256];
1210 unsigned char bufPe[128];
1211 unsigned char bufQe[128];
1212 unsigned char bufDe[256];
1213 unsigned char bufEe[1];
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001214
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001215 mbedtls_rsa_context ctx;
1216
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 mbedtls_rsa_init(&ctx);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001218
1219 /* Setup RSA context */
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1221 input_N->len ? input_N->x : NULL, input_N->len,
1222 input_P->len ? input_P->x : NULL, input_P->len,
1223 input_Q->len ? input_Q->x : NULL, input_Q->len,
1224 input_D->len ? input_D->x : NULL, input_D->len,
1225 input_E->len ? input_E->x : NULL, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001226
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001228
1229 /*
1230 * Export parameters and compare to original ones.
1231 */
1232
1233 /* N and E must always be present. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 if (!successive) {
1235 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, bufNe, input_N->len,
1236 NULL, 0, NULL, 0, NULL, 0,
1237 bufEe, input_E->len) == 0);
1238 } else {
1239 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, bufNe, input_N->len,
1240 NULL, 0, NULL, 0, NULL, 0,
1241 NULL, 0) == 0);
1242 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1243 NULL, 0, NULL, 0, NULL, 0,
1244 bufEe, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001245 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 TEST_ASSERT(memcmp(input_N->x, bufNe, input_N->len) == 0);
1247 TEST_ASSERT(memcmp(input_E->x, bufEe, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001248
1249 /* If we were providing enough information to setup a complete private context,
1250 * we expect to be able to export all core parameters. */
1251
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 if (is_priv) {
1253 if (!successive) {
1254 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1255 bufPe, input_P->len ? input_P->len : sizeof(bufPe),
1256 bufQe, input_Q->len ? input_Q->len : sizeof(bufQe),
1257 bufDe, input_D->len ? input_D->len : sizeof(bufDe),
1258 NULL, 0) == 0);
1259 } else {
1260 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1261 bufPe, input_P->len ? input_P->len : sizeof(bufPe),
1262 NULL, 0, NULL, 0,
1263 NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001264
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0, NULL, 0,
1266 bufQe, input_Q->len ? input_Q->len : sizeof(bufQe),
1267 NULL, 0, NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001268
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0, NULL, 0, NULL, 0,
1270 bufDe, input_D->len ? input_D->len : sizeof(bufDe),
1271 NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001272 }
1273
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 if (input_P->len) {
1275 TEST_ASSERT(memcmp(input_P->x, bufPe, input_P->len) == 0);
1276 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001277
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 if (input_Q->len) {
1279 TEST_ASSERT(memcmp(input_Q->x, bufQe, input_Q->len) == 0);
1280 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001281
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 if (input_D->len) {
1283 TEST_ASSERT(memcmp(input_D->x, bufDe, input_D->len) == 0);
1284 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001285
1286 }
1287
1288exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 mbedtls_rsa_free(&ctx);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001290}
1291/* END_CASE */
1292
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001293/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001294void mbedtls_rsa_import_raw(data_t *input_N,
1295 data_t *input_P, data_t *input_Q,
1296 data_t *input_D, data_t *input_E,
1297 int successive,
1298 int is_priv,
1299 int res_check,
1300 int res_complete)
Hanno Beckerc77ab892017-08-23 11:01:06 +01001301{
Hanno Beckere1582a82017-09-29 11:51:05 +01001302 /* Buffers used for encryption-decryption test */
1303 unsigned char *buf_orig = NULL;
1304 unsigned char *buf_enc = NULL;
1305 unsigned char *buf_dec = NULL;
1306
Hanno Beckerc77ab892017-08-23 11:01:06 +01001307 mbedtls_rsa_context ctx;
Hanno Becker3f3ae852017-10-02 10:08:39 +01001308
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 mbedtls_rsa_init(&ctx);
Hanno Becker3f3ae852017-10-02 10:08:39 +01001310
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 if (!successive) {
1312 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1313 (input_N->len > 0) ? input_N->x : NULL, input_N->len,
1314 (input_P->len > 0) ? input_P->x : NULL, input_P->len,
1315 (input_Q->len > 0) ? input_Q->x : NULL, input_Q->len,
1316 (input_D->len > 0) ? input_D->x : NULL, input_D->len,
1317 (input_E->len > 0) ? input_E->x : NULL,
1318 input_E->len) == 0);
1319 } else {
Hanno Beckerc77ab892017-08-23 11:01:06 +01001320 /* Import N, P, Q, D, E separately.
1321 * This should make no functional difference. */
1322
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1324 (input_N->len > 0) ? input_N->x : NULL, input_N->len,
1325 NULL, 0, NULL, 0, NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001326
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1328 NULL, 0,
1329 (input_P->len > 0) ? input_P->x : NULL, input_P->len,
1330 NULL, 0, NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001331
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1333 NULL, 0, NULL, 0,
1334 (input_Q->len > 0) ? input_Q->x : NULL, input_Q->len,
1335 NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001336
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1338 NULL, 0, NULL, 0, NULL, 0,
1339 (input_D->len > 0) ? input_D->x : NULL, input_D->len,
1340 NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001341
Gilles Peskine449bd832023-01-11 14:50:10 +01001342 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1343 NULL, 0, NULL, 0, NULL, 0, NULL, 0,
1344 (input_E->len > 0) ? input_E->x : NULL,
1345 input_E->len) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001346 }
1347
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == res_complete);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001349
Hanno Beckere1582a82017-09-29 11:51:05 +01001350 /* On expected success, perform some public and private
1351 * key operations to check if the key is working properly. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 if (res_complete == 0) {
1353 if (is_priv) {
1354 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == res_check);
1355 } else {
1356 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == res_check);
1357 }
Hanno Becker04877a42017-10-11 10:01:33 +01001358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 if (res_check != 0) {
Hanno Becker04877a42017-10-11 10:01:33 +01001360 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001361 }
Hanno Beckere1582a82017-09-29 11:51:05 +01001362
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 buf_orig = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1364 buf_enc = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1365 buf_dec = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1366 if (buf_orig == NULL || buf_enc == NULL || buf_dec == NULL) {
Hanno Beckere1582a82017-09-29 11:51:05 +01001367 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 }
Hanno Beckere1582a82017-09-29 11:51:05 +01001369
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001370 /* This test uses an insecure RNG, suitable only for testing.
1371 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 TEST_ASSERT(mbedtls_test_rnd_std_rand(NULL,
1373 buf_orig, mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001374
1375 /* Make sure the number we're generating is smaller than the modulus */
1376 buf_orig[0] = 0x00;
1377
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 TEST_ASSERT(mbedtls_rsa_public(&ctx, buf_orig, buf_enc) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001379
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 if (is_priv) {
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001381 /* This test uses an insecure RNG, suitable only for testing.
1382 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_std_rand,
1384 NULL, buf_enc,
1385 buf_dec) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001386
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 TEST_ASSERT(memcmp(buf_orig, buf_dec,
1388 mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001389 }
1390 }
1391
Hanno Beckerc77ab892017-08-23 11:01:06 +01001392exit:
1393
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 mbedtls_free(buf_orig);
1395 mbedtls_free(buf_enc);
1396 mbedtls_free(buf_dec);
Hanno Becker3f3ae852017-10-02 10:08:39 +01001397
Gilles Peskine449bd832023-01-11 14:50:10 +01001398 mbedtls_rsa_free(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001399}
1400/* END_CASE */
1401
Valerio Setti8e6093d2024-01-23 15:19:07 +01001402/* BEGIN_CASE */
Valerio Setti6d597f12024-01-24 13:44:41 +01001403void rsa_parse_pkcs1_key(int is_public, data_t *input, int exp_ret_val)
Valerio Setti6def24c2024-01-24 12:33:04 +01001404{
1405 mbedtls_rsa_context rsa_ctx;
Valerio Setti6d597f12024-01-24 13:44:41 +01001406
Valerio Setti6def24c2024-01-24 12:33:04 +01001407 mbedtls_rsa_init(&rsa_ctx);
1408
Valerio Setti6d597f12024-01-24 13:44:41 +01001409 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001410 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), exp_ret_val);
Valerio Setti6d597f12024-01-24 13:44:41 +01001411 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001412 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), exp_ret_val);
Valerio Setti6d597f12024-01-24 13:44:41 +01001413 }
Valerio Setti6def24c2024-01-24 12:33:04 +01001414
1415exit:
1416 mbedtls_rsa_free(&rsa_ctx);
1417}
1418/* END_CASE */
1419
1420/* BEGIN_CASE */
Valerio Setti1533c3f2024-01-24 11:24:20 +01001421void rsa_parse_write_pkcs1_key(int is_public, data_t *input)
Valerio Setti8e6093d2024-01-23 15:19:07 +01001422{
1423 mbedtls_rsa_context rsa_ctx;
Valerio Setti8e6093d2024-01-23 15:19:07 +01001424 unsigned char *output_buf = NULL;
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001425 unsigned char *output_end, *output_p;
1426 size_t output_len;
Valerio Setti8e6093d2024-01-23 15:19:07 +01001427
1428 mbedtls_rsa_init(&rsa_ctx);
1429
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001430 TEST_CALLOC(output_buf, input->len);
1431 output_end = output_buf + input->len;
1432 output_p = output_end;
1433
Valerio Setti1533c3f2024-01-24 11:24:20 +01001434 /* Parse the key and write it back to output_buf. */
Valerio Setti8e6093d2024-01-23 15:19:07 +01001435 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001436 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001437 TEST_EQUAL(mbedtls_rsa_write_pubkey(&rsa_ctx, output_buf, &output_p), input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001438 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001439 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001440 TEST_EQUAL(mbedtls_rsa_write_key(&rsa_ctx, output_buf, &output_p), input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001441 }
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001442 output_len = output_end - output_p;
Valerio Setti1533c3f2024-01-24 11:24:20 +01001443
1444 /* Check that the written key matches with the one provided in input. */
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001445 TEST_MEMORY_COMPARE(output_p, output_len, input->x, input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001446
1447exit:
1448 mbedtls_free(output_buf);
1449 mbedtls_rsa_free(&rsa_ctx);
1450}
1451/* END_CASE */
1452
Valerio Settia8886452024-01-30 17:35:49 +01001453/* BEGIN_CASE */
1454void rsa_key_write_incremental(int is_public, data_t *input)
1455{
1456 mbedtls_rsa_context rsa_ctx;
Valerio Settic701cb22024-02-02 11:09:37 +01001457 unsigned char *buf = NULL, *end, *p;
1458 size_t i, written_data;
Valerio Settia8886452024-01-30 17:35:49 +01001459
1460 mbedtls_rsa_init(&rsa_ctx);
1461
1462 /* This is supposed to succeed as the real target of this test are the
1463 * write attempt below. */
1464 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001465 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
Valerio Settia8886452024-01-30 17:35:49 +01001466 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001467 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
Valerio Settia8886452024-01-30 17:35:49 +01001468 }
1469
Valerio Settic701cb22024-02-02 11:09:37 +01001470 /* Test with an output buffer smaller than required. */
Valerio Settia8886452024-01-30 17:35:49 +01001471 for (i = 1; i < input->len; i++) {
1472 TEST_CALLOC(buf, i);
1473 end = buf + i;
Valerio Settic701cb22024-02-02 11:09:37 +01001474 p = end;
Valerio Settia8886452024-01-30 17:35:49 +01001475 /* We don't care much about the return value as long as it fails. */
1476 if (is_public) {
Valerio Settic701cb22024-02-02 11:09:37 +01001477 TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) != 0);
Valerio Settia8886452024-01-30 17:35:49 +01001478 } else {
Valerio Settic701cb22024-02-02 11:09:37 +01001479 TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) != 0);
Valerio Settia8886452024-01-30 17:35:49 +01001480 }
1481 mbedtls_free(buf);
1482 buf = NULL;
1483 }
1484
Valerio Settic701cb22024-02-02 11:09:37 +01001485 /* Test with an output buffer equal or larger than what it is strictly required. */
1486 for (i = input->len; i < (2 * input->len); i++) {
1487 TEST_CALLOC(buf, i);
1488 end = buf + i;
1489 p = end;
1490 /* This time all write functions must succeed. */
1491 if (is_public) {
1492 TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) > 0);
1493 } else {
1494 TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) > 0);
1495 }
1496 written_data = (end - p);
1497 TEST_MEMORY_COMPARE(p, written_data, input->x, input->len);
1498 mbedtls_free(buf);
1499 buf = NULL;
Valerio Settia8886452024-01-30 17:35:49 +01001500 }
1501
1502exit:
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001503 mbedtls_free(buf);
Valerio Settia8886452024-01-30 17:35:49 +01001504 mbedtls_rsa_free(&rsa_ctx);
1505}
1506/* END_CASE */
1507
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001509void rsa_selftest()
Paul Bakker42a29bf2009-07-07 20:18:41 +00001510{
Manuel Pégourié-Gonnardfb8d90a2023-03-16 10:47:59 +01001511 MD_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +01001512 TEST_ASSERT(mbedtls_rsa_self_test(1) == 0);
Manuel Pégourié-Gonnardfb8d90a2023-03-16 10:47:59 +01001513
1514exit:
1515 MD_PSA_DONE();
Paul Bakker42a29bf2009-07-07 20:18:41 +00001516}
Paul Bakker33b43f12013-08-20 11:48:36 +02001517/* END_CASE */