blob: 470495dff5f5af926d054c58eb8293761da17d64 [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/ecdsa.h"
Paul Bakker33b43f12013-08-20 11:48:36 +02003/* END_HEADER */
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +01004
Paul Bakker33b43f12013-08-20 11:48:36 +02005/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02006 * depends_on:MBEDTLS_ECDSA_C
Paul Bakker33b43f12013-08-20 11:48:36 +02007 * END_DEPENDENCIES
8 */
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +01009
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050010/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010011void ecdsa_invalid_param()
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050012{
13 mbedtls_ecdsa_context ctx;
14 mbedtls_ecp_keypair key;
15 mbedtls_ecp_group grp;
16 mbedtls_ecp_group_id valid_group = MBEDTLS_ECP_DP_SECP192R1;
17 mbedtls_ecp_point P;
18 mbedtls_md_type_t valid_md = MBEDTLS_MD_SHA256;
19 mbedtls_mpi m;
20 size_t slen;
21 unsigned char buf[42] = { 0 };
22
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010023 mbedtls_ecdsa_init(&ctx);
24 mbedtls_ecp_keypair_init(&key);
25 mbedtls_ecp_group_init(&grp);
26 mbedtls_ecp_point_init(&P);
27 mbedtls_mpi_init(&m);
Gabor Mezei1b5800d2022-09-28 15:45:59 +020028
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010029 TEST_INVALID_PARAM(mbedtls_ecdsa_init(NULL));
30 TEST_VALID_PARAM(mbedtls_ecdsa_free(NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050031
32#if defined(MBEDTLS_ECP_RESTARTABLE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010033 TEST_INVALID_PARAM(mbedtls_ecdsa_restart_init(NULL));
34 TEST_VALID_PARAM(mbedtls_ecdsa_restart_free(NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050035#endif /* MBEDTLS_ECP_RESTARTABLE */
36
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010037 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
38 mbedtls_ecdsa_sign(NULL, &m, &m, &m,
39 buf, sizeof(buf),
40 mbedtls_test_rnd_std_rand,
41 NULL));
42 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
43 mbedtls_ecdsa_sign(&grp, NULL, &m, &m,
44 buf, sizeof(buf),
45 mbedtls_test_rnd_std_rand,
46 NULL));
47 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
48 mbedtls_ecdsa_sign(&grp, &m, NULL, &m,
49 buf, sizeof(buf),
50 mbedtls_test_rnd_std_rand,
51 NULL));
52 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
53 mbedtls_ecdsa_sign(&grp, &m, &m, NULL,
54 buf, sizeof(buf),
55 mbedtls_test_rnd_std_rand,
56 NULL));
57 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
58 mbedtls_ecdsa_sign(&grp, &m, &m, &m,
59 NULL, sizeof(buf),
60 mbedtls_test_rnd_std_rand,
61 NULL));
62 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
63 mbedtls_ecdsa_sign(&grp, &m, &m, &m,
64 buf, sizeof(buf),
65 NULL, NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050066
67#if defined(MBEDTLS_ECDSA_DETERMINISTIC)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010068 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
69 mbedtls_ecdsa_sign_det_ext(NULL, &m, &m, &m,
70 buf, sizeof(buf),
71 valid_md,
72 mbedtls_test_rnd_std_rand,
73 NULL));
74 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
75 mbedtls_ecdsa_sign_det_ext(&grp, NULL, &m, &m,
76 buf, sizeof(buf),
77 valid_md,
78 mbedtls_test_rnd_std_rand,
79 NULL));
80 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
81 mbedtls_ecdsa_sign_det_ext(&grp, &m, NULL, &m,
82 buf, sizeof(buf),
83 valid_md,
84 mbedtls_test_rnd_std_rand,
85 NULL));
86 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
87 mbedtls_ecdsa_sign_det_ext(&grp, &m, &m, NULL,
88 buf, sizeof(buf),
89 valid_md,
90 mbedtls_test_rnd_std_rand,
91 NULL));
92 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
93 mbedtls_ecdsa_sign_det_ext(&grp, &m, &m, &m,
94 NULL, sizeof(buf),
95 valid_md,
96 mbedtls_test_rnd_std_rand,
97 NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -050098#endif /* MBEDTLS_ECDSA_DETERMINISTIC */
99
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100100 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
101 mbedtls_ecdsa_verify(NULL,
102 buf, sizeof(buf),
103 &P, &m, &m));
104 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
105 mbedtls_ecdsa_verify(&grp,
106 NULL, sizeof(buf),
107 &P, &m, &m));
108 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
109 mbedtls_ecdsa_verify(&grp,
110 buf, sizeof(buf),
111 NULL, &m, &m));
112 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
113 mbedtls_ecdsa_verify(&grp,
114 buf, sizeof(buf),
115 &P, NULL, &m));
116 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
117 mbedtls_ecdsa_verify(&grp,
118 buf, sizeof(buf),
119 &P, &m, NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100121 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
122 mbedtls_ecdsa_write_signature(NULL, valid_md, buf, sizeof(buf),
123 buf, &slen, mbedtls_test_rnd_std_rand,
124 NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100126 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
127 mbedtls_ecdsa_write_signature(&ctx, valid_md, NULL, sizeof(buf),
128 buf, &slen, mbedtls_test_rnd_std_rand,
129 NULL));
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100131 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
132 mbedtls_ecdsa_write_signature(&ctx, valid_md, buf, sizeof(buf),
133 NULL, &slen, mbedtls_test_rnd_std_rand,
134 NULL));
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200135
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100136 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
137 mbedtls_ecdsa_write_signature(&ctx, valid_md, buf, sizeof(buf),
138 buf, NULL, mbedtls_test_rnd_std_rand,
139 NULL));
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100141 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
142 mbedtls_ecdsa_write_signature_restartable(NULL, valid_md, buf,
143 sizeof(buf), buf, &slen,
144 mbedtls_test_rnd_std_rand,
145 NULL, NULL));
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200146
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
148 mbedtls_ecdsa_write_signature_restartable(&ctx, valid_md, NULL,
149 sizeof(buf), buf, &slen,
150 mbedtls_test_rnd_std_rand,
151 NULL, NULL));
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200152
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100153 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
154 mbedtls_ecdsa_write_signature_restartable(&ctx, valid_md, buf,
155 sizeof(buf), NULL, &slen,
156 mbedtls_test_rnd_std_rand,
157 NULL, NULL));
Ronald Cron6c5bd7f2020-06-10 14:08:26 +0200158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100159 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
160 mbedtls_ecdsa_write_signature_restartable(&ctx, valid_md, buf,
161 sizeof(buf), buf, NULL,
162 mbedtls_test_rnd_std_rand,
163 NULL, NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500164
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100165 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
166 mbedtls_ecdsa_read_signature(NULL,
167 buf, sizeof(buf),
168 buf, sizeof(buf)));
169 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
170 mbedtls_ecdsa_read_signature(&ctx,
171 NULL, sizeof(buf),
172 buf, sizeof(buf)));
173 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
174 mbedtls_ecdsa_read_signature(&ctx,
175 buf, sizeof(buf),
176 NULL, sizeof(buf)));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100178 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
179 mbedtls_ecdsa_read_signature_restartable(NULL,
180 buf, sizeof(buf),
181 buf, sizeof(buf),
182 NULL));
183 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
184 mbedtls_ecdsa_read_signature_restartable(&ctx,
185 NULL, sizeof(buf),
186 buf, sizeof(buf),
187 NULL));
188 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
189 mbedtls_ecdsa_read_signature_restartable(&ctx,
190 buf, sizeof(buf),
191 NULL, sizeof(buf),
192 NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500193
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100194 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
195 mbedtls_ecdsa_genkey(NULL, valid_group,
196 mbedtls_test_rnd_std_rand,
197 NULL));
198 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
199 mbedtls_ecdsa_genkey(&ctx, valid_group,
200 NULL, NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500201
202
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100203 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
204 mbedtls_ecdsa_from_keypair(NULL, &key));
205 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
206 mbedtls_ecdsa_from_keypair(&ctx, NULL));
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500207
208exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 mbedtls_ecdsa_free(&ctx);
210 mbedtls_ecp_keypair_free(&key);
211 mbedtls_ecp_group_free(&grp);
212 mbedtls_ecp_point_free(&P);
213 mbedtls_mpi_free(&m);
Gabor Mezei1b5800d2022-09-28 15:45:59 +0200214
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500215 return;
216}
217/* END_CASE */
218
Paul Bakker33b43f12013-08-20 11:48:36 +0200219/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100220void ecdsa_prim_zero(int id)
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100221{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200222 mbedtls_ecp_group grp;
223 mbedtls_ecp_point Q;
224 mbedtls_mpi d, r, s;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200225 mbedtls_test_rnd_pseudo_info rnd_info;
Andrzej Kurekc470b6b2019-01-31 08:20:20 -0500226 unsigned char buf[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100227
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100228 mbedtls_ecp_group_init(&grp);
229 mbedtls_ecp_point_init(&Q);
230 mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
231 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
232 memset(buf, 0, sizeof(buf));
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100233
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
235 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
236 &mbedtls_test_rnd_pseudo_rand,
237 &rnd_info) == 0);
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100238
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100239 TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, buf, sizeof(buf),
240 &mbedtls_test_rnd_pseudo_rand,
241 &rnd_info) == 0);
242 TEST_ASSERT(mbedtls_ecdsa_verify(&grp, buf, sizeof(buf), &Q, &r, &s) == 0);
TRodziewicz5feb6702021-04-06 19:55:17 +0200243
TRodziewicz40de3c92021-04-07 19:16:18 +0200244exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100245 mbedtls_ecp_group_free(&grp);
246 mbedtls_ecp_point_free(&Q);
247 mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
TRodziewicz40de3c92021-04-07 19:16:18 +0200248}
249/* END_CASE */
250
251/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100252void ecdsa_prim_random(int id)
TRodziewicz40de3c92021-04-07 19:16:18 +0200253{
254 mbedtls_ecp_group grp;
255 mbedtls_ecp_point Q;
256 mbedtls_mpi d, r, s;
257 mbedtls_test_rnd_pseudo_info rnd_info;
258 unsigned char buf[MBEDTLS_MD_MAX_SIZE];
259
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 mbedtls_ecp_group_init(&grp);
261 mbedtls_ecp_point_init(&Q);
262 mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
263 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
264 memset(buf, 0, sizeof(buf));
TRodziewicz40de3c92021-04-07 19:16:18 +0200265
266 /* prepare material for signature */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100267 TEST_ASSERT(mbedtls_test_rnd_pseudo_rand(&rnd_info,
268 buf, sizeof(buf)) == 0);
269 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
270 TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
271 &mbedtls_test_rnd_pseudo_rand,
272 &rnd_info) == 0);
TRodziewicz40de3c92021-04-07 19:16:18 +0200273
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100274 TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, buf, sizeof(buf),
275 &mbedtls_test_rnd_pseudo_rand,
276 &rnd_info) == 0);
277 TEST_ASSERT(mbedtls_ecdsa_verify(&grp, buf, sizeof(buf), &Q, &r, &s) == 0);
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100278
Paul Bakkerbd51b262014-07-10 15:26:12 +0200279exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100280 mbedtls_ecp_group_free(&grp);
281 mbedtls_ecp_point_free(&Q);
282 mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
Manuel Pégourié-Gonnardd1c71502013-01-26 19:09:07 +0100283}
Paul Bakker33b43f12013-08-20 11:48:36 +0200284/* END_CASE */
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100285
Paul Bakker33b43f12013-08-20 11:48:36 +0200286/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100287void ecdsa_prim_test_vectors(int id, char *d_str, char *xQ_str,
288 char *yQ_str, data_t *rnd_buf,
289 data_t *hash, char *r_str, char *s_str,
290 int result)
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100291{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 mbedtls_ecp_group grp;
293 mbedtls_ecp_point Q;
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200294 mbedtls_mpi d, r, s, r_check, s_check, zero;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200295 mbedtls_test_rnd_buf_info rnd_info;
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100296
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100297 mbedtls_ecp_group_init(&grp);
298 mbedtls_ecp_point_init(&Q);
299 mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
300 mbedtls_mpi_init(&r_check); mbedtls_mpi_init(&s_check);
301 mbedtls_mpi_init(&zero);
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100302
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100303 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
304 TEST_ASSERT(mbedtls_ecp_point_read_string(&Q, 16, xQ_str, yQ_str) == 0);
305 TEST_ASSERT(mbedtls_test_read_mpi(&d, d_str) == 0);
306 TEST_ASSERT(mbedtls_test_read_mpi(&r_check, r_str) == 0);
307 TEST_ASSERT(mbedtls_test_read_mpi(&s_check, s_str) == 0);
Gilles Peskinebef30192021-03-24 00:48:57 +0100308 rnd_info.fallback_f_rng = mbedtls_test_rnd_std_rand;
309 rnd_info.fallback_p_rng = NULL;
Azim Khand30ca132017-06-09 04:32:58 +0100310 rnd_info.buf = rnd_buf->x;
311 rnd_info.length = rnd_buf->len;
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100312
Azim Khand30ca132017-06-09 04:32:58 +0100313 /* Fix rnd_buf->x by shifting it left if necessary */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314 if (grp.nbits % 8 != 0) {
315 unsigned char shift = 8 - (grp.nbits % 8);
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100316 size_t i;
317
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100318 for (i = 0; i < rnd_info.length - 1; i++) {
319 rnd_buf->x[i] = rnd_buf->x[i] << shift | rnd_buf->x[i+1] >> (8 - shift);
320 }
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100321
Azim Khand30ca132017-06-09 04:32:58 +0100322 rnd_buf->x[rnd_info.length-1] <<= shift;
Manuel Pégourié-Gonnardfae079e2014-01-06 11:00:07 +0100323 }
324
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100325 TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, hash->x, hash->len,
326 mbedtls_test_rnd_buffer_rand, &rnd_info) == result);
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100327
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100328 if (result == 0) {
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200329 /* Check we generated the expected values */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100330 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&r, &r_check), 0);
331 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&s, &s_check), 0);
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100332
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200333 /* Valid signature */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100334 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len,
335 &Q, &r_check, &s_check), 0);
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200336
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200337 /* Invalid signature: wrong public key (G instead of Q) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len,
339 &grp.G, &r_check, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
Manuel Pégourié-Gonnardd0a66cc2018-06-13 09:53:21 +0200340
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200341 /* Invalid signatures: r or s or both one off */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100342 TEST_EQUAL(mbedtls_mpi_sub_int(&r, &r_check, 1), 0);
343 TEST_EQUAL(mbedtls_mpi_add_int(&s, &s_check, 1), 0);
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200344
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
346 &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
347 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
348 &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
349 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
350 &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200351
352 /* Invalid signatures: r, s or both (CVE-2022-21449) are zero */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100353 TEST_EQUAL(mbedtls_mpi_lset(&zero, 0), 0);
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200354
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100355 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
356 &zero, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
357 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
358 &r_check, &zero), MBEDTLS_ERR_ECP_VERIFY_FAILED);
359 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
360 &zero, &zero), MBEDTLS_ERR_ECP_VERIFY_FAILED);
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200361
362 /* Invalid signatures: r, s or both are == N */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100363 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
364 &grp.N, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
365 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
366 &r_check, &grp.N), MBEDTLS_ERR_ECP_VERIFY_FAILED);
367 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
368 &grp.N, &grp.N), MBEDTLS_ERR_ECP_VERIFY_FAILED);
Manuel Pégourié-Gonnard5aeb61c2022-04-21 09:25:23 +0200369
370 /* Invalid signatures: r, s or both are negative */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100371 TEST_EQUAL(mbedtls_mpi_sub_mpi(&r, &r_check, &grp.N), 0);
372 TEST_EQUAL(mbedtls_mpi_sub_mpi(&s, &s_check, &grp.N), 0);
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200373
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100374 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
375 &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
376 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
377 &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
378 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
379 &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200380
381 /* Invalid signatures: r or s or both are > N */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100382 TEST_EQUAL(mbedtls_mpi_add_mpi(&r, &r_check, &grp.N), 0);
383 TEST_EQUAL(mbedtls_mpi_add_mpi(&s, &s_check, &grp.N), 0);
Manuel Pégourié-Gonnardbcaba032022-04-20 10:34:22 +0200384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
386 &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
387 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
388 &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
389 TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
390 &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
Darryl Greenf5bcbed2017-11-17 17:09:31 +0000391 }
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100392
Paul Bakkerbd51b262014-07-10 15:26:12 +0200393exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100394 mbedtls_ecp_group_free(&grp);
395 mbedtls_ecp_point_free(&Q);
396 mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
397 mbedtls_mpi_free(&r_check); mbedtls_mpi_free(&s_check);
398 mbedtls_mpi_free(&zero);
Manuel Pégourié-Gonnard602a8972013-01-27 08:10:28 +0100399}
Paul Bakker33b43f12013-08-20 11:48:36 +0200400/* END_CASE */
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100403void ecdsa_det_test_vectors(int id, char *d_str, int md_alg, char *msg,
404 char *r_str, char *s_str)
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100405{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 mbedtls_ecp_group grp;
407 mbedtls_mpi d, r, s, r_check, s_check;
408 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100409 size_t hlen;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100411
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100412 mbedtls_ecp_group_init(&grp);
413 mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
414 mbedtls_mpi_init(&r_check); mbedtls_mpi_init(&s_check);
415 memset(hash, 0, sizeof(hash));
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100416
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100417 TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
418 TEST_ASSERT(mbedtls_test_read_mpi(&d, d_str) == 0);
419 TEST_ASSERT(mbedtls_test_read_mpi(&r_check, r_str) == 0);
420 TEST_ASSERT(mbedtls_test_read_mpi(&s_check, s_str) == 0);
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100421
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100422 md_info = mbedtls_md_info_from_type(md_alg);
423 TEST_ASSERT(md_info != NULL);
424 hlen = mbedtls_md_get_size(md_info);
425 TEST_ASSERT(mbedtls_md(md_info, (const unsigned char *) msg,
426 strlen(msg), hash) == 0);
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100427
Janos Follath651eac82019-01-04 15:51:24 +0000428 TEST_ASSERT(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 mbedtls_ecdsa_sign_det_ext(&grp, &r, &s, &d, hash, hlen,
430 md_alg, mbedtls_test_rnd_std_rand,
431 NULL)
432 == 0);
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100433
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100434 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&r, &r_check) == 0);
435 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&s, &s_check) == 0);
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100436
Paul Bakkerbd51b262014-07-10 15:26:12 +0200437exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 mbedtls_ecp_group_free(&grp);
439 mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
440 mbedtls_mpi_free(&r_check); mbedtls_mpi_free(&s_check);
Manuel Pégourié-Gonnard4daaef72014-01-06 14:25:56 +0100441}
442/* END_CASE */
443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100445void ecdsa_write_read_zero(int id)
TRodziewicz40de3c92021-04-07 19:16:18 +0200446{
447 mbedtls_ecdsa_context ctx;
448 mbedtls_test_rnd_pseudo_info rnd_info;
449 unsigned char hash[32];
450 unsigned char sig[200];
451 size_t sig_len, i;
452
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100453 mbedtls_ecdsa_init(&ctx);
454 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
455 memset(hash, 0, sizeof(hash));
456 memset(sig, 0x2a, sizeof(sig));
TRodziewicz40de3c92021-04-07 19:16:18 +0200457
458 /* generate signing key */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100459 TEST_ASSERT(mbedtls_ecdsa_genkey(&ctx, id,
460 &mbedtls_test_rnd_pseudo_rand,
461 &rnd_info) == 0);
TRodziewicz40de3c92021-04-07 19:16:18 +0200462
463 /* generate and write signature, then read and verify it */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100464 TEST_ASSERT(mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256,
465 hash, sizeof(hash),
466 sig, &sig_len, &mbedtls_test_rnd_pseudo_rand,
467 &rnd_info) == 0);
468 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
469 sig, sig_len) == 0);
TRodziewicz40de3c92021-04-07 19:16:18 +0200470
471 /* check we didn't write past the announced length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100472 for (i = sig_len; i < sizeof(sig); i++) {
473 TEST_ASSERT(sig[i] == 0x2a);
474 }
TRodziewicz40de3c92021-04-07 19:16:18 +0200475
476 /* try verification with invalid length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100477 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
478 sig, sig_len - 1) != 0);
479 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
480 sig, sig_len + 1) != 0);
TRodziewicz40de3c92021-04-07 19:16:18 +0200481
482 /* try invalid sequence tag */
483 sig[0]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100484 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
485 sig, sig_len) != 0);
TRodziewicz40de3c92021-04-07 19:16:18 +0200486 sig[0]--;
487
488 /* try modifying r */
489 sig[10]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100490 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
491 sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
TRodziewicz40de3c92021-04-07 19:16:18 +0200492 sig[10]--;
493
494 /* try modifying s */
495 sig[sig_len - 1]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
497 sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
TRodziewicz40de3c92021-04-07 19:16:18 +0200498 sig[sig_len - 1]--;
499
500exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100501 mbedtls_ecdsa_free(&ctx);
TRodziewicz40de3c92021-04-07 19:16:18 +0200502}
503/* END_CASE */
504
505/* BEGIN_CASE depends_on:MBEDTLS_SHA256_C */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506void ecdsa_write_read_random(int id)
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200507{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 mbedtls_ecdsa_context ctx;
Ronald Cron351f0ee2020-06-10 12:12:18 +0200509 mbedtls_test_rnd_pseudo_info rnd_info;
Manuel Pégourié-Gonnarddfdcac92015-03-31 11:41:42 +0200510 unsigned char hash[32];
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200511 unsigned char sig[200];
512 size_t sig_len, i;
513
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 mbedtls_ecdsa_init(&ctx);
515 memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
516 memset(hash, 0, sizeof(hash));
517 memset(sig, 0x2a, sizeof(sig));
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200518
TRodziewicz40de3c92021-04-07 19:16:18 +0200519 /* prepare material for signature */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100520 TEST_ASSERT(mbedtls_test_rnd_pseudo_rand(&rnd_info,
521 hash, sizeof(hash)) == 0);
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200522
TRodziewicz40de3c92021-04-07 19:16:18 +0200523 /* generate signing key */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100524 TEST_ASSERT(mbedtls_ecdsa_genkey(&ctx, id,
525 &mbedtls_test_rnd_pseudo_rand,
526 &rnd_info) == 0);
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200527
TRodziewicz40de3c92021-04-07 19:16:18 +0200528 /* generate and write signature, then read and verify it */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100529 TEST_ASSERT(mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256,
530 hash, sizeof(hash),
531 sig, &sig_len, &mbedtls_test_rnd_pseudo_rand,
532 &rnd_info) == 0);
533 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
534 sig, sig_len) == 0);
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200535
TRodziewicz40de3c92021-04-07 19:16:18 +0200536 /* check we didn't write past the announced length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100537 for (i = sig_len; i < sizeof(sig); i++) {
538 TEST_ASSERT(sig[i] == 0x2a);
539 }
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200540
TRodziewicz40de3c92021-04-07 19:16:18 +0200541 /* try verification with invalid length */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100542 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
543 sig, sig_len - 1) != 0);
544 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
545 sig, sig_len + 1) != 0);
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200546
TRodziewicz40de3c92021-04-07 19:16:18 +0200547 /* try invalid sequence tag */
548 sig[0]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100549 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
550 sig, sig_len) != 0);
TRodziewicz40de3c92021-04-07 19:16:18 +0200551 sig[0]--;
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200552
TRodziewicz40de3c92021-04-07 19:16:18 +0200553 /* try modifying r */
554 sig[10]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100555 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
556 sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
TRodziewicz40de3c92021-04-07 19:16:18 +0200557 sig[10]--;
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200558
TRodziewicz40de3c92021-04-07 19:16:18 +0200559 /* try modifying s */
560 sig[sig_len - 1]++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100561 TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
562 sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
TRodziewicz40de3c92021-04-07 19:16:18 +0200563 sig[sig_len - 1]--;
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200564
Paul Bakkerbd51b262014-07-10 15:26:12 +0200565exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100566 mbedtls_ecdsa_free(&ctx);
Manuel Pégourié-Gonnardb694b482013-08-08 13:30:57 +0200567}
568/* END_CASE */
Manuel Pégourié-Gonnard937340b2014-01-06 10:27:16 +0100569
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200570/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571void ecdsa_read_restart(int id, data_t *pk, data_t *hash, data_t *sig,
572 int max_ops, int min_restart, int max_restart)
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200573{
574 mbedtls_ecdsa_context ctx;
575 mbedtls_ecdsa_restart_ctx rs_ctx;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200576 int ret, cnt_restart;
577
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100578 mbedtls_ecdsa_init(&ctx);
579 mbedtls_ecdsa_restart_init(&rs_ctx);
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200580
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100581 TEST_ASSERT(mbedtls_ecp_group_load(&ctx.grp, id) == 0);
582 TEST_ASSERT(mbedtls_ecp_point_read_binary(&ctx.grp, &ctx.Q,
583 pk->x, pk->len) == 0);
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200584
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100585 mbedtls_ecp_set_max_ops(max_ops);
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200586
587 cnt_restart = 0;
588 do {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100589 ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
590 hash->x, hash->len, sig->x, sig->len,
591 &rs_ctx);
592 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200593
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594 TEST_ASSERT(ret == 0);
595 TEST_ASSERT(cnt_restart >= min_restart);
596 TEST_ASSERT(cnt_restart <= max_restart);
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200597
598 /* try modifying r */
Ronald Cron9ed40732020-06-25 09:03:34 +0200599
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100600 TEST_ASSERT(sig->len > 10);
Ronald Cron9ed40732020-06-25 09:03:34 +0200601 sig->x[10]++;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200602 do {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603 ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
604 hash->x, hash->len, sig->x, sig->len,
605 &rs_ctx);
606 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
607 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_VERIFY_FAILED);
Ronald Cron9ed40732020-06-25 09:03:34 +0200608 sig->x[10]--;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200609
610 /* try modifying s */
Ronald Cron9ed40732020-06-25 09:03:34 +0200611 sig->x[sig->len - 1]++;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200612 do {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100613 ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
614 hash->x, hash->len, sig->x, sig->len,
615 &rs_ctx);
616 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
617 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_VERIFY_FAILED);
Ronald Cron9ed40732020-06-25 09:03:34 +0200618 sig->x[sig->len - 1]--;
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200619
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200620 /* Do we leak memory when aborting an operation?
621 * This test only makes sense when we actually restart */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100622 if (min_restart > 0) {
623 ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
624 hash->x, hash->len, sig->x, sig->len,
625 &rs_ctx);
626 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200627 }
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200628
629exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100630 mbedtls_ecdsa_free(&ctx);
631 mbedtls_ecdsa_restart_free(&rs_ctx);
Manuel Pégourié-Gonnard722e5152017-04-21 11:04:47 +0200632}
633/* END_CASE */
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200634
635/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_DETERMINISTIC */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100636void ecdsa_write_restart(int id, char *d_str, int md_alg,
637 char *msg, data_t *sig_check,
638 int max_ops, int min_restart, int max_restart)
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200639{
640 int ret, cnt_restart;
641 mbedtls_ecdsa_restart_ctx rs_ctx;
642 mbedtls_ecdsa_context ctx;
643 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
644 unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
Ronald Cron9ed40732020-06-25 09:03:34 +0200645 size_t hlen, slen;
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200646 const mbedtls_md_info_t *md_info;
647
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100648 mbedtls_ecdsa_restart_init(&rs_ctx);
649 mbedtls_ecdsa_init(&ctx);
650 memset(hash, 0, sizeof(hash));
651 memset(sig, 0, sizeof(sig));
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200652
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100653 TEST_ASSERT(mbedtls_ecp_group_load(&ctx.grp, id) == 0);
654 TEST_ASSERT(mbedtls_test_read_mpi(&ctx.d, d_str) == 0);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200655
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100656 md_info = mbedtls_md_info_from_type(md_alg);
657 TEST_ASSERT(md_info != NULL);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200658
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100659 hlen = mbedtls_md_get_size(md_info);
660 TEST_ASSERT(mbedtls_md(md_info,
661 (const unsigned char *) msg, strlen(msg),
662 hash) == 0);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200663
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100664 mbedtls_ecp_set_max_ops(max_ops);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200665
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100666 slen = sizeof(sig);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200667 cnt_restart = 0;
668 do {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100669 ret = mbedtls_ecdsa_write_signature_restartable(&ctx,
670 md_alg,
671 hash,
672 hlen,
673 sig,
674 &slen,
675 NULL,
676 NULL,
677 &rs_ctx);
678 } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200679
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100680 TEST_ASSERT(ret == 0);
681 TEST_ASSERT(slen == sig_check->len);
682 TEST_ASSERT(memcmp(sig, sig_check->x, slen) == 0);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200683
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100684 TEST_ASSERT(cnt_restart >= min_restart);
685 TEST_ASSERT(cnt_restart <= max_restart);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200686
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200687 /* Do we leak memory when aborting an operation?
688 * This test only makes sense when we actually restart */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100689 if (min_restart > 0) {
690 ret = mbedtls_ecdsa_write_signature_restartable(&ctx,
691 md_alg,
692 hash,
693 hlen,
694 sig,
695 &slen,
696 NULL,
697 NULL,
698 &rs_ctx);
699 TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
Manuel Pégourié-Gonnard46ba7f32017-08-28 12:20:39 +0200700 }
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200701
702exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100703 mbedtls_ecdsa_restart_free(&rs_ctx);
704 mbedtls_ecdsa_free(&ctx);
Manuel Pégourié-Gonnardeb402f32017-04-25 10:57:30 +0200705}
706/* END_CASE */
Dave Rodgman535dcce2022-08-10 11:32:07 +0100707
708/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100709void ecdsa_verify(int grp_id, char *x, char *y, char *r, char *s, data_t *content, int expected)
Dave Rodgman535dcce2022-08-10 11:32:07 +0100710{
Dave Rodgman535dcce2022-08-10 11:32:07 +0100711 mbedtls_ecdsa_context ctx;
712 mbedtls_mpi sig_r, sig_s;
Dave Rodgman535dcce2022-08-10 11:32:07 +0100713
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 mbedtls_ecdsa_init(&ctx);
715 mbedtls_mpi_init(&sig_r);
716 mbedtls_mpi_init(&sig_s);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100717
718 /* Prepare ECP group context */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100719 TEST_EQUAL(mbedtls_ecp_group_load(&ctx.grp, grp_id), 0);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100720
721 /* Prepare public key */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100722 TEST_EQUAL(mbedtls_test_read_mpi(&ctx.Q.X, x), 0);
723 TEST_EQUAL(mbedtls_test_read_mpi(&ctx.Q.Y, y), 0);
724 TEST_EQUAL(mbedtls_mpi_lset(&ctx.Q.Z, 1), 0);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100725
726 /* Prepare signature R & S */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100727 TEST_EQUAL(mbedtls_test_read_mpi(&sig_r, r), 0);
728 TEST_EQUAL(mbedtls_test_read_mpi(&sig_s, s), 0);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100729
730 /* Test whether public key has expected validity */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100731 TEST_EQUAL(mbedtls_ecp_check_pubkey(&ctx.grp, &ctx.Q),
732 expected == MBEDTLS_ERR_ECP_INVALID_KEY ? MBEDTLS_ERR_ECP_INVALID_KEY : 0);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100733
734 /* Verification */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100735 int result = mbedtls_ecdsa_verify(&ctx.grp, content->x, content->len, &ctx.Q, &sig_r, &sig_s);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100736
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100737 TEST_EQUAL(result, expected);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100738exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100739 mbedtls_ecdsa_free(&ctx);
740 mbedtls_mpi_free(&sig_r);
741 mbedtls_mpi_free(&sig_s);
Dave Rodgman535dcce2022-08-10 11:32:07 +0100742}
Dave Rodgmanc763e172022-08-10 12:21:23 +0100743/* END_CASE */