blob: e82452927ed70028534e6ce9560c1981fb415e80 [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"
Chris Jones66a4cd42021-03-09 16:04:12 +00003#include "rsa_alt_helpers.h"
Valerio Setti8e6093d2024-01-23 15:19:07 +01004#include "rsa_internal.h"
Paul Bakker33b43f12013-08-20 11:48:36 +02005/* END_HEADER */
Paul Bakker42a29bf2009-07-07 20:18:41 +00006
Paul Bakker33b43f12013-08-20 11:48:36 +02007/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02008 * depends_on:MBEDTLS_RSA_C:MBEDTLS_BIGNUM_C:MBEDTLS_GENPRIME
Paul Bakker33b43f12013-08-20 11:48:36 +02009 * END_DEPENDENCIES
10 */
Paul Bakker5690efc2011-05-26 13:16:06 +000011
Paul Bakker33b43f12013-08-20 11:48:36 +020012/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +010013void rsa_invalid_param()
Ronald Cronea7631b2021-06-03 18:51:59 +020014{
15 mbedtls_rsa_context ctx;
16 const int invalid_padding = 42;
17 const int invalid_hash_id = 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010018 unsigned char buf[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
19 size_t buf_len = sizeof(buf);
Ronald Cronea7631b2021-06-03 18:51:59 +020020
Gilles Peskine449bd832023-01-11 14:50:10 +010021 mbedtls_rsa_init(&ctx);
Ronald Cronea7631b2021-06-03 18:51:59 +020022
Gilles Peskine449bd832023-01-11 14:50:10 +010023 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
24 invalid_padding,
25 MBEDTLS_MD_NONE),
26 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cronea7631b2021-06-03 18:51:59 +020027
Gilles Peskine449bd832023-01-11 14:50:10 +010028 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
29 MBEDTLS_RSA_PKCS_V21,
30 invalid_hash_id),
31 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cronea7631b2021-06-03 18:51:59 +020032
Gilles Peskine449bd832023-01-11 14:50:10 +010033 TEST_EQUAL(mbedtls_rsa_pkcs1_sign(&ctx, NULL,
34 NULL, MBEDTLS_MD_NONE,
35 buf_len,
36 NULL, buf),
37 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010038
Gilles Peskine449bd832023-01-11 14:50:10 +010039 TEST_EQUAL(mbedtls_rsa_pkcs1_sign(&ctx, NULL,
40 NULL, MBEDTLS_MD_SHA256,
41 0,
42 NULL, buf),
43 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010044
Gilles Peskine449bd832023-01-11 14:50:10 +010045 TEST_EQUAL(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_NONE,
46 buf_len,
47 NULL, buf),
48 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010049
Gilles Peskine449bd832023-01-11 14:50:10 +010050 TEST_EQUAL(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_SHA256,
51 0,
52 NULL, buf),
53 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010054
Ronald Cron3a0375f2021-06-08 10:22:28 +020055#if !defined(MBEDTLS_PKCS1_V15)
Gilles Peskine449bd832023-01-11 14:50:10 +010056 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
57 MBEDTLS_RSA_PKCS_V15,
58 MBEDTLS_MD_NONE),
59 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cron3a0375f2021-06-08 10:22:28 +020060#endif
61
Tuvshinzaya Erdenekhuufe7524d2022-09-01 16:07:18 +010062#if defined(MBEDTLS_PKCS1_V15)
Gilles Peskine449bd832023-01-11 14:50:10 +010063 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_sign(&ctx, NULL,
64 NULL, MBEDTLS_MD_NONE,
65 buf_len,
66 NULL, buf),
67 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010068
Gilles Peskine449bd832023-01-11 14:50:10 +010069 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_sign(&ctx, NULL,
70 NULL, MBEDTLS_MD_SHA256,
71 0,
72 NULL, buf),
73 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010074
Gilles Peskine449bd832023-01-11 14:50:10 +010075 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_verify(&ctx, MBEDTLS_MD_NONE,
76 buf_len,
77 NULL, buf),
78 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010079
Gilles Peskine449bd832023-01-11 14:50:10 +010080 TEST_EQUAL(mbedtls_rsa_rsassa_pkcs1_v15_verify(&ctx, MBEDTLS_MD_SHA256,
81 0,
82 NULL, buf),
83 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +010084
85
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010086#endif
87
Ronald Cron3a0375f2021-06-08 10:22:28 +020088#if !defined(MBEDTLS_PKCS1_V21)
Gilles Peskine449bd832023-01-11 14:50:10 +010089 TEST_EQUAL(mbedtls_rsa_set_padding(&ctx,
90 MBEDTLS_RSA_PKCS_V21,
91 MBEDTLS_MD_NONE),
92 MBEDTLS_ERR_RSA_INVALID_PADDING);
Ronald Cron3a0375f2021-06-08 10:22:28 +020093#endif
94
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +010095#if defined(MBEDTLS_PKCS1_V21)
Gilles Peskine449bd832023-01-11 14:50:10 +010096 TEST_EQUAL(mbedtls_rsa_rsassa_pss_sign_ext(&ctx, NULL, NULL,
97 MBEDTLS_MD_NONE, buf_len,
98 NULL, buf_len,
99 buf),
100 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100101
Gilles Peskine449bd832023-01-11 14:50:10 +0100102 TEST_EQUAL(mbedtls_rsa_rsassa_pss_sign_ext(&ctx, NULL, NULL,
103 MBEDTLS_MD_SHA256, 0,
104 NULL, buf_len,
105 buf),
106 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +0100107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify_ext(&ctx, MBEDTLS_MD_NONE,
109 buf_len, NULL,
110 MBEDTLS_MD_NONE,
111 buf_len, buf),
112 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100113
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify_ext(&ctx, MBEDTLS_MD_SHA256,
115 0, NULL,
116 MBEDTLS_MD_NONE,
117 buf_len, buf),
118 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu08b22342022-09-01 16:18:00 +0100119
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify(&ctx, MBEDTLS_MD_NONE,
121 buf_len,
122 NULL, buf),
123 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100124
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 TEST_EQUAL(mbedtls_rsa_rsassa_pss_verify(&ctx, MBEDTLS_MD_SHA256,
126 0,
127 NULL, buf),
128 MBEDTLS_ERR_RSA_BAD_INPUT_DATA);
Tuvshinzaya Erdenekhuu7e2e2a92022-07-26 10:09:24 +0100129#endif
130
Ronald Cronea7631b2021-06-03 18:51:59 +0200131exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 mbedtls_rsa_free(&ctx);
Ronald Cronea7631b2021-06-03 18:51:59 +0200133}
134/* END_CASE */
135
136/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100137void rsa_init_free(int reinit)
Gilles Peskine914afe12021-02-01 17:55:24 +0100138{
139 mbedtls_rsa_context ctx;
140
141 /* Double free is not explicitly documented to work, but we rely on it
142 * even inside the library so that you can call mbedtls_rsa_free()
143 * unconditionally on an error path without checking whether it has
144 * already been called in the success path. */
145
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 mbedtls_rsa_init(&ctx);
147 mbedtls_rsa_free(&ctx);
Gilles Peskine914afe12021-02-01 17:55:24 +0100148
Gilles Peskine449bd832023-01-11 14:50:10 +0100149 if (reinit) {
150 mbedtls_rsa_init(&ctx);
151 }
152 mbedtls_rsa_free(&ctx);
Gilles Peskine914afe12021-02-01 17:55:24 +0100153
154 /* This test case always succeeds, functionally speaking. A plausible
155 * bug might trigger an invalid pointer dereference or a memory leak. */
156 goto exit;
157}
158/* END_CASE */
159
Manuel Pégourié-Gonnard236c4e22022-07-16 08:35:06 +0200160/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100161void mbedtls_rsa_pkcs1_sign(data_t *message_str, int padding_mode,
162 int digest, int mod, char *input_P,
163 char *input_Q, char *input_N, char *input_E,
164 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000165{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200166 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100168 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200169 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000170
Gilles Peskine449bd832023-01-11 14:50:10 +0100171 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
172 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
173 mbedtls_rsa_init(&ctx);
174 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
175 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 memset(output, 0x00, sizeof(output));
178 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
181 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
182 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
183 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000184
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100186 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
187 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
189 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 TEST_ASSERT(mbedtls_rsa_pkcs1_sign(
192 &ctx, &mbedtls_test_rnd_pseudo_rand, &rnd_info,
193 digest, message_str->len, message_str->x,
194 output) == result);
195 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
198 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000199 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000200
Paul Bakkerbd51b262014-07-10 15:26:12 +0200201exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
203 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
204 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000205}
Paul Bakker33b43f12013-08-20 11:48:36 +0200206/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000207
Manuel Pégourié-Gonnard236c4e22022-07-16 08:35:06 +0200208/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100209void mbedtls_rsa_pkcs1_verify(data_t *message_str, int padding_mode,
210 int digest, int mod,
211 char *input_N, char *input_E,
212 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000213{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100215 mbedtls_mpi N, E;
216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
218 mbedtls_rsa_init(&ctx);
219 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
220 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000221
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
223 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
224 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100225 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
226 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 TEST_ASSERT(mbedtls_rsa_pkcs1_verify(&ctx, digest, message_str->len, message_str->x,
230 result_str->x) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100231
Paul Bakkerbd51b262014-07-10 15:26:12 +0200232exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
234 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000235}
Paul Bakker33b43f12013-08-20 11:48:36 +0200236/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000237
Paul Bakker821fb082009-07-12 13:26:42 +0000238
Paul Bakker33b43f12013-08-20 11:48:36 +0200239/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100240void rsa_pkcs1_sign_raw(data_t *hash_result,
241 int padding_mode, int mod,
242 char *input_P, char *input_Q,
243 char *input_N, char *input_E,
244 data_t *result_str)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000245{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200246 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200247 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100248 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200249 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 mbedtls_rsa_init(&ctx);
252 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
253 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
Paul Bakker821fb082009-07-12 13:26:42 +0000254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
256 MBEDTLS_MD_NONE) == 0);
Paul Elliotte57dd2d2021-06-25 11:13:24 +0100257
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 memset(output, 0x00, sizeof(output));
259 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000260
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
262 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
263 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
264 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000265
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100267 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
268 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
270 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000271
Paul Bakker821fb082009-07-12 13:26:42 +0000272
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 TEST_ASSERT(mbedtls_rsa_pkcs1_sign(&ctx, &mbedtls_test_rnd_pseudo_rand,
274 &rnd_info, MBEDTLS_MD_NONE,
275 hash_result->len,
276 hash_result->x, output) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000277
Paul Bakker821fb082009-07-12 13:26:42 +0000278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
280 ctx.len, result_str->len) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000281
Paul Bakkerbd51b262014-07-10 15:26:12 +0200282exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
284 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100285
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000287}
Paul Bakker33b43f12013-08-20 11:48:36 +0200288/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000289
Paul Bakker33b43f12013-08-20 11:48:36 +0200290/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100291void rsa_pkcs1_verify_raw(data_t *hash_result,
292 int padding_mode, int mod,
293 char *input_N, char *input_E,
294 data_t *result_str, int correct)
Paul Bakker821fb082009-07-12 13:26:42 +0000295{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200296 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297 mbedtls_rsa_context ctx;
Paul Bakker821fb082009-07-12 13:26:42 +0000298
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100299 mbedtls_mpi N, E;
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100301
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 mbedtls_rsa_init(&ctx);
303 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
304 MBEDTLS_MD_NONE) == 0);
305 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000306
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
308 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100311 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
312 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000314
Paul Bakker821fb082009-07-12 13:26:42 +0000315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 TEST_ASSERT(mbedtls_rsa_pkcs1_verify(&ctx, MBEDTLS_MD_NONE, hash_result->len, hash_result->x,
317 result_str->x) == correct);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100318
Paul Bakkerbd51b262014-07-10 15:26:12 +0200319exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
321 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000322}
Paul Bakker33b43f12013-08-20 11:48:36 +0200323/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000324
Paul Bakker33b43f12013-08-20 11:48:36 +0200325/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100326void mbedtls_rsa_pkcs1_encrypt(data_t *message_str, int padding_mode,
327 int mod, char *input_N, char *input_E,
328 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000329{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200330 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331 mbedtls_rsa_context ctx;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200332 mbedtls_test_rnd_pseudo_info rnd_info;
Paul Bakker997bbd12011-03-13 15:45:42 +0000333
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100334 mbedtls_mpi N, E;
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker821fb082009-07-12 13:26:42 +0000338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 mbedtls_rsa_init(&ctx);
340 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
341 MBEDTLS_MD_NONE) == 0);
342 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
345 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100348 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
349 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000351
Paul Bakker42a29bf2009-07-07 20:18:41 +0000352
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 TEST_ASSERT(mbedtls_rsa_pkcs1_encrypt(&ctx,
354 &mbedtls_test_rnd_pseudo_rand,
355 &rnd_info, message_str->len,
356 message_str->x,
357 output) == result);
358 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
361 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000362 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100363
Paul Bakkerbd51b262014-07-10 15:26:12 +0200364exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
366 mbedtls_rsa_free(&ctx);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000367}
Paul Bakker33b43f12013-08-20 11:48:36 +0200368/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000369
Paul Bakker33b43f12013-08-20 11:48:36 +0200370/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100371void rsa_pkcs1_encrypt_bad_rng(data_t *message_str, int padding_mode,
372 int mod, char *input_N, char *input_E,
373 data_t *result_str, int result)
Paul Bakkera6656852010-07-18 19:47:14 +0000374{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200375 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 mbedtls_rsa_context ctx;
Paul Bakkera6656852010-07-18 19:47:14 +0000377
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100378 mbedtls_mpi N, E;
379
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
381 mbedtls_rsa_init(&ctx);
382 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
383 MBEDTLS_MD_NONE) == 0);
384 memset(output, 0x00, sizeof(output));
Paul Bakkera6656852010-07-18 19:47:14 +0000385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
387 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100390 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
391 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100392 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000393
Paul Bakkera6656852010-07-18 19:47:14 +0000394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 TEST_ASSERT(mbedtls_rsa_pkcs1_encrypt(&ctx, &mbedtls_test_rnd_zero_rand,
396 NULL, message_str->len,
397 message_str->x,
398 output) == result);
399 if (result == 0) {
Paul Bakkera6656852010-07-18 19:47:14 +0000400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
402 ctx.len, result_str->len) == 0);
Paul Bakkera6656852010-07-18 19:47:14 +0000403 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100404
Paul Bakkerbd51b262014-07-10 15:26:12 +0200405exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
407 mbedtls_rsa_free(&ctx);
Paul Bakkera6656852010-07-18 19:47:14 +0000408}
Paul Bakker33b43f12013-08-20 11:48:36 +0200409/* END_CASE */
Paul Bakkera6656852010-07-18 19:47:14 +0000410
Paul Bakker33b43f12013-08-20 11:48:36 +0200411/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100412void mbedtls_rsa_pkcs1_decrypt(data_t *message_str, int padding_mode,
413 int mod, char *input_P,
414 char *input_Q, char *input_N,
415 char *input_E, int max_output,
416 data_t *result_str, int result)
Paul Bakker42a29bf2009-07-07 20:18:41 +0000417{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200418 unsigned char output[32];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 mbedtls_rsa_context ctx;
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000420 size_t output_len;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200421 mbedtls_test_rnd_pseudo_info rnd_info;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100422 mbedtls_mpi N, P, Q, E;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
425 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 mbedtls_rsa_init(&ctx);
428 TEST_ASSERT(mbedtls_rsa_set_padding(&ctx, padding_mode,
429 MBEDTLS_MD_NONE) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000430
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 memset(output, 0x00, sizeof(output));
432 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker42a29bf2009-07-07 20:18:41 +0000433
Paul Bakker42a29bf2009-07-07 20:18:41 +0000434
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
436 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
437 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
438 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100441 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
442 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
444 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000445
Paul Bakker69998dd2009-07-11 19:15:20 +0000446 output_len = 0;
Paul Bakker42a29bf2009-07-07 20:18:41 +0000447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 TEST_ASSERT(mbedtls_rsa_pkcs1_decrypt(&ctx, mbedtls_test_rnd_pseudo_rand,
449 &rnd_info,
450 &output_len, message_str->x, output,
451 max_output) == result);
452 if (result == 0) {
Paul Bakker42a29bf2009-07-07 20:18:41 +0000453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
455 output_len,
456 result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000457 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000458
Paul Bakkerbd51b262014-07-10 15:26:12 +0200459exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
461 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
462 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000463}
Paul Bakker33b43f12013-08-20 11:48:36 +0200464/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000465
Paul Bakker33b43f12013-08-20 11:48:36 +0200466/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100467void mbedtls_rsa_public(data_t *message_str, int mod,
468 char *input_N, char *input_E,
469 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000470{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200471 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
Paul Bakker821fb082009-07-12 13:26:42 +0000473
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100474 mbedtls_mpi N, E;
475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
477 mbedtls_rsa_init(&ctx);
478 mbedtls_rsa_init(&ctx2);
479 memset(output, 0x00, sizeof(output));
Paul Bakker821fb082009-07-12 13:26:42 +0000480
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
482 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
Gilles Peskine058d0092021-06-09 16:24:35 +0200485
486 /* Check test data consistency */
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100487 TEST_EQUAL(message_str->len, (size_t) ((mod + 7) / 8));
488 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
489 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 TEST_ASSERT(mbedtls_rsa_public(&ctx, message_str->x, output) == result);
493 if (result == 0) {
Paul Bakker821fb082009-07-12 13:26:42 +0000494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
496 ctx.len, result_str->len) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000497 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100498
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100499 /* And now with the copy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 TEST_ASSERT(mbedtls_rsa_copy(&ctx2, &ctx) == 0);
Paul Bakkerbd51b262014-07-10 15:26:12 +0200501 /* clear the original to be sure */
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 mbedtls_rsa_free(&ctx);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100503
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx2) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 memset(output, 0x00, sizeof(output));
507 TEST_ASSERT(mbedtls_rsa_public(&ctx2, message_str->x, output) == result);
508 if (result == 0) {
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100509
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
511 ctx.len, result_str->len) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100512 }
513
Paul Bakkerbd51b262014-07-10 15:26:12 +0200514exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
516 mbedtls_rsa_free(&ctx);
517 mbedtls_rsa_free(&ctx2);
Paul Bakker821fb082009-07-12 13:26:42 +0000518}
Paul Bakker33b43f12013-08-20 11:48:36 +0200519/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000520
Paul Bakker33b43f12013-08-20 11:48:36 +0200521/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100522void mbedtls_rsa_private(data_t *message_str, int mod,
523 char *input_P, char *input_Q,
524 char *input_N, char *input_E,
525 data_t *result_str, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000526{
Ron Eldorfdc15bd2018-11-22 15:47:51 +0200527 unsigned char output[256];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 mbedtls_rsa_context ctx, ctx2; /* Also test mbedtls_rsa_copy() while at it */
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100529 mbedtls_mpi N, P, Q, E;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200530 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200531 int i;
Paul Bakker821fb082009-07-12 13:26:42 +0000532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 mbedtls_mpi_init(&N); mbedtls_mpi_init(&P);
534 mbedtls_mpi_init(&Q); mbedtls_mpi_init(&E);
535 mbedtls_rsa_init(&ctx);
536 mbedtls_rsa_init(&ctx2);
Paul Bakker821fb082009-07-12 13:26:42 +0000537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 memset(&rnd_info, 0, sizeof(mbedtls_test_rnd_pseudo_info));
Paul Bakker821fb082009-07-12 13:26:42 +0000539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
541 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
542 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
543 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, &P, &Q, NULL, &E) == 0);
Gilles Peskine058d0092021-06-09 16:24:35 +0200546
547 /* Check test data consistency */
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100548 TEST_EQUAL(message_str->len, (size_t) ((mod + 7) / 8));
549 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (size_t) ((mod + 7) / 8));
550 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), (size_t) mod);
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
552 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000553
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200554 /* repeat three times to test updating of blinding values */
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 for (i = 0; i < 3; i++) {
556 memset(output, 0x00, sizeof(output));
557 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_pseudo_rand,
558 &rnd_info, message_str->x,
559 output) == result);
560 if (result == 0) {
Paul Bakker821fb082009-07-12 13:26:42 +0000561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
563 ctx.len,
564 result_str->len) == 0);
Manuel Pégourié-Gonnard735b8fc2013-09-13 12:57:23 +0200565 }
Paul Bakker821fb082009-07-12 13:26:42 +0000566 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000567
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100568 /* And now one more time with the copy */
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 TEST_ASSERT(mbedtls_rsa_copy(&ctx2, &ctx) == 0);
Paul Bakkerbd51b262014-07-10 15:26:12 +0200570 /* clear the original to be sure */
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 mbedtls_rsa_free(&ctx);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx2) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 memset(output, 0x00, sizeof(output));
576 TEST_ASSERT(mbedtls_rsa_private(&ctx2, mbedtls_test_rnd_pseudo_rand,
577 &rnd_info, message_str->x,
578 output) == result);
579 if (result == 0) {
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100580
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 TEST_ASSERT(mbedtls_test_hexcmp(output, result_str->x,
582 ctx2.len,
583 result_str->len) == 0);
Manuel Pégourié-Gonnardc4919bc2014-02-03 11:16:44 +0100584 }
585
Paul Bakkerbd51b262014-07-10 15:26:12 +0200586exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 mbedtls_mpi_free(&N); mbedtls_mpi_free(&P);
588 mbedtls_mpi_free(&Q); mbedtls_mpi_free(&E);
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100589
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 mbedtls_rsa_free(&ctx); mbedtls_rsa_free(&ctx2);
Paul Bakker42a29bf2009-07-07 20:18:41 +0000591}
Paul Bakker33b43f12013-08-20 11:48:36 +0200592/* END_CASE */
Paul Bakker42a29bf2009-07-07 20:18:41 +0000593
Paul Bakker33b43f12013-08-20 11:48:36 +0200594/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100595void rsa_check_privkey_null()
Paul Bakker37940d9f2009-07-10 22:38:58 +0000596{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_rsa_context ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 memset(&ctx, 0x00, sizeof(mbedtls_rsa_context));
Paul Bakker37940d9f2009-07-10 22:38:58 +0000599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED);
Paul Bakker37940d9f2009-07-10 22:38:58 +0000601}
Paul Bakker33b43f12013-08-20 11:48:36 +0200602/* END_CASE */
Paul Bakker37940d9f2009-07-10 22:38:58 +0000603
Paul Bakker33b43f12013-08-20 11:48:36 +0200604/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100605void mbedtls_rsa_check_pubkey(char *input_N, char *input_E, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000606{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_rsa_context ctx;
Hanno Beckerceb7a9d2017-08-23 08:33:08 +0100608 mbedtls_mpi N, E;
Paul Bakker821fb082009-07-12 13:26:42 +0000609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 mbedtls_mpi_init(&N); mbedtls_mpi_init(&E);
611 mbedtls_rsa_init(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000612
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 if (strlen(input_N)) {
614 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000615 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 if (strlen(input_E)) {
617 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000618 }
619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 TEST_ASSERT(mbedtls_rsa_import(&ctx, &N, NULL, NULL, NULL, &E) == 0);
621 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100622
Paul Bakkerbd51b262014-07-10 15:26:12 +0200623exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 mbedtls_mpi_free(&N); mbedtls_mpi_free(&E);
625 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000626}
Paul Bakker33b43f12013-08-20 11:48:36 +0200627/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000628
Paul Bakker33b43f12013-08-20 11:48:36 +0200629/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100630void mbedtls_rsa_check_privkey(int mod, char *input_P, char *input_Q,
631 char *input_N, char *input_E, char *input_D,
632 char *input_DP, char *input_DQ, char *input_QP,
633 int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000634{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635 mbedtls_rsa_context ctx;
Paul Bakker821fb082009-07-12 13:26:42 +0000636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 mbedtls_rsa_init(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000638
Paul Bakker33b43f12013-08-20 11:48:36 +0200639 ctx.len = mod / 8;
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (strlen(input_P)) {
641 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.P, input_P) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000642 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (strlen(input_Q)) {
644 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.Q, input_Q) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000645 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 if (strlen(input_N)) {
647 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.N, input_N) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000648 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (strlen(input_E)) {
650 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.E, input_E) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000651 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (strlen(input_D)) {
653 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.D, input_D) == 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000654 }
Hanno Becker131134f2017-08-23 08:31:07 +0100655#if !defined(MBEDTLS_RSA_NO_CRT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 if (strlen(input_DP)) {
657 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.DP, input_DP) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000658 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 if (strlen(input_DQ)) {
660 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.DQ, input_DQ) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000661 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if (strlen(input_QP)) {
663 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.QP, input_QP) == 0);
Paul Bakker31417a72012-09-27 20:41:37 +0000664 }
Hanno Becker131134f2017-08-23 08:31:07 +0100665#else
Werner Lewisf65a3272022-07-07 11:38:44 +0100666 ((void) input_DP);
667 ((void) input_DQ);
668 ((void) input_QP);
Hanno Becker131134f2017-08-23 08:31:07 +0100669#endif
Paul Bakker821fb082009-07-12 13:26:42 +0000670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == result);
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100672
Paul Bakkerbd51b262014-07-10 15:26:12 +0200673exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000675}
Paul Bakker33b43f12013-08-20 11:48:36 +0200676/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000677
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100678/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100679void rsa_check_pubpriv(int mod, char *input_Npub, char *input_Epub,
680 char *input_P, char *input_Q, char *input_N,
681 char *input_E, char *input_D, char *input_DP,
682 char *input_DQ, char *input_QP, int result)
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100683{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 mbedtls_rsa_context pub, prv;
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 mbedtls_rsa_init(&pub);
687 mbedtls_rsa_init(&prv);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100688
689 pub.len = mod / 8;
690 prv.len = mod / 8;
691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 if (strlen(input_Npub)) {
693 TEST_ASSERT(mbedtls_test_read_mpi(&pub.N, input_Npub) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100694 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 if (strlen(input_Epub)) {
696 TEST_ASSERT(mbedtls_test_read_mpi(&pub.E, input_Epub) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100697 }
698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 if (strlen(input_P)) {
700 TEST_ASSERT(mbedtls_test_read_mpi(&prv.P, input_P) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100701 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 if (strlen(input_Q)) {
703 TEST_ASSERT(mbedtls_test_read_mpi(&prv.Q, input_Q) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100704 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 if (strlen(input_N)) {
706 TEST_ASSERT(mbedtls_test_read_mpi(&prv.N, input_N) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100707 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 if (strlen(input_E)) {
709 TEST_ASSERT(mbedtls_test_read_mpi(&prv.E, input_E) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100710 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 if (strlen(input_D)) {
712 TEST_ASSERT(mbedtls_test_read_mpi(&prv.D, input_D) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100713 }
Hanno Becker131134f2017-08-23 08:31:07 +0100714#if !defined(MBEDTLS_RSA_NO_CRT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 if (strlen(input_DP)) {
716 TEST_ASSERT(mbedtls_test_read_mpi(&prv.DP, input_DP) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100717 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 if (strlen(input_DQ)) {
719 TEST_ASSERT(mbedtls_test_read_mpi(&prv.DQ, input_DQ) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100720 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 if (strlen(input_QP)) {
722 TEST_ASSERT(mbedtls_test_read_mpi(&prv.QP, input_QP) == 0);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100723 }
Hanno Becker131134f2017-08-23 08:31:07 +0100724#else
Werner Lewisf65a3272022-07-07 11:38:44 +0100725 ((void) input_DP);
726 ((void) input_DQ);
727 ((void) input_QP);
Hanno Becker131134f2017-08-23 08:31:07 +0100728#endif
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 TEST_ASSERT(mbedtls_rsa_check_pub_priv(&pub, &prv) == result);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100731
732exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 mbedtls_rsa_free(&pub);
734 mbedtls_rsa_free(&prv);
Manuel Pégourié-Gonnard2f8d1f92014-11-06 14:02:51 +0100735}
736/* END_CASE */
737
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200738/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100739void mbedtls_rsa_gen_key(int nrbits, int exponent, int result)
Paul Bakker821fb082009-07-12 13:26:42 +0000740{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741 mbedtls_rsa_context ctx;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 mbedtls_rsa_init(&ctx);
Paul Bakkerc0a1a312011-12-04 17:12:15 +0000743
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200744 /* This test uses an insecure RNG, suitable only for testing.
745 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 TEST_ASSERT(mbedtls_rsa_gen_key(&ctx, mbedtls_test_rnd_std_rand, NULL, nrbits,
747 exponent) == result);
748 if (result == 0) {
749 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == 0);
750 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&ctx.P, &ctx.Q) > 0);
Paul Bakker821fb082009-07-12 13:26:42 +0000751 }
Paul Bakker58ef6ec2013-01-03 11:33:48 +0100752
Paul Bakkerbd51b262014-07-10 15:26:12 +0200753exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 mbedtls_rsa_free(&ctx);
Paul Bakker821fb082009-07-12 13:26:42 +0000755}
Paul Bakker33b43f12013-08-20 11:48:36 +0200756/* END_CASE */
Paul Bakker821fb082009-07-12 13:26:42 +0000757
Manuel Pégourié-Gonnard1d1174a2022-07-16 08:41:34 +0200758/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759void mbedtls_rsa_deduce_primes(char *input_N,
760 char *input_D,
761 char *input_E,
762 char *output_P,
763 char *output_Q,
764 int corrupt, int result)
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100765{
766 mbedtls_mpi N, P, Pp, Q, Qp, D, E;
767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 mbedtls_mpi_init(&N);
769 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
770 mbedtls_mpi_init(&Pp); mbedtls_mpi_init(&Qp);
771 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
774 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
775 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
776 TEST_ASSERT(mbedtls_test_read_mpi(&Qp, output_P) == 0);
777 TEST_ASSERT(mbedtls_test_read_mpi(&Pp, output_Q) == 0);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 if (corrupt) {
780 TEST_ASSERT(mbedtls_mpi_add_int(&D, &D, 2) == 0);
781 }
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100782
783 /* Try to deduce P, Q from N, D, E only. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 TEST_ASSERT(mbedtls_rsa_deduce_primes(&N, &D, &E, &P, &Q) == result);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100785
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 if (!corrupt) {
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100787 /* Check if (P,Q) = (Pp, Qp) or (P,Q) = (Qp, Pp) */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 TEST_ASSERT((mbedtls_mpi_cmp_mpi(&P, &Pp) == 0 && mbedtls_mpi_cmp_mpi(&Q, &Qp) == 0) ||
789 (mbedtls_mpi_cmp_mpi(&P, &Qp) == 0 && mbedtls_mpi_cmp_mpi(&Q, &Pp) == 0));
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100790 }
791
792exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 mbedtls_mpi_free(&N);
794 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
795 mbedtls_mpi_free(&Pp); mbedtls_mpi_free(&Qp);
796 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckere78fd8d2017-08-23 11:00:44 +0100797}
798/* END_CASE */
799
Hanno Becker6b4ce492017-08-23 11:00:21 +0100800/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100801void mbedtls_rsa_deduce_private_exponent(char *input_P,
802 char *input_Q,
803 char *input_E,
804 char *output_D,
805 int corrupt, int result)
Hanno Becker6b4ce492017-08-23 11:00:21 +0100806{
807 mbedtls_mpi P, Q, D, Dp, E, R, Rp;
808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
810 mbedtls_mpi_init(&D); mbedtls_mpi_init(&Dp);
811 mbedtls_mpi_init(&E);
812 mbedtls_mpi_init(&R); mbedtls_mpi_init(&Rp);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
815 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
816 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
817 TEST_ASSERT(mbedtls_test_read_mpi(&Dp, output_D) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100818
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 if (corrupt) {
Hanno Becker6b4ce492017-08-23 11:00:21 +0100820 /* Make E even */
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 0) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100822 }
823
824 /* Try to deduce D from N, P, Q, E. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 TEST_ASSERT(mbedtls_rsa_deduce_private_exponent(&P, &Q,
826 &E, &D) == result);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 if (!corrupt) {
Hanno Becker6b4ce492017-08-23 11:00:21 +0100829 /*
830 * Check that D and Dp agree modulo LCM(P-1, Q-1).
831 */
832
833 /* Replace P,Q by P-1, Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 TEST_ASSERT(mbedtls_mpi_sub_int(&P, &P, 1) == 0);
835 TEST_ASSERT(mbedtls_mpi_sub_int(&Q, &Q, 1) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100836
837 /* Check D == Dp modulo P-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &D, &P) == 0);
839 TEST_ASSERT(mbedtls_mpi_mod_mpi(&Rp, &Dp, &P) == 0);
840 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &Rp) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100841
842 /* Check D == Dp modulo Q-1 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &D, &Q) == 0);
844 TEST_ASSERT(mbedtls_mpi_mod_mpi(&Rp, &Dp, &Q) == 0);
845 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &Rp) == 0);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100846 }
847
848exit:
849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
851 mbedtls_mpi_free(&D); mbedtls_mpi_free(&Dp);
852 mbedtls_mpi_free(&E);
853 mbedtls_mpi_free(&R); mbedtls_mpi_free(&Rp);
Hanno Becker6b4ce492017-08-23 11:00:21 +0100854}
855/* END_CASE */
856
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200857/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100858void mbedtls_rsa_import(char *input_N,
859 char *input_P,
860 char *input_Q,
861 char *input_D,
862 char *input_E,
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100863 int bitlen,
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 int successive,
865 int is_priv,
866 int res_check,
867 int res_complete)
Hanno Beckerc77ab892017-08-23 11:01:06 +0100868{
869 mbedtls_mpi N, P, Q, D, E;
870 mbedtls_rsa_context ctx;
871
Hanno Beckere1582a82017-09-29 11:51:05 +0100872 /* Buffers used for encryption-decryption test */
873 unsigned char *buf_orig = NULL;
874 unsigned char *buf_enc = NULL;
875 unsigned char *buf_dec = NULL;
876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 const int have_N = (strlen(input_N) > 0);
878 const int have_P = (strlen(input_P) > 0);
879 const int have_Q = (strlen(input_Q) > 0);
880 const int have_D = (strlen(input_D) > 0);
881 const int have_E = (strlen(input_E) > 0);
Hanno Becker4d6e8342017-09-29 11:50:18 +0100882
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 mbedtls_rsa_init(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100884
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 mbedtls_mpi_init(&N);
886 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
887 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 if (have_N) {
890 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100891 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100892
893 if (have_P) {
894 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
895 }
896
897 if (have_Q) {
898 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
899 }
900
901 if (have_D) {
902 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
903 }
904
905 if (have_E) {
906 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
907 }
908
909 if (!successive) {
910 TEST_ASSERT(mbedtls_rsa_import(&ctx,
911 have_N ? &N : NULL,
912 have_P ? &P : NULL,
913 have_Q ? &Q : NULL,
914 have_D ? &D : NULL,
915 have_E ? &E : NULL) == 0);
916 } else {
Hanno Beckerc77ab892017-08-23 11:01:06 +0100917 /* Import N, P, Q, D, E separately.
918 * This should make no functional difference. */
919
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 TEST_ASSERT(mbedtls_rsa_import(&ctx,
921 have_N ? &N : NULL,
922 NULL, NULL, NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 TEST_ASSERT(mbedtls_rsa_import(&ctx,
925 NULL,
926 have_P ? &P : NULL,
927 NULL, NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 TEST_ASSERT(mbedtls_rsa_import(&ctx,
930 NULL, NULL,
931 have_Q ? &Q : NULL,
932 NULL, NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 TEST_ASSERT(mbedtls_rsa_import(&ctx,
935 NULL, NULL, NULL,
936 have_D ? &D : NULL,
937 NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 TEST_ASSERT(mbedtls_rsa_import(&ctx,
940 NULL, NULL, NULL, NULL,
941 have_E ? &E : NULL) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100942 }
943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == res_complete);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100945
Hanno Beckere1582a82017-09-29 11:51:05 +0100946 /* On expected success, perform some public and private
947 * key operations to check if the key is working properly. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 if (res_complete == 0) {
Gilles Peskine19f1adf2024-02-01 22:17:44 +0100949 TEST_EQUAL(mbedtls_rsa_get_bitlen(&ctx), bitlen);
950 TEST_EQUAL(mbedtls_rsa_get_len(&ctx), (bitlen + 7) / 8);
951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 if (is_priv) {
953 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == res_check);
954 } else {
955 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == res_check);
956 }
Hanno Becker04877a42017-10-11 10:01:33 +0100957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 if (res_check != 0) {
Hanno Becker04877a42017-10-11 10:01:33 +0100959 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 }
Hanno Beckere1582a82017-09-29 11:51:05 +0100961
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 buf_orig = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
963 buf_enc = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
964 buf_dec = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
965 if (buf_orig == NULL || buf_enc == NULL || buf_dec == NULL) {
Hanno Beckere1582a82017-09-29 11:51:05 +0100966 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 }
Hanno Beckere1582a82017-09-29 11:51:05 +0100968
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200969 /* This test uses an insecure RNG, suitable only for testing.
970 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 TEST_ASSERT(mbedtls_test_rnd_std_rand(NULL,
972 buf_orig, mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100973
974 /* Make sure the number we're generating is smaller than the modulus */
975 buf_orig[0] = 0x00;
976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 TEST_ASSERT(mbedtls_rsa_public(&ctx, buf_orig, buf_enc) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 if (is_priv) {
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +0200980 /* This test uses an insecure RNG, suitable only for testing.
981 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_std_rand,
983 NULL, buf_enc,
984 buf_dec) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 TEST_ASSERT(memcmp(buf_orig, buf_dec,
987 mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +0100988 }
989 }
990
Hanno Beckerc77ab892017-08-23 11:01:06 +0100991exit:
992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 mbedtls_free(buf_orig);
994 mbedtls_free(buf_enc);
995 mbedtls_free(buf_dec);
Hanno Beckere1582a82017-09-29 11:51:05 +0100996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 mbedtls_rsa_free(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +0100998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 mbedtls_mpi_free(&N);
1000 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1001 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001002}
1003/* END_CASE */
1004
Hanno Becker417f2d62017-08-23 11:44:51 +01001005/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001006void mbedtls_rsa_export(char *input_N,
1007 char *input_P,
1008 char *input_Q,
1009 char *input_D,
1010 char *input_E,
1011 int is_priv,
1012 int successive)
Hanno Becker417f2d62017-08-23 11:44:51 +01001013{
1014 /* Original MPI's with which we set up the RSA context */
1015 mbedtls_mpi N, P, Q, D, E;
1016
1017 /* Exported MPI's */
1018 mbedtls_mpi Ne, Pe, Qe, De, Ee;
1019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 const int have_N = (strlen(input_N) > 0);
1021 const int have_P = (strlen(input_P) > 0);
1022 const int have_Q = (strlen(input_Q) > 0);
1023 const int have_D = (strlen(input_D) > 0);
1024 const int have_E = (strlen(input_E) > 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001025
Hanno Becker417f2d62017-08-23 11:44:51 +01001026 mbedtls_rsa_context ctx;
1027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 mbedtls_rsa_init(&ctx);
Hanno Becker417f2d62017-08-23 11:44:51 +01001029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 mbedtls_mpi_init(&N);
1031 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
1032 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Becker417f2d62017-08-23 11:44:51 +01001033
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 mbedtls_mpi_init(&Ne);
1035 mbedtls_mpi_init(&Pe); mbedtls_mpi_init(&Qe);
1036 mbedtls_mpi_init(&De); mbedtls_mpi_init(&Ee);
Hanno Becker417f2d62017-08-23 11:44:51 +01001037
1038 /* Setup RSA context */
1039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 if (have_N) {
1041 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1042 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 if (have_P) {
1045 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
1046 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 if (have_Q) {
1049 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
1050 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 if (have_D) {
1053 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
1054 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001055
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 if (have_E) {
1057 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1058 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 TEST_ASSERT(mbedtls_rsa_import(&ctx,
1061 strlen(input_N) ? &N : NULL,
1062 strlen(input_P) ? &P : NULL,
1063 strlen(input_Q) ? &Q : NULL,
1064 strlen(input_D) ? &D : NULL,
1065 strlen(input_E) ? &E : NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001066
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001068
1069 /*
1070 * Export parameters and compare to original ones.
1071 */
1072
1073 /* N and E must always be present. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 if (!successive) {
1075 TEST_ASSERT(mbedtls_rsa_export(&ctx, &Ne, NULL, NULL, NULL, &Ee) == 0);
1076 } else {
1077 TEST_ASSERT(mbedtls_rsa_export(&ctx, &Ne, NULL, NULL, NULL, NULL) == 0);
1078 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, NULL, NULL, &Ee) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001079 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &Ne) == 0);
1081 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&E, &Ee) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001082
1083 /* If we were providing enough information to setup a complete private context,
1084 * we expect to be able to export all core parameters. */
1085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 if (is_priv) {
1087 if (!successive) {
1088 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, &Pe, &Qe,
1089 &De, NULL) == 0);
1090 } else {
1091 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, &Pe, NULL,
1092 NULL, NULL) == 0);
1093 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, &Qe,
1094 NULL, NULL) == 0);
1095 TEST_ASSERT(mbedtls_rsa_export(&ctx, NULL, NULL, NULL,
1096 &De, NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001097 }
1098
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 if (have_P) {
1100 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P, &Pe) == 0);
1101 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 if (have_Q) {
1104 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &Qe) == 0);
1105 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001106
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (have_D) {
1108 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&D, &De) == 0);
1109 }
Hanno Becker417f2d62017-08-23 11:44:51 +01001110
1111 /* While at it, perform a sanity check */
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 TEST_ASSERT(mbedtls_rsa_validate_params(&Ne, &Pe, &Qe, &De, &Ee,
1113 NULL, NULL) == 0);
Hanno Becker417f2d62017-08-23 11:44:51 +01001114 }
1115
1116exit:
1117
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 mbedtls_rsa_free(&ctx);
Hanno Becker417f2d62017-08-23 11:44:51 +01001119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 mbedtls_mpi_free(&N);
1121 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1122 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Becker417f2d62017-08-23 11:44:51 +01001123
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 mbedtls_mpi_free(&Ne);
1125 mbedtls_mpi_free(&Pe); mbedtls_mpi_free(&Qe);
1126 mbedtls_mpi_free(&De); mbedtls_mpi_free(&Ee);
Hanno Becker417f2d62017-08-23 11:44:51 +01001127}
1128/* END_CASE */
1129
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001130/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001131void mbedtls_rsa_validate_params(char *input_N,
1132 char *input_P,
1133 char *input_Q,
1134 char *input_D,
1135 char *input_E,
1136 int prng, int result)
Hanno Beckerce002632017-08-23 13:22:36 +01001137{
1138 /* Original MPI's with which we set up the RSA context */
1139 mbedtls_mpi N, P, Q, D, E;
1140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 const int have_N = (strlen(input_N) > 0);
1142 const int have_P = (strlen(input_P) > 0);
1143 const int have_Q = (strlen(input_Q) > 0);
1144 const int have_D = (strlen(input_D) > 0);
1145 const int have_E = (strlen(input_E) > 0);
Hanno Beckerce002632017-08-23 13:22:36 +01001146
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 mbedtls_mpi_init(&N);
1148 mbedtls_mpi_init(&P); mbedtls_mpi_init(&Q);
1149 mbedtls_mpi_init(&D); mbedtls_mpi_init(&E);
Hanno Beckerce002632017-08-23 13:22:36 +01001150
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 if (have_N) {
1152 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1153 }
Hanno Beckerce002632017-08-23 13:22:36 +01001154
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 if (have_P) {
1156 TEST_ASSERT(mbedtls_test_read_mpi(&P, input_P) == 0);
1157 }
Hanno Beckerce002632017-08-23 13:22:36 +01001158
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 if (have_Q) {
1160 TEST_ASSERT(mbedtls_test_read_mpi(&Q, input_Q) == 0);
1161 }
Hanno Beckerce002632017-08-23 13:22:36 +01001162
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 if (have_D) {
1164 TEST_ASSERT(mbedtls_test_read_mpi(&D, input_D) == 0);
1165 }
Hanno Beckerce002632017-08-23 13:22:36 +01001166
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 if (have_E) {
1168 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1169 }
Hanno Beckerce002632017-08-23 13:22:36 +01001170
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001171 /* This test uses an insecure RNG, suitable only for testing.
1172 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 TEST_ASSERT(mbedtls_rsa_validate_params(have_N ? &N : NULL,
1174 have_P ? &P : NULL,
1175 have_Q ? &Q : NULL,
1176 have_D ? &D : NULL,
1177 have_E ? &E : NULL,
1178 prng ? mbedtls_test_rnd_std_rand : NULL,
1179 prng ? NULL : NULL) == result);
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001180
Hanno Beckerce002632017-08-23 13:22:36 +01001181exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 mbedtls_mpi_free(&N);
1183 mbedtls_mpi_free(&P); mbedtls_mpi_free(&Q);
1184 mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);
Hanno Beckerce002632017-08-23 13:22:36 +01001185}
1186/* END_CASE */
1187
Manuel Pégourié-Gonnard1d1174a2022-07-16 08:41:34 +02001188/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001189void mbedtls_rsa_export_raw(data_t *input_N, data_t *input_P,
1190 data_t *input_Q, data_t *input_D,
1191 data_t *input_E, int is_priv,
1192 int successive)
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001193{
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001194 /* Exported buffers */
Ron Eldorfdc15bd2018-11-22 15:47:51 +02001195 unsigned char bufNe[256];
1196 unsigned char bufPe[128];
1197 unsigned char bufQe[128];
1198 unsigned char bufDe[256];
1199 unsigned char bufEe[1];
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001200
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001201 mbedtls_rsa_context ctx;
1202
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 mbedtls_rsa_init(&ctx);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001204
1205 /* Setup RSA context */
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1207 input_N->len ? input_N->x : NULL, input_N->len,
1208 input_P->len ? input_P->x : NULL, input_P->len,
1209 input_Q->len ? input_Q->x : NULL, input_Q->len,
1210 input_D->len ? input_D->x : NULL, input_D->len,
1211 input_E->len ? input_E->x : NULL, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001212
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001214
1215 /*
1216 * Export parameters and compare to original ones.
1217 */
1218
1219 /* N and E must always be present. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 if (!successive) {
1221 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, bufNe, input_N->len,
1222 NULL, 0, NULL, 0, NULL, 0,
1223 bufEe, input_E->len) == 0);
1224 } else {
1225 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, bufNe, input_N->len,
1226 NULL, 0, NULL, 0, NULL, 0,
1227 NULL, 0) == 0);
1228 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1229 NULL, 0, NULL, 0, NULL, 0,
1230 bufEe, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001231 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 TEST_ASSERT(memcmp(input_N->x, bufNe, input_N->len) == 0);
1233 TEST_ASSERT(memcmp(input_E->x, bufEe, input_E->len) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001234
1235 /* If we were providing enough information to setup a complete private context,
1236 * we expect to be able to export all core parameters. */
1237
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 if (is_priv) {
1239 if (!successive) {
1240 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1241 bufPe, input_P->len ? input_P->len : sizeof(bufPe),
1242 bufQe, input_Q->len ? input_Q->len : sizeof(bufQe),
1243 bufDe, input_D->len ? input_D->len : sizeof(bufDe),
1244 NULL, 0) == 0);
1245 } else {
1246 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0,
1247 bufPe, input_P->len ? input_P->len : sizeof(bufPe),
1248 NULL, 0, NULL, 0,
1249 NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0, NULL, 0,
1252 bufQe, input_Q->len ? input_Q->len : sizeof(bufQe),
1253 NULL, 0, NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001254
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 TEST_ASSERT(mbedtls_rsa_export_raw(&ctx, NULL, 0, NULL, 0, NULL, 0,
1256 bufDe, input_D->len ? input_D->len : sizeof(bufDe),
1257 NULL, 0) == 0);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001258 }
1259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 if (input_P->len) {
1261 TEST_ASSERT(memcmp(input_P->x, bufPe, input_P->len) == 0);
1262 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001263
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 if (input_Q->len) {
1265 TEST_ASSERT(memcmp(input_Q->x, bufQe, input_Q->len) == 0);
1266 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001267
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 if (input_D->len) {
1269 TEST_ASSERT(memcmp(input_D->x, bufDe, input_D->len) == 0);
1270 }
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001271
1272 }
1273
1274exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 mbedtls_rsa_free(&ctx);
Hanno Beckerf1b9a2c2017-08-23 11:49:22 +01001276}
1277/* END_CASE */
1278
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001279/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001280void mbedtls_rsa_import_raw(data_t *input_N,
1281 data_t *input_P, data_t *input_Q,
1282 data_t *input_D, data_t *input_E,
1283 int successive,
1284 int is_priv,
1285 int res_check,
1286 int res_complete)
Hanno Beckerc77ab892017-08-23 11:01:06 +01001287{
Hanno Beckere1582a82017-09-29 11:51:05 +01001288 /* Buffers used for encryption-decryption test */
1289 unsigned char *buf_orig = NULL;
1290 unsigned char *buf_enc = NULL;
1291 unsigned char *buf_dec = NULL;
1292
Hanno Beckerc77ab892017-08-23 11:01:06 +01001293 mbedtls_rsa_context ctx;
Hanno Becker3f3ae852017-10-02 10:08:39 +01001294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 mbedtls_rsa_init(&ctx);
Hanno Becker3f3ae852017-10-02 10:08:39 +01001296
Gilles Peskine449bd832023-01-11 14:50:10 +01001297 if (!successive) {
1298 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1299 (input_N->len > 0) ? input_N->x : NULL, input_N->len,
1300 (input_P->len > 0) ? input_P->x : NULL, input_P->len,
1301 (input_Q->len > 0) ? input_Q->x : NULL, input_Q->len,
1302 (input_D->len > 0) ? input_D->x : NULL, input_D->len,
1303 (input_E->len > 0) ? input_E->x : NULL,
1304 input_E->len) == 0);
1305 } else {
Hanno Beckerc77ab892017-08-23 11:01:06 +01001306 /* Import N, P, Q, D, E separately.
1307 * This should make no functional difference. */
1308
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1310 (input_N->len > 0) ? input_N->x : NULL, input_N->len,
1311 NULL, 0, NULL, 0, NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001312
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1314 NULL, 0,
1315 (input_P->len > 0) ? input_P->x : NULL, input_P->len,
1316 NULL, 0, NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001317
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1319 NULL, 0, NULL, 0,
1320 (input_Q->len > 0) ? input_Q->x : NULL, input_Q->len,
1321 NULL, 0, NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001322
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1324 NULL, 0, NULL, 0, NULL, 0,
1325 (input_D->len > 0) ? input_D->x : NULL, input_D->len,
1326 NULL, 0) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001327
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 TEST_ASSERT(mbedtls_rsa_import_raw(&ctx,
1329 NULL, 0, NULL, 0, NULL, 0, NULL, 0,
1330 (input_E->len > 0) ? input_E->x : NULL,
1331 input_E->len) == 0);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001332 }
1333
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 TEST_ASSERT(mbedtls_rsa_complete(&ctx) == res_complete);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001335
Hanno Beckere1582a82017-09-29 11:51:05 +01001336 /* On expected success, perform some public and private
1337 * key operations to check if the key is working properly. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 if (res_complete == 0) {
1339 if (is_priv) {
1340 TEST_ASSERT(mbedtls_rsa_check_privkey(&ctx) == res_check);
1341 } else {
1342 TEST_ASSERT(mbedtls_rsa_check_pubkey(&ctx) == res_check);
1343 }
Hanno Becker04877a42017-10-11 10:01:33 +01001344
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 if (res_check != 0) {
Hanno Becker04877a42017-10-11 10:01:33 +01001346 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 }
Hanno Beckere1582a82017-09-29 11:51:05 +01001348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 buf_orig = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1350 buf_enc = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1351 buf_dec = mbedtls_calloc(1, mbedtls_rsa_get_len(&ctx));
1352 if (buf_orig == NULL || buf_enc == NULL || buf_dec == NULL) {
Hanno Beckere1582a82017-09-29 11:51:05 +01001353 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001354 }
Hanno Beckere1582a82017-09-29 11:51:05 +01001355
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001356 /* This test uses an insecure RNG, suitable only for testing.
1357 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 TEST_ASSERT(mbedtls_test_rnd_std_rand(NULL,
1359 buf_orig, mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001360
1361 /* Make sure the number we're generating is smaller than the modulus */
1362 buf_orig[0] = 0x00;
1363
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 TEST_ASSERT(mbedtls_rsa_public(&ctx, buf_orig, buf_enc) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001365
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 if (is_priv) {
Manuel Pégourié-Gonnard5ef4e8d2022-07-16 08:57:19 +02001367 /* This test uses an insecure RNG, suitable only for testing.
1368 * In production, always use a cryptographically strong RNG! */
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 TEST_ASSERT(mbedtls_rsa_private(&ctx, mbedtls_test_rnd_std_rand,
1370 NULL, buf_enc,
1371 buf_dec) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001372
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 TEST_ASSERT(memcmp(buf_orig, buf_dec,
1374 mbedtls_rsa_get_len(&ctx)) == 0);
Hanno Beckere1582a82017-09-29 11:51:05 +01001375 }
1376 }
1377
Hanno Beckerc77ab892017-08-23 11:01:06 +01001378exit:
1379
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 mbedtls_free(buf_orig);
1381 mbedtls_free(buf_enc);
1382 mbedtls_free(buf_dec);
Hanno Becker3f3ae852017-10-02 10:08:39 +01001383
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 mbedtls_rsa_free(&ctx);
Hanno Beckerc77ab892017-08-23 11:01:06 +01001385}
1386/* END_CASE */
1387
Valerio Setti8e6093d2024-01-23 15:19:07 +01001388/* BEGIN_CASE */
Valerio Setti6d597f12024-01-24 13:44:41 +01001389void rsa_parse_pkcs1_key(int is_public, data_t *input, int exp_ret_val)
Valerio Setti6def24c2024-01-24 12:33:04 +01001390{
1391 mbedtls_rsa_context rsa_ctx;
Valerio Setti6d597f12024-01-24 13:44:41 +01001392
Valerio Setti6def24c2024-01-24 12:33:04 +01001393 mbedtls_rsa_init(&rsa_ctx);
1394
Valerio Setti6d597f12024-01-24 13:44:41 +01001395 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001396 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), exp_ret_val);
Valerio Setti6d597f12024-01-24 13:44:41 +01001397 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001398 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), exp_ret_val);
Valerio Setti6d597f12024-01-24 13:44:41 +01001399 }
Valerio Setti6def24c2024-01-24 12:33:04 +01001400
1401exit:
1402 mbedtls_rsa_free(&rsa_ctx);
1403}
1404/* END_CASE */
1405
1406/* BEGIN_CASE */
Valerio Setti1533c3f2024-01-24 11:24:20 +01001407void rsa_parse_write_pkcs1_key(int is_public, data_t *input)
Valerio Setti8e6093d2024-01-23 15:19:07 +01001408{
1409 mbedtls_rsa_context rsa_ctx;
Valerio Setti8e6093d2024-01-23 15:19:07 +01001410 unsigned char *output_buf = NULL;
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001411 unsigned char *output_end, *output_p;
1412 size_t output_len;
Valerio Setti8e6093d2024-01-23 15:19:07 +01001413
1414 mbedtls_rsa_init(&rsa_ctx);
1415
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001416 TEST_CALLOC(output_buf, input->len);
1417 output_end = output_buf + input->len;
1418 output_p = output_end;
1419
Valerio Setti1533c3f2024-01-24 11:24:20 +01001420 /* Parse the key and write it back to output_buf. */
Valerio Setti8e6093d2024-01-23 15:19:07 +01001421 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001422 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001423 TEST_EQUAL(mbedtls_rsa_write_pubkey(&rsa_ctx, output_buf, &output_p), input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001424 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001425 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001426 TEST_EQUAL(mbedtls_rsa_write_key(&rsa_ctx, output_buf, &output_p), input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001427 }
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001428 output_len = output_end - output_p;
Valerio Setti1533c3f2024-01-24 11:24:20 +01001429
1430 /* Check that the written key matches with the one provided in input. */
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001431 TEST_MEMORY_COMPARE(output_p, output_len, input->x, input->len);
Valerio Setti8e6093d2024-01-23 15:19:07 +01001432
1433exit:
1434 mbedtls_free(output_buf);
1435 mbedtls_rsa_free(&rsa_ctx);
1436}
1437/* END_CASE */
1438
Valerio Settia8886452024-01-30 17:35:49 +01001439/* BEGIN_CASE */
1440void rsa_key_write_incremental(int is_public, data_t *input)
1441{
1442 mbedtls_rsa_context rsa_ctx;
Valerio Settic701cb22024-02-02 11:09:37 +01001443 unsigned char *buf = NULL, *end, *p;
1444 size_t i, written_data;
Valerio Settia8886452024-01-30 17:35:49 +01001445
1446 mbedtls_rsa_init(&rsa_ctx);
1447
1448 /* This is supposed to succeed as the real target of this test are the
1449 * write attempt below. */
1450 if (is_public) {
Valerio Setti201e6432024-02-01 17:19:37 +01001451 TEST_EQUAL(mbedtls_rsa_parse_pubkey(&rsa_ctx, input->x, input->len), 0);
Valerio Settia8886452024-01-30 17:35:49 +01001452 } else {
Valerio Setti135ebde2024-02-01 17:00:29 +01001453 TEST_EQUAL(mbedtls_rsa_parse_key(&rsa_ctx, input->x, input->len), 0);
Valerio Settia8886452024-01-30 17:35:49 +01001454 }
1455
Valerio Settic701cb22024-02-02 11:09:37 +01001456 /* Test with an output buffer smaller than required. */
Valerio Settia8886452024-01-30 17:35:49 +01001457 for (i = 1; i < input->len; i++) {
1458 TEST_CALLOC(buf, i);
1459 end = buf + i;
Valerio Settic701cb22024-02-02 11:09:37 +01001460 p = end;
Valerio Settia8886452024-01-30 17:35:49 +01001461 /* We don't care much about the return value as long as it fails. */
1462 if (is_public) {
Valerio Settic701cb22024-02-02 11:09:37 +01001463 TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) != 0);
Valerio Settia8886452024-01-30 17:35:49 +01001464 } else {
Valerio Settic701cb22024-02-02 11:09:37 +01001465 TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) != 0);
Valerio Settia8886452024-01-30 17:35:49 +01001466 }
1467 mbedtls_free(buf);
1468 buf = NULL;
1469 }
1470
Valerio Settic701cb22024-02-02 11:09:37 +01001471 /* Test with an output buffer equal or larger than what it is strictly required. */
1472 for (i = input->len; i < (2 * input->len); i++) {
1473 TEST_CALLOC(buf, i);
1474 end = buf + i;
1475 p = end;
1476 /* This time all write functions must succeed. */
1477 if (is_public) {
1478 TEST_ASSERT(mbedtls_rsa_write_pubkey(&rsa_ctx, buf, &p) > 0);
1479 } else {
1480 TEST_ASSERT(mbedtls_rsa_write_key(&rsa_ctx, buf, &p) > 0);
1481 }
1482 written_data = (end - p);
1483 TEST_MEMORY_COMPARE(p, written_data, input->x, input->len);
1484 mbedtls_free(buf);
1485 buf = NULL;
Valerio Settia8886452024-01-30 17:35:49 +01001486 }
1487
1488exit:
Valerio Setti56cfe2f2024-02-01 17:53:26 +01001489 mbedtls_free(buf);
Valerio Settia8886452024-01-30 17:35:49 +01001490 mbedtls_rsa_free(&rsa_ctx);
1491}
1492/* END_CASE */
1493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001495void rsa_selftest()
Paul Bakker42a29bf2009-07-07 20:18:41 +00001496{
Manuel Pégourié-Gonnardfb8d90a2023-03-16 10:47:59 +01001497 MD_PSA_INIT();
Gilles Peskine449bd832023-01-11 14:50:10 +01001498 TEST_ASSERT(mbedtls_rsa_self_test(1) == 0);
Manuel Pégourié-Gonnardfb8d90a2023-03-16 10:47:59 +01001499
1500exit:
1501 MD_PSA_DONE();
Paul Bakker42a29bf2009-07-07 20:18:41 +00001502}
Paul Bakker33b43f12013-08-20 11:48:36 +02001503/* END_CASE */