From 6b4152f1896e07ed94dc82663846ae9d38d4ca42 Mon Sep 17 00:00:00 2001 From: Billy Brumley Date: Mon, 2 Sep 2019 15:03:26 +0300 Subject: [PATCH] [test] computing ECC cofactors: regression test Reviewed-by: Nicola Tuveri Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/9827) --- test/ectest.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/test/ectest.c b/test/ectest.c index cfe6d869eb..2cbbd4e340 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -1679,9 +1679,8 @@ static int check_named_curve_test(int id) group_cofactor)) || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0) /* The order is not an optional field, so this should fail */ - || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, NULL, - group_cofactor)) - || !TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0) + || TEST_true(EC_GROUP_set_generator(gtest, group_gen, NULL, + group_cofactor)) || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order, other_cofactor)) || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0) @@ -1856,6 +1855,89 @@ err: return r; } +/*- + * For named curves, test that: + * - the lib correctly computes the cofactor if passed a NULL or zero cofactor + * - a nonsensical cofactor throws an error (negative test) + * - nonsensical orders throw errors (negative tests) + */ +static int cardinality_test(int n) +{ + int ret = 0; + int nid = curves[n].nid; + BN_CTX *ctx = NULL; + EC_GROUP *g1 = NULL, *g2 = NULL; + EC_POINT *g2_gen = NULL; + BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL, + *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL; + + TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid)); + + if (!TEST_ptr(ctx = BN_CTX_new()) + || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid)) + || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) { + EC_GROUP_free(g1); + EC_GROUP_free(g2); + BN_CTX_free(ctx); + return 0; + } + + BN_CTX_start(ctx); + g1_p = BN_CTX_get(ctx); + g1_a = BN_CTX_get(ctx); + g1_b = BN_CTX_get(ctx); + g1_x = BN_CTX_get(ctx); + g1_y = BN_CTX_get(ctx); + g1_order = BN_CTX_get(ctx); + g1_cf = BN_CTX_get(ctx); + + if (!TEST_ptr(g2_cf = BN_CTX_get(ctx)) + /* pull out the explicit curve parameters */ + || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx)) + || !TEST_true(EC_POINT_get_affine_coordinates(g1, + EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx)) + || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1))) + || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx)) + /* construct g2 manually with g1 parameters */ + || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx)) + || !TEST_ptr(g2_gen = EC_POINT_new(g2)) + || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx)) + /* pass NULL cofactor: lib should compute it */ + || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)) + || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx)) + || !TEST_BN_eq(g1_cf, g2_cf) + /* pass zero cofactor: lib should compute it */ + || !TEST_true(BN_set_word(g2_cf, 0)) + || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf)) + || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx)) + || !TEST_BN_eq(g1_cf, g2_cf) + /* negative test for invalid cofactor */ + || !TEST_true(BN_set_word(g2_cf, 0)) + || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one())) + || TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf)) + /* negative test for NULL order */ + || TEST_true(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL)) + /* negative test for zero order */ + || !TEST_true(BN_set_word(g1_order, 0)) + || TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)) + /* negative test for negative order */ + || !TEST_true(BN_set_word(g2_cf, 0)) + || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one())) + || TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)) + /* negative test for too large order */ + || !TEST_true(BN_lshift(g1_order, g1_p, 2)) + || TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))) + goto err; + ret = 1; + err: + EC_POINT_free(g2_gen); + EC_GROUP_free(g1); + EC_GROUP_free(g2); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} + static int check_ec_key_field_public_range_test(int id) { int ret = 0, type = 0; @@ -1921,6 +2003,7 @@ int setup_tests(void) return 0; ADD_TEST(parameter_test); + ADD_ALL_TESTS(cardinality_test, crv_len); ADD_TEST(prime_field_tests); # ifndef OPENSSL_NO_EC2M ADD_TEST(char2_field_tests); -- 2.39.2