| /* BEGIN_HEADER */ |
| #include "mbedtls/ecp.h" |
| |
| #include "ecp_invasive.h" |
| |
| #if defined(MBEDTLS_TEST_HOOKS) && \ |
| (defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ |
| defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ |
| defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)) |
| # define HAVE_FIX_NEGATIVE |
| #endif |
| |
| #define ECP_PF_UNKNOWN -1 |
| |
| #define ECP_PT_RESET(x) \ |
| mbedtls_ecp_point_free(x); \ |
| mbedtls_ecp_point_init(x); |
| |
| /* END_HEADER */ |
| |
| /* BEGIN_DEPENDENCIES |
| * depends_on:MBEDTLS_ECP_C |
| * END_DEPENDENCIES |
| */ |
| |
| /* BEGIN_CASE depends_on:NOT_DEFINED */ |
| void ecp_invalid_param() |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point P; |
| int invalid_fmt = 42; |
| size_t olen; |
| unsigned char buf[42] = { 0 }; |
| |
| TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA, |
| mbedtls_ecp_point_write_binary(&grp, &P, invalid_fmt, &olen, buf, |
| sizeof(buf))); |
| TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA, |
| mbedtls_ecp_tls_write_point(&grp, &P, invalid_fmt, &olen, buf, |
| sizeof(buf))); |
| |
| exit: |
| return; |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name) |
| { |
| const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name; |
| |
| by_id = mbedtls_ecp_curve_info_from_grp_id(id); |
| by_tls = mbedtls_ecp_curve_info_from_tls_id(tls_id); |
| by_name = mbedtls_ecp_curve_info_from_name(name); |
| TEST_ASSERT(by_id != NULL); |
| TEST_ASSERT(by_tls != NULL); |
| TEST_ASSERT(by_name != NULL); |
| |
| TEST_ASSERT(by_id == by_tls); |
| TEST_ASSERT(by_id == by_name); |
| |
| TEST_ASSERT(by_id->bit_size == size); |
| TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS); |
| TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex, int ret) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point P; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&P); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&P.X, 16, x_hex) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, 16, y_hex) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, 16, z_hex) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&P); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ |
| void ecp_test_vect_restart(int id, |
| char *dA_str, |
| char *xA_str, |
| char *yA_str, |
| char *dB_str, |
| char *xZ_str, |
| char *yZ_str, |
| int max_ops, |
| int min_restarts, |
| int max_restarts) |
| { |
| /* |
| * Test for early restart. Based on test vectors like ecp_test_vect(), |
| * but for the sake of simplicity only does half of each side. It's |
| * important to test both base point and random point, though, as memory |
| * management is different in each case. |
| * |
| * Don't try using too precise bounds for restarts as the exact number |
| * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and |
| * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may |
| * change in the future. A factor 2 is a minimum safety margin. |
| * |
| * For reference, with mbed TLS 2.4 and default settings, for P-256: |
| * - Random point mult: ~3250M |
| * - Cold base point mult: ~3300M |
| * - Hot base point mult: ~1100M |
| * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum): |
| * - Random point mult: ~3850M |
| */ |
| mbedtls_ecp_restart_ctx ctx; |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point R, P; |
| mbedtls_mpi dA, xA, yA, dB, xZ, yZ; |
| int cnt_restarts; |
| int ret; |
| mbedtls_test_rnd_pseudo_info rnd_info; |
| |
| mbedtls_ecp_restart_init(&ctx); |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&R); |
| mbedtls_ecp_point_init(&P); |
| mbedtls_mpi_init(&dA); |
| mbedtls_mpi_init(&xA); |
| mbedtls_mpi_init(&yA); |
| mbedtls_mpi_init(&dB); |
| mbedtls_mpi_init(&xZ); |
| mbedtls_mpi_init(&yZ); |
| memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&dA, 16, dA_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xA, 16, xA_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&yA, 16, yA_str) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&dB, 16, dB_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xZ, 16, xZ_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&yZ, 16, yZ_str) == 0); |
| |
| mbedtls_ecp_set_max_ops((unsigned)max_ops); |
| |
| /* Base point case */ |
| cnt_restarts = 0; |
| do { |
| ECP_PT_RESET(&R); |
| ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G, |
| &mbedtls_test_rnd_pseudo_rand, |
| &rnd_info, &ctx); |
| } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts); |
| |
| TEST_ASSERT(ret == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0); |
| |
| TEST_ASSERT(cnt_restarts >= min_restarts); |
| TEST_ASSERT(cnt_restarts <= max_restarts); |
| |
| /* Non-base point case */ |
| mbedtls_ecp_copy(&P, &R); |
| cnt_restarts = 0; |
| do { |
| ECP_PT_RESET(&R); |
| ret = mbedtls_ecp_mul_restartable( |
| &grp, &R, &dB, &P, &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx); |
| } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts); |
| |
| TEST_ASSERT(ret == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0); |
| |
| TEST_ASSERT(cnt_restarts >= min_restarts); |
| TEST_ASSERT(cnt_restarts <= max_restarts); |
| |
| /* Do we leak memory when aborting an operation? |
| * This test only makes sense when we actually restart */ |
| if (min_restarts > 0) { |
| ret = mbedtls_ecp_mul_restartable( |
| &grp, &R, &dB, &P, &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx); |
| TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS); |
| } |
| |
| exit: |
| mbedtls_ecp_restart_free(&ctx); |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&R); |
| mbedtls_ecp_point_free(&P); |
| mbedtls_mpi_free(&dA); |
| mbedtls_mpi_free(&xA); |
| mbedtls_mpi_free(&yA); |
| mbedtls_mpi_free(&dB); |
| mbedtls_mpi_free(&xZ); |
| mbedtls_mpi_free(&yZ); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */ |
| void ecp_muladd_restart(int id, |
| char *xR_str, |
| char *yR_str, |
| char *u1_str, |
| char *u2_str, |
| char *xQ_str, |
| char *yQ_str, |
| int max_ops, |
| int min_restarts, |
| int max_restarts) |
| { |
| /* |
| * Compute R = u1 * G + u2 * Q |
| * (test vectors mostly taken from ECDSA intermediate results) |
| * |
| * See comments at the top of ecp_test_vect_restart() |
| */ |
| mbedtls_ecp_restart_ctx ctx; |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point R, Q; |
| mbedtls_mpi u1, u2, xR, yR; |
| int cnt_restarts; |
| int ret; |
| |
| mbedtls_ecp_restart_init(&ctx); |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&R); |
| mbedtls_ecp_point_init(&Q); |
| mbedtls_mpi_init(&u1); |
| mbedtls_mpi_init(&u2); |
| mbedtls_mpi_init(&xR); |
| mbedtls_mpi_init(&yR); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&u1, 16, u1_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&u2, 16, u2_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xR, 16, xR_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&yR, 16, yR_str) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, 16, xQ_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, 16, yQ_str) == 0); |
| TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0); |
| |
| mbedtls_ecp_set_max_ops((unsigned)max_ops); |
| |
| cnt_restarts = 0; |
| do { |
| ECP_PT_RESET(&R); |
| ret = mbedtls_ecp_muladd_restartable(&grp, &R, &u1, &grp.G, &u2, &Q, |
| &ctx); |
| } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts); |
| |
| TEST_ASSERT(ret == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0); |
| |
| TEST_ASSERT(cnt_restarts >= min_restarts); |
| TEST_ASSERT(cnt_restarts <= max_restarts); |
| |
| /* Do we leak memory when aborting an operation? |
| * This test only makes sense when we actually restart */ |
| if (min_restarts > 0) { |
| ret = mbedtls_ecp_muladd_restartable(&grp, &R, &u1, &grp.G, &u2, &Q, |
| &ctx); |
| TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS); |
| } |
| |
| exit: |
| mbedtls_ecp_restart_free(&ctx); |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&R); |
| mbedtls_ecp_point_free(&Q); |
| mbedtls_mpi_free(&u1); |
| mbedtls_mpi_free(&u2); |
| mbedtls_mpi_free(&xR); |
| mbedtls_mpi_free(&yR); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_test_vect(int id, |
| char *dA_str, |
| char *xA_str, |
| char *yA_str, |
| char *dB_str, |
| char *xB_str, |
| char *yB_str, |
| char *xZ_str, |
| char *yZ_str) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point R; |
| mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ; |
| mbedtls_test_rnd_pseudo_info rnd_info; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&R); |
| mbedtls_mpi_init(&dA); |
| mbedtls_mpi_init(&xA); |
| mbedtls_mpi_init(&yA); |
| mbedtls_mpi_init(&dB); |
| mbedtls_mpi_init(&xB); |
| mbedtls_mpi_init(&yB); |
| mbedtls_mpi_init(&xZ); |
| mbedtls_mpi_init(&yZ); |
| memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&dA, 16, dA_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xA, 16, xA_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&yA, 16, yA_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&dB, 16, dB_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xB, 16, xB_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&yB, 16, yB_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xZ, 16, xZ_str) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&yZ, 16, yZ_str) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&R); |
| mbedtls_mpi_free(&dA); |
| mbedtls_mpi_free(&xA); |
| mbedtls_mpi_free(&yA); |
| mbedtls_mpi_free(&dB); |
| mbedtls_mpi_free(&xB); |
| mbedtls_mpi_free(&yB); |
| mbedtls_mpi_free(&xZ); |
| mbedtls_mpi_free(&yZ); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_test_vec_x(int id, |
| char *dA_hex, |
| char *xA_hex, |
| char *dB_hex, |
| char *xB_hex, |
| char *xS_hex) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point R; |
| mbedtls_mpi dA, xA, dB, xB, xS; |
| mbedtls_test_rnd_pseudo_info rnd_info; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&R); |
| mbedtls_mpi_init(&dA); |
| mbedtls_mpi_init(&xA); |
| mbedtls_mpi_init(&dB); |
| mbedtls_mpi_init(&xB); |
| mbedtls_mpi_init(&xS); |
| memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&dA, 16, dA_hex) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&dB, 16, dB_hex) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xA, 16, xA_hex) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xB, 16, xB_hex) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&xS, 16, xS_hex) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R, |
| &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&R); |
| mbedtls_mpi_free(&dA); |
| mbedtls_mpi_free(&xA); |
| mbedtls_mpi_free(&dB); |
| mbedtls_mpi_free(&xB); |
| mbedtls_mpi_free(&xS); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_test_mul(int id, |
| data_t *n_hex, |
| data_t *Px_hex, |
| data_t *Py_hex, |
| data_t *Pz_hex, |
| data_t *nPx_hex, |
| data_t *nPy_hex, |
| data_t *nPz_hex, |
| int expected_ret) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point P, nP, R; |
| mbedtls_mpi n; |
| mbedtls_test_rnd_pseudo_info rnd_info; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&R); |
| mbedtls_ecp_point_init(&P); |
| mbedtls_ecp_point_init(&nP); |
| mbedtls_mpi_init(&n); |
| memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0); |
| |
| TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0); |
| |
| TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0); |
| TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0); |
| TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0); |
| TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len) == 0); |
| TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len) == 0); |
| TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P, &mbedtls_test_rnd_pseudo_rand, |
| &rnd_info) == expected_ret); |
| |
| if (expected_ret == 0) { |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0); |
| } |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&R); |
| mbedtls_ecp_point_free(&P); |
| mbedtls_ecp_point_free(&nP); |
| mbedtls_mpi_free(&n); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_test_mul_rng(int id, data_t *d_hex) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_mpi d; |
| mbedtls_ecp_point Q; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_mpi_init(&d); |
| mbedtls_ecp_point_init(&Q); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0); |
| |
| TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G, |
| &mbedtls_test_rnd_zero_rand, |
| NULL) == MBEDTLS_ERR_ECP_RANDOM_FAILED); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_mpi_free(&d); |
| mbedtls_ecp_point_free(&Q); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ |
| void ecp_muladd(int id, |
| data_t *u1_bin, |
| data_t *P1_bin, |
| data_t *u2_bin, |
| data_t *P2_bin, |
| data_t *expected_result) |
| { |
| /* Compute R = u1 * P1 + u2 * P2 */ |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point P1, P2, R; |
| mbedtls_mpi u1, u2; |
| uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN]; |
| size_t len; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&P1); |
| mbedtls_ecp_point_init(&P2); |
| mbedtls_ecp_point_init(&R); |
| mbedtls_mpi_init(&u1); |
| mbedtls_mpi_init(&u2); |
| |
| TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id)); |
| TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len)); |
| TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len)); |
| TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1, P1_bin->x, |
| P1_bin->len)); |
| TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2, P2_bin->x, |
| P2_bin->len)); |
| |
| TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2)); |
| TEST_EQUAL(0, mbedtls_ecp_point_write_binary( |
| &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED, &len, |
| actual_result, sizeof(actual_result))); |
| TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN); |
| |
| ASSERT_COMPARE(expected_result->x, expected_result->len, actual_result, |
| len); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&P1); |
| mbedtls_ecp_point_free(&P2); |
| mbedtls_ecp_point_free(&R); |
| mbedtls_mpi_free(&u1); |
| mbedtls_mpi_free(&u2); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_fast_mod(int id, char *N_str) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_mpi N, R; |
| |
| mbedtls_mpi_init(&N); |
| mbedtls_mpi_init(&R); |
| mbedtls_ecp_group_init(&grp); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&N, 16, N_str) == 0); |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| TEST_ASSERT(grp.modp != NULL); |
| |
| /* |
| * Store correct result before we touch N |
| */ |
| TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0); |
| |
| TEST_ASSERT(grp.modp(&N) == 0); |
| TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3); |
| |
| /* |
| * Use mod rather than addition/subtraction in case previous test fails |
| */ |
| TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0); |
| |
| exit: |
| mbedtls_mpi_free(&N); |
| mbedtls_mpi_free(&R); |
| mbedtls_ecp_group_free(&grp); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_write_binary(int id, |
| char *x, |
| char *y, |
| char *z, |
| int format, |
| data_t *out, |
| int blen, |
| int ret) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point P; |
| unsigned char buf[256]; |
| size_t olen; |
| |
| memset(buf, 0, sizeof(buf)); |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&P); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&P.X, 16, x) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, 16, y) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, 16, z) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format, &olen, buf, |
| blen) == ret); |
| |
| if (ret == 0) { |
| TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN); |
| TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0); |
| } |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&P); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z, int ret) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point P; |
| mbedtls_mpi X, Y, Z; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&P); |
| mbedtls_mpi_init(&X); |
| mbedtls_mpi_init(&Y); |
| mbedtls_mpi_init(&Z); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, x) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&Y, 16, y) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&Z, 16, z) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == |
| ret); |
| |
| if (ret == 0) { |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0); |
| if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) { |
| TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0); |
| TEST_ASSERT(P.Y.p == NULL); |
| TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0); |
| } else { |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0); |
| } |
| } |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&P); |
| mbedtls_mpi_free(&X); |
| mbedtls_mpi_free(&Y); |
| mbedtls_mpi_free(&Z); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_tls_read_point(int id, |
| data_t *buf, |
| char *x, |
| char *y, |
| char *z, |
| int ret) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point P; |
| mbedtls_mpi X, Y, Z; |
| const unsigned char *vbuf = buf->x; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&P); |
| mbedtls_mpi_init(&X); |
| mbedtls_mpi_init(&Y); |
| mbedtls_mpi_init(&Z); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, x) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&Y, 16, y) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&Z, 16, z) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret); |
| |
| if (ret == 0) { |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0); |
| TEST_ASSERT((uint32_t)(vbuf - buf->x) == buf->len); |
| } |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&P); |
| mbedtls_mpi_free(&X); |
| mbedtls_mpi_free(&Y); |
| mbedtls_mpi_free(&Z); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_tls_write_read_point(int id) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point pt; |
| unsigned char buf[256]; |
| const unsigned char *vbuf; |
| size_t olen; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&pt); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| memset(buf, 0x00, sizeof(buf)); |
| vbuf = buf; |
| TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G, |
| MBEDTLS_ECP_PF_COMPRESSED, &olen, |
| buf, 256) == 0); |
| TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == |
| MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE); |
| TEST_ASSERT(vbuf == buf + olen); |
| |
| memset(buf, 0x00, sizeof(buf)); |
| vbuf = buf; |
| TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G, |
| MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, |
| buf, 256) == 0); |
| TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0); |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0); |
| TEST_ASSERT(vbuf == buf + olen); |
| |
| memset(buf, 0x00, sizeof(buf)); |
| vbuf = buf; |
| TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0); |
| TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt, |
| MBEDTLS_ECP_PF_COMPRESSED, &olen, |
| buf, 256) == 0); |
| TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0); |
| TEST_ASSERT(mbedtls_ecp_is_zero(&pt)); |
| TEST_ASSERT(vbuf == buf + olen); |
| |
| memset(buf, 0x00, sizeof(buf)); |
| vbuf = buf; |
| TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0); |
| TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt, |
| MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, |
| buf, 256) == 0); |
| TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0); |
| TEST_ASSERT(mbedtls_ecp_is_zero(&pt)); |
| TEST_ASSERT(vbuf == buf + olen); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&pt); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_tls_read_group(data_t *buf, |
| int result, |
| int bits, |
| int record_len) |
| { |
| mbedtls_ecp_group grp; |
| const unsigned char *vbuf = buf->x; |
| int ret; |
| |
| mbedtls_ecp_group_init(&grp); |
| |
| ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len); |
| |
| TEST_ASSERT(ret == result); |
| if (ret == 0) { |
| TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t)bits); |
| TEST_ASSERT(vbuf - buf->x == record_len); |
| } |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void ecp_tls_write_read_group(int id) |
| { |
| mbedtls_ecp_group grp1, grp2; |
| unsigned char buf[10]; |
| const unsigned char *vbuf = buf; |
| size_t len; |
| int ret; |
| |
| mbedtls_ecp_group_init(&grp1); |
| mbedtls_ecp_group_init(&grp2); |
| memset(buf, 0x00, sizeof(buf)); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0); |
| ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len); |
| TEST_ASSERT(ret == 0); |
| |
| if (ret == 0) { |
| TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0); |
| TEST_ASSERT(grp1.id == grp2.id); |
| } |
| |
| exit: |
| mbedtls_ecp_group_free(&grp1); |
| mbedtls_ecp_group_free(&grp2); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_check_privkey(int id, char *key_hex, int ret) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_mpi d; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_mpi_init(&d); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&d, 16, key_hex) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_mpi_free(&d); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_check_pub_priv(int id_pub, |
| char *Qx_pub, |
| char *Qy_pub, |
| int id, |
| char *d, |
| char *Qx, |
| char *Qy, |
| int ret) |
| { |
| mbedtls_ecp_keypair pub, prv; |
| mbedtls_test_rnd_pseudo_info rnd_info; |
| |
| mbedtls_ecp_keypair_init(&pub); |
| mbedtls_ecp_keypair_init(&prv); |
| memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); |
| |
| if (id_pub != MBEDTLS_ECP_DP_NONE) |
| TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0); |
| TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0); |
| |
| if (id != MBEDTLS_ECP_DP_NONE) |
| TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0); |
| TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0); |
| TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, 16, d) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv, |
| &mbedtls_test_rnd_pseudo_rand, |
| &rnd_info) == ret); |
| |
| exit: |
| mbedtls_ecp_keypair_free(&pub); |
| mbedtls_ecp_keypair_free(&prv); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_gen_keypair(int id) |
| { |
| mbedtls_ecp_group grp; |
| mbedtls_ecp_point Q; |
| mbedtls_mpi d; |
| mbedtls_test_rnd_pseudo_info rnd_info; |
| |
| mbedtls_ecp_group_init(&grp); |
| mbedtls_ecp_point_init(&Q); |
| mbedtls_mpi_init(&d); |
| memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); |
| |
| TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q, |
| &mbedtls_test_rnd_pseudo_rand, |
| &rnd_info) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0); |
| |
| exit: |
| mbedtls_ecp_group_free(&grp); |
| mbedtls_ecp_point_free(&Q); |
| mbedtls_mpi_free(&d); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_gen_key(int id) |
| { |
| mbedtls_ecp_keypair key; |
| mbedtls_test_rnd_pseudo_info rnd_info; |
| |
| mbedtls_ecp_keypair_init(&key); |
| memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info)); |
| |
| TEST_ASSERT(mbedtls_ecp_gen_key(id, &key, &mbedtls_test_rnd_pseudo_rand, |
| &rnd_info) == 0); |
| |
| TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0); |
| TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0); |
| |
| exit: |
| mbedtls_ecp_keypair_free(&key); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE */ |
| void mbedtls_ecp_read_key(int grp_id, |
| data_t *in_key, |
| int expected, |
| int canonical) |
| { |
| int ret = 0; |
| mbedtls_ecp_keypair key; |
| mbedtls_ecp_keypair key2; |
| |
| mbedtls_ecp_keypair_init(&key); |
| mbedtls_ecp_keypair_init(&key2); |
| |
| ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len); |
| TEST_ASSERT(ret == expected); |
| |
| if (expected == 0) { |
| ret = mbedtls_ecp_check_privkey(&key.grp, &key.d); |
| TEST_ASSERT(ret == 0); |
| |
| if (canonical) { |
| unsigned char buf[MBEDTLS_ECP_MAX_BYTES]; |
| |
| ret = mbedtls_ecp_write_key(&key, buf, in_key->len); |
| TEST_ASSERT(ret == 0); |
| |
| ASSERT_COMPARE(in_key->x, in_key->len, buf, in_key->len); |
| } else { |
| unsigned char export1[MBEDTLS_ECP_MAX_BYTES]; |
| unsigned char export2[MBEDTLS_ECP_MAX_BYTES]; |
| |
| ret = mbedtls_ecp_write_key(&key, export1, in_key->len); |
| TEST_ASSERT(ret == 0); |
| |
| ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len); |
| TEST_ASSERT(ret == expected); |
| |
| ret = mbedtls_ecp_write_key(&key2, export2, in_key->len); |
| TEST_ASSERT(ret == 0); |
| |
| ASSERT_COMPARE(export1, in_key->len, export2, in_key->len); |
| } |
| } |
| |
| exit: |
| mbedtls_ecp_keypair_free(&key); |
| mbedtls_ecp_keypair_free(&key2); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE depends_on:HAVE_FIX_NEGATIVE */ |
| void fix_negative(data_t *N_bin, int c, int bits) |
| { |
| mbedtls_mpi C, M, N; |
| |
| mbedtls_mpi_init(&C); |
| mbedtls_mpi_init(&M); |
| mbedtls_mpi_init(&N); |
| |
| /* C = - c * 2^bits (positive since c is negative) */ |
| TEST_EQUAL(0, mbedtls_mpi_lset(&C, -c)); |
| TEST_EQUAL(0, mbedtls_mpi_shift_l(&C, bits)); |
| |
| TEST_EQUAL(0, mbedtls_mpi_read_binary(&N, N_bin->x, N_bin->len)); |
| TEST_EQUAL(0, mbedtls_mpi_grow(&N, C.n)); |
| |
| /* M = N - C = - ( C - N ) (expected result of fix_negative) */ |
| TEST_EQUAL(0, mbedtls_mpi_sub_mpi(&M, &N, &C)); |
| |
| mbedtls_ecp_fix_negative(&N, c, bits); |
| |
| TEST_EQUAL(0, mbedtls_mpi_cmp_mpi(&N, &M)); |
| |
| exit: |
| mbedtls_mpi_free(&C); |
| mbedtls_mpi_free(&M); |
| mbedtls_mpi_free(&N); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED */ |
| void genkey_mx_known_answer(int bits, data_t *seed, data_t *expected) |
| { |
| mbedtls_test_rnd_buf_info rnd_info; |
| mbedtls_mpi d; |
| int ret; |
| uint8_t *actual = NULL; |
| |
| mbedtls_mpi_init(&d); |
| rnd_info.buf = seed->x; |
| rnd_info.length = seed->len; |
| rnd_info.fallback_f_rng = NULL; |
| rnd_info.fallback_p_rng = NULL; |
| |
| ASSERT_ALLOC(actual, expected->len); |
| |
| ret = mbedtls_ecp_gen_privkey_mx(bits, &d, mbedtls_test_rnd_buffer_rand, |
| &rnd_info); |
| |
| if (expected->len == 0) { |
| /* Expecting an error (happens if there isn't enough randomness) */ |
| TEST_ASSERT(ret != 0); |
| } else { |
| TEST_EQUAL(ret, 0); |
| TEST_EQUAL((size_t)bits + 1, mbedtls_mpi_bitlen(&d)); |
| TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len)); |
| /* Test the exact result. This assumes that the output of the |
| * RNG is used in a specific way, which is overly constraining. |
| * The advantage is that it's easier to test the expected properties |
| * of the generated key: |
| * - The most significant bit must be at a specific positions |
| * (can be enforced by checking the bit-length). |
| * - The least significant bits must have specific values |
| * (can be enforced by checking these bits). |
| * - Other bits must be random (by testing with different RNG outputs, |
| * we validate that those bits are indeed influenced by the RNG). */ |
| ASSERT_COMPARE(expected->x, expected->len, actual, expected->len); |
| } |
| |
| exit: |
| mbedtls_free(actual); |
| mbedtls_mpi_free(&d); |
| } |
| /* END_CASE */ |
| |
| /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ |
| void ecp_selftest() |
| { |
| TEST_ASSERT(mbedtls_ecp_self_test(1) == 0); |
| } |
| /* END_CASE */ |