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