1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * Low level APIs are deprecated for public use, but still ok for internal use. 12e1051a39Sopenharmony_ci */ 13e1051a39Sopenharmony_ci#include "internal/deprecated.h" 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_ci#include "internal/nelem.h" 16e1051a39Sopenharmony_ci#include "testutil.h" 17e1051a39Sopenharmony_ci#include <openssl/ec.h> 18e1051a39Sopenharmony_ci#include "ec_local.h" 19e1051a39Sopenharmony_ci#include <openssl/objects.h> 20e1051a39Sopenharmony_ci 21e1051a39Sopenharmony_cistatic size_t crv_len = 0; 22e1051a39Sopenharmony_cistatic EC_builtin_curve *curves = NULL; 23e1051a39Sopenharmony_ci 24e1051a39Sopenharmony_ci/* sanity checks field_inv function pointer in EC_METHOD */ 25e1051a39Sopenharmony_cistatic int group_field_tests(const EC_GROUP *group, BN_CTX *ctx) 26e1051a39Sopenharmony_ci{ 27e1051a39Sopenharmony_ci BIGNUM *a = NULL, *b = NULL, *c = NULL; 28e1051a39Sopenharmony_ci int ret = 0; 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci if (group->meth->field_inv == NULL || group->meth->field_mul == NULL) 31e1051a39Sopenharmony_ci return 1; 32e1051a39Sopenharmony_ci 33e1051a39Sopenharmony_ci BN_CTX_start(ctx); 34e1051a39Sopenharmony_ci a = BN_CTX_get(ctx); 35e1051a39Sopenharmony_ci b = BN_CTX_get(ctx); 36e1051a39Sopenharmony_ci if (!TEST_ptr(c = BN_CTX_get(ctx)) 37e1051a39Sopenharmony_ci /* 1/1 = 1 */ 38e1051a39Sopenharmony_ci || !TEST_true(group->meth->field_inv(group, b, BN_value_one(), ctx)) 39e1051a39Sopenharmony_ci || !TEST_true(BN_is_one(b)) 40e1051a39Sopenharmony_ci /* (1/a)*a = 1 */ 41e1051a39Sopenharmony_ci || !TEST_true(BN_rand(a, BN_num_bits(group->field) - 1, 42e1051a39Sopenharmony_ci BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) 43e1051a39Sopenharmony_ci || !TEST_true(group->meth->field_inv(group, b, a, ctx)) 44e1051a39Sopenharmony_ci || (group->meth->field_encode && 45e1051a39Sopenharmony_ci !TEST_true(group->meth->field_encode(group, a, a, ctx))) 46e1051a39Sopenharmony_ci || (group->meth->field_encode && 47e1051a39Sopenharmony_ci !TEST_true(group->meth->field_encode(group, b, b, ctx))) 48e1051a39Sopenharmony_ci || !TEST_true(group->meth->field_mul(group, c, a, b, ctx)) 49e1051a39Sopenharmony_ci || (group->meth->field_decode && 50e1051a39Sopenharmony_ci !TEST_true(group->meth->field_decode(group, c, c, ctx))) 51e1051a39Sopenharmony_ci || !TEST_true(BN_is_one(c))) 52e1051a39Sopenharmony_ci goto err; 53e1051a39Sopenharmony_ci 54e1051a39Sopenharmony_ci /* 1/0 = error */ 55e1051a39Sopenharmony_ci BN_zero(a); 56e1051a39Sopenharmony_ci if (!TEST_false(group->meth->field_inv(group, b, a, ctx)) 57e1051a39Sopenharmony_ci || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC) 58e1051a39Sopenharmony_ci || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) == 59e1051a39Sopenharmony_ci EC_R_CANNOT_INVERT) 60e1051a39Sopenharmony_ci /* 1/p = error */ 61e1051a39Sopenharmony_ci || !TEST_false(group->meth->field_inv(group, b, group->field, ctx)) 62e1051a39Sopenharmony_ci || !TEST_true(ERR_GET_LIB(ERR_peek_last_error()) == ERR_LIB_EC) 63e1051a39Sopenharmony_ci || !TEST_true(ERR_GET_REASON(ERR_peek_last_error()) == 64e1051a39Sopenharmony_ci EC_R_CANNOT_INVERT)) 65e1051a39Sopenharmony_ci goto err; 66e1051a39Sopenharmony_ci 67e1051a39Sopenharmony_ci ERR_clear_error(); 68e1051a39Sopenharmony_ci ret = 1; 69e1051a39Sopenharmony_ci err: 70e1051a39Sopenharmony_ci BN_CTX_end(ctx); 71e1051a39Sopenharmony_ci return ret; 72e1051a39Sopenharmony_ci} 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_ci/* wrapper for group_field_tests for explicit curve params and EC_METHOD */ 75e1051a39Sopenharmony_cistatic int field_tests(const EC_METHOD *meth, const unsigned char *params, 76e1051a39Sopenharmony_ci int len) 77e1051a39Sopenharmony_ci{ 78e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 79e1051a39Sopenharmony_ci BIGNUM *p = NULL, *a = NULL, *b = NULL; 80e1051a39Sopenharmony_ci EC_GROUP *group = NULL; 81e1051a39Sopenharmony_ci int ret = 0; 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci if (!TEST_ptr(ctx = BN_CTX_new())) 84e1051a39Sopenharmony_ci return 0; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci BN_CTX_start(ctx); 87e1051a39Sopenharmony_ci p = BN_CTX_get(ctx); 88e1051a39Sopenharmony_ci a = BN_CTX_get(ctx); 89e1051a39Sopenharmony_ci if (!TEST_ptr(b = BN_CTX_get(ctx)) 90e1051a39Sopenharmony_ci || !TEST_ptr(group = EC_GROUP_new(meth)) 91e1051a39Sopenharmony_ci || !TEST_true(BN_bin2bn(params, len, p)) 92e1051a39Sopenharmony_ci || !TEST_true(BN_bin2bn(params + len, len, a)) 93e1051a39Sopenharmony_ci || !TEST_true(BN_bin2bn(params + 2 * len, len, b)) 94e1051a39Sopenharmony_ci || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) 95e1051a39Sopenharmony_ci || !group_field_tests(group, ctx)) 96e1051a39Sopenharmony_ci goto err; 97e1051a39Sopenharmony_ci ret = 1; 98e1051a39Sopenharmony_ci 99e1051a39Sopenharmony_ci err: 100e1051a39Sopenharmony_ci BN_CTX_end(ctx); 101e1051a39Sopenharmony_ci BN_CTX_free(ctx); 102e1051a39Sopenharmony_ci if (group != NULL) 103e1051a39Sopenharmony_ci EC_GROUP_free(group); 104e1051a39Sopenharmony_ci return ret; 105e1051a39Sopenharmony_ci} 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci/* NIST prime curve P-256 */ 108e1051a39Sopenharmony_cistatic const unsigned char params_p256[] = { 109e1051a39Sopenharmony_ci /* p */ 110e1051a39Sopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 111e1051a39Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 112e1051a39Sopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 113e1051a39Sopenharmony_ci /* a */ 114e1051a39Sopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 115e1051a39Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 116e1051a39Sopenharmony_ci 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 117e1051a39Sopenharmony_ci /* b */ 118e1051a39Sopenharmony_ci 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 119e1051a39Sopenharmony_ci 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 120e1051a39Sopenharmony_ci 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B 121e1051a39Sopenharmony_ci}; 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M 124e1051a39Sopenharmony_ci/* NIST binary curve B-283 */ 125e1051a39Sopenharmony_cistatic const unsigned char params_b283[] = { 126e1051a39Sopenharmony_ci /* p */ 127e1051a39Sopenharmony_ci 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 128e1051a39Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 129e1051a39Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, 130e1051a39Sopenharmony_ci /* a */ 131e1051a39Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 132e1051a39Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 133e1051a39Sopenharmony_ci 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 134e1051a39Sopenharmony_ci /* b */ 135e1051a39Sopenharmony_ci 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A, 136e1051a39Sopenharmony_ci 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2, 137e1051a39Sopenharmony_ci 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5 138e1051a39Sopenharmony_ci}; 139e1051a39Sopenharmony_ci#endif 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci/* test EC_GFp_simple_method directly */ 142e1051a39Sopenharmony_cistatic int field_tests_ecp_simple(void) 143e1051a39Sopenharmony_ci{ 144e1051a39Sopenharmony_ci TEST_info("Testing EC_GFp_simple_method()\n"); 145e1051a39Sopenharmony_ci return field_tests(EC_GFp_simple_method(), params_p256, 146e1051a39Sopenharmony_ci sizeof(params_p256) / 3); 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci/* test EC_GFp_mont_method directly */ 150e1051a39Sopenharmony_cistatic int field_tests_ecp_mont(void) 151e1051a39Sopenharmony_ci{ 152e1051a39Sopenharmony_ci TEST_info("Testing EC_GFp_mont_method()\n"); 153e1051a39Sopenharmony_ci return field_tests(EC_GFp_mont_method(), params_p256, 154e1051a39Sopenharmony_ci sizeof(params_p256) / 3); 155e1051a39Sopenharmony_ci} 156e1051a39Sopenharmony_ci 157e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M 158e1051a39Sopenharmony_ci/* Test that decoding of invalid GF2m field parameters fails. */ 159e1051a39Sopenharmony_cistatic int ec2m_field_sanity(void) 160e1051a39Sopenharmony_ci{ 161e1051a39Sopenharmony_ci int ret = 0; 162e1051a39Sopenharmony_ci BN_CTX *ctx = BN_CTX_new(); 163e1051a39Sopenharmony_ci BIGNUM *p, *a, *b; 164e1051a39Sopenharmony_ci EC_GROUP *group1 = NULL, *group2 = NULL, *group3 = NULL; 165e1051a39Sopenharmony_ci 166e1051a39Sopenharmony_ci TEST_info("Testing GF2m hardening\n"); 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_ci BN_CTX_start(ctx); 169e1051a39Sopenharmony_ci p = BN_CTX_get(ctx); 170e1051a39Sopenharmony_ci a = BN_CTX_get(ctx); 171e1051a39Sopenharmony_ci if (!TEST_ptr(b = BN_CTX_get(ctx)) 172e1051a39Sopenharmony_ci || !TEST_true(BN_one(a)) 173e1051a39Sopenharmony_ci || !TEST_true(BN_one(b))) 174e1051a39Sopenharmony_ci goto out; 175e1051a39Sopenharmony_ci 176e1051a39Sopenharmony_ci /* Even pentanomial value should be rejected */ 177e1051a39Sopenharmony_ci if (!TEST_true(BN_set_word(p, 0xf2))) 178e1051a39Sopenharmony_ci goto out; 179e1051a39Sopenharmony_ci if (!TEST_ptr_null(group1 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) 180e1051a39Sopenharmony_ci TEST_error("Zero constant term accepted in GF2m polynomial"); 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci /* Odd hexanomial should also be rejected */ 183e1051a39Sopenharmony_ci if (!TEST_true(BN_set_word(p, 0xf3))) 184e1051a39Sopenharmony_ci goto out; 185e1051a39Sopenharmony_ci if (!TEST_ptr_null(group2 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) 186e1051a39Sopenharmony_ci TEST_error("Hexanomial accepted as GF2m polynomial"); 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci /* Excessive polynomial degree should also be rejected */ 189e1051a39Sopenharmony_ci if (!TEST_true(BN_set_word(p, 0x71)) 190e1051a39Sopenharmony_ci || !TEST_true(BN_set_bit(p, OPENSSL_ECC_MAX_FIELD_BITS + 1))) 191e1051a39Sopenharmony_ci goto out; 192e1051a39Sopenharmony_ci if (!TEST_ptr_null(group3 = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) 193e1051a39Sopenharmony_ci TEST_error("GF2m polynomial degree > %d accepted", 194e1051a39Sopenharmony_ci OPENSSL_ECC_MAX_FIELD_BITS); 195e1051a39Sopenharmony_ci 196e1051a39Sopenharmony_ci ret = group1 == NULL && group2 == NULL && group3 == NULL; 197e1051a39Sopenharmony_ci 198e1051a39Sopenharmony_ci out: 199e1051a39Sopenharmony_ci EC_GROUP_free(group1); 200e1051a39Sopenharmony_ci EC_GROUP_free(group2); 201e1051a39Sopenharmony_ci EC_GROUP_free(group3); 202e1051a39Sopenharmony_ci BN_CTX_end(ctx); 203e1051a39Sopenharmony_ci BN_CTX_free(ctx); 204e1051a39Sopenharmony_ci 205e1051a39Sopenharmony_ci return ret; 206e1051a39Sopenharmony_ci} 207e1051a39Sopenharmony_ci 208e1051a39Sopenharmony_ci/* test EC_GF2m_simple_method directly */ 209e1051a39Sopenharmony_cistatic int field_tests_ec2_simple(void) 210e1051a39Sopenharmony_ci{ 211e1051a39Sopenharmony_ci TEST_info("Testing EC_GF2m_simple_method()\n"); 212e1051a39Sopenharmony_ci return field_tests(EC_GF2m_simple_method(), params_b283, 213e1051a39Sopenharmony_ci sizeof(params_b283) / 3); 214e1051a39Sopenharmony_ci} 215e1051a39Sopenharmony_ci#endif 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ci/* test default method for a named curve */ 218e1051a39Sopenharmony_cistatic int field_tests_default(int n) 219e1051a39Sopenharmony_ci{ 220e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 221e1051a39Sopenharmony_ci EC_GROUP *group = NULL; 222e1051a39Sopenharmony_ci int nid = curves[n].nid; 223e1051a39Sopenharmony_ci int ret = 0; 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci TEST_info("Testing curve %s\n", OBJ_nid2sn(nid)); 226e1051a39Sopenharmony_ci 227e1051a39Sopenharmony_ci if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) 228e1051a39Sopenharmony_ci || !TEST_ptr(ctx = BN_CTX_new()) 229e1051a39Sopenharmony_ci || !group_field_tests(group, ctx)) 230e1051a39Sopenharmony_ci goto err; 231e1051a39Sopenharmony_ci 232e1051a39Sopenharmony_ci ret = 1; 233e1051a39Sopenharmony_ci err: 234e1051a39Sopenharmony_ci if (group != NULL) 235e1051a39Sopenharmony_ci EC_GROUP_free(group); 236e1051a39Sopenharmony_ci if (ctx != NULL) 237e1051a39Sopenharmony_ci BN_CTX_free(ctx); 238e1051a39Sopenharmony_ci return ret; 239e1051a39Sopenharmony_ci} 240e1051a39Sopenharmony_ci 241e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 242e1051a39Sopenharmony_ci/* 243e1051a39Sopenharmony_ci * Tests a point known to cause an incorrect underflow in an old version of 244e1051a39Sopenharmony_ci * ecp_nist521.c 245e1051a39Sopenharmony_ci */ 246e1051a39Sopenharmony_cistatic int underflow_test(void) 247e1051a39Sopenharmony_ci{ 248e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 249e1051a39Sopenharmony_ci EC_GROUP *grp = NULL; 250e1051a39Sopenharmony_ci EC_POINT *P = NULL, *Q = NULL, *R = NULL; 251e1051a39Sopenharmony_ci BIGNUM *x1 = NULL, *y1 = NULL, *z1 = NULL, *x2 = NULL, *y2 = NULL; 252e1051a39Sopenharmony_ci BIGNUM *k = NULL; 253e1051a39Sopenharmony_ci int testresult = 0; 254e1051a39Sopenharmony_ci const char *x1str = 255e1051a39Sopenharmony_ci "1534f0077fffffe87e9adcfe000000000000000000003e05a21d2400002e031b1f4" 256e1051a39Sopenharmony_ci "b80000c6fafa4f3c1288798d624a247b5e2ffffffffffffffefe099241900004"; 257e1051a39Sopenharmony_ci const char *p521m1 = 258e1051a39Sopenharmony_ci "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 259e1051a39Sopenharmony_ci "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"; 260e1051a39Sopenharmony_ci 261e1051a39Sopenharmony_ci ctx = BN_CTX_new(); 262e1051a39Sopenharmony_ci if (!TEST_ptr(ctx)) 263e1051a39Sopenharmony_ci return 0; 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci BN_CTX_start(ctx); 266e1051a39Sopenharmony_ci x1 = BN_CTX_get(ctx); 267e1051a39Sopenharmony_ci y1 = BN_CTX_get(ctx); 268e1051a39Sopenharmony_ci z1 = BN_CTX_get(ctx); 269e1051a39Sopenharmony_ci x2 = BN_CTX_get(ctx); 270e1051a39Sopenharmony_ci y2 = BN_CTX_get(ctx); 271e1051a39Sopenharmony_ci k = BN_CTX_get(ctx); 272e1051a39Sopenharmony_ci if (!TEST_ptr(k)) 273e1051a39Sopenharmony_ci goto err; 274e1051a39Sopenharmony_ci 275e1051a39Sopenharmony_ci grp = EC_GROUP_new_by_curve_name(NID_secp521r1); 276e1051a39Sopenharmony_ci P = EC_POINT_new(grp); 277e1051a39Sopenharmony_ci Q = EC_POINT_new(grp); 278e1051a39Sopenharmony_ci R = EC_POINT_new(grp); 279e1051a39Sopenharmony_ci if (!TEST_ptr(grp) || !TEST_ptr(P) || !TEST_ptr(Q) || !TEST_ptr(R)) 280e1051a39Sopenharmony_ci goto err; 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci if (!TEST_int_gt(BN_hex2bn(&x1, x1str), 0) 283e1051a39Sopenharmony_ci || !TEST_int_gt(BN_hex2bn(&y1, p521m1), 0) 284e1051a39Sopenharmony_ci || !TEST_int_gt(BN_hex2bn(&z1, p521m1), 0) 285e1051a39Sopenharmony_ci || !TEST_int_gt(BN_hex2bn(&k, "02"), 0) 286e1051a39Sopenharmony_ci || !TEST_true(ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(grp, P, x1, 287e1051a39Sopenharmony_ci y1, z1, ctx)) 288e1051a39Sopenharmony_ci || !TEST_true(EC_POINT_mul(grp, Q, NULL, P, k, ctx)) 289e1051a39Sopenharmony_ci || !TEST_true(EC_POINT_get_affine_coordinates(grp, Q, x1, y1, ctx)) 290e1051a39Sopenharmony_ci || !TEST_true(EC_POINT_dbl(grp, R, P, ctx)) 291e1051a39Sopenharmony_ci || !TEST_true(EC_POINT_get_affine_coordinates(grp, R, x2, y2, ctx))) 292e1051a39Sopenharmony_ci goto err; 293e1051a39Sopenharmony_ci 294e1051a39Sopenharmony_ci if (!TEST_int_eq(BN_cmp(x1, x2), 0) 295e1051a39Sopenharmony_ci || !TEST_int_eq(BN_cmp(y1, y2), 0)) 296e1051a39Sopenharmony_ci goto err; 297e1051a39Sopenharmony_ci 298e1051a39Sopenharmony_ci testresult = 1; 299e1051a39Sopenharmony_ci 300e1051a39Sopenharmony_ci err: 301e1051a39Sopenharmony_ci BN_CTX_end(ctx); 302e1051a39Sopenharmony_ci EC_POINT_free(P); 303e1051a39Sopenharmony_ci EC_POINT_free(Q); 304e1051a39Sopenharmony_ci EC_POINT_free(R); 305e1051a39Sopenharmony_ci EC_GROUP_free(grp); 306e1051a39Sopenharmony_ci BN_CTX_free(ctx); 307e1051a39Sopenharmony_ci 308e1051a39Sopenharmony_ci return testresult; 309e1051a39Sopenharmony_ci} 310e1051a39Sopenharmony_ci#endif 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci/* 313e1051a39Sopenharmony_ci * Tests behavior of the EC_KEY_set_private_key 314e1051a39Sopenharmony_ci */ 315e1051a39Sopenharmony_cistatic int set_private_key(void) 316e1051a39Sopenharmony_ci{ 317e1051a39Sopenharmony_ci EC_KEY *key = NULL, *aux_key = NULL; 318e1051a39Sopenharmony_ci int testresult = 0; 319e1051a39Sopenharmony_ci 320e1051a39Sopenharmony_ci key = EC_KEY_new_by_curve_name(NID_secp224r1); 321e1051a39Sopenharmony_ci aux_key = EC_KEY_new_by_curve_name(NID_secp224r1); 322e1051a39Sopenharmony_ci if (!TEST_ptr(key) 323e1051a39Sopenharmony_ci || !TEST_ptr(aux_key) 324e1051a39Sopenharmony_ci || !TEST_int_eq(EC_KEY_generate_key(key), 1) 325e1051a39Sopenharmony_ci || !TEST_int_eq(EC_KEY_generate_key(aux_key), 1)) 326e1051a39Sopenharmony_ci goto err; 327e1051a39Sopenharmony_ci 328e1051a39Sopenharmony_ci /* Test setting a valid private key */ 329e1051a39Sopenharmony_ci if (!TEST_int_eq(EC_KEY_set_private_key(key, aux_key->priv_key), 1)) 330e1051a39Sopenharmony_ci goto err; 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ci /* Test compliance with legacy behavior for NULL private keys */ 333e1051a39Sopenharmony_ci if (!TEST_int_eq(EC_KEY_set_private_key(key, NULL), 0) 334e1051a39Sopenharmony_ci || !TEST_ptr_null(key->priv_key)) 335e1051a39Sopenharmony_ci goto err; 336e1051a39Sopenharmony_ci 337e1051a39Sopenharmony_ci testresult = 1; 338e1051a39Sopenharmony_ci 339e1051a39Sopenharmony_ci err: 340e1051a39Sopenharmony_ci EC_KEY_free(key); 341e1051a39Sopenharmony_ci EC_KEY_free(aux_key); 342e1051a39Sopenharmony_ci return testresult; 343e1051a39Sopenharmony_ci} 344e1051a39Sopenharmony_ci 345e1051a39Sopenharmony_ci/* 346e1051a39Sopenharmony_ci * Tests behavior of the decoded_from_explicit_params flag and API 347e1051a39Sopenharmony_ci */ 348e1051a39Sopenharmony_cistatic int decoded_flag_test(void) 349e1051a39Sopenharmony_ci{ 350e1051a39Sopenharmony_ci EC_GROUP *grp; 351e1051a39Sopenharmony_ci EC_GROUP *grp_copy = NULL; 352e1051a39Sopenharmony_ci ECPARAMETERS *ecparams = NULL; 353e1051a39Sopenharmony_ci ECPKPARAMETERS *ecpkparams = NULL; 354e1051a39Sopenharmony_ci EC_KEY *key = NULL; 355e1051a39Sopenharmony_ci unsigned char *encodedparams = NULL; 356e1051a39Sopenharmony_ci const unsigned char *encp; 357e1051a39Sopenharmony_ci int encodedlen; 358e1051a39Sopenharmony_ci int testresult = 0; 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci /* Test EC_GROUP_new not setting the flag */ 361e1051a39Sopenharmony_ci grp = EC_GROUP_new(EC_GFp_simple_method()); 362e1051a39Sopenharmony_ci if (!TEST_ptr(grp) 363e1051a39Sopenharmony_ci || !TEST_int_eq(grp->decoded_from_explicit_params, 0)) 364e1051a39Sopenharmony_ci goto err; 365e1051a39Sopenharmony_ci EC_GROUP_free(grp); 366e1051a39Sopenharmony_ci 367e1051a39Sopenharmony_ci /* Test EC_GROUP_new_by_curve_name not setting the flag */ 368e1051a39Sopenharmony_ci grp = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); 369e1051a39Sopenharmony_ci if (!TEST_ptr(grp) 370e1051a39Sopenharmony_ci || !TEST_int_eq(grp->decoded_from_explicit_params, 0)) 371e1051a39Sopenharmony_ci goto err; 372e1051a39Sopenharmony_ci 373e1051a39Sopenharmony_ci /* Test EC_GROUP_new_from_ecparameters not setting the flag */ 374e1051a39Sopenharmony_ci if (!TEST_ptr(ecparams = EC_GROUP_get_ecparameters(grp, NULL)) 375e1051a39Sopenharmony_ci || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecparameters(ecparams)) 376e1051a39Sopenharmony_ci || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)) 377e1051a39Sopenharmony_ci goto err; 378e1051a39Sopenharmony_ci EC_GROUP_free(grp_copy); 379e1051a39Sopenharmony_ci grp_copy = NULL; 380e1051a39Sopenharmony_ci ECPARAMETERS_free(ecparams); 381e1051a39Sopenharmony_ci ecparams = NULL; 382e1051a39Sopenharmony_ci 383e1051a39Sopenharmony_ci /* Test EC_GROUP_new_from_ecpkparameters not setting the flag */ 384e1051a39Sopenharmony_ci if (!TEST_int_eq(EC_GROUP_get_asn1_flag(grp), OPENSSL_EC_NAMED_CURVE) 385e1051a39Sopenharmony_ci || !TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL)) 386e1051a39Sopenharmony_ci || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams)) 387e1051a39Sopenharmony_ci || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0) 388e1051a39Sopenharmony_ci || !TEST_ptr(key = EC_KEY_new()) 389e1051a39Sopenharmony_ci /* Test EC_KEY_decoded_from_explicit_params on key without a group */ 390e1051a39Sopenharmony_ci || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), -1) 391e1051a39Sopenharmony_ci || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1) 392e1051a39Sopenharmony_ci /* Test EC_KEY_decoded_from_explicit_params negative case */ 393e1051a39Sopenharmony_ci || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 0)) 394e1051a39Sopenharmony_ci goto err; 395e1051a39Sopenharmony_ci EC_GROUP_free(grp_copy); 396e1051a39Sopenharmony_ci grp_copy = NULL; 397e1051a39Sopenharmony_ci ECPKPARAMETERS_free(ecpkparams); 398e1051a39Sopenharmony_ci ecpkparams = NULL; 399e1051a39Sopenharmony_ci 400e1051a39Sopenharmony_ci /* Test d2i_ECPKParameters with named params not setting the flag */ 401e1051a39Sopenharmony_ci if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0) 402e1051a39Sopenharmony_ci || !TEST_ptr(encp = encodedparams) 403e1051a39Sopenharmony_ci || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen)) 404e1051a39Sopenharmony_ci || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)) 405e1051a39Sopenharmony_ci goto err; 406e1051a39Sopenharmony_ci EC_GROUP_free(grp_copy); 407e1051a39Sopenharmony_ci grp_copy = NULL; 408e1051a39Sopenharmony_ci OPENSSL_free(encodedparams); 409e1051a39Sopenharmony_ci encodedparams = NULL; 410e1051a39Sopenharmony_ci 411e1051a39Sopenharmony_ci /* Asn1 flag stays set to explicit with EC_GROUP_new_from_ecpkparameters */ 412e1051a39Sopenharmony_ci EC_GROUP_set_asn1_flag(grp, OPENSSL_EC_EXPLICIT_CURVE); 413e1051a39Sopenharmony_ci if (!TEST_ptr(ecpkparams = EC_GROUP_get_ecpkparameters(grp, NULL)) 414e1051a39Sopenharmony_ci || !TEST_ptr(grp_copy = EC_GROUP_new_from_ecpkparameters(ecpkparams)) 415e1051a39Sopenharmony_ci || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE) 416e1051a39Sopenharmony_ci || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 0)) 417e1051a39Sopenharmony_ci goto err; 418e1051a39Sopenharmony_ci EC_GROUP_free(grp_copy); 419e1051a39Sopenharmony_ci grp_copy = NULL; 420e1051a39Sopenharmony_ci 421e1051a39Sopenharmony_ci /* Test d2i_ECPKParameters with explicit params setting the flag */ 422e1051a39Sopenharmony_ci if (!TEST_int_gt(encodedlen = i2d_ECPKParameters(grp, &encodedparams), 0) 423e1051a39Sopenharmony_ci || !TEST_ptr(encp = encodedparams) 424e1051a39Sopenharmony_ci || !TEST_ptr(grp_copy = d2i_ECPKParameters(NULL, &encp, encodedlen)) 425e1051a39Sopenharmony_ci || !TEST_int_eq(EC_GROUP_get_asn1_flag(grp_copy), OPENSSL_EC_EXPLICIT_CURVE) 426e1051a39Sopenharmony_ci || !TEST_int_eq(grp_copy->decoded_from_explicit_params, 1) 427e1051a39Sopenharmony_ci || !TEST_int_eq(EC_KEY_set_group(key, grp_copy), 1) 428e1051a39Sopenharmony_ci /* Test EC_KEY_decoded_from_explicit_params positive case */ 429e1051a39Sopenharmony_ci || !TEST_int_eq(EC_KEY_decoded_from_explicit_params(key), 1)) 430e1051a39Sopenharmony_ci goto err; 431e1051a39Sopenharmony_ci 432e1051a39Sopenharmony_ci testresult = 1; 433e1051a39Sopenharmony_ci 434e1051a39Sopenharmony_ci err: 435e1051a39Sopenharmony_ci EC_KEY_free(key); 436e1051a39Sopenharmony_ci EC_GROUP_free(grp); 437e1051a39Sopenharmony_ci EC_GROUP_free(grp_copy); 438e1051a39Sopenharmony_ci ECPARAMETERS_free(ecparams); 439e1051a39Sopenharmony_ci ECPKPARAMETERS_free(ecpkparams); 440e1051a39Sopenharmony_ci OPENSSL_free(encodedparams); 441e1051a39Sopenharmony_ci 442e1051a39Sopenharmony_ci return testresult; 443e1051a39Sopenharmony_ci} 444e1051a39Sopenharmony_ci 445e1051a39Sopenharmony_cistatic 446e1051a39Sopenharmony_ciint ecpkparams_i2d2i_test(int n) 447e1051a39Sopenharmony_ci{ 448e1051a39Sopenharmony_ci EC_GROUP *g1 = NULL, *g2 = NULL; 449e1051a39Sopenharmony_ci FILE *fp = NULL; 450e1051a39Sopenharmony_ci int nid = curves[n].nid; 451e1051a39Sopenharmony_ci int testresult = 0; 452e1051a39Sopenharmony_ci 453e1051a39Sopenharmony_ci /* create group */ 454e1051a39Sopenharmony_ci if (!TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))) 455e1051a39Sopenharmony_ci goto end; 456e1051a39Sopenharmony_ci 457e1051a39Sopenharmony_ci /* encode params to file */ 458e1051a39Sopenharmony_ci if (!TEST_ptr(fp = fopen("params.der", "wb")) 459e1051a39Sopenharmony_ci || !TEST_true(i2d_ECPKParameters_fp(fp, g1))) 460e1051a39Sopenharmony_ci goto end; 461e1051a39Sopenharmony_ci 462e1051a39Sopenharmony_ci /* flush and close file */ 463e1051a39Sopenharmony_ci if (!TEST_int_eq(fclose(fp), 0)) { 464e1051a39Sopenharmony_ci fp = NULL; 465e1051a39Sopenharmony_ci goto end; 466e1051a39Sopenharmony_ci } 467e1051a39Sopenharmony_ci fp = NULL; 468e1051a39Sopenharmony_ci 469e1051a39Sopenharmony_ci /* decode params from file */ 470e1051a39Sopenharmony_ci if (!TEST_ptr(fp = fopen("params.der", "rb")) 471e1051a39Sopenharmony_ci || !TEST_ptr(g2 = d2i_ECPKParameters_fp(fp, NULL))) 472e1051a39Sopenharmony_ci goto end; 473e1051a39Sopenharmony_ci 474e1051a39Sopenharmony_ci testresult = 1; /* PASS */ 475e1051a39Sopenharmony_ci 476e1051a39Sopenharmony_ciend: 477e1051a39Sopenharmony_ci if (fp != NULL) 478e1051a39Sopenharmony_ci fclose(fp); 479e1051a39Sopenharmony_ci 480e1051a39Sopenharmony_ci EC_GROUP_free(g1); 481e1051a39Sopenharmony_ci EC_GROUP_free(g2); 482e1051a39Sopenharmony_ci 483e1051a39Sopenharmony_ci return testresult; 484e1051a39Sopenharmony_ci} 485e1051a39Sopenharmony_ci 486e1051a39Sopenharmony_ciint setup_tests(void) 487e1051a39Sopenharmony_ci{ 488e1051a39Sopenharmony_ci crv_len = EC_get_builtin_curves(NULL, 0); 489e1051a39Sopenharmony_ci if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len)) 490e1051a39Sopenharmony_ci || !TEST_true(EC_get_builtin_curves(curves, crv_len))) 491e1051a39Sopenharmony_ci return 0; 492e1051a39Sopenharmony_ci 493e1051a39Sopenharmony_ci ADD_TEST(field_tests_ecp_simple); 494e1051a39Sopenharmony_ci ADD_TEST(field_tests_ecp_mont); 495e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC2M 496e1051a39Sopenharmony_ci ADD_TEST(ec2m_field_sanity); 497e1051a39Sopenharmony_ci ADD_TEST(field_tests_ec2_simple); 498e1051a39Sopenharmony_ci#endif 499e1051a39Sopenharmony_ci ADD_ALL_TESTS(field_tests_default, crv_len); 500e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 501e1051a39Sopenharmony_ci ADD_TEST(underflow_test); 502e1051a39Sopenharmony_ci#endif 503e1051a39Sopenharmony_ci ADD_TEST(set_private_key); 504e1051a39Sopenharmony_ci ADD_TEST(decoded_flag_test); 505e1051a39Sopenharmony_ci ADD_ALL_TESTS(ecpkparams_i2d2i_test, crv_len); 506e1051a39Sopenharmony_ci 507e1051a39Sopenharmony_ci return 1; 508e1051a39Sopenharmony_ci} 509e1051a39Sopenharmony_ci 510e1051a39Sopenharmony_civoid cleanup_tests(void) 511e1051a39Sopenharmony_ci{ 512e1051a39Sopenharmony_ci OPENSSL_free(curves); 513e1051a39Sopenharmony_ci} 514