1a8e1175bSopenharmony_ci/* BEGIN_HEADER */
2a8e1175bSopenharmony_ci#include "mbedtls/ecdsa.h"
3a8e1175bSopenharmony_ci/* END_HEADER */
4a8e1175bSopenharmony_ci
5a8e1175bSopenharmony_ci/* BEGIN_DEPENDENCIES
6a8e1175bSopenharmony_ci * depends_on:MBEDTLS_ECDSA_C
7a8e1175bSopenharmony_ci * END_DEPENDENCIES
8a8e1175bSopenharmony_ci */
9a8e1175bSopenharmony_ci
10a8e1175bSopenharmony_ci/* BEGIN_CASE */
11a8e1175bSopenharmony_civoid ecdsa_prim_zero(int id)
12a8e1175bSopenharmony_ci{
13a8e1175bSopenharmony_ci    mbedtls_ecp_group grp;
14a8e1175bSopenharmony_ci    mbedtls_ecp_point Q;
15a8e1175bSopenharmony_ci    mbedtls_mpi d, r, s;
16a8e1175bSopenharmony_ci    mbedtls_test_rnd_pseudo_info rnd_info;
17a8e1175bSopenharmony_ci    unsigned char buf[MBEDTLS_MD_MAX_SIZE];
18a8e1175bSopenharmony_ci
19a8e1175bSopenharmony_ci    mbedtls_ecp_group_init(&grp);
20a8e1175bSopenharmony_ci    mbedtls_ecp_point_init(&Q);
21a8e1175bSopenharmony_ci    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
22a8e1175bSopenharmony_ci    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
23a8e1175bSopenharmony_ci    memset(buf, 0, sizeof(buf));
24a8e1175bSopenharmony_ci
25a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
26a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
27a8e1175bSopenharmony_ci                                        &mbedtls_test_rnd_pseudo_rand,
28a8e1175bSopenharmony_ci                                        &rnd_info) == 0);
29a8e1175bSopenharmony_ci
30a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, buf, sizeof(buf),
31a8e1175bSopenharmony_ci                                   &mbedtls_test_rnd_pseudo_rand,
32a8e1175bSopenharmony_ci                                   &rnd_info) == 0);
33a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_verify(&grp, buf, sizeof(buf), &Q, &r, &s) == 0);
34a8e1175bSopenharmony_ci
35a8e1175bSopenharmony_ciexit:
36a8e1175bSopenharmony_ci    mbedtls_ecp_group_free(&grp);
37a8e1175bSopenharmony_ci    mbedtls_ecp_point_free(&Q);
38a8e1175bSopenharmony_ci    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
39a8e1175bSopenharmony_ci}
40a8e1175bSopenharmony_ci/* END_CASE */
41a8e1175bSopenharmony_ci
42a8e1175bSopenharmony_ci/* BEGIN_CASE */
43a8e1175bSopenharmony_civoid ecdsa_prim_random(int id)
44a8e1175bSopenharmony_ci{
45a8e1175bSopenharmony_ci    mbedtls_ecp_group grp;
46a8e1175bSopenharmony_ci    mbedtls_ecp_point Q;
47a8e1175bSopenharmony_ci    mbedtls_mpi d, r, s;
48a8e1175bSopenharmony_ci    mbedtls_test_rnd_pseudo_info rnd_info;
49a8e1175bSopenharmony_ci    unsigned char buf[MBEDTLS_MD_MAX_SIZE];
50a8e1175bSopenharmony_ci
51a8e1175bSopenharmony_ci    mbedtls_ecp_group_init(&grp);
52a8e1175bSopenharmony_ci    mbedtls_ecp_point_init(&Q);
53a8e1175bSopenharmony_ci    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
54a8e1175bSopenharmony_ci    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
55a8e1175bSopenharmony_ci    memset(buf, 0, sizeof(buf));
56a8e1175bSopenharmony_ci
57a8e1175bSopenharmony_ci    /* prepare material for signature */
58a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_rnd_pseudo_rand(&rnd_info,
59a8e1175bSopenharmony_ci                                             buf, sizeof(buf)) == 0);
60a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
61a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
62a8e1175bSopenharmony_ci                                        &mbedtls_test_rnd_pseudo_rand,
63a8e1175bSopenharmony_ci                                        &rnd_info) == 0);
64a8e1175bSopenharmony_ci
65a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, buf, sizeof(buf),
66a8e1175bSopenharmony_ci                                   &mbedtls_test_rnd_pseudo_rand,
67a8e1175bSopenharmony_ci                                   &rnd_info) == 0);
68a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_verify(&grp, buf, sizeof(buf), &Q, &r, &s) == 0);
69a8e1175bSopenharmony_ci
70a8e1175bSopenharmony_ciexit:
71a8e1175bSopenharmony_ci    mbedtls_ecp_group_free(&grp);
72a8e1175bSopenharmony_ci    mbedtls_ecp_point_free(&Q);
73a8e1175bSopenharmony_ci    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
74a8e1175bSopenharmony_ci}
75a8e1175bSopenharmony_ci/* END_CASE */
76a8e1175bSopenharmony_ci
77a8e1175bSopenharmony_ci/* BEGIN_CASE */
78a8e1175bSopenharmony_civoid ecdsa_prim_test_vectors(int id, char *d_str, char *xQ_str,
79a8e1175bSopenharmony_ci                             char *yQ_str, data_t *rnd_buf,
80a8e1175bSopenharmony_ci                             data_t *hash, char *r_str, char *s_str,
81a8e1175bSopenharmony_ci                             int result)
82a8e1175bSopenharmony_ci{
83a8e1175bSopenharmony_ci    mbedtls_ecp_group grp;
84a8e1175bSopenharmony_ci    mbedtls_ecp_point Q;
85a8e1175bSopenharmony_ci    mbedtls_mpi d, r, s, r_check, s_check, zero;
86a8e1175bSopenharmony_ci    mbedtls_test_rnd_buf_info rnd_info;
87a8e1175bSopenharmony_ci
88a8e1175bSopenharmony_ci    mbedtls_ecp_group_init(&grp);
89a8e1175bSopenharmony_ci    mbedtls_ecp_point_init(&Q);
90a8e1175bSopenharmony_ci    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
91a8e1175bSopenharmony_ci    mbedtls_mpi_init(&r_check); mbedtls_mpi_init(&s_check);
92a8e1175bSopenharmony_ci    mbedtls_mpi_init(&zero);
93a8e1175bSopenharmony_ci
94a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
95a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_point_read_string(&Q, 16, xQ_str, yQ_str) == 0);
96a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_read_mpi(&d, d_str) == 0);
97a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_read_mpi(&r_check, r_str) == 0);
98a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_read_mpi(&s_check, s_str) == 0);
99a8e1175bSopenharmony_ci    rnd_info.fallback_f_rng = mbedtls_test_rnd_std_rand;
100a8e1175bSopenharmony_ci    rnd_info.fallback_p_rng = NULL;
101a8e1175bSopenharmony_ci    rnd_info.buf = rnd_buf->x;
102a8e1175bSopenharmony_ci    rnd_info.length = rnd_buf->len;
103a8e1175bSopenharmony_ci
104a8e1175bSopenharmony_ci    /* Fix rnd_buf->x by shifting it left if necessary */
105a8e1175bSopenharmony_ci    if (grp.nbits % 8 != 0) {
106a8e1175bSopenharmony_ci        unsigned char shift = 8 - (grp.nbits % 8);
107a8e1175bSopenharmony_ci        size_t i;
108a8e1175bSopenharmony_ci
109a8e1175bSopenharmony_ci        for (i = 0; i < rnd_info.length - 1; i++) {
110a8e1175bSopenharmony_ci            rnd_buf->x[i] = rnd_buf->x[i] << shift | rnd_buf->x[i+1] >> (8 - shift);
111a8e1175bSopenharmony_ci        }
112a8e1175bSopenharmony_ci
113a8e1175bSopenharmony_ci        rnd_buf->x[rnd_info.length-1] <<= shift;
114a8e1175bSopenharmony_ci    }
115a8e1175bSopenharmony_ci
116a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_sign(&grp, &r, &s, &d, hash->x, hash->len,
117a8e1175bSopenharmony_ci                                   mbedtls_test_rnd_buffer_rand, &rnd_info) == result);
118a8e1175bSopenharmony_ci
119a8e1175bSopenharmony_ci    if (result == 0) {
120a8e1175bSopenharmony_ci        /* Check we generated the expected values */
121a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&r, &r_check), 0);
122a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&s, &s_check), 0);
123a8e1175bSopenharmony_ci
124a8e1175bSopenharmony_ci        /* Valid signature */
125a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len,
126a8e1175bSopenharmony_ci                                        &Q, &r_check, &s_check), 0);
127a8e1175bSopenharmony_ci
128a8e1175bSopenharmony_ci        /* Invalid signature: wrong public key (G instead of Q) */
129a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len,
130a8e1175bSopenharmony_ci                                        &grp.G, &r_check, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
131a8e1175bSopenharmony_ci
132a8e1175bSopenharmony_ci        /* Invalid signatures: r or s or both one off */
133a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_sub_int(&r, &r_check, 1), 0);
134a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_add_int(&s, &s_check, 1), 0);
135a8e1175bSopenharmony_ci
136a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
137a8e1175bSopenharmony_ci                                        &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
138a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
139a8e1175bSopenharmony_ci                                        &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
140a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
141a8e1175bSopenharmony_ci                                        &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
142a8e1175bSopenharmony_ci
143a8e1175bSopenharmony_ci        /* Invalid signatures: r, s or both (CVE-2022-21449) are zero */
144a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_lset(&zero, 0), 0);
145a8e1175bSopenharmony_ci
146a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
147a8e1175bSopenharmony_ci                                        &zero, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
148a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
149a8e1175bSopenharmony_ci                                        &r_check, &zero), MBEDTLS_ERR_ECP_VERIFY_FAILED);
150a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
151a8e1175bSopenharmony_ci                                        &zero, &zero), MBEDTLS_ERR_ECP_VERIFY_FAILED);
152a8e1175bSopenharmony_ci
153a8e1175bSopenharmony_ci        /* Invalid signatures: r, s or both are == N */
154a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
155a8e1175bSopenharmony_ci                                        &grp.N, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
156a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
157a8e1175bSopenharmony_ci                                        &r_check, &grp.N), MBEDTLS_ERR_ECP_VERIFY_FAILED);
158a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
159a8e1175bSopenharmony_ci                                        &grp.N, &grp.N), MBEDTLS_ERR_ECP_VERIFY_FAILED);
160a8e1175bSopenharmony_ci
161a8e1175bSopenharmony_ci        /* Invalid signatures: r, s or both are negative */
162a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_sub_mpi(&r, &r_check, &grp.N), 0);
163a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_sub_mpi(&s, &s_check, &grp.N), 0);
164a8e1175bSopenharmony_ci
165a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
166a8e1175bSopenharmony_ci                                        &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
167a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
168a8e1175bSopenharmony_ci                                        &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
169a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
170a8e1175bSopenharmony_ci                                        &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
171a8e1175bSopenharmony_ci
172a8e1175bSopenharmony_ci        /* Invalid signatures: r or s or both are > N */
173a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_add_mpi(&r, &r_check, &grp.N), 0);
174a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_mpi_add_mpi(&s, &s_check, &grp.N), 0);
175a8e1175bSopenharmony_ci
176a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
177a8e1175bSopenharmony_ci                                        &r, &s_check), MBEDTLS_ERR_ECP_VERIFY_FAILED);
178a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
179a8e1175bSopenharmony_ci                                        &r_check, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
180a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_ecdsa_verify(&grp, hash->x, hash->len, &Q,
181a8e1175bSopenharmony_ci                                        &r, &s), MBEDTLS_ERR_ECP_VERIFY_FAILED);
182a8e1175bSopenharmony_ci    }
183a8e1175bSopenharmony_ci
184a8e1175bSopenharmony_ciexit:
185a8e1175bSopenharmony_ci    mbedtls_ecp_group_free(&grp);
186a8e1175bSopenharmony_ci    mbedtls_ecp_point_free(&Q);
187a8e1175bSopenharmony_ci    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
188a8e1175bSopenharmony_ci    mbedtls_mpi_free(&r_check); mbedtls_mpi_free(&s_check);
189a8e1175bSopenharmony_ci    mbedtls_mpi_free(&zero);
190a8e1175bSopenharmony_ci}
191a8e1175bSopenharmony_ci/* END_CASE */
192a8e1175bSopenharmony_ci
193a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_ECDSA_DETERMINISTIC */
194a8e1175bSopenharmony_civoid ecdsa_det_test_vectors(int id, char *d_str, int md_alg, data_t *hash,
195a8e1175bSopenharmony_ci                            char *r_str, char *s_str)
196a8e1175bSopenharmony_ci{
197a8e1175bSopenharmony_ci    mbedtls_ecp_group grp;
198a8e1175bSopenharmony_ci    mbedtls_mpi d, r, s, r_check, s_check;
199a8e1175bSopenharmony_ci
200a8e1175bSopenharmony_ci    MD_PSA_INIT();
201a8e1175bSopenharmony_ci
202a8e1175bSopenharmony_ci    mbedtls_ecp_group_init(&grp);
203a8e1175bSopenharmony_ci    mbedtls_mpi_init(&d); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s);
204a8e1175bSopenharmony_ci    mbedtls_mpi_init(&r_check); mbedtls_mpi_init(&s_check);
205a8e1175bSopenharmony_ci
206a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
207a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_read_mpi(&d, d_str) == 0);
208a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_read_mpi(&r_check, r_str) == 0);
209a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_read_mpi(&s_check, s_str) == 0);
210a8e1175bSopenharmony_ci
211a8e1175bSopenharmony_ci    TEST_ASSERT(
212a8e1175bSopenharmony_ci        mbedtls_ecdsa_sign_det_ext(&grp, &r, &s, &d,
213a8e1175bSopenharmony_ci                                   hash->x, hash->len, md_alg,
214a8e1175bSopenharmony_ci                                   mbedtls_test_rnd_std_rand,
215a8e1175bSopenharmony_ci                                   NULL)
216a8e1175bSopenharmony_ci        == 0);
217a8e1175bSopenharmony_ci
218a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&r, &r_check) == 0);
219a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&s, &s_check) == 0);
220a8e1175bSopenharmony_ci
221a8e1175bSopenharmony_ciexit:
222a8e1175bSopenharmony_ci    mbedtls_ecp_group_free(&grp);
223a8e1175bSopenharmony_ci    mbedtls_mpi_free(&d); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s);
224a8e1175bSopenharmony_ci    mbedtls_mpi_free(&r_check); mbedtls_mpi_free(&s_check);
225a8e1175bSopenharmony_ci    MD_PSA_DONE();
226a8e1175bSopenharmony_ci}
227a8e1175bSopenharmony_ci/* END_CASE */
228a8e1175bSopenharmony_ci
229a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_MD_CAN_SHA256 */
230a8e1175bSopenharmony_civoid ecdsa_write_read_zero(int id)
231a8e1175bSopenharmony_ci{
232a8e1175bSopenharmony_ci    mbedtls_ecdsa_context ctx;
233a8e1175bSopenharmony_ci    mbedtls_test_rnd_pseudo_info rnd_info;
234a8e1175bSopenharmony_ci    unsigned char hash[32];
235a8e1175bSopenharmony_ci    unsigned char sig[200];
236a8e1175bSopenharmony_ci    size_t sig_len, i;
237a8e1175bSopenharmony_ci
238a8e1175bSopenharmony_ci    MD_PSA_INIT();
239a8e1175bSopenharmony_ci
240a8e1175bSopenharmony_ci    mbedtls_ecdsa_init(&ctx);
241a8e1175bSopenharmony_ci    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
242a8e1175bSopenharmony_ci    memset(hash, 0, sizeof(hash));
243a8e1175bSopenharmony_ci    memset(sig, 0x2a, sizeof(sig));
244a8e1175bSopenharmony_ci
245a8e1175bSopenharmony_ci    /* generate signing key */
246a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_genkey(&ctx, id,
247a8e1175bSopenharmony_ci                                     &mbedtls_test_rnd_pseudo_rand,
248a8e1175bSopenharmony_ci                                     &rnd_info) == 0);
249a8e1175bSopenharmony_ci
250a8e1175bSopenharmony_ci    /* generate and write signature, then read and verify it */
251a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256,
252a8e1175bSopenharmony_ci                                              hash, sizeof(hash),
253a8e1175bSopenharmony_ci                                              sig, sizeof(sig), &sig_len,
254a8e1175bSopenharmony_ci                                              &mbedtls_test_rnd_pseudo_rand,
255a8e1175bSopenharmony_ci                                              &rnd_info) == 0);
256a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
257a8e1175bSopenharmony_ci                                             sig, sig_len) == 0);
258a8e1175bSopenharmony_ci
259a8e1175bSopenharmony_ci    /* check we didn't write past the announced length */
260a8e1175bSopenharmony_ci    for (i = sig_len; i < sizeof(sig); i++) {
261a8e1175bSopenharmony_ci        TEST_ASSERT(sig[i] == 0x2a);
262a8e1175bSopenharmony_ci    }
263a8e1175bSopenharmony_ci
264a8e1175bSopenharmony_ci    /* try verification with invalid length */
265a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
266a8e1175bSopenharmony_ci                                             sig, sig_len - 1) != 0);
267a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
268a8e1175bSopenharmony_ci                                             sig, sig_len + 1) != 0);
269a8e1175bSopenharmony_ci
270a8e1175bSopenharmony_ci    /* try invalid sequence tag */
271a8e1175bSopenharmony_ci    sig[0]++;
272a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
273a8e1175bSopenharmony_ci                                             sig, sig_len) != 0);
274a8e1175bSopenharmony_ci    sig[0]--;
275a8e1175bSopenharmony_ci
276a8e1175bSopenharmony_ci    /* try modifying r */
277a8e1175bSopenharmony_ci    sig[10]++;
278a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
279a8e1175bSopenharmony_ci                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
280a8e1175bSopenharmony_ci    sig[10]--;
281a8e1175bSopenharmony_ci
282a8e1175bSopenharmony_ci    /* try modifying s */
283a8e1175bSopenharmony_ci    sig[sig_len - 1]++;
284a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
285a8e1175bSopenharmony_ci                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
286a8e1175bSopenharmony_ci    sig[sig_len - 1]--;
287a8e1175bSopenharmony_ci
288a8e1175bSopenharmony_ciexit:
289a8e1175bSopenharmony_ci    mbedtls_ecdsa_free(&ctx);
290a8e1175bSopenharmony_ci    MD_PSA_DONE();
291a8e1175bSopenharmony_ci}
292a8e1175bSopenharmony_ci/* END_CASE */
293a8e1175bSopenharmony_ci
294a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_MD_CAN_SHA256 */
295a8e1175bSopenharmony_civoid ecdsa_write_read_random(int id)
296a8e1175bSopenharmony_ci{
297a8e1175bSopenharmony_ci    mbedtls_ecdsa_context ctx;
298a8e1175bSopenharmony_ci    mbedtls_test_rnd_pseudo_info rnd_info;
299a8e1175bSopenharmony_ci    unsigned char hash[32];
300a8e1175bSopenharmony_ci    unsigned char sig[200];
301a8e1175bSopenharmony_ci    size_t sig_len, i;
302a8e1175bSopenharmony_ci
303a8e1175bSopenharmony_ci    MD_PSA_INIT();
304a8e1175bSopenharmony_ci
305a8e1175bSopenharmony_ci    mbedtls_ecdsa_init(&ctx);
306a8e1175bSopenharmony_ci    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
307a8e1175bSopenharmony_ci    memset(hash, 0, sizeof(hash));
308a8e1175bSopenharmony_ci    memset(sig, 0x2a, sizeof(sig));
309a8e1175bSopenharmony_ci
310a8e1175bSopenharmony_ci    /* prepare material for signature */
311a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_rnd_pseudo_rand(&rnd_info,
312a8e1175bSopenharmony_ci                                             hash, sizeof(hash)) == 0);
313a8e1175bSopenharmony_ci
314a8e1175bSopenharmony_ci    /* generate signing key */
315a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_genkey(&ctx, id,
316a8e1175bSopenharmony_ci                                     &mbedtls_test_rnd_pseudo_rand,
317a8e1175bSopenharmony_ci                                     &rnd_info) == 0);
318a8e1175bSopenharmony_ci
319a8e1175bSopenharmony_ci    /* generate and write signature, then read and verify it */
320a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_write_signature(&ctx, MBEDTLS_MD_SHA256,
321a8e1175bSopenharmony_ci                                              hash, sizeof(hash),
322a8e1175bSopenharmony_ci                                              sig, sizeof(sig), &sig_len,
323a8e1175bSopenharmony_ci                                              &mbedtls_test_rnd_pseudo_rand,
324a8e1175bSopenharmony_ci                                              &rnd_info) == 0);
325a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
326a8e1175bSopenharmony_ci                                             sig, sig_len) == 0);
327a8e1175bSopenharmony_ci
328a8e1175bSopenharmony_ci    /* check we didn't write past the announced length */
329a8e1175bSopenharmony_ci    for (i = sig_len; i < sizeof(sig); i++) {
330a8e1175bSopenharmony_ci        TEST_ASSERT(sig[i] == 0x2a);
331a8e1175bSopenharmony_ci    }
332a8e1175bSopenharmony_ci
333a8e1175bSopenharmony_ci    /* try verification with invalid length */
334a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
335a8e1175bSopenharmony_ci                                             sig, sig_len - 1) != 0);
336a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
337a8e1175bSopenharmony_ci                                             sig, sig_len + 1) != 0);
338a8e1175bSopenharmony_ci
339a8e1175bSopenharmony_ci    /* try invalid sequence tag */
340a8e1175bSopenharmony_ci    sig[0]++;
341a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
342a8e1175bSopenharmony_ci                                             sig, sig_len) != 0);
343a8e1175bSopenharmony_ci    sig[0]--;
344a8e1175bSopenharmony_ci
345a8e1175bSopenharmony_ci    /* try modifying r */
346a8e1175bSopenharmony_ci    sig[10]++;
347a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
348a8e1175bSopenharmony_ci                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
349a8e1175bSopenharmony_ci    sig[10]--;
350a8e1175bSopenharmony_ci
351a8e1175bSopenharmony_ci    /* try modifying s */
352a8e1175bSopenharmony_ci    sig[sig_len - 1]++;
353a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecdsa_read_signature(&ctx, hash, sizeof(hash),
354a8e1175bSopenharmony_ci                                             sig, sig_len) == MBEDTLS_ERR_ECP_VERIFY_FAILED);
355a8e1175bSopenharmony_ci    sig[sig_len - 1]--;
356a8e1175bSopenharmony_ci
357a8e1175bSopenharmony_ciexit:
358a8e1175bSopenharmony_ci    mbedtls_ecdsa_free(&ctx);
359a8e1175bSopenharmony_ci    MD_PSA_DONE();
360a8e1175bSopenharmony_ci}
361a8e1175bSopenharmony_ci/* END_CASE */
362a8e1175bSopenharmony_ci
363a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
364a8e1175bSopenharmony_civoid ecdsa_read_restart(int id, data_t *pk, data_t *hash, data_t *sig,
365a8e1175bSopenharmony_ci                        int max_ops, int min_restart, int max_restart)
366a8e1175bSopenharmony_ci{
367a8e1175bSopenharmony_ci    mbedtls_ecdsa_context ctx;
368a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_ctx rs_ctx;
369a8e1175bSopenharmony_ci    int ret, cnt_restart;
370a8e1175bSopenharmony_ci
371a8e1175bSopenharmony_ci    mbedtls_ecdsa_init(&ctx);
372a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_init(&rs_ctx);
373a8e1175bSopenharmony_ci
374a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_group_load(&ctx.grp, id) == 0);
375a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_point_read_binary(&ctx.grp, &ctx.Q,
376a8e1175bSopenharmony_ci                                              pk->x, pk->len) == 0);
377a8e1175bSopenharmony_ci
378a8e1175bSopenharmony_ci    mbedtls_ecp_set_max_ops(max_ops);
379a8e1175bSopenharmony_ci
380a8e1175bSopenharmony_ci    cnt_restart = 0;
381a8e1175bSopenharmony_ci    do {
382a8e1175bSopenharmony_ci        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
383a8e1175bSopenharmony_ci                                                       hash->x, hash->len, sig->x, sig->len,
384a8e1175bSopenharmony_ci                                                       &rs_ctx);
385a8e1175bSopenharmony_ci    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
386a8e1175bSopenharmony_ci
387a8e1175bSopenharmony_ci    TEST_ASSERT(ret == 0);
388a8e1175bSopenharmony_ci    TEST_ASSERT(cnt_restart >= min_restart);
389a8e1175bSopenharmony_ci    TEST_ASSERT(cnt_restart <= max_restart);
390a8e1175bSopenharmony_ci
391a8e1175bSopenharmony_ci    /* try modifying r */
392a8e1175bSopenharmony_ci
393a8e1175bSopenharmony_ci    TEST_ASSERT(sig->len > 10);
394a8e1175bSopenharmony_ci    sig->x[10]++;
395a8e1175bSopenharmony_ci    do {
396a8e1175bSopenharmony_ci        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
397a8e1175bSopenharmony_ci                                                       hash->x, hash->len, sig->x, sig->len,
398a8e1175bSopenharmony_ci                                                       &rs_ctx);
399a8e1175bSopenharmony_ci    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
400a8e1175bSopenharmony_ci    TEST_ASSERT(ret == MBEDTLS_ERR_ECP_VERIFY_FAILED);
401a8e1175bSopenharmony_ci    sig->x[10]--;
402a8e1175bSopenharmony_ci
403a8e1175bSopenharmony_ci    /* try modifying s */
404a8e1175bSopenharmony_ci    sig->x[sig->len - 1]++;
405a8e1175bSopenharmony_ci    do {
406a8e1175bSopenharmony_ci        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
407a8e1175bSopenharmony_ci                                                       hash->x, hash->len, sig->x, sig->len,
408a8e1175bSopenharmony_ci                                                       &rs_ctx);
409a8e1175bSopenharmony_ci    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
410a8e1175bSopenharmony_ci    TEST_ASSERT(ret == MBEDTLS_ERR_ECP_VERIFY_FAILED);
411a8e1175bSopenharmony_ci    sig->x[sig->len - 1]--;
412a8e1175bSopenharmony_ci
413a8e1175bSopenharmony_ci    /* Do we leak memory when aborting an operation?
414a8e1175bSopenharmony_ci     * This test only makes sense when we actually restart */
415a8e1175bSopenharmony_ci    if (min_restart > 0) {
416a8e1175bSopenharmony_ci        ret = mbedtls_ecdsa_read_signature_restartable(&ctx,
417a8e1175bSopenharmony_ci                                                       hash->x, hash->len, sig->x, sig->len,
418a8e1175bSopenharmony_ci                                                       &rs_ctx);
419a8e1175bSopenharmony_ci        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
420a8e1175bSopenharmony_ci    }
421a8e1175bSopenharmony_ci
422a8e1175bSopenharmony_ciexit:
423a8e1175bSopenharmony_ci    mbedtls_ecdsa_free(&ctx);
424a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_free(&rs_ctx);
425a8e1175bSopenharmony_ci}
426a8e1175bSopenharmony_ci/* END_CASE */
427a8e1175bSopenharmony_ci
428a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECDSA_DETERMINISTIC */
429a8e1175bSopenharmony_civoid ecdsa_write_restart(int id, char *d_str, int md_alg,
430a8e1175bSopenharmony_ci                         data_t *hash, data_t *sig_check,
431a8e1175bSopenharmony_ci                         int max_ops, int min_restart, int max_restart)
432a8e1175bSopenharmony_ci{
433a8e1175bSopenharmony_ci    int ret, cnt_restart;
434a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_ctx rs_ctx;
435a8e1175bSopenharmony_ci    mbedtls_ecdsa_context ctx;
436a8e1175bSopenharmony_ci    unsigned char sig[MBEDTLS_ECDSA_MAX_LEN];
437a8e1175bSopenharmony_ci    size_t slen;
438a8e1175bSopenharmony_ci
439a8e1175bSopenharmony_ci    MD_PSA_INIT();
440a8e1175bSopenharmony_ci
441a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_init(&rs_ctx);
442a8e1175bSopenharmony_ci    mbedtls_ecdsa_init(&ctx);
443a8e1175bSopenharmony_ci    memset(sig, 0, sizeof(sig));
444a8e1175bSopenharmony_ci
445a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_ecp_group_load(&ctx.grp, id) == 0);
446a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_test_read_mpi(&ctx.d, d_str) == 0);
447a8e1175bSopenharmony_ci
448a8e1175bSopenharmony_ci    mbedtls_ecp_set_max_ops(max_ops);
449a8e1175bSopenharmony_ci
450a8e1175bSopenharmony_ci    slen = sizeof(sig);
451a8e1175bSopenharmony_ci    cnt_restart = 0;
452a8e1175bSopenharmony_ci    do {
453a8e1175bSopenharmony_ci        ret = mbedtls_ecdsa_write_signature_restartable(&ctx,
454a8e1175bSopenharmony_ci                                                        md_alg,
455a8e1175bSopenharmony_ci                                                        hash->x,
456a8e1175bSopenharmony_ci                                                        hash->len,
457a8e1175bSopenharmony_ci                                                        sig,
458a8e1175bSopenharmony_ci                                                        sizeof(sig),
459a8e1175bSopenharmony_ci                                                        &slen,
460a8e1175bSopenharmony_ci                                                        mbedtls_test_rnd_std_rand,
461a8e1175bSopenharmony_ci                                                        NULL,
462a8e1175bSopenharmony_ci                                                        &rs_ctx);
463a8e1175bSopenharmony_ci    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restart);
464a8e1175bSopenharmony_ci
465a8e1175bSopenharmony_ci    TEST_ASSERT(ret == 0);
466a8e1175bSopenharmony_ci    TEST_ASSERT(slen == sig_check->len);
467a8e1175bSopenharmony_ci    TEST_ASSERT(memcmp(sig, sig_check->x, slen) == 0);
468a8e1175bSopenharmony_ci
469a8e1175bSopenharmony_ci    TEST_ASSERT(cnt_restart >= min_restart);
470a8e1175bSopenharmony_ci    TEST_ASSERT(cnt_restart <= max_restart);
471a8e1175bSopenharmony_ci
472a8e1175bSopenharmony_ci    /* Do we leak memory when aborting an operation?
473a8e1175bSopenharmony_ci     * This test only makes sense when we actually restart */
474a8e1175bSopenharmony_ci    if (min_restart > 0) {
475a8e1175bSopenharmony_ci        ret = mbedtls_ecdsa_write_signature_restartable(&ctx,
476a8e1175bSopenharmony_ci                                                        md_alg,
477a8e1175bSopenharmony_ci                                                        hash->x,
478a8e1175bSopenharmony_ci                                                        hash->len,
479a8e1175bSopenharmony_ci                                                        sig,
480a8e1175bSopenharmony_ci                                                        sizeof(sig),
481a8e1175bSopenharmony_ci                                                        &slen,
482a8e1175bSopenharmony_ci                                                        mbedtls_test_rnd_std_rand,
483a8e1175bSopenharmony_ci                                                        NULL,
484a8e1175bSopenharmony_ci                                                        &rs_ctx);
485a8e1175bSopenharmony_ci        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
486a8e1175bSopenharmony_ci    }
487a8e1175bSopenharmony_ci
488a8e1175bSopenharmony_ciexit:
489a8e1175bSopenharmony_ci    mbedtls_ecdsa_restart_free(&rs_ctx);
490a8e1175bSopenharmony_ci    mbedtls_ecdsa_free(&ctx);
491a8e1175bSopenharmony_ci    MD_PSA_DONE();
492a8e1175bSopenharmony_ci}
493a8e1175bSopenharmony_ci/* END_CASE */
494a8e1175bSopenharmony_ci
495a8e1175bSopenharmony_ci/* BEGIN_CASE */
496a8e1175bSopenharmony_civoid ecdsa_verify(int grp_id, char *x, char *y, char *r, char *s, data_t *content, int expected)
497a8e1175bSopenharmony_ci{
498a8e1175bSopenharmony_ci    mbedtls_ecdsa_context ctx;
499a8e1175bSopenharmony_ci    mbedtls_mpi sig_r, sig_s;
500a8e1175bSopenharmony_ci
501a8e1175bSopenharmony_ci    mbedtls_ecdsa_init(&ctx);
502a8e1175bSopenharmony_ci    mbedtls_mpi_init(&sig_r);
503a8e1175bSopenharmony_ci    mbedtls_mpi_init(&sig_s);
504a8e1175bSopenharmony_ci
505a8e1175bSopenharmony_ci    /* Prepare ECP group context */
506a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_ecp_group_load(&ctx.grp, grp_id), 0);
507a8e1175bSopenharmony_ci
508a8e1175bSopenharmony_ci    /* Prepare public key */
509a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_test_read_mpi(&ctx.Q.X, x), 0);
510a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_test_read_mpi(&ctx.Q.Y, y), 0);
511a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_mpi_lset(&ctx.Q.Z, 1), 0);
512a8e1175bSopenharmony_ci
513a8e1175bSopenharmony_ci    /* Prepare signature R & S */
514a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_test_read_mpi(&sig_r, r), 0);
515a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_test_read_mpi(&sig_s, s), 0);
516a8e1175bSopenharmony_ci
517a8e1175bSopenharmony_ci    /* Test whether public key has expected validity */
518a8e1175bSopenharmony_ci    TEST_EQUAL(mbedtls_ecp_check_pubkey(&ctx.grp, &ctx.Q),
519a8e1175bSopenharmony_ci               expected == MBEDTLS_ERR_ECP_INVALID_KEY ? MBEDTLS_ERR_ECP_INVALID_KEY : 0);
520a8e1175bSopenharmony_ci
521a8e1175bSopenharmony_ci    /* Verification */
522a8e1175bSopenharmony_ci    int result = mbedtls_ecdsa_verify(&ctx.grp, content->x, content->len, &ctx.Q, &sig_r, &sig_s);
523a8e1175bSopenharmony_ci
524a8e1175bSopenharmony_ci    TEST_EQUAL(result, expected);
525a8e1175bSopenharmony_ciexit:
526a8e1175bSopenharmony_ci    mbedtls_ecdsa_free(&ctx);
527a8e1175bSopenharmony_ci    mbedtls_mpi_free(&sig_r);
528a8e1175bSopenharmony_ci    mbedtls_mpi_free(&sig_s);
529a8e1175bSopenharmony_ci}
530a8e1175bSopenharmony_ci/* END_CASE */
531