1 /* 2 * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved 4 * 5 * Licensed under the Apache License 2.0 (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 */ 10 11 /* 12 * EC_KEY low level APIs are deprecated for public use, but still ok for 13 * internal use. 14 */ 15 #include "internal/deprecated.h" 16 17 #include <string.h> 18 #include "internal/nelem.h" 19 #include "testutil.h" 20 21 #include <openssl/ec.h> 22 #ifndef OPENSSL_NO_ENGINE 23 # include <openssl/engine.h> 24 #endif 25 #include <openssl/err.h> 26 #include <openssl/obj_mac.h> 27 #include <openssl/objects.h> 28 #include <openssl/rand.h> 29 #include <openssl/bn.h> 30 #include <openssl/opensslconf.h> 31 #include <openssl/core_names.h> 32 #include <openssl/param_build.h> 33 #include <openssl/evp.h> 34 35 static size_t crv_len = 0; 36 static EC_builtin_curve *curves = NULL; 37 38 /* test multiplication with group order, long and negative scalars */ 39 static int group_order_tests(EC_GROUP *group) 40 { 41 BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL; 42 EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL; 43 const EC_POINT *G = NULL; 44 BN_CTX *ctx = NULL; 45 int i = 0, r = 0; 46 47 if (!TEST_ptr(n1 = BN_new()) 48 || !TEST_ptr(n2 = BN_new()) 49 || !TEST_ptr(order = BN_new()) 50 || !TEST_ptr(ctx = BN_CTX_new()) 51 || !TEST_ptr(G = EC_GROUP_get0_generator(group)) 52 || !TEST_ptr(P = EC_POINT_new(group)) 53 || !TEST_ptr(Q = EC_POINT_new(group)) 54 || !TEST_ptr(R = EC_POINT_new(group)) 55 || !TEST_ptr(S = EC_POINT_new(group))) 56 goto err; 57 58 if (!TEST_true(EC_GROUP_get_order(group, order, ctx)) 59 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 60 || !TEST_true(EC_POINT_is_at_infinity(group, Q)) 61 #ifndef OPENSSL_NO_DEPRECATED_3_0 62 || !TEST_true(EC_GROUP_precompute_mult(group, ctx)) 63 #endif 64 || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) 65 || !TEST_true(EC_POINT_is_at_infinity(group, Q)) 66 || !TEST_true(EC_POINT_copy(P, G)) 67 || !TEST_true(BN_one(n1)) 68 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx)) 69 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)) 70 || !TEST_true(BN_sub(n1, order, n1)) 71 || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx)) 72 || !TEST_true(EC_POINT_invert(group, Q, ctx)) 73 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))) 74 goto err; 75 76 for (i = 1; i <= 2; i++) { 77 #ifndef OPENSSL_NO_DEPRECATED_3_0 78 const BIGNUM *scalars[6]; 79 const EC_POINT *points[6]; 80 #endif 81 82 if (!TEST_true(BN_set_word(n1, i)) 83 /* 84 * If i == 1, P will be the predefined generator for which 85 * EC_GROUP_precompute_mult has set up precomputation. 86 */ 87 || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx)) 88 || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx))) 89 || !TEST_true(BN_one(n1)) 90 /* n1 = 1 - order */ 91 || !TEST_true(BN_sub(n1, n1, order)) 92 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx)) 93 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)) 94 95 /* n2 = 1 + order */ 96 || !TEST_true(BN_add(n2, order, BN_value_one())) 97 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 98 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)) 99 100 /* n2 = (1 - order) * (1 + order) = 1 - order^2 */ 101 || !TEST_true(BN_mul(n2, n1, n2, ctx)) 102 || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 103 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))) 104 goto err; 105 106 /* n2 = order^2 - 1 */ 107 BN_set_negative(n2, 0); 108 if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx)) 109 /* Add P to verify the result. */ 110 || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx)) 111 || !TEST_true(EC_POINT_is_at_infinity(group, Q)) 112 || !TEST_false(EC_POINT_is_at_infinity(group, P))) 113 goto err; 114 115 #ifndef OPENSSL_NO_DEPRECATED_3_0 116 /* Exercise EC_POINTs_mul, including corner cases. */ 117 scalars[0] = scalars[1] = BN_value_one(); 118 points[0] = points[1] = P; 119 120 if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx)) 121 || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx)) 122 || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx))) 123 goto err; 124 125 scalars[0] = n1; 126 points[0] = Q; /* => infinity */ 127 scalars[1] = n2; 128 points[1] = P; /* => -P */ 129 scalars[2] = n1; 130 points[2] = Q; /* => infinity */ 131 scalars[3] = n2; 132 points[3] = Q; /* => infinity */ 133 scalars[4] = n1; 134 points[4] = P; /* => P */ 135 scalars[5] = n2; 136 points[5] = Q; /* => infinity */ 137 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx)) 138 || !TEST_true(EC_POINT_is_at_infinity(group, P))) 139 goto err; 140 #endif 141 } 142 143 r = 1; 144 err: 145 if (r == 0 && i != 0) 146 TEST_info(i == 1 ? "allowing precomputation" : 147 "without precomputation"); 148 EC_POINT_free(P); 149 EC_POINT_free(Q); 150 EC_POINT_free(R); 151 EC_POINT_free(S); 152 BN_free(n1); 153 BN_free(n2); 154 BN_free(order); 155 BN_CTX_free(ctx); 156 return r; 157 } 158 159 static int prime_field_tests(void) 160 { 161 BN_CTX *ctx = NULL; 162 BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL; 163 EC_GROUP *group = NULL; 164 EC_POINT *P = NULL, *Q = NULL, *R = NULL; 165 BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL; 166 #ifndef OPENSSL_NO_DEPRECATED_3_0 167 const EC_POINT *points[4]; 168 const BIGNUM *scalars[4]; 169 #endif 170 unsigned char buf[100]; 171 size_t len, r = 0; 172 int k; 173 174 if (!TEST_ptr(ctx = BN_CTX_new()) 175 || !TEST_ptr(p = BN_new()) 176 || !TEST_ptr(a = BN_new()) 177 || !TEST_ptr(b = BN_new()) 178 || !TEST_true(BN_hex2bn(&p, "17")) 179 || !TEST_true(BN_hex2bn(&a, "1")) 180 || !TEST_true(BN_hex2bn(&b, "1")) 181 || !TEST_ptr(group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) 182 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))) 183 goto err; 184 185 TEST_info("Curve defined by Weierstrass equation"); 186 TEST_note(" y^2 = x^3 + a*x + b (mod p)"); 187 test_output_bignum("a", a); 188 test_output_bignum("b", b); 189 test_output_bignum("p", p); 190 191 buf[0] = 0; 192 if (!TEST_ptr(P = EC_POINT_new(group)) 193 || !TEST_ptr(Q = EC_POINT_new(group)) 194 || !TEST_ptr(R = EC_POINT_new(group)) 195 || !TEST_true(EC_POINT_set_to_infinity(group, P)) 196 || !TEST_true(EC_POINT_is_at_infinity(group, P)) 197 || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx)) 198 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)) 199 || !TEST_true(EC_POINT_is_at_infinity(group, P)) 200 || !TEST_ptr(x = BN_new()) 201 || !TEST_ptr(y = BN_new()) 202 || !TEST_ptr(z = BN_new()) 203 || !TEST_ptr(yplusone = BN_new()) 204 || !TEST_true(BN_hex2bn(&x, "D")) 205 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx))) 206 goto err; 207 208 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) { 209 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx))) 210 goto err; 211 TEST_info("Point is not on curve"); 212 test_output_bignum("x", x); 213 test_output_bignum("y", y); 214 goto err; 215 } 216 217 TEST_note("A cyclic subgroup:"); 218 k = 100; 219 do { 220 if (!TEST_int_ne(k--, 0)) 221 goto err; 222 223 if (EC_POINT_is_at_infinity(group, P)) { 224 TEST_note(" point at infinity"); 225 } else { 226 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, 227 ctx))) 228 goto err; 229 230 test_output_bignum("x", x); 231 test_output_bignum("y", y); 232 } 233 234 if (!TEST_true(EC_POINT_copy(R, P)) 235 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))) 236 goto err; 237 238 } while (!EC_POINT_is_at_infinity(group, P)); 239 240 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx)) 241 || !TEST_true(EC_POINT_is_at_infinity(group, P))) 242 goto err; 243 244 len = 245 EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, 246 sizeof(buf), ctx); 247 if (!TEST_size_t_ne(len, 0) 248 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx)) 249 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx))) 250 goto err; 251 test_output_memory("Generator as octet string, compressed form:", 252 buf, len); 253 254 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, 255 buf, sizeof(buf), ctx); 256 if (!TEST_size_t_ne(len, 0) 257 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx)) 258 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx))) 259 goto err; 260 test_output_memory("Generator as octet string, uncompressed form:", 261 buf, len); 262 263 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, 264 buf, sizeof(buf), ctx); 265 if (!TEST_size_t_ne(len, 0) 266 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx)) 267 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx))) 268 goto err; 269 test_output_memory("Generator as octet string, hybrid form:", 270 buf, len); 271 272 if (!TEST_true(EC_POINT_invert(group, P, ctx)) 273 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)) 274 275 /* 276 * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, 277 * 2000) -- not a NIST curve, but commonly used 278 */ 279 280 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF" 281 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) 282 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) 283 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF" 284 "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) 285 || !TEST_true(BN_hex2bn(&b, "1C97BEFC" 286 "54BD7A8B65ACF89F81D4D4ADC565FA45")) 287 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) 288 || !TEST_true(BN_hex2bn(&x, "4A96B568" 289 "8EF573284664698968C38BB913CBFC82")) 290 || !TEST_true(BN_hex2bn(&y, "23a62855" 291 "3168947d59dcc912042351377ac5fb32")) 292 || !TEST_true(BN_add(yplusone, y, BN_value_one())) 293 /* 294 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 295 * and therefore setting the coordinates should fail. 296 */ 297 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, 298 ctx)) 299 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) 300 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 301 || !TEST_true(BN_hex2bn(&z, "0100000000" 302 "000000000001F4C8F927AED3CA752257")) 303 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one())) 304 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx))) 305 goto err; 306 TEST_info("SEC2 curve secp160r1 -- Generator"); 307 test_output_bignum("x", x); 308 test_output_bignum("y", y); 309 /* G_y value taken from the standard: */ 310 if (!TEST_true(BN_hex2bn(&z, "23a62855" 311 "3168947d59dcc912042351377ac5fb32")) 312 || !TEST_BN_eq(y, z) 313 || !TEST_int_eq(EC_GROUP_get_degree(group), 160) 314 || !group_order_tests(group) 315 316 /* Curve P-192 (FIPS PUB 186-2, App. 6) */ 317 318 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFF" 319 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) 320 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) 321 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFF" 322 "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) 323 || !TEST_true(BN_hex2bn(&b, "64210519E59C80E7" 324 "0FA7E9AB72243049FEB8DEECC146B9B1")) 325 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) 326 || !TEST_true(BN_hex2bn(&x, "188DA80EB03090F6" 327 "7CBF20EB43A18800F4FF0AFD82FF1012")) 328 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 329 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 330 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFF" 331 "FFFFFFFF99DEF836146BC9B1B4D22831")) 332 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one())) 333 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx))) 334 goto err; 335 336 TEST_info("NIST curve P-192 -- Generator"); 337 test_output_bignum("x", x); 338 test_output_bignum("y", y); 339 /* G_y value taken from the standard: */ 340 if (!TEST_true(BN_hex2bn(&z, "07192B95FFC8DA78" 341 "631011ED6B24CDD573F977A11E794811")) 342 || !TEST_BN_eq(y, z) 343 || !TEST_true(BN_add(yplusone, y, BN_value_one())) 344 /* 345 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 346 * and therefore setting the coordinates should fail. 347 */ 348 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, 349 ctx)) 350 || !TEST_int_eq(EC_GROUP_get_degree(group), 192) 351 || !group_order_tests(group) 352 353 /* Curve P-224 (FIPS PUB 186-2, App. 6) */ 354 355 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFF" 356 "FFFFFFFF000000000000000000000001")) 357 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) 358 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFF" 359 "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) 360 || !TEST_true(BN_hex2bn(&b, "B4050A850C04B3ABF5413256" 361 "5044B0B7D7BFD8BA270B39432355FFB4")) 362 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) 363 || !TEST_true(BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B9" 364 "4A03C1D356C21122343280D6115C1D21")) 365 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) 366 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 367 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF" 368 "FFFF16A2E0B8F03E13DD29455C5C2A3D")) 369 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one())) 370 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx))) 371 goto err; 372 373 TEST_info("NIST curve P-224 -- Generator"); 374 test_output_bignum("x", x); 375 test_output_bignum("y", y); 376 /* G_y value taken from the standard: */ 377 if (!TEST_true(BN_hex2bn(&z, "BD376388B5F723FB4C22DFE6" 378 "CD4375A05A07476444D5819985007E34")) 379 || !TEST_BN_eq(y, z) 380 || !TEST_true(BN_add(yplusone, y, BN_value_one())) 381 /* 382 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 383 * and therefore setting the coordinates should fail. 384 */ 385 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, 386 ctx)) 387 || !TEST_int_eq(EC_GROUP_get_degree(group), 224) 388 || !group_order_tests(group) 389 390 /* Curve P-256 (FIPS PUB 186-2, App. 6) */ 391 392 || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000" 393 "00000000FFFFFFFFFFFFFFFFFFFFFFFF")) 394 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) 395 || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000" 396 "00000000FFFFFFFFFFFFFFFFFFFFFFFC")) 397 || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC" 398 "651D06B0CC53B0F63BCE3C3E27D2604B")) 399 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) 400 401 || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2" 402 "77037D812DEB33A0F4A13945D898C296")) 403 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 404 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 405 || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF" 406 "BCE6FAADA7179E84F3B9CAC2FC632551")) 407 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one())) 408 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx))) 409 goto err; 410 411 TEST_info("NIST curve P-256 -- Generator"); 412 test_output_bignum("x", x); 413 test_output_bignum("y", y); 414 /* G_y value taken from the standard: */ 415 if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16" 416 "2BCE33576B315ECECBB6406837BF51F5")) 417 || !TEST_BN_eq(y, z) 418 || !TEST_true(BN_add(yplusone, y, BN_value_one())) 419 /* 420 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 421 * and therefore setting the coordinates should fail. 422 */ 423 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, 424 ctx)) 425 || !TEST_int_eq(EC_GROUP_get_degree(group), 256) 426 || !group_order_tests(group) 427 428 /* Curve P-384 (FIPS PUB 186-2, App. 6) */ 429 430 || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 431 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" 432 "FFFFFFFF0000000000000000FFFFFFFF")) 433 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) 434 || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 435 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" 436 "FFFFFFFF0000000000000000FFFFFFFC")) 437 || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19" 438 "181D9C6EFE8141120314088F5013875A" 439 "C656398D8A2ED19D2A85C8EDD3EC2AEF")) 440 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) 441 442 || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74" 443 "6E1D3B628BA79B9859F741E082542A38" 444 "5502F25DBF55296C3A545E3872760AB7")) 445 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx)) 446 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 447 || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 448 "FFFFFFFFFFFFFFFFC7634D81F4372DDF" 449 "581A0DB248B0A77AECEC196ACCC52973")) 450 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one())) 451 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx))) 452 goto err; 453 454 TEST_info("NIST curve P-384 -- Generator"); 455 test_output_bignum("x", x); 456 test_output_bignum("y", y); 457 /* G_y value taken from the standard: */ 458 if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29" 459 "F8F41DBD289A147CE9DA3113B5F0B8C0" 460 "0A60B1CE1D7E819D7A431D7C90EA0E5F")) 461 || !TEST_BN_eq(y, z) 462 || !TEST_true(BN_add(yplusone, y, BN_value_one())) 463 /* 464 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 465 * and therefore setting the coordinates should fail. 466 */ 467 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, 468 ctx)) 469 || !TEST_int_eq(EC_GROUP_get_degree(group), 384) 470 || !group_order_tests(group) 471 472 /* Curve P-521 (FIPS PUB 186-2, App. 6) */ 473 || !TEST_true(BN_hex2bn(&p, "1FF" 474 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 475 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 476 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 477 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) 478 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) 479 || !TEST_true(BN_hex2bn(&a, "1FF" 480 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 481 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 482 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 483 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")) 484 || !TEST_true(BN_hex2bn(&b, "051" 485 "953EB9618E1C9A1F929A21A0B68540EE" 486 "A2DA725B99B315F3B8B489918EF109E1" 487 "56193951EC7E937B1652C0BD3BB1BF07" 488 "3573DF883D2C34F1EF451FD46B503F00")) 489 || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) 490 || !TEST_true(BN_hex2bn(&x, "C6" 491 "858E06B70404E9CD9E3ECB662395B442" 492 "9C648139053FB521F828AF606B4D3DBA" 493 "A14B5E77EFE75928FE1DC127A2FFA8DE" 494 "3348B3C1856A429BF97E7E31C2E5BD66")) 495 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx)) 496 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 497 || !TEST_true(BN_hex2bn(&z, "1FF" 498 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 499 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA" 500 "51868783BF2F966B7FCC0148F709A5D0" 501 "3BB5C9B8899C47AEBB6FB71E91386409")) 502 || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one())) 503 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx))) 504 goto err; 505 506 TEST_info("NIST curve P-521 -- Generator"); 507 test_output_bignum("x", x); 508 test_output_bignum("y", y); 509 /* G_y value taken from the standard: */ 510 if (!TEST_true(BN_hex2bn(&z, "118" 511 "39296A789A3BC0045C8A5FB42C7D1BD9" 512 "98F54449579B446817AFBD17273E662C" 513 "97EE72995EF42640C550B9013FAD0761" 514 "353C7086A272C24088BE94769FD16650")) 515 || !TEST_BN_eq(y, z) 516 || !TEST_true(BN_add(yplusone, y, BN_value_one())) 517 /* 518 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 519 * and therefore setting the coordinates should fail. 520 */ 521 || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, 522 ctx)) 523 || !TEST_int_eq(EC_GROUP_get_degree(group), 521) 524 || !group_order_tests(group) 525 526 /* more tests using the last curve */ 527 528 /* Restore the point that got mangled in the (x, y + 1) test. */ 529 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) 530 || !TEST_true(EC_POINT_copy(Q, P)) 531 || !TEST_false(EC_POINT_is_at_infinity(group, Q)) 532 || !TEST_true(EC_POINT_dbl(group, P, P, ctx)) 533 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 534 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */ 535 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx)) 536 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx)) 537 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */ 538 || !TEST_false(EC_POINT_is_at_infinity(group, Q))) 539 goto err; 540 541 #ifndef OPENSSL_NO_DEPRECATED_3_0 542 TEST_note("combined multiplication ..."); 543 points[0] = Q; 544 points[1] = Q; 545 points[2] = Q; 546 points[3] = Q; 547 548 if (!TEST_true(EC_GROUP_get_order(group, z, ctx)) 549 || !TEST_true(BN_add(y, z, BN_value_one())) 550 || !TEST_BN_even(y) 551 || !TEST_true(BN_rshift1(y, y))) 552 goto err; 553 554 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ 555 scalars[1] = y; 556 557 /* z is still the group order */ 558 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 559 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) 560 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)) 561 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx)) 562 || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0)) 563 || !TEST_true(BN_add(z, z, y))) 564 goto err; 565 BN_set_negative(z, 1); 566 scalars[0] = y; 567 scalars[1] = z; /* z = -(order + y) */ 568 569 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 570 || !TEST_true(EC_POINT_is_at_infinity(group, P)) 571 || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0)) 572 || !TEST_true(BN_add(z, x, y))) 573 goto err; 574 BN_set_negative(z, 1); 575 scalars[0] = x; 576 scalars[1] = y; 577 scalars[2] = z; /* z = -(x+y) */ 578 579 if (!TEST_ptr(scalar3 = BN_new())) 580 goto err; 581 BN_zero(scalar3); 582 scalars[3] = scalar3; 583 584 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) 585 || !TEST_true(EC_POINT_is_at_infinity(group, P))) 586 goto err; 587 #endif 588 TEST_note(" ok\n"); 589 r = 1; 590 err: 591 BN_CTX_free(ctx); 592 BN_free(p); 593 BN_free(a); 594 BN_free(b); 595 EC_GROUP_free(group); 596 EC_POINT_free(P); 597 EC_POINT_free(Q); 598 EC_POINT_free(R); 599 BN_free(x); 600 BN_free(y); 601 BN_free(z); 602 BN_free(yplusone); 603 BN_free(scalar3); 604 return r; 605 } 606 607 #ifndef OPENSSL_NO_EC2M 608 609 static struct c2_curve_test { 610 const char *name; 611 const char *p; 612 const char *a; 613 const char *b; 614 const char *x; 615 const char *y; 616 int ybit; 617 const char *order; 618 const char *cof; 619 int degree; 620 } char2_curve_tests[] = { 621 /* Curve K-163 (FIPS PUB 186-2, App. 6) */ 622 { 623 "NIST curve K-163", 624 "0800000000000000000000000000000000000000C9", 625 "1", 626 "1", 627 "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", 628 "0289070FB05D38FF58321F2E800536D538CCDAA3D9", 629 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163 630 }, 631 /* Curve B-163 (FIPS PUB 186-2, App. 6) */ 632 { 633 "NIST curve B-163", 634 "0800000000000000000000000000000000000000C9", 635 "1", 636 "020A601907B8C953CA1481EB10512F78744A3205FD", 637 "03F0EBA16286A2D57EA0991168D4994637E8343E36", 638 "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", 639 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163 640 }, 641 /* Curve K-233 (FIPS PUB 186-2, App. 6) */ 642 { 643 "NIST curve K-233", 644 "020000000000000000000000000000000000000004000000000000000001", 645 "0", 646 "1", 647 "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", 648 "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", 649 0, 650 "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", 651 "4", 233 652 }, 653 /* Curve B-233 (FIPS PUB 186-2, App. 6) */ 654 { 655 "NIST curve B-233", 656 "020000000000000000000000000000000000000004000000000000000001", 657 "000000000000000000000000000000000000000000000000000000000001", 658 "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", 659 "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", 660 "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", 661 1, 662 "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 663 "2", 233 664 }, 665 /* Curve K-283 (FIPS PUB 186-2, App. 6) */ 666 { 667 "NIST curve K-283", 668 "08000000" 669 "00000000000000000000000000000000000000000000000000000000000010A1", 670 "0", 671 "1", 672 "0503213F" 673 "78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", 674 "01CCDA38" 675 "0F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", 676 0, 677 "01FFFFFF" 678 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", 679 "4", 283 680 }, 681 /* Curve B-283 (FIPS PUB 186-2, App. 6) */ 682 { 683 "NIST curve B-283", 684 "08000000" 685 "00000000000000000000000000000000000000000000000000000000000010A1", 686 "00000000" 687 "0000000000000000000000000000000000000000000000000000000000000001", 688 "027B680A" 689 "C8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 690 "05F93925" 691 "8DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", 692 "03676854" 693 "FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", 694 1, 695 "03FFFFFF" 696 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 697 "2", 283 698 }, 699 /* Curve K-409 (FIPS PUB 186-2, App. 6) */ 700 { 701 "NIST curve K-409", 702 "0200000000000000000000000000000000000000" 703 "0000000000000000000000000000000000000000008000000000000000000001", 704 "0", 705 "1", 706 "0060F05F658F49C1AD3AB1890F7184210EFD0987" 707 "E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", 708 "01E369050B7C4E42ACBA1DACBF04299C3460782F" 709 "918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", 710 1, 711 "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 712 "FFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", 713 "4", 409 714 }, 715 /* Curve B-409 (FIPS PUB 186-2, App. 6) */ 716 { 717 "NIST curve B-409", 718 "0200000000000000000000000000000000000000" 719 "0000000000000000000000000000000000000000008000000000000000000001", 720 "0000000000000000000000000000000000000000" 721 "0000000000000000000000000000000000000000000000000000000000000001", 722 "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422E" 723 "F1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", 724 "015D4860D088DDB3496B0C6064756260441CDE4A" 725 "F1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", 726 "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5" 727 "A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", 728 1, 729 "0100000000000000000000000000000000000000" 730 "00000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", 731 "2", 409 732 }, 733 /* Curve K-571 (FIPS PUB 186-2, App. 6) */ 734 { 735 "NIST curve K-571", 736 "800000000000000" 737 "0000000000000000000000000000000000000000000000000000000000000000" 738 "0000000000000000000000000000000000000000000000000000000000000425", 739 "0", 740 "1", 741 "026EB7A859923FBC" 742 "82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E6" 743 "47DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", 744 "0349DC807F4FBF37" 745 "4F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA7" 746 "4FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", 747 0, 748 "0200000000000000" 749 "00000000000000000000000000000000000000000000000000000000131850E1" 750 "F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", 751 "4", 571 752 }, 753 /* Curve B-571 (FIPS PUB 186-2, App. 6) */ 754 { 755 "NIST curve B-571", 756 "800000000000000" 757 "0000000000000000000000000000000000000000000000000000000000000000" 758 "0000000000000000000000000000000000000000000000000000000000000425", 759 "0000000000000000" 760 "0000000000000000000000000000000000000000000000000000000000000000" 761 "0000000000000000000000000000000000000000000000000000000000000001", 762 "02F40E7E2221F295" 763 "DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA5933" 764 "2BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", 765 "0303001D34B85629" 766 "6C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293" 767 "CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", 768 "037BF27342DA639B" 769 "6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A57" 770 "6291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", 771 1, 772 "03FFFFFFFFFFFFFF" 773 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18" 774 "FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", 775 "2", 571 776 } 777 }; 778 779 static int char2_curve_test(int n) 780 { 781 int r = 0; 782 BN_CTX *ctx = NULL; 783 BIGNUM *p = NULL, *a = NULL, *b = NULL; 784 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL; 785 EC_GROUP *group = NULL; 786 EC_POINT *P = NULL, *Q = NULL, *R = NULL; 787 # ifndef OPENSSL_NO_DEPRECATED_3_0 788 const EC_POINT *points[3]; 789 const BIGNUM *scalars[3]; 790 # endif 791 struct c2_curve_test *const test = char2_curve_tests + n; 792 793 if (!TEST_ptr(ctx = BN_CTX_new()) 794 || !TEST_ptr(p = BN_new()) 795 || !TEST_ptr(a = BN_new()) 796 || !TEST_ptr(b = BN_new()) 797 || !TEST_ptr(x = BN_new()) 798 || !TEST_ptr(y = BN_new()) 799 || !TEST_ptr(z = BN_new()) 800 || !TEST_ptr(yplusone = BN_new()) 801 || !TEST_true(BN_hex2bn(&p, test->p)) 802 || !TEST_true(BN_hex2bn(&a, test->a)) 803 || !TEST_true(BN_hex2bn(&b, test->b)) 804 || !TEST_true(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) 805 || !TEST_ptr(P = EC_POINT_new(group)) 806 || !TEST_ptr(Q = EC_POINT_new(group)) 807 || !TEST_ptr(R = EC_POINT_new(group)) 808 || !TEST_true(BN_hex2bn(&x, test->x)) 809 || !TEST_true(BN_hex2bn(&y, test->y)) 810 || !TEST_true(BN_add(yplusone, y, BN_value_one()))) 811 goto err; 812 813 /* Change test based on whether binary point compression is enabled or not. */ 814 # ifdef OPENSSL_EC_BIN_PT_COMP 815 /* 816 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 817 * and therefore setting the coordinates should fail. 818 */ 819 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx)) 820 || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 821 test->y_bit, 822 ctx)) 823 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 824 || !TEST_true(BN_hex2bn(&z, test->order)) 825 || !TEST_true(BN_hex2bn(&cof, test->cof)) 826 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof)) 827 || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx))) 828 goto err; 829 TEST_info("%s -- Generator", test->name); 830 test_output_bignum("x", x); 831 test_output_bignum("y", y); 832 /* G_y value taken from the standard: */ 833 if (!TEST_true(BN_hex2bn(&z, test->y)) 834 || !TEST_BN_eq(y, z)) 835 goto err; 836 # else 837 /* 838 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 839 * and therefore setting the coordinates should fail. 840 */ 841 if (!TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone, ctx)) 842 || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) 843 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 844 || !TEST_true(BN_hex2bn(&z, test->order)) 845 || !TEST_true(BN_hex2bn(&cof, test->cof)) 846 || !TEST_true(EC_GROUP_set_generator(group, P, z, cof))) 847 goto err; 848 TEST_info("%s -- Generator:", test->name); 849 test_output_bignum("x", x); 850 test_output_bignum("y", y); 851 # endif 852 853 if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree) 854 || !group_order_tests(group)) 855 goto err; 856 857 /* more tests using the last curve */ 858 if (n == OSSL_NELEM(char2_curve_tests) - 1) { 859 if (!TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx)) 860 || !TEST_true(EC_POINT_copy(Q, P)) 861 || !TEST_false(EC_POINT_is_at_infinity(group, Q)) 862 || !TEST_true(EC_POINT_dbl(group, P, P, ctx)) 863 || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0) 864 || !TEST_true(EC_POINT_invert(group, Q, ctx)) /* P = -2Q */ 865 || !TEST_true(EC_POINT_add(group, R, P, Q, ctx)) 866 || !TEST_true(EC_POINT_add(group, R, R, Q, ctx)) 867 || !TEST_true(EC_POINT_is_at_infinity(group, R)) /* R = P + 2Q */ 868 || !TEST_false(EC_POINT_is_at_infinity(group, Q))) 869 goto err; 870 871 # ifndef OPENSSL_NO_DEPRECATED_3_0 872 TEST_note("combined multiplication ..."); 873 points[0] = Q; 874 points[1] = Q; 875 points[2] = Q; 876 877 if (!TEST_true(BN_add(y, z, BN_value_one())) 878 || !TEST_BN_even(y) 879 || !TEST_true(BN_rshift1(y, y))) 880 goto err; 881 scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ 882 scalars[1] = y; 883 884 /* z is still the group order */ 885 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 886 || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) 887 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx)) 888 || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))) 889 goto err; 890 891 if (!TEST_true(BN_rand(y, BN_num_bits(y), 0, 0)) 892 || !TEST_true(BN_add(z, z, y))) 893 goto err; 894 BN_set_negative(z, 1); 895 scalars[0] = y; 896 scalars[1] = z; /* z = -(order + y) */ 897 898 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) 899 || !TEST_true(EC_POINT_is_at_infinity(group, P))) 900 goto err; 901 902 if (!TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0)) 903 || !TEST_true(BN_add(z, x, y))) 904 goto err; 905 BN_set_negative(z, 1); 906 scalars[0] = x; 907 scalars[1] = y; 908 scalars[2] = z; /* z = -(x+y) */ 909 910 if (!TEST_true(EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) 911 || !TEST_true(EC_POINT_is_at_infinity(group, P))) 912 goto err; 913 # endif 914 } 915 916 r = 1; 917 err: 918 BN_CTX_free(ctx); 919 BN_free(p); 920 BN_free(a); 921 BN_free(b); 922 BN_free(x); 923 BN_free(y); 924 BN_free(z); 925 BN_free(yplusone); 926 BN_free(cof); 927 EC_POINT_free(P); 928 EC_POINT_free(Q); 929 EC_POINT_free(R); 930 EC_GROUP_free(group); 931 return r; 932 } 933 934 static int char2_field_tests(void) 935 { 936 BN_CTX *ctx = NULL; 937 BIGNUM *p = NULL, *a = NULL, *b = NULL; 938 EC_GROUP *group = NULL; 939 EC_POINT *P = NULL, *Q = NULL, *R = NULL; 940 BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL; 941 unsigned char buf[100]; 942 size_t len; 943 int k, r = 0; 944 945 if (!TEST_ptr(ctx = BN_CTX_new()) 946 || !TEST_ptr(p = BN_new()) 947 || !TEST_ptr(a = BN_new()) 948 || !TEST_ptr(b = BN_new()) 949 || !TEST_true(BN_hex2bn(&p, "13")) 950 || !TEST_true(BN_hex2bn(&a, "3")) 951 || !TEST_true(BN_hex2bn(&b, "1"))) 952 goto err; 953 954 if (!TEST_ptr(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) 955 || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))) 956 goto err; 957 958 TEST_info("Curve defined by Weierstrass equation"); 959 TEST_note(" y^2 + x*y = x^3 + a*x^2 + b (mod p)"); 960 test_output_bignum("a", a); 961 test_output_bignum("b", b); 962 test_output_bignum("p", p); 963 964 if (!TEST_ptr(P = EC_POINT_new(group)) 965 || !TEST_ptr(Q = EC_POINT_new(group)) 966 || !TEST_ptr(R = EC_POINT_new(group)) 967 || !TEST_true(EC_POINT_set_to_infinity(group, P)) 968 || !TEST_true(EC_POINT_is_at_infinity(group, P))) 969 goto err; 970 971 buf[0] = 0; 972 if (!TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx)) 973 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)) 974 || !TEST_true(EC_POINT_is_at_infinity(group, P)) 975 || !TEST_ptr(x = BN_new()) 976 || !TEST_ptr(y = BN_new()) 977 || !TEST_ptr(z = BN_new()) 978 || !TEST_ptr(cof = BN_new()) 979 || !TEST_ptr(yplusone = BN_new()) 980 || !TEST_true(BN_hex2bn(&x, "6")) 981 /* Change test based on whether binary point compression is enabled or not. */ 982 # ifdef OPENSSL_EC_BIN_PT_COMP 983 || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)) 984 # else 985 || !TEST_true(BN_hex2bn(&y, "8")) 986 || !TEST_true(EC_POINT_set_affine_coordinates(group, Q, x, y, ctx)) 987 # endif 988 ) 989 goto err; 990 if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) { 991 /* Change test based on whether binary point compression is enabled or not. */ 992 # ifdef OPENSSL_EC_BIN_PT_COMP 993 if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx))) 994 goto err; 995 # endif 996 TEST_info("Point is not on curve"); 997 test_output_bignum("x", x); 998 test_output_bignum("y", y); 999 goto err; 1000 } 1001 1002 TEST_note("A cyclic subgroup:"); 1003 k = 100; 1004 do { 1005 if (!TEST_int_ne(k--, 0)) 1006 goto err; 1007 1008 if (EC_POINT_is_at_infinity(group, P)) 1009 TEST_note(" point at infinity"); 1010 else { 1011 if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, 1012 ctx))) 1013 goto err; 1014 1015 test_output_bignum("x", x); 1016 test_output_bignum("y", y); 1017 } 1018 1019 if (!TEST_true(EC_POINT_copy(R, P)) 1020 || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))) 1021 goto err; 1022 } 1023 while (!EC_POINT_is_at_infinity(group, P)); 1024 1025 if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx)) 1026 || !TEST_true(EC_POINT_is_at_infinity(group, P))) 1027 goto err; 1028 1029 /* Change test based on whether binary point compression is enabled or not. */ 1030 # ifdef OPENSSL_EC_BIN_PT_COMP 1031 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, 1032 buf, sizeof(buf), ctx); 1033 if (!TEST_size_t_ne(len, 0) 1034 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx)) 1035 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx))) 1036 goto err; 1037 test_output_memory("Generator as octet string, compressed form:", 1038 buf, len); 1039 # endif 1040 1041 len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, 1042 buf, sizeof(buf), ctx); 1043 if (!TEST_size_t_ne(len, 0) 1044 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx)) 1045 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx))) 1046 goto err; 1047 test_output_memory("Generator as octet string, uncompressed form:", 1048 buf, len); 1049 1050 /* Change test based on whether binary point compression is enabled or not. */ 1051 # ifdef OPENSSL_EC_BIN_PT_COMP 1052 len = 1053 EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof(buf), 1054 ctx); 1055 if (!TEST_size_t_ne(len, 0) 1056 || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx)) 1057 || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx))) 1058 goto err; 1059 test_output_memory("Generator as octet string, hybrid form:", 1060 buf, len); 1061 # endif 1062 1063 if (!TEST_true(EC_POINT_invert(group, P, ctx)) 1064 || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))) 1065 goto err; 1066 1067 TEST_note("\n"); 1068 1069 r = 1; 1070 err: 1071 BN_CTX_free(ctx); 1072 BN_free(p); 1073 BN_free(a); 1074 BN_free(b); 1075 EC_GROUP_free(group); 1076 EC_POINT_free(P); 1077 EC_POINT_free(Q); 1078 EC_POINT_free(R); 1079 BN_free(x); 1080 BN_free(y); 1081 BN_free(z); 1082 BN_free(cof); 1083 BN_free(yplusone); 1084 return r; 1085 } 1086 1087 static int hybrid_point_encoding_test(void) 1088 { 1089 BIGNUM *x = NULL, *y = NULL; 1090 EC_GROUP *group = NULL; 1091 EC_POINT *point = NULL; 1092 unsigned char *buf = NULL; 1093 size_t len; 1094 int r = 0; 1095 1096 if (!TEST_true(BN_dec2bn(&x, "0")) 1097 || !TEST_true(BN_dec2bn(&y, "1")) 1098 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_sect571k1)) 1099 || !TEST_ptr(point = EC_POINT_new(group)) 1100 || !TEST_true(EC_POINT_set_affine_coordinates(group, point, x, y, NULL)) 1101 || !TEST_size_t_ne(0, (len = EC_POINT_point2oct(group, 1102 point, 1103 POINT_CONVERSION_HYBRID, 1104 NULL, 1105 0, 1106 NULL))) 1107 || !TEST_ptr(buf = OPENSSL_malloc(len)) 1108 || !TEST_size_t_eq(len, EC_POINT_point2oct(group, 1109 point, 1110 POINT_CONVERSION_HYBRID, 1111 buf, 1112 len, 1113 NULL))) 1114 goto err; 1115 1116 r = 1; 1117 1118 /* buf contains a valid hybrid point, check that we can decode it. */ 1119 if (!TEST_true(EC_POINT_oct2point(group, point, buf, len, NULL))) 1120 r = 0; 1121 1122 /* Flip the y_bit and verify that the invalid encoding is rejected. */ 1123 buf[0] ^= 1; 1124 if (!TEST_false(EC_POINT_oct2point(group, point, buf, len, NULL))) 1125 r = 0; 1126 1127 err: 1128 BN_free(x); 1129 BN_free(y); 1130 EC_GROUP_free(group); 1131 EC_POINT_free(point); 1132 OPENSSL_free(buf); 1133 return r; 1134 } 1135 #endif 1136 1137 static int internal_curve_test(int n) 1138 { 1139 EC_GROUP *group = NULL; 1140 int nid = curves[n].nid; 1141 1142 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) { 1143 TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n", 1144 OBJ_nid2sn(nid)); 1145 return 0; 1146 } 1147 if (!TEST_true(EC_GROUP_check(group, NULL))) { 1148 TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid)); 1149 EC_GROUP_free(group); 1150 return 0; 1151 } 1152 EC_GROUP_free(group); 1153 return 1; 1154 } 1155 1156 static int internal_curve_test_method(int n) 1157 { 1158 int r, nid = curves[n].nid; 1159 EC_GROUP *group; 1160 1161 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) { 1162 TEST_info("Curve %s failed\n", OBJ_nid2sn(nid)); 1163 return 0; 1164 } 1165 r = group_order_tests(group); 1166 EC_GROUP_free(group); 1167 return r; 1168 } 1169 1170 static int group_field_test(void) 1171 { 1172 int r = 1; 1173 BIGNUM *secp521r1_field = NULL; 1174 BIGNUM *sect163r2_field = NULL; 1175 EC_GROUP *secp521r1_group = NULL; 1176 EC_GROUP *sect163r2_group = NULL; 1177 1178 BN_hex2bn(&secp521r1_field, 1179 "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1180 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1181 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1182 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" 1183 "FFFF"); 1184 1185 1186 BN_hex2bn(§163r2_field, 1187 "08000000000000000000000000000000" 1188 "00000000C9"); 1189 1190 secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1); 1191 if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group))) 1192 r = 0; 1193 1194 # ifndef OPENSSL_NO_EC2M 1195 sect163r2_group = EC_GROUP_new_by_curve_name(NID_sect163r2); 1196 if (BN_cmp(sect163r2_field, EC_GROUP_get0_field(sect163r2_group))) 1197 r = 0; 1198 # endif 1199 1200 EC_GROUP_free(secp521r1_group); 1201 EC_GROUP_free(sect163r2_group); 1202 BN_free(secp521r1_field); 1203 BN_free(sect163r2_field); 1204 return r; 1205 } 1206 1207 /* 1208 * nistp_test_params contains magic numbers for testing 1209 * several NIST curves with characteristic > 3. 1210 */ 1211 struct nistp_test_params { 1212 const int nid; 1213 int degree; 1214 /* 1215 * Qx, Qy and D are taken from 1216 * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf 1217 * Otherwise, values are standard curve parameters from FIPS 180-3 1218 */ 1219 const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d; 1220 }; 1221 1222 static const struct nistp_test_params nistp_tests_params[] = { 1223 { 1224 /* P-224 */ 1225 NID_secp224r1, 1226 224, 1227 /* p */ 1228 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", 1229 /* a */ 1230 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", 1231 /* b */ 1232 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", 1233 /* Qx */ 1234 "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", 1235 /* Qy */ 1236 "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", 1237 /* Gx */ 1238 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", 1239 /* Gy */ 1240 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", 1241 /* order */ 1242 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 1243 /* d */ 1244 "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", 1245 }, 1246 { 1247 /* P-256 */ 1248 NID_X9_62_prime256v1, 1249 256, 1250 /* p */ 1251 "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 1252 /* a */ 1253 "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 1254 /* b */ 1255 "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 1256 /* Qx */ 1257 "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", 1258 /* Qy */ 1259 "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", 1260 /* Gx */ 1261 "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 1262 /* Gy */ 1263 "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 1264 /* order */ 1265 "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 1266 /* d */ 1267 "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", 1268 }, 1269 { 1270 /* P-521 */ 1271 NID_secp521r1, 1272 521, 1273 /* p */ 1274 "1ff" 1275 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 1276 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 1277 /* a */ 1278 "1ff" 1279 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 1280 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", 1281 /* b */ 1282 "051" 1283 "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1" 1284 "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", 1285 /* Qx */ 1286 "0098" 1287 "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e" 1288 "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", 1289 /* Qy */ 1290 "0164" 1291 "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8" 1292 "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", 1293 /* Gx */ 1294 "c6" 1295 "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba" 1296 "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", 1297 /* Gy */ 1298 "118" 1299 "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c" 1300 "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", 1301 /* order */ 1302 "1ff" 1303 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa" 1304 "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", 1305 /* d */ 1306 "0100" 1307 "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee" 1308 "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", 1309 }, 1310 }; 1311 1312 static int nistp_single_test(int idx) 1313 { 1314 const struct nistp_test_params *test = nistp_tests_params + idx; 1315 BN_CTX *ctx = NULL; 1316 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; 1317 BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL; 1318 EC_GROUP *NISTP = NULL; 1319 EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL; 1320 int r = 0; 1321 1322 TEST_note("NIST curve P-%d (optimised implementation):", 1323 test->degree); 1324 if (!TEST_ptr(ctx = BN_CTX_new()) 1325 || !TEST_ptr(p = BN_new()) 1326 || !TEST_ptr(a = BN_new()) 1327 || !TEST_ptr(b = BN_new()) 1328 || !TEST_ptr(x = BN_new()) 1329 || !TEST_ptr(y = BN_new()) 1330 || !TEST_ptr(m = BN_new()) 1331 || !TEST_ptr(n = BN_new()) 1332 || !TEST_ptr(order = BN_new()) 1333 || !TEST_ptr(yplusone = BN_new()) 1334 1335 || !TEST_ptr(NISTP = EC_GROUP_new_by_curve_name(test->nid)) 1336 || !TEST_true(BN_hex2bn(&p, test->p)) 1337 || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) 1338 || !TEST_true(BN_hex2bn(&a, test->a)) 1339 || !TEST_true(BN_hex2bn(&b, test->b)) 1340 || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx)) 1341 || !TEST_ptr(G = EC_POINT_new(NISTP)) 1342 || !TEST_ptr(P = EC_POINT_new(NISTP)) 1343 || !TEST_ptr(Q = EC_POINT_new(NISTP)) 1344 || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP)) 1345 || !TEST_true(BN_hex2bn(&x, test->Qx)) 1346 || !TEST_true(BN_hex2bn(&y, test->Qy)) 1347 || !TEST_true(BN_add(yplusone, y, BN_value_one())) 1348 /* 1349 * When (x, y) is on the curve, (x, y + 1) is, as it happens, not, 1350 * and therefore setting the coordinates should fail. 1351 */ 1352 || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, 1353 yplusone, ctx)) 1354 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y, 1355 ctx)) 1356 || !TEST_true(BN_hex2bn(&x, test->Gx)) 1357 || !TEST_true(BN_hex2bn(&y, test->Gy)) 1358 || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx)) 1359 || !TEST_true(BN_hex2bn(&order, test->order)) 1360 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) 1361 || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree)) 1362 goto err; 1363 1364 TEST_note("NIST test vectors ... "); 1365 if (!TEST_true(BN_hex2bn(&n, test->d))) 1366 goto err; 1367 /* fixed point multiplication */ 1368 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); 1369 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))) 1370 goto err; 1371 /* random point multiplication */ 1372 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); 1373 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1374 1375 /* set generator to P = 2*G, where G is the standard generator */ 1376 || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx)) 1377 || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) 1378 /* set the scalar to m=n/2, where n is the NIST test scalar */ 1379 || !TEST_true(BN_rshift(m, n, 1))) 1380 goto err; 1381 1382 /* test the non-standard generator */ 1383 /* fixed point multiplication */ 1384 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); 1385 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))) 1386 goto err; 1387 /* random point multiplication */ 1388 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); 1389 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1390 #ifndef OPENSSL_NO_DEPRECATED_3_0 1391 /* We have not performed precomp so this should be false */ 1392 || !TEST_false(EC_GROUP_have_precompute_mult(NISTP)) 1393 /* now repeat all tests with precomputation */ 1394 || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx)) 1395 #endif 1396 ) 1397 goto err; 1398 1399 /* fixed point multiplication */ 1400 EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); 1401 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))) 1402 goto err; 1403 /* random point multiplication */ 1404 EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); 1405 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) 1406 1407 /* reset generator */ 1408 || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))) 1409 goto err; 1410 /* fixed point multiplication */ 1411 EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); 1412 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))) 1413 goto err; 1414 /* random point multiplication */ 1415 EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); 1416 if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))) 1417 goto err; 1418 1419 /* regression test for felem_neg bug */ 1420 if (!TEST_true(BN_set_word(m, 32)) 1421 || !TEST_true(BN_set_word(n, 31)) 1422 || !TEST_true(EC_POINT_copy(P, G)) 1423 || !TEST_true(EC_POINT_invert(NISTP, P, ctx)) 1424 || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx)) 1425 || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx))) 1426 goto err; 1427 1428 r = 1; 1429 err: 1430 EC_GROUP_free(NISTP); 1431 EC_POINT_free(G); 1432 EC_POINT_free(P); 1433 EC_POINT_free(Q); 1434 EC_POINT_free(Q_CHECK); 1435 BN_free(n); 1436 BN_free(m); 1437 BN_free(p); 1438 BN_free(a); 1439 BN_free(b); 1440 BN_free(x); 1441 BN_free(y); 1442 BN_free(order); 1443 BN_free(yplusone); 1444 BN_CTX_free(ctx); 1445 return r; 1446 } 1447 1448 static const unsigned char p521_named[] = { 1449 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, 1450 }; 1451 1452 static const unsigned char p521_explicit[] = { 1453 0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a, 1454 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 1455 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1456 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1457 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1458 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1459 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1460 0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 1461 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1462 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1463 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1464 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1465 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1466 0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a, 1467 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72, 1468 0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09, 1469 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0, 1470 0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34, 1471 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00, 1472 0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17, 1473 0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04, 1474 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e, 1475 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, 1476 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 1477 0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 1478 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e, 1479 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 1480 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 1481 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 1482 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 1483 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 1484 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 1485 0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1486 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1487 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa, 1488 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 1489 0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae, 1490 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01, 1491 }; 1492 1493 /* 1494 * This test validates a named curve's group parameters using 1495 * EC_GROUP_check_named_curve(). It also checks that modifying any of the 1496 * group parameters results in the curve not being valid. 1497 */ 1498 static int check_named_curve_test(int id) 1499 { 1500 int ret = 0, nid, field_nid, has_seed; 1501 EC_GROUP *group = NULL, *gtest = NULL; 1502 const EC_POINT *group_gen = NULL; 1503 EC_POINT *other_gen = NULL; 1504 BIGNUM *group_p = NULL, *group_a = NULL, *group_b = NULL; 1505 BIGNUM *other_p = NULL, *other_a = NULL, *other_b = NULL; 1506 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL; 1507 BIGNUM *other_order = NULL; 1508 const BIGNUM *group_order = NULL; 1509 BN_CTX *bn_ctx = NULL; 1510 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED"; 1511 static size_t invalid_seed_len = sizeof(invalid_seed); 1512 1513 /* Do some setup */ 1514 nid = curves[id].nid; 1515 if (!TEST_ptr(bn_ctx = BN_CTX_new()) 1516 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) 1517 || !TEST_ptr(gtest = EC_GROUP_dup(group)) 1518 || !TEST_ptr(group_p = BN_new()) 1519 || !TEST_ptr(group_a = BN_new()) 1520 || !TEST_ptr(group_b = BN_new()) 1521 || !TEST_ptr(group_cofactor = BN_new()) 1522 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group)) 1523 || !TEST_ptr(group_order = EC_GROUP_get0_order(group)) 1524 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL)) 1525 || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL)) 1526 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group)) 1527 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL)) 1528 || !TEST_ptr(other_order = BN_dup(group_order)) 1529 || !TEST_true(BN_add_word(other_order, 1)) 1530 || !TEST_ptr(other_a = BN_dup(group_a)) 1531 || !TEST_true(BN_add_word(other_a, 1)) 1532 || !TEST_ptr(other_b = BN_dup(group_b)) 1533 || !TEST_true(BN_add_word(other_b, 1)) 1534 || !TEST_ptr(other_cofactor = BN_dup(group_cofactor)) 1535 || !TEST_true(BN_add_word(other_cofactor, 1))) 1536 goto err; 1537 1538 /* Determine if the built-in curve has a seed field set */ 1539 has_seed = (EC_GROUP_get_seed_len(group) > 0); 1540 field_nid = EC_GROUP_get_field_type(group); 1541 if (field_nid == NID_X9_62_characteristic_two_field) { 1542 if (!TEST_ptr(other_p = BN_dup(group_p)) 1543 || !TEST_true(BN_lshift1(other_p, other_p))) 1544 goto err; 1545 } else { 1546 if (!TEST_ptr(other_p = BN_dup(group_p))) 1547 goto err; 1548 /* 1549 * Just choosing any arbitrary prime does not work.. 1550 * Setting p via ec_GFp_nist_group_set_curve() needs the prime to be a 1551 * nist prime. So only select one of these as an alternate prime. 1552 */ 1553 if (!TEST_ptr(BN_copy(other_p, 1554 BN_ucmp(BN_get0_nist_prime_192(), other_p) == 0 ? 1555 BN_get0_nist_prime_256() : 1556 BN_get0_nist_prime_192()))) 1557 goto err; 1558 } 1559 1560 /* Passes because this is a valid curve */ 1561 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid) 1562 /* Only NIST curves pass */ 1563 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 1, NULL), 1564 EC_curve_nid2nist(nid) != NULL ? nid : NID_undef)) 1565 goto err; 1566 1567 /* Fail if the curve name doesn't match the parameters */ 1568 EC_GROUP_set_curve_name(group, nid + 1); 1569 ERR_set_mark(); 1570 if (!TEST_int_le(EC_GROUP_check_named_curve(group, 0, NULL), 0)) 1571 goto err; 1572 ERR_pop_to_mark(); 1573 1574 /* Restore curve name and ensure it's passing */ 1575 EC_GROUP_set_curve_name(group, nid); 1576 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)) 1577 goto err; 1578 1579 if (!TEST_int_eq(EC_GROUP_set_seed(group, invalid_seed, invalid_seed_len), 1580 invalid_seed_len)) 1581 goto err; 1582 1583 if (has_seed) { 1584 /* 1585 * If the built-in curve has a seed and we set the seed to another value 1586 * then it will fail the check. 1587 */ 1588 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), 0)) 1589 goto err; 1590 } else { 1591 /* 1592 * If the built-in curve does not have a seed then setting the seed will 1593 * pass the check (as the seed is optional). 1594 */ 1595 if (!TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)) 1596 goto err; 1597 } 1598 /* Pass if the seed is unknown (as it is optional) */ 1599 if (!TEST_int_eq(EC_GROUP_set_seed(group, NULL, 0), 1) 1600 || !TEST_int_eq(EC_GROUP_check_named_curve(group, 0, NULL), nid)) 1601 goto err; 1602 1603 /* Check that a duped group passes */ 1604 if (!TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)) 1605 goto err; 1606 1607 /* check that changing any generator parameter fails */ 1608 if (!TEST_true(EC_GROUP_set_generator(gtest, other_gen, group_order, 1609 group_cofactor)) 1610 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0) 1611 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, other_order, 1612 group_cofactor)) 1613 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0) 1614 /* The order is not an optional field, so this should fail */ 1615 || !TEST_false(EC_GROUP_set_generator(gtest, group_gen, NULL, 1616 group_cofactor)) 1617 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order, 1618 other_cofactor)) 1619 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), 0) 1620 /* Check that if the cofactor is not set then it still passes */ 1621 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order, 1622 NULL)) 1623 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid) 1624 /* check that restoring the generator passes */ 1625 || !TEST_true(EC_GROUP_set_generator(gtest, group_gen, group_order, 1626 group_cofactor)) 1627 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)) 1628 goto err; 1629 1630 /* 1631 * check that changing any curve parameter fails 1632 * 1633 * Setting arbitrary p, a or b might fail for some EC_GROUPs 1634 * depending on the internal EC_METHOD implementation, hence run 1635 * these tests conditionally to the success of EC_GROUP_set_curve(). 1636 */ 1637 ERR_set_mark(); 1638 if (EC_GROUP_set_curve(gtest, other_p, group_a, group_b, NULL)) { 1639 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)) 1640 goto err; 1641 } else { 1642 /* clear the error stack if EC_GROUP_set_curve() failed */ 1643 ERR_pop_to_mark(); 1644 ERR_set_mark(); 1645 } 1646 if (EC_GROUP_set_curve(gtest, group_p, other_a, group_b, NULL)) { 1647 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)) 1648 goto err; 1649 } else { 1650 /* clear the error stack if EC_GROUP_set_curve() failed */ 1651 ERR_pop_to_mark(); 1652 ERR_set_mark(); 1653 } 1654 if (EC_GROUP_set_curve(gtest, group_p, group_a, other_b, NULL)) { 1655 if (!TEST_int_le(EC_GROUP_check_named_curve(gtest, 0, NULL), 0)) 1656 goto err; 1657 } else { 1658 /* clear the error stack if EC_GROUP_set_curve() failed */ 1659 ERR_pop_to_mark(); 1660 ERR_set_mark(); 1661 } 1662 ERR_pop_to_mark(); 1663 1664 /* Check that restoring the curve parameters passes */ 1665 if (!TEST_true(EC_GROUP_set_curve(gtest, group_p, group_a, group_b, NULL)) 1666 || !TEST_int_eq(EC_GROUP_check_named_curve(gtest, 0, NULL), nid)) 1667 goto err; 1668 1669 ret = 1; 1670 err: 1671 BN_free(group_p); 1672 BN_free(other_p); 1673 BN_free(group_a); 1674 BN_free(other_a); 1675 BN_free(group_b); 1676 BN_free(other_b); 1677 BN_free(group_cofactor); 1678 BN_free(other_cofactor); 1679 BN_free(other_order); 1680 EC_POINT_free(other_gen); 1681 EC_GROUP_free(gtest); 1682 EC_GROUP_free(group); 1683 BN_CTX_free(bn_ctx); 1684 return ret; 1685 } 1686 1687 /* 1688 * This checks the lookup capability of EC_GROUP_check_named_curve() 1689 * when the given group was created with explicit parameters. 1690 * 1691 * It is possible to retrieve an alternative alias that does not match 1692 * the original nid in this case. 1693 */ 1694 static int check_named_curve_lookup_test(int id) 1695 { 1696 int ret = 0, nid, rv = 0; 1697 EC_GROUP *g = NULL , *ga = NULL; 1698 ECPARAMETERS *p = NULL, *pa = NULL; 1699 BN_CTX *ctx = NULL; 1700 1701 /* Do some setup */ 1702 nid = curves[id].nid; 1703 if (!TEST_ptr(ctx = BN_CTX_new()) 1704 || !TEST_ptr(g = EC_GROUP_new_by_curve_name(nid)) 1705 || !TEST_ptr(p = EC_GROUP_get_ecparameters(g, NULL))) 1706 goto err; 1707 1708 /* replace with group from explicit parameters */ 1709 EC_GROUP_free(g); 1710 if (!TEST_ptr(g = EC_GROUP_new_from_ecparameters(p))) 1711 goto err; 1712 1713 if (!TEST_int_gt(rv = EC_GROUP_check_named_curve(g, 0, NULL), 0)) 1714 goto err; 1715 if (rv != nid) { 1716 /* 1717 * Found an alias: 1718 * fail if the returned nid is not an alias of the original group. 1719 * 1720 * The comparison here is done by comparing two explicit 1721 * parameter EC_GROUPs with EC_GROUP_cmp(), to ensure the 1722 * comparison happens with unnamed EC_GROUPs using the same 1723 * EC_METHODs. 1724 */ 1725 if (!TEST_ptr(ga = EC_GROUP_new_by_curve_name(rv)) 1726 || !TEST_ptr(pa = EC_GROUP_get_ecparameters(ga, NULL))) 1727 goto err; 1728 1729 /* replace with group from explicit parameters, then compare */ 1730 EC_GROUP_free(ga); 1731 if (!TEST_ptr(ga = EC_GROUP_new_from_ecparameters(pa)) 1732 || !TEST_int_eq(EC_GROUP_cmp(g, ga, ctx), 0)) 1733 goto err; 1734 } 1735 1736 ret = 1; 1737 1738 err: 1739 EC_GROUP_free(g); 1740 EC_GROUP_free(ga); 1741 ECPARAMETERS_free(p); 1742 ECPARAMETERS_free(pa); 1743 BN_CTX_free(ctx); 1744 1745 return ret; 1746 } 1747 1748 /* 1749 * Sometime we cannot compare nids for equality, as the built-in curve table 1750 * includes aliases with different names for the same curve. 1751 * 1752 * This function returns TRUE (1) if the checked nids are identical, or if they 1753 * alias to the same curve. FALSE (0) otherwise. 1754 */ 1755 static ossl_inline 1756 int are_ec_nids_compatible(int n1d, int n2d) 1757 { 1758 int ret = 0; 1759 switch (n1d) { 1760 #ifndef OPENSSL_NO_EC2M 1761 case NID_sect113r1: 1762 case NID_wap_wsg_idm_ecid_wtls4: 1763 ret = (n2d == NID_sect113r1 || n2d == NID_wap_wsg_idm_ecid_wtls4); 1764 break; 1765 case NID_sect163k1: 1766 case NID_wap_wsg_idm_ecid_wtls3: 1767 ret = (n2d == NID_sect163k1 || n2d == NID_wap_wsg_idm_ecid_wtls3); 1768 break; 1769 case NID_sect233k1: 1770 case NID_wap_wsg_idm_ecid_wtls10: 1771 ret = (n2d == NID_sect233k1 || n2d == NID_wap_wsg_idm_ecid_wtls10); 1772 break; 1773 case NID_sect233r1: 1774 case NID_wap_wsg_idm_ecid_wtls11: 1775 ret = (n2d == NID_sect233r1 || n2d == NID_wap_wsg_idm_ecid_wtls11); 1776 break; 1777 case NID_X9_62_c2pnb163v1: 1778 case NID_wap_wsg_idm_ecid_wtls5: 1779 ret = (n2d == NID_X9_62_c2pnb163v1 1780 || n2d == NID_wap_wsg_idm_ecid_wtls5); 1781 break; 1782 #endif /* OPENSSL_NO_EC2M */ 1783 case NID_secp112r1: 1784 case NID_wap_wsg_idm_ecid_wtls6: 1785 ret = (n2d == NID_secp112r1 || n2d == NID_wap_wsg_idm_ecid_wtls6); 1786 break; 1787 case NID_secp160r2: 1788 case NID_wap_wsg_idm_ecid_wtls7: 1789 ret = (n2d == NID_secp160r2 || n2d == NID_wap_wsg_idm_ecid_wtls7); 1790 break; 1791 #ifdef OPENSSL_NO_EC_NISTP_64_GCC_128 1792 case NID_secp224r1: 1793 case NID_wap_wsg_idm_ecid_wtls12: 1794 ret = (n2d == NID_secp224r1 || n2d == NID_wap_wsg_idm_ecid_wtls12); 1795 break; 1796 #else 1797 /* 1798 * For SEC P-224 we want to ensure that the SECP nid is returned, as 1799 * that is associated with a specialized method. 1800 */ 1801 case NID_wap_wsg_idm_ecid_wtls12: 1802 ret = (n2d == NID_secp224r1); 1803 break; 1804 #endif /* def(OPENSSL_NO_EC_NISTP_64_GCC_128) */ 1805 1806 default: 1807 ret = (n1d == n2d); 1808 } 1809 return ret; 1810 } 1811 1812 /* 1813 * This checks that EC_GROUP_bew_from_ecparameters() returns a "named" 1814 * EC_GROUP for built-in curves. 1815 * 1816 * Note that it is possible to retrieve an alternative alias that does not match 1817 * the original nid. 1818 * 1819 * Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. 1820 */ 1821 static int check_named_curve_from_ecparameters(int id) 1822 { 1823 int ret = 0, nid, tnid; 1824 EC_GROUP *group = NULL, *tgroup = NULL, *tmpg = NULL; 1825 const EC_POINT *group_gen = NULL; 1826 EC_POINT *other_gen = NULL; 1827 BIGNUM *group_cofactor = NULL, *other_cofactor = NULL; 1828 BIGNUM *other_gen_x = NULL, *other_gen_y = NULL; 1829 const BIGNUM *group_order = NULL; 1830 BIGNUM *other_order = NULL; 1831 BN_CTX *bn_ctx = NULL; 1832 static const unsigned char invalid_seed[] = "THIS IS NOT A VALID SEED"; 1833 static size_t invalid_seed_len = sizeof(invalid_seed); 1834 ECPARAMETERS *params = NULL, *other_params = NULL; 1835 EC_GROUP *g_ary[8] = {NULL}; 1836 EC_GROUP **g_next = &g_ary[0]; 1837 ECPARAMETERS *p_ary[8] = {NULL}; 1838 ECPARAMETERS **p_next = &p_ary[0]; 1839 1840 /* Do some setup */ 1841 nid = curves[id].nid; 1842 TEST_note("Curve %s", OBJ_nid2sn(nid)); 1843 if (!TEST_ptr(bn_ctx = BN_CTX_new())) 1844 return ret; 1845 BN_CTX_start(bn_ctx); 1846 1847 if (/* Allocations */ 1848 !TEST_ptr(group_cofactor = BN_CTX_get(bn_ctx)) 1849 || !TEST_ptr(other_gen_x = BN_CTX_get(bn_ctx)) 1850 || !TEST_ptr(other_gen_y = BN_CTX_get(bn_ctx)) 1851 || !TEST_ptr(other_order = BN_CTX_get(bn_ctx)) 1852 || !TEST_ptr(other_cofactor = BN_CTX_get(bn_ctx)) 1853 /* Generate reference group and params */ 1854 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) 1855 || !TEST_ptr(params = EC_GROUP_get_ecparameters(group, NULL)) 1856 || !TEST_ptr(group_gen = EC_GROUP_get0_generator(group)) 1857 || !TEST_ptr(group_order = EC_GROUP_get0_order(group)) 1858 || !TEST_true(EC_GROUP_get_cofactor(group, group_cofactor, NULL)) 1859 /* compute `other_*` values */ 1860 || !TEST_ptr(tmpg = EC_GROUP_dup(group)) 1861 || !TEST_ptr(other_gen = EC_POINT_dup(group_gen, group)) 1862 || !TEST_true(EC_POINT_add(group, other_gen, group_gen, group_gen, NULL)) 1863 || !TEST_true(EC_POINT_get_affine_coordinates(group, other_gen, 1864 other_gen_x, other_gen_y, bn_ctx)) 1865 || !TEST_true(BN_copy(other_order, group_order)) 1866 || !TEST_true(BN_add_word(other_order, 1)) 1867 || !TEST_true(BN_copy(other_cofactor, group_cofactor)) 1868 || !TEST_true(BN_add_word(other_cofactor, 1))) 1869 goto err; 1870 1871 EC_POINT_free(other_gen); 1872 other_gen = NULL; 1873 1874 if (!TEST_ptr(other_gen = EC_POINT_new(tmpg)) 1875 || !TEST_true(EC_POINT_set_affine_coordinates(tmpg, other_gen, 1876 other_gen_x, other_gen_y, 1877 bn_ctx))) 1878 goto err; 1879 1880 /* 1881 * ########################### 1882 * # Actual tests start here # 1883 * ########################### 1884 */ 1885 1886 /* 1887 * Creating a group from built-in explicit parameters returns a 1888 * "named" EC_GROUP 1889 */ 1890 if (!TEST_ptr(tgroup = *g_next++ = EC_GROUP_new_from_ecparameters(params)) 1891 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef)) 1892 goto err; 1893 /* 1894 * We cannot always guarantee the names match, as the built-in table 1895 * contains aliases for the same curve with different names. 1896 */ 1897 if (!TEST_true(are_ec_nids_compatible(nid, tnid))) { 1898 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid)); 1899 goto err; 1900 } 1901 /* Ensure that the OPENSSL_EC_EXPLICIT_CURVE ASN1 flag is set. */ 1902 if (!TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), OPENSSL_EC_EXPLICIT_CURVE)) 1903 goto err; 1904 1905 /* 1906 * An invalid seed in the parameters should be ignored: expect a "named" 1907 * group. 1908 */ 1909 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, invalid_seed, invalid_seed_len), 1910 invalid_seed_len) 1911 || !TEST_ptr(other_params = *p_next++ = 1912 EC_GROUP_get_ecparameters(tmpg, NULL)) 1913 || !TEST_ptr(tgroup = *g_next++ = 1914 EC_GROUP_new_from_ecparameters(other_params)) 1915 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef) 1916 || !TEST_true(are_ec_nids_compatible(nid, tnid)) 1917 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), 1918 OPENSSL_EC_EXPLICIT_CURVE)) { 1919 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid)); 1920 goto err; 1921 } 1922 1923 /* 1924 * A null seed in the parameters should be ignored, as it is optional: 1925 * expect a "named" group. 1926 */ 1927 if (!TEST_int_eq(EC_GROUP_set_seed(tmpg, NULL, 0), 1) 1928 || !TEST_ptr(other_params = *p_next++ = 1929 EC_GROUP_get_ecparameters(tmpg, NULL)) 1930 || !TEST_ptr(tgroup = *g_next++ = 1931 EC_GROUP_new_from_ecparameters(other_params)) 1932 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef) 1933 || !TEST_true(are_ec_nids_compatible(nid, tnid)) 1934 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), 1935 OPENSSL_EC_EXPLICIT_CURVE)) { 1936 TEST_info("nid = %s, tnid = %s", OBJ_nid2sn(nid), OBJ_nid2sn(tnid)); 1937 goto err; 1938 } 1939 1940 /* 1941 * Check that changing any of the generator parameters does not yield a 1942 * match with the built-in curves 1943 */ 1944 if (/* Other gen, same group order & cofactor */ 1945 !TEST_true(EC_GROUP_set_generator(tmpg, other_gen, group_order, 1946 group_cofactor)) 1947 || !TEST_ptr(other_params = *p_next++ = 1948 EC_GROUP_get_ecparameters(tmpg, NULL)) 1949 || !TEST_ptr(tgroup = *g_next++ = 1950 EC_GROUP_new_from_ecparameters(other_params)) 1951 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef) 1952 /* Same gen & cofactor, different order */ 1953 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, other_order, 1954 group_cofactor)) 1955 || !TEST_ptr(other_params = *p_next++ = 1956 EC_GROUP_get_ecparameters(tmpg, NULL)) 1957 || !TEST_ptr(tgroup = *g_next++ = 1958 EC_GROUP_new_from_ecparameters(other_params)) 1959 || !TEST_int_eq((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef) 1960 /* The order is not an optional field, so this should fail */ 1961 || !TEST_false(EC_GROUP_set_generator(tmpg, group_gen, NULL, 1962 group_cofactor)) 1963 /* Check that a wrong cofactor is ignored, and we still match */ 1964 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order, 1965 other_cofactor)) 1966 || !TEST_ptr(other_params = *p_next++ = 1967 EC_GROUP_get_ecparameters(tmpg, NULL)) 1968 || !TEST_ptr(tgroup = *g_next++ = 1969 EC_GROUP_new_from_ecparameters(other_params)) 1970 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef) 1971 || !TEST_true(are_ec_nids_compatible(nid, tnid)) 1972 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), 1973 OPENSSL_EC_EXPLICIT_CURVE) 1974 /* Check that if the cofactor is not set then it still matches */ 1975 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order, 1976 NULL)) 1977 || !TEST_ptr(other_params = *p_next++ = 1978 EC_GROUP_get_ecparameters(tmpg, NULL)) 1979 || !TEST_ptr(tgroup = *g_next++ = 1980 EC_GROUP_new_from_ecparameters(other_params)) 1981 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef) 1982 || !TEST_true(are_ec_nids_compatible(nid, tnid)) 1983 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), 1984 OPENSSL_EC_EXPLICIT_CURVE) 1985 /* check that restoring the generator passes */ 1986 || !TEST_true(EC_GROUP_set_generator(tmpg, group_gen, group_order, 1987 group_cofactor)) 1988 || !TEST_ptr(other_params = *p_next++ = 1989 EC_GROUP_get_ecparameters(tmpg, NULL)) 1990 || !TEST_ptr(tgroup = *g_next++ = 1991 EC_GROUP_new_from_ecparameters(other_params)) 1992 || !TEST_int_ne((tnid = EC_GROUP_get_curve_name(tgroup)), NID_undef) 1993 || !TEST_true(are_ec_nids_compatible(nid, tnid)) 1994 || !TEST_int_eq(EC_GROUP_get_asn1_flag(tgroup), 1995 OPENSSL_EC_EXPLICIT_CURVE)) 1996 goto err; 1997 1998 ret = 1; 1999 err: 2000 for (g_next = &g_ary[0]; g_next < g_ary + OSSL_NELEM(g_ary); g_next++) 2001 EC_GROUP_free(*g_next); 2002 for (p_next = &p_ary[0]; p_next < p_ary + OSSL_NELEM(g_ary); p_next++) 2003 ECPARAMETERS_free(*p_next); 2004 ECPARAMETERS_free(params); 2005 EC_POINT_free(other_gen); 2006 EC_GROUP_free(tmpg); 2007 EC_GROUP_free(group); 2008 BN_CTX_end(bn_ctx); 2009 BN_CTX_free(bn_ctx); 2010 return ret; 2011 } 2012 2013 2014 static int parameter_test(void) 2015 { 2016 EC_GROUP *group = NULL, *group2 = NULL; 2017 ECPARAMETERS *ecparameters = NULL; 2018 unsigned char *buf = NULL; 2019 int r = 0, len; 2020 2021 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1)) 2022 || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL)) 2023 || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters)) 2024 || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0)) 2025 goto err; 2026 2027 EC_GROUP_free(group); 2028 group = NULL; 2029 2030 /* Test the named curve encoding, which should be default. */ 2031 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1)) 2032 || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0) 2033 || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named))) 2034 goto err; 2035 2036 OPENSSL_free(buf); 2037 buf = NULL; 2038 2039 /* 2040 * Test the explicit encoding. P-521 requires correctly zero-padding the 2041 * curve coefficients. 2042 */ 2043 EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE); 2044 if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0) 2045 || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit))) 2046 goto err; 2047 2048 r = 1; 2049 err: 2050 EC_GROUP_free(group); 2051 EC_GROUP_free(group2); 2052 ECPARAMETERS_free(ecparameters); 2053 OPENSSL_free(buf); 2054 return r; 2055 } 2056 2057 /* 2058 * This test validates converting an EC_GROUP to an OSSL_PARAM array 2059 * using EC_GROUP_to_params(). A named and an explicit curve are tested. 2060 */ 2061 static int ossl_parameter_test(void) 2062 { 2063 EC_GROUP *group_nmd = NULL, *group_nmd2 = NULL, *group_nmd3 = NULL; 2064 EC_GROUP *group_exp = NULL, *group_exp2 = NULL; 2065 OSSL_PARAM *params_nmd = NULL, *params_nmd2 = NULL; 2066 OSSL_PARAM *params_exp = NULL, *params_exp2 = NULL; 2067 unsigned char *buf = NULL, *buf2 = NULL; 2068 BN_CTX *bn_ctx = NULL; 2069 OSSL_PARAM_BLD *bld = NULL; 2070 BIGNUM *p, *a, *b; 2071 const EC_POINT *group_gen = NULL; 2072 size_t bsize; 2073 int r = 0; 2074 2075 if (!TEST_ptr(bn_ctx = BN_CTX_new())) 2076 goto err; 2077 2078 /* test named curve */ 2079 if (!TEST_ptr(group_nmd = EC_GROUP_new_by_curve_name(NID_secp384r1)) 2080 /* test with null BN_CTX */ 2081 || !TEST_ptr(params_nmd = EC_GROUP_to_params( 2082 group_nmd, NULL, NULL, NULL)) 2083 || !TEST_ptr(group_nmd2 = EC_GROUP_new_from_params( 2084 params_nmd, NULL, NULL)) 2085 || !TEST_int_eq(EC_GROUP_cmp(group_nmd, group_nmd2, NULL), 0) 2086 /* test with BN_CTX set */ 2087 || !TEST_ptr(params_nmd2 = EC_GROUP_to_params( 2088 group_nmd, NULL, NULL, bn_ctx)) 2089 || !TEST_ptr(group_nmd3 = EC_GROUP_new_from_params( 2090 params_nmd2, NULL, NULL)) 2091 || !TEST_int_eq(EC_GROUP_cmp(group_nmd, group_nmd3, NULL), 0)) 2092 goto err; 2093 2094 /* test explicit curve */ 2095 if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())) 2096 goto err; 2097 2098 BN_CTX_start(bn_ctx); 2099 p = BN_CTX_get(bn_ctx); 2100 a = BN_CTX_get(bn_ctx); 2101 b = BN_CTX_get(bn_ctx); 2102 2103 if (!TEST_true(EC_GROUP_get_curve(group_nmd, p, a, b, bn_ctx)) 2104 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string( 2105 bld, OSSL_PKEY_PARAM_EC_FIELD_TYPE, SN_X9_62_prime_field, 0)) 2106 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, p)) 2107 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a)) 2108 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))) 2109 goto err; 2110 2111 if (EC_GROUP_get0_seed(group_nmd) != NULL) { 2112 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string( 2113 bld, OSSL_PKEY_PARAM_EC_SEED, EC_GROUP_get0_seed(group_nmd), 2114 EC_GROUP_get_seed_len(group_nmd)))) 2115 goto err; 2116 } 2117 if (EC_GROUP_get0_cofactor(group_nmd) != NULL) { 2118 if (!TEST_true(OSSL_PARAM_BLD_push_BN( 2119 bld, OSSL_PKEY_PARAM_EC_COFACTOR, 2120 EC_GROUP_get0_cofactor(group_nmd)))) 2121 goto err; 2122 } 2123 2124 if (!TEST_ptr(group_gen = EC_GROUP_get0_generator(group_nmd)) 2125 || !TEST_size_t_gt(bsize = EC_POINT_point2oct( 2126 group_nmd, EC_GROUP_get0_generator(group_nmd), 2127 POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx), 0) 2128 || !TEST_ptr(buf2 = OPENSSL_malloc(bsize)) 2129 || !TEST_size_t_eq(EC_POINT_point2oct( 2130 group_nmd, EC_GROUP_get0_generator(group_nmd), 2131 POINT_CONVERSION_UNCOMPRESSED, buf2, bsize, bn_ctx), bsize) 2132 || !TEST_true(OSSL_PARAM_BLD_push_octet_string( 2133 bld, OSSL_PKEY_PARAM_EC_GENERATOR, buf2, bsize)) 2134 || !TEST_true(OSSL_PARAM_BLD_push_BN( 2135 bld, OSSL_PKEY_PARAM_EC_ORDER, EC_GROUP_get0_order(group_nmd)))) 2136 goto err; 2137 2138 if (!TEST_ptr(params_exp = OSSL_PARAM_BLD_to_param(bld)) 2139 || !TEST_ptr(group_exp = 2140 EC_GROUP_new_from_params(params_exp, NULL, NULL)) 2141 || !TEST_ptr(params_exp2 = 2142 EC_GROUP_to_params(group_exp, NULL, NULL, NULL)) 2143 || !TEST_ptr(group_exp2 = 2144 EC_GROUP_new_from_params(params_exp2, NULL, NULL)) 2145 || !TEST_int_eq(EC_GROUP_cmp(group_exp, group_exp2, NULL), 0)) 2146 goto err; 2147 2148 r = 1; 2149 2150 err: 2151 EC_GROUP_free(group_nmd); 2152 EC_GROUP_free(group_nmd2); 2153 EC_GROUP_free(group_nmd3); 2154 OSSL_PARAM_free(params_nmd); 2155 OSSL_PARAM_free(params_nmd2); 2156 OPENSSL_free(buf); 2157 2158 EC_GROUP_free(group_exp); 2159 EC_GROUP_free(group_exp2); 2160 BN_CTX_end(bn_ctx); 2161 BN_CTX_free(bn_ctx); 2162 OPENSSL_free(buf2); 2163 OSSL_PARAM_BLD_free(bld); 2164 OSSL_PARAM_free(params_exp); 2165 OSSL_PARAM_free(params_exp2); 2166 return r; 2167 } 2168 2169 /*- 2170 * random 256-bit explicit parameters curve, cofactor absent 2171 * order: 0x0c38d96a9f892b88772ec2e39614a82f4f (132 bit) 2172 * cofactor: 0x12bc94785251297abfafddf1565100da (125 bit) 2173 */ 2174 static const unsigned char params_cf_pass[] = { 2175 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 2176 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xe5, 0x00, 0x1f, 0xc5, 2177 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d, 2178 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93, 2179 0x44, 0x88, 0xe6, 0x91, 0x30, 0x44, 0x04, 0x20, 0xe5, 0x00, 0x1f, 0xc5, 2180 0xca, 0x71, 0x9d, 0x8e, 0xf7, 0x07, 0x4b, 0x48, 0x37, 0xf9, 0x33, 0x2d, 2181 0x71, 0xbf, 0x79, 0xe7, 0xdc, 0x91, 0xc2, 0xff, 0xb6, 0x7b, 0xc3, 0x93, 2182 0x44, 0x88, 0xe6, 0x8e, 0x04, 0x20, 0x18, 0x8c, 0x59, 0x57, 0xc4, 0xbc, 2183 0x85, 0x57, 0xc3, 0x66, 0x9f, 0x89, 0xd5, 0x92, 0x0d, 0x7e, 0x42, 0x27, 2184 0x07, 0x64, 0xaa, 0x26, 0xed, 0x89, 0xc4, 0x09, 0x05, 0x4d, 0xc7, 0x23, 2185 0x47, 0xda, 0x04, 0x41, 0x04, 0x1b, 0x6b, 0x41, 0x0b, 0xf9, 0xfb, 0x77, 2186 0xfd, 0x50, 0xb7, 0x3e, 0x23, 0xa3, 0xec, 0x9a, 0x3b, 0x09, 0x31, 0x6b, 2187 0xfa, 0xf6, 0xce, 0x1f, 0xff, 0xeb, 0x57, 0x93, 0x24, 0x70, 0xf3, 0xf4, 2188 0xba, 0x7e, 0xfa, 0x86, 0x6e, 0x19, 0x89, 0xe3, 0x55, 0x6d, 0x5a, 0xe9, 2189 0xc0, 0x3d, 0xbc, 0xfb, 0xaf, 0xad, 0xd4, 0x7e, 0xa6, 0xe5, 0xfa, 0x1a, 2190 0x58, 0x07, 0x9e, 0x8f, 0x0d, 0x3b, 0xf7, 0x38, 0xca, 0x02, 0x11, 0x0c, 2191 0x38, 0xd9, 0x6a, 0x9f, 0x89, 0x2b, 0x88, 0x77, 0x2e, 0xc2, 0xe3, 0x96, 2192 0x14, 0xa8, 0x2f, 0x4f 2193 }; 2194 2195 /*- 2196 * random 256-bit explicit parameters curve, cofactor absent 2197 * order: 0x045a75c0c17228ebd9b169a10e34a22101 (131 bit) 2198 * cofactor: 0x2e134b4ede82649f67a2e559d361e5fe (126 bit) 2199 */ 2200 static const unsigned char params_cf_fail[] = { 2201 0x30, 0x81, 0xcd, 0x02, 0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 2202 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x21, 0x00, 0xc8, 0x95, 0x27, 0x37, 2203 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b, 2204 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0, 2205 0x33, 0xc2, 0xea, 0x13, 0x30, 0x44, 0x04, 0x20, 0xc8, 0x95, 0x27, 0x37, 2206 0xe8, 0xe1, 0xfd, 0xcc, 0xf9, 0x6e, 0x0c, 0xa6, 0x21, 0xc1, 0x7d, 0x6b, 2207 0x9d, 0x44, 0x42, 0xea, 0x73, 0x4e, 0x04, 0xb6, 0xac, 0x62, 0x50, 0xd0, 2208 0x33, 0xc2, 0xea, 0x10, 0x04, 0x20, 0xbf, 0xa6, 0xa8, 0x05, 0x1d, 0x09, 2209 0xac, 0x70, 0x39, 0xbb, 0x4d, 0xb2, 0x90, 0x8a, 0x15, 0x41, 0x14, 0x1d, 2210 0x11, 0x86, 0x9f, 0x13, 0xa2, 0x63, 0x1a, 0xda, 0x95, 0x22, 0x4d, 0x02, 2211 0x15, 0x0a, 0x04, 0x41, 0x04, 0xaf, 0x16, 0x71, 0xf9, 0xc4, 0xc8, 0x59, 2212 0x1d, 0xa3, 0x6f, 0xe7, 0xc3, 0x57, 0xa1, 0xfa, 0x9f, 0x49, 0x7c, 0x11, 2213 0x27, 0x05, 0xa0, 0x7f, 0xff, 0xf9, 0xe0, 0xe7, 0x92, 0xdd, 0x9c, 0x24, 2214 0x8e, 0xc7, 0xb9, 0x52, 0x71, 0x3f, 0xbc, 0x7f, 0x6a, 0x9f, 0x35, 0x70, 2215 0xe1, 0x27, 0xd5, 0x35, 0x8a, 0x13, 0xfa, 0xa8, 0x33, 0x3e, 0xd4, 0x73, 2216 0x1c, 0x14, 0x58, 0x9e, 0xc7, 0x0a, 0x87, 0x65, 0x8d, 0x02, 0x11, 0x04, 2217 0x5a, 0x75, 0xc0, 0xc1, 0x72, 0x28, 0xeb, 0xd9, 0xb1, 0x69, 0xa1, 0x0e, 2218 0x34, 0xa2, 0x21, 0x01 2219 }; 2220 2221 /*- 2222 * Test two random 256-bit explicit parameters curves with absent cofactor. 2223 * The two curves are chosen to roughly straddle the bounds at which the lib 2224 * can compute the cofactor automatically, roughly 4*sqrt(p). So test that: 2225 * 2226 * - params_cf_pass: order is sufficiently close to p to compute cofactor 2227 * - params_cf_fail: order is too far away from p to compute cofactor 2228 * 2229 * For standards-compliant curves, cofactor is chosen as small as possible. 2230 * So you can see neither of these curves are fit for cryptographic use. 2231 * 2232 * Some standards even mandate an upper bound on the cofactor, e.g. SECG1 v2: 2233 * h <= 2**(t/8) where t is the security level of the curve, for which the lib 2234 * will always succeed in computing the cofactor. Neither of these curves 2235 * conform to that -- this is just robustness testing. 2236 */ 2237 static int cofactor_range_test(void) 2238 { 2239 EC_GROUP *group = NULL; 2240 BIGNUM *cf = NULL; 2241 int ret = 0; 2242 const unsigned char *b1 = (const unsigned char *)params_cf_fail; 2243 const unsigned char *b2 = (const unsigned char *)params_cf_pass; 2244 2245 if (!TEST_ptr(group = d2i_ECPKParameters(NULL, &b1, sizeof(params_cf_fail))) 2246 || !TEST_BN_eq_zero(EC_GROUP_get0_cofactor(group)) 2247 || !TEST_ptr(group = d2i_ECPKParameters(&group, &b2, 2248 sizeof(params_cf_pass))) 2249 || !TEST_int_gt(BN_hex2bn(&cf, "12bc94785251297abfafddf1565100da"), 0) 2250 || !TEST_BN_eq(cf, EC_GROUP_get0_cofactor(group))) 2251 goto err; 2252 ret = 1; 2253 err: 2254 BN_free(cf); 2255 EC_GROUP_free(group); 2256 return ret; 2257 } 2258 2259 /*- 2260 * For named curves, test that: 2261 * - the lib correctly computes the cofactor if passed a NULL or zero cofactor 2262 * - a nonsensical cofactor throws an error (negative test) 2263 * - nonsensical orders throw errors (negative tests) 2264 */ 2265 static int cardinality_test(int n) 2266 { 2267 int ret = 0, is_binary = 0; 2268 int nid = curves[n].nid; 2269 BN_CTX *ctx = NULL; 2270 EC_GROUP *g1 = NULL, *g2 = NULL; 2271 EC_POINT *g2_gen = NULL; 2272 BIGNUM *g1_p = NULL, *g1_a = NULL, *g1_b = NULL, *g1_x = NULL, *g1_y = NULL, 2273 *g1_order = NULL, *g1_cf = NULL, *g2_cf = NULL; 2274 2275 TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid)); 2276 2277 if (!TEST_ptr(ctx = BN_CTX_new()) 2278 || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))) { 2279 BN_CTX_free(ctx); 2280 return 0; 2281 } 2282 2283 is_binary = (EC_GROUP_get_field_type(g1) == NID_X9_62_characteristic_two_field); 2284 2285 BN_CTX_start(ctx); 2286 g1_p = BN_CTX_get(ctx); 2287 g1_a = BN_CTX_get(ctx); 2288 g1_b = BN_CTX_get(ctx); 2289 g1_x = BN_CTX_get(ctx); 2290 g1_y = BN_CTX_get(ctx); 2291 g1_order = BN_CTX_get(ctx); 2292 g1_cf = BN_CTX_get(ctx); 2293 2294 if (!TEST_ptr(g2_cf = BN_CTX_get(ctx)) 2295 /* pull out the explicit curve parameters */ 2296 || !TEST_true(EC_GROUP_get_curve(g1, g1_p, g1_a, g1_b, ctx)) 2297 || !TEST_true(EC_POINT_get_affine_coordinates(g1, 2298 EC_GROUP_get0_generator(g1), g1_x, g1_y, ctx)) 2299 || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1))) 2300 || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx)) 2301 /* construct g2 manually with g1 parameters */ 2302 #ifndef OPENSSL_NO_EC2M 2303 || !TEST_ptr(g2 = (is_binary) ? 2304 EC_GROUP_new_curve_GF2m(g1_p, g1_a, g1_b, ctx) : 2305 EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx)) 2306 #else 2307 || !TEST_int_eq(0, is_binary) 2308 || !TEST_ptr(g2 = EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx)) 2309 #endif 2310 || !TEST_ptr(g2_gen = EC_POINT_new(g2)) 2311 || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx)) 2312 /* pass NULL cofactor: lib should compute it */ 2313 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)) 2314 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx)) 2315 || !TEST_BN_eq(g1_cf, g2_cf) 2316 /* pass zero cofactor: lib should compute it */ 2317 || !TEST_true(BN_set_word(g2_cf, 0)) 2318 || !TEST_true(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf)) 2319 || !TEST_true(EC_GROUP_get_cofactor(g2, g2_cf, ctx)) 2320 || !TEST_BN_eq(g1_cf, g2_cf) 2321 /* negative test for invalid cofactor */ 2322 || !TEST_true(BN_set_word(g2_cf, 0)) 2323 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one())) 2324 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, g2_cf)) 2325 /* negative test for NULL order */ 2326 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, NULL, NULL)) 2327 /* negative test for zero order */ 2328 || !TEST_true(BN_set_word(g1_order, 0)) 2329 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)) 2330 /* negative test for negative order */ 2331 || !TEST_true(BN_set_word(g2_cf, 0)) 2332 || !TEST_true(BN_sub(g2_cf, g2_cf, BN_value_one())) 2333 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL)) 2334 /* negative test for too large order */ 2335 || !TEST_true(BN_lshift(g1_order, g1_p, 2)) 2336 || !TEST_false(EC_GROUP_set_generator(g2, g2_gen, g1_order, NULL))) 2337 goto err; 2338 ret = 1; 2339 err: 2340 EC_POINT_free(g2_gen); 2341 EC_GROUP_free(g1); 2342 EC_GROUP_free(g2); 2343 BN_CTX_end(ctx); 2344 BN_CTX_free(ctx); 2345 return ret; 2346 } 2347 2348 static int check_ec_key_field_public_range_test(int id) 2349 { 2350 int ret = 0, type = 0; 2351 const EC_POINT *pub = NULL; 2352 const EC_GROUP *group = NULL; 2353 const BIGNUM *field = NULL; 2354 BIGNUM *x = NULL, *y = NULL; 2355 EC_KEY *key = NULL; 2356 2357 if (!TEST_ptr(x = BN_new()) 2358 || !TEST_ptr(y = BN_new()) 2359 || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid)) 2360 || !TEST_ptr(group = EC_KEY_get0_group(key)) 2361 || !TEST_ptr(field = EC_GROUP_get0_field(group)) 2362 || !TEST_int_gt(EC_KEY_generate_key(key), 0) 2363 || !TEST_int_gt(EC_KEY_check_key(key), 0) 2364 || !TEST_ptr(pub = EC_KEY_get0_public_key(key)) 2365 || !TEST_int_gt(EC_POINT_get_affine_coordinates(group, pub, x, y, 2366 NULL), 0)) 2367 goto err; 2368 2369 /* 2370 * Make the public point out of range by adding the field (which will still 2371 * be the same point on the curve). The add is different for char2 fields. 2372 */ 2373 type = EC_GROUP_get_field_type(group); 2374 #ifndef OPENSSL_NO_EC2M 2375 if (type == NID_X9_62_characteristic_two_field) { 2376 /* test for binary curves */ 2377 if (!TEST_true(BN_GF2m_add(x, x, field))) 2378 goto err; 2379 } else 2380 #endif 2381 if (type == NID_X9_62_prime_field) { 2382 /* test for prime curves */ 2383 if (!TEST_true(BN_add(x, x, field))) 2384 goto err; 2385 } else { 2386 /* this should never happen */ 2387 TEST_error("Unsupported EC_METHOD field_type"); 2388 goto err; 2389 } 2390 if (!TEST_int_le(EC_KEY_set_public_key_affine_coordinates(key, x, y), 0)) 2391 goto err; 2392 2393 ret = 1; 2394 err: 2395 BN_free(x); 2396 BN_free(y); 2397 EC_KEY_free(key); 2398 return ret; 2399 } 2400 2401 /* 2402 * Helper for ec_point_hex2point_test 2403 * 2404 * Self-tests EC_POINT_point2hex() against EC_POINT_hex2point() for the given 2405 * (group,P) pair. 2406 * 2407 * If P is NULL use point at infinity. 2408 */ 2409 static ossl_inline 2410 int ec_point_hex2point_test_helper(const EC_GROUP *group, const EC_POINT *P, 2411 point_conversion_form_t form, 2412 BN_CTX *bnctx) 2413 { 2414 int ret = 0; 2415 EC_POINT *Q = NULL, *Pinf = NULL; 2416 char *hex = NULL; 2417 2418 if (P == NULL) { 2419 /* If P is NULL use point at infinity. */ 2420 if (!TEST_ptr(Pinf = EC_POINT_new(group)) 2421 || !TEST_true(EC_POINT_set_to_infinity(group, Pinf))) 2422 goto err; 2423 P = Pinf; 2424 } 2425 2426 if (!TEST_ptr(hex = EC_POINT_point2hex(group, P, form, bnctx)) 2427 || !TEST_ptr(Q = EC_POINT_hex2point(group, hex, NULL, bnctx)) 2428 || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, bnctx))) 2429 goto err; 2430 2431 /* 2432 * The next check is most likely superfluous, as EC_POINT_cmp should already 2433 * cover this. 2434 * Nonetheless it increases the test coverage for EC_POINT_is_at_infinity, 2435 * so we include it anyway! 2436 */ 2437 if (Pinf != NULL 2438 && !TEST_true(EC_POINT_is_at_infinity(group, Q))) 2439 goto err; 2440 2441 ret = 1; 2442 2443 err: 2444 EC_POINT_free(Pinf); 2445 OPENSSL_free(hex); 2446 EC_POINT_free(Q); 2447 2448 return ret; 2449 } 2450 2451 /* 2452 * This test self-validates EC_POINT_hex2point() and EC_POINT_point2hex() 2453 */ 2454 static int ec_point_hex2point_test(int id) 2455 { 2456 int ret = 0, nid; 2457 EC_GROUP *group = NULL; 2458 const EC_POINT *G = NULL; 2459 EC_POINT *P = NULL; 2460 BN_CTX *bnctx = NULL; 2461 2462 /* Do some setup */ 2463 nid = curves[id].nid; 2464 if (!TEST_ptr(bnctx = BN_CTX_new()) 2465 || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid)) 2466 || !TEST_ptr(G = EC_GROUP_get0_generator(group)) 2467 || !TEST_ptr(P = EC_POINT_dup(G, group))) 2468 goto err; 2469 2470 if (!TEST_true(ec_point_hex2point_test_helper(group, P, 2471 POINT_CONVERSION_COMPRESSED, 2472 bnctx)) 2473 || !TEST_true(ec_point_hex2point_test_helper(group, NULL, 2474 POINT_CONVERSION_COMPRESSED, 2475 bnctx)) 2476 || !TEST_true(ec_point_hex2point_test_helper(group, P, 2477 POINT_CONVERSION_UNCOMPRESSED, 2478 bnctx)) 2479 || !TEST_true(ec_point_hex2point_test_helper(group, NULL, 2480 POINT_CONVERSION_UNCOMPRESSED, 2481 bnctx)) 2482 || !TEST_true(ec_point_hex2point_test_helper(group, P, 2483 POINT_CONVERSION_HYBRID, 2484 bnctx)) 2485 || !TEST_true(ec_point_hex2point_test_helper(group, NULL, 2486 POINT_CONVERSION_HYBRID, 2487 bnctx))) 2488 goto err; 2489 2490 ret = 1; 2491 2492 err: 2493 EC_POINT_free(P); 2494 EC_GROUP_free(group); 2495 BN_CTX_free(bnctx); 2496 2497 return ret; 2498 } 2499 2500 static int do_test_custom_explicit_fromdata(EC_GROUP *group, BN_CTX *ctx, 2501 unsigned char *gen, int gen_size) 2502 { 2503 int ret = 0, i_out; 2504 EVP_PKEY_CTX *pctx = NULL; 2505 EVP_PKEY *pkeyparam = NULL; 2506 OSSL_PARAM_BLD *bld = NULL; 2507 const char *field_name; 2508 OSSL_PARAM *params = NULL; 2509 const OSSL_PARAM *gettable; 2510 BIGNUM *p, *a, *b; 2511 BIGNUM *p_out = NULL, *a_out = NULL, *b_out = NULL; 2512 BIGNUM *order_out = NULL, *cofactor_out = NULL; 2513 char name[80]; 2514 unsigned char buf[1024]; 2515 size_t buf_len, name_len; 2516 #ifndef OPENSSL_NO_EC2M 2517 unsigned int k1 = 0, k2 = 0, k3 = 0; 2518 const char *basis_name = NULL; 2519 #endif 2520 2521 p = BN_CTX_get(ctx); 2522 a = BN_CTX_get(ctx); 2523 b = BN_CTX_get(ctx); 2524 2525 if (!TEST_ptr(b) 2526 || !TEST_ptr(bld = OSSL_PARAM_BLD_new())) 2527 goto err; 2528 2529 if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) { 2530 field_name = SN_X9_62_prime_field; 2531 } else { 2532 field_name = SN_X9_62_characteristic_two_field; 2533 #ifndef OPENSSL_NO_EC2M 2534 if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) { 2535 basis_name = SN_X9_62_tpBasis; 2536 if (!TEST_true(EC_GROUP_get_trinomial_basis(group, &k1))) 2537 goto err; 2538 } else { 2539 basis_name = SN_X9_62_ppBasis; 2540 if (!TEST_true(EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3))) 2541 goto err; 2542 } 2543 #endif /* OPENSSL_NO_EC2M */ 2544 } 2545 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)) 2546 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld, 2547 OSSL_PKEY_PARAM_EC_FIELD_TYPE, field_name, 0)) 2548 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, p)) 2549 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a)) 2550 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))) 2551 goto err; 2552 2553 if (EC_GROUP_get0_seed(group) != NULL) { 2554 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld, 2555 OSSL_PKEY_PARAM_EC_SEED, EC_GROUP_get0_seed(group), 2556 EC_GROUP_get_seed_len(group)))) 2557 goto err; 2558 } 2559 if (EC_GROUP_get0_cofactor(group) != NULL) { 2560 if (!TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR, 2561 EC_GROUP_get0_cofactor(group)))) 2562 goto err; 2563 } 2564 2565 if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld, 2566 OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_size)) 2567 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_ORDER, 2568 EC_GROUP_get0_order(group)))) 2569 goto err; 2570 2571 if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld)) 2572 || !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) 2573 || !TEST_int_gt(EVP_PKEY_fromdata_init(pctx), 0) 2574 || !TEST_int_gt(EVP_PKEY_fromdata(pctx, &pkeyparam, 2575 EVP_PKEY_KEY_PARAMETERS, params), 0)) 2576 goto err; 2577 2578 /*- Check that all the set values are retrievable -*/ 2579 2580 /* There should be no match to a group name since the generator changed */ 2581 if (!TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam, 2582 OSSL_PKEY_PARAM_GROUP_NAME, name, sizeof(name), 2583 &name_len))) 2584 goto err; 2585 2586 /* The encoding should be explicit as it has no group */ 2587 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam, 2588 OSSL_PKEY_PARAM_EC_ENCODING, 2589 name, sizeof(name), &name_len)) 2590 || !TEST_str_eq(name, OSSL_PKEY_EC_ENCODING_EXPLICIT)) 2591 goto err; 2592 2593 if (!TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam, 2594 OSSL_PKEY_PARAM_EC_FIELD_TYPE, name, sizeof(name), 2595 &name_len)) 2596 || !TEST_str_eq(name, field_name)) 2597 goto err; 2598 2599 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam, 2600 OSSL_PKEY_PARAM_EC_GENERATOR, buf, sizeof(buf), &buf_len)) 2601 || !TEST_mem_eq(buf, (int)buf_len, gen, gen_size)) 2602 goto err; 2603 2604 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_P, &p_out)) 2605 || !TEST_BN_eq(p_out, p) 2606 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_A, 2607 &a_out)) 2608 || !TEST_BN_eq(a_out, a) 2609 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_B, 2610 &b_out)) 2611 || !TEST_BN_eq(b_out, b) 2612 || !TEST_true(EVP_PKEY_get_bn_param(pkeyparam, OSSL_PKEY_PARAM_EC_ORDER, 2613 &order_out)) 2614 || !TEST_BN_eq(order_out, EC_GROUP_get0_order(group))) 2615 goto err; 2616 2617 if (EC_GROUP_get0_cofactor(group) != NULL) { 2618 if (!TEST_true(EVP_PKEY_get_bn_param(pkeyparam, 2619 OSSL_PKEY_PARAM_EC_COFACTOR, &cofactor_out)) 2620 || !TEST_BN_eq(cofactor_out, EC_GROUP_get0_cofactor(group))) 2621 goto err; 2622 } 2623 if (EC_GROUP_get0_seed(group) != NULL) { 2624 if (!TEST_true(EVP_PKEY_get_octet_string_param(pkeyparam, 2625 OSSL_PKEY_PARAM_EC_SEED, buf, sizeof(buf), &buf_len)) 2626 || !TEST_mem_eq(buf, buf_len, EC_GROUP_get0_seed(group), 2627 EC_GROUP_get_seed_len(group))) 2628 goto err; 2629 } 2630 2631 if (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field) { 2632 /* No extra fields should be set for a prime field */ 2633 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2634 OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out)) 2635 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2636 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out)) 2637 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2638 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out)) 2639 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2640 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out)) 2641 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2642 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out)) 2643 || !TEST_false(EVP_PKEY_get_utf8_string_param(pkeyparam, 2644 OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name), 2645 &name_len))) 2646 goto err; 2647 } else { 2648 #ifndef OPENSSL_NO_EC2M 2649 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam, 2650 OSSL_PKEY_PARAM_EC_CHAR2_M, &i_out)) 2651 || !TEST_int_eq(EC_GROUP_get_degree(group), i_out) 2652 || !TEST_true(EVP_PKEY_get_utf8_string_param(pkeyparam, 2653 OSSL_PKEY_PARAM_EC_CHAR2_TYPE, name, sizeof(name), 2654 &name_len)) 2655 || !TEST_str_eq(name, basis_name)) 2656 goto err; 2657 2658 if (EC_GROUP_get_basis_type(group) == NID_X9_62_tpBasis) { 2659 if (!TEST_true(EVP_PKEY_get_int_param(pkeyparam, 2660 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out)) 2661 || !TEST_int_eq(k1, i_out) 2662 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2663 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out)) 2664 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2665 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out)) 2666 || !TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2667 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out))) 2668 goto err; 2669 } else { 2670 if (!TEST_false(EVP_PKEY_get_int_param(pkeyparam, 2671 OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, &i_out)) 2672 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam, 2673 OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, &i_out)) 2674 || !TEST_int_eq(k1, i_out) 2675 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam, 2676 OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, &i_out)) 2677 || !TEST_int_eq(k2, i_out) 2678 || !TEST_true(EVP_PKEY_get_int_param(pkeyparam, 2679 OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, &i_out)) 2680 || !TEST_int_eq(k3, i_out)) 2681 goto err; 2682 } 2683 #endif /* OPENSSL_NO_EC2M */ 2684 } 2685 if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pkeyparam)) 2686 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_GROUP_NAME)) 2687 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ENCODING)) 2688 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_FIELD_TYPE)) 2689 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_P)) 2690 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_A)) 2691 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_B)) 2692 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_GENERATOR)) 2693 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_ORDER)) 2694 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_COFACTOR)) 2695 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_SEED)) 2696 #ifndef OPENSSL_NO_EC2M 2697 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_M)) 2698 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TYPE)) 2699 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS)) 2700 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K1)) 2701 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K2)) 2702 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_CHAR2_PP_K3)) 2703 #endif 2704 ) 2705 goto err; 2706 ret = 1; 2707 err: 2708 BN_free(order_out); 2709 BN_free(cofactor_out); 2710 BN_free(a_out); 2711 BN_free(b_out); 2712 BN_free(p_out); 2713 OSSL_PARAM_free(params); 2714 OSSL_PARAM_BLD_free(bld); 2715 EVP_PKEY_free(pkeyparam); 2716 EVP_PKEY_CTX_free(pctx); 2717 return ret; 2718 } 2719 2720 /* 2721 * check the EC_METHOD respects the supplied EC_GROUP_set_generator G 2722 */ 2723 static int custom_generator_test(int id) 2724 { 2725 int ret = 0, nid, bsize; 2726 EC_GROUP *group = NULL; 2727 EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL; 2728 BN_CTX *ctx = NULL; 2729 BIGNUM *k = NULL; 2730 unsigned char *b1 = NULL, *b2 = NULL; 2731 2732 /* Do some setup */ 2733 nid = curves[id].nid; 2734 TEST_note("Curve %s", OBJ_nid2sn(nid)); 2735 if (!TEST_ptr(ctx = BN_CTX_new())) 2736 return 0; 2737 2738 BN_CTX_start(ctx); 2739 2740 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) 2741 goto err; 2742 2743 /* expected byte length of encoded points */ 2744 bsize = (EC_GROUP_get_degree(group) + 7) / 8; 2745 bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */ 2746 2747 if (!TEST_ptr(k = BN_CTX_get(ctx)) 2748 /* fetch a testing scalar k != 0,1 */ 2749 || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1, 2750 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) 2751 /* make k even */ 2752 || !TEST_true(BN_clear_bit(k, 0)) 2753 || !TEST_ptr(G2 = EC_POINT_new(group)) 2754 || !TEST_ptr(Q1 = EC_POINT_new(group)) 2755 /* Q1 := kG */ 2756 || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx)) 2757 /* pull out the bytes of that */ 2758 || !TEST_int_eq(EC_POINT_point2oct(group, Q1, 2759 POINT_CONVERSION_UNCOMPRESSED, NULL, 2760 0, ctx), bsize) 2761 || !TEST_ptr(b1 = OPENSSL_malloc(bsize)) 2762 || !TEST_int_eq(EC_POINT_point2oct(group, Q1, 2763 POINT_CONVERSION_UNCOMPRESSED, b1, 2764 bsize, ctx), bsize) 2765 /* new generator is G2 := 2G */ 2766 || !TEST_true(EC_POINT_dbl(group, G2, EC_GROUP_get0_generator(group), 2767 ctx)) 2768 || !TEST_true(EC_GROUP_set_generator(group, G2, 2769 EC_GROUP_get0_order(group), 2770 EC_GROUP_get0_cofactor(group))) 2771 || !TEST_ptr(Q2 = EC_POINT_new(group)) 2772 || !TEST_true(BN_rshift1(k, k)) 2773 /* Q2 := k/2 G2 */ 2774 || !TEST_true(EC_POINT_mul(group, Q2, k, NULL, NULL, ctx)) 2775 || !TEST_int_eq(EC_POINT_point2oct(group, Q2, 2776 POINT_CONVERSION_UNCOMPRESSED, NULL, 2777 0, ctx), bsize) 2778 || !TEST_ptr(b2 = OPENSSL_malloc(bsize)) 2779 || !TEST_int_eq(EC_POINT_point2oct(group, Q2, 2780 POINT_CONVERSION_UNCOMPRESSED, b2, 2781 bsize, ctx), bsize) 2782 /* Q1 = kG = k/2 G2 = Q2 should hold */ 2783 || !TEST_mem_eq(b1, bsize, b2, bsize)) 2784 goto err; 2785 2786 if (!do_test_custom_explicit_fromdata(group, ctx, b1, bsize)) 2787 goto err; 2788 2789 ret = 1; 2790 2791 err: 2792 EC_POINT_free(Q1); 2793 EC_POINT_free(Q2); 2794 EC_POINT_free(G2); 2795 EC_GROUP_free(group); 2796 BN_CTX_end(ctx); 2797 BN_CTX_free(ctx); 2798 OPENSSL_free(b1); 2799 OPENSSL_free(b2); 2800 2801 return ret; 2802 } 2803 2804 /* 2805 * check creation of curves from explicit params through the public API 2806 */ 2807 static int custom_params_test(int id) 2808 { 2809 int ret = 0, nid, bsize; 2810 const char *curve_name = NULL; 2811 EC_GROUP *group = NULL, *altgroup = NULL; 2812 EC_POINT *G2 = NULL, *Q1 = NULL, *Q2 = NULL; 2813 const EC_POINT *Q = NULL; 2814 BN_CTX *ctx = NULL; 2815 BIGNUM *k = NULL; 2816 unsigned char *buf1 = NULL, *buf2 = NULL; 2817 const BIGNUM *z = NULL, *cof = NULL, *priv1 = NULL; 2818 BIGNUM *p = NULL, *a = NULL, *b = NULL; 2819 int is_prime = 0; 2820 EC_KEY *eckey1 = NULL, *eckey2 = NULL; 2821 EVP_PKEY *pkey1 = NULL, *pkey2 = NULL; 2822 EVP_PKEY_CTX *pctx1 = NULL, *pctx2 = NULL, *dctx = NULL; 2823 size_t sslen, t; 2824 unsigned char *pub1 = NULL , *pub2 = NULL; 2825 OSSL_PARAM_BLD *param_bld = NULL; 2826 OSSL_PARAM *params1 = NULL, *params2 = NULL; 2827 2828 /* Do some setup */ 2829 nid = curves[id].nid; 2830 curve_name = OBJ_nid2sn(nid); 2831 TEST_note("Curve %s", curve_name); 2832 2833 if (nid == NID_sm2) 2834 return TEST_skip("custom params not supported with SM2"); 2835 2836 if (!TEST_ptr(ctx = BN_CTX_new())) 2837 return 0; 2838 2839 BN_CTX_start(ctx); 2840 if (!TEST_ptr(p = BN_CTX_get(ctx)) 2841 || !TEST_ptr(a = BN_CTX_get(ctx)) 2842 || !TEST_ptr(b = BN_CTX_get(ctx)) 2843 || !TEST_ptr(k = BN_CTX_get(ctx))) 2844 goto err; 2845 2846 if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) 2847 goto err; 2848 2849 is_prime = EC_GROUP_get_field_type(group) == NID_X9_62_prime_field; 2850 #ifdef OPENSSL_NO_EC2M 2851 if (!is_prime) { 2852 ret = TEST_skip("binary curves not supported in this build"); 2853 goto err; 2854 } 2855 #endif 2856 2857 /* expected byte length of encoded points */ 2858 bsize = (EC_GROUP_get_degree(group) + 7) / 8; 2859 bsize = 1 + 2 * bsize; /* UNCOMPRESSED_POINT format */ 2860 2861 /* extract parameters from built-in curve */ 2862 if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)) 2863 || !TEST_ptr(G2 = EC_POINT_new(group)) 2864 /* new generator is G2 := 2G */ 2865 || !TEST_true(EC_POINT_dbl(group, G2, 2866 EC_GROUP_get0_generator(group), ctx)) 2867 /* pull out the bytes of that */ 2868 || !TEST_int_eq(EC_POINT_point2oct(group, G2, 2869 POINT_CONVERSION_UNCOMPRESSED, 2870 NULL, 0, ctx), bsize) 2871 || !TEST_ptr(buf1 = OPENSSL_malloc(bsize)) 2872 || !TEST_int_eq(EC_POINT_point2oct(group, G2, 2873 POINT_CONVERSION_UNCOMPRESSED, 2874 buf1, bsize, ctx), bsize) 2875 || !TEST_ptr(z = EC_GROUP_get0_order(group)) 2876 || !TEST_ptr(cof = EC_GROUP_get0_cofactor(group)) 2877 ) 2878 goto err; 2879 2880 /* create a new group using same params (but different generator) */ 2881 if (is_prime) { 2882 if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GFp(p, a, b, ctx))) 2883 goto err; 2884 } 2885 #ifndef OPENSSL_NO_EC2M 2886 else { 2887 if (!TEST_ptr(altgroup = EC_GROUP_new_curve_GF2m(p, a, b, ctx))) 2888 goto err; 2889 } 2890 #endif 2891 2892 /* set 2*G as the generator of altgroup */ 2893 EC_POINT_free(G2); /* discard G2 as it refers to the original group */ 2894 if (!TEST_ptr(G2 = EC_POINT_new(altgroup)) 2895 || !TEST_true(EC_POINT_oct2point(altgroup, G2, buf1, bsize, ctx)) 2896 || !TEST_int_eq(EC_POINT_is_on_curve(altgroup, G2, ctx), 1) 2897 || !TEST_true(EC_GROUP_set_generator(altgroup, G2, z, cof)) 2898 ) 2899 goto err; 2900 2901 /* verify math checks out */ 2902 if (/* allocate temporary points on group and altgroup */ 2903 !TEST_ptr(Q1 = EC_POINT_new(group)) 2904 || !TEST_ptr(Q2 = EC_POINT_new(altgroup)) 2905 /* fetch a testing scalar k != 0,1 */ 2906 || !TEST_true(BN_rand(k, EC_GROUP_order_bits(group) - 1, 2907 BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) 2908 /* make k even */ 2909 || !TEST_true(BN_clear_bit(k, 0)) 2910 /* Q1 := kG on group */ 2911 || !TEST_true(EC_POINT_mul(group, Q1, k, NULL, NULL, ctx)) 2912 /* pull out the bytes of that */ 2913 || !TEST_int_eq(EC_POINT_point2oct(group, Q1, 2914 POINT_CONVERSION_UNCOMPRESSED, 2915 NULL, 0, ctx), bsize) 2916 || !TEST_int_eq(EC_POINT_point2oct(group, Q1, 2917 POINT_CONVERSION_UNCOMPRESSED, 2918 buf1, bsize, ctx), bsize) 2919 /* k := k/2 */ 2920 || !TEST_true(BN_rshift1(k, k)) 2921 /* Q2 := k/2 G2 on altgroup */ 2922 || !TEST_true(EC_POINT_mul(altgroup, Q2, k, NULL, NULL, ctx)) 2923 /* pull out the bytes of that */ 2924 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2, 2925 POINT_CONVERSION_UNCOMPRESSED, 2926 NULL, 0, ctx), bsize) 2927 || !TEST_ptr(buf2 = OPENSSL_malloc(bsize)) 2928 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q2, 2929 POINT_CONVERSION_UNCOMPRESSED, 2930 buf2, bsize, ctx), bsize) 2931 /* Q1 = kG = k/2 G2 = Q2 should hold */ 2932 || !TEST_mem_eq(buf1, bsize, buf2, bsize)) 2933 goto err; 2934 2935 /* create two `EC_KEY`s on altgroup */ 2936 if (!TEST_ptr(eckey1 = EC_KEY_new()) 2937 || !TEST_true(EC_KEY_set_group(eckey1, altgroup)) 2938 || !TEST_true(EC_KEY_generate_key(eckey1)) 2939 || !TEST_ptr(eckey2 = EC_KEY_new()) 2940 || !TEST_true(EC_KEY_set_group(eckey2, altgroup)) 2941 || !TEST_true(EC_KEY_generate_key(eckey2))) 2942 goto err; 2943 2944 /* retrieve priv1 for later */ 2945 if (!TEST_ptr(priv1 = EC_KEY_get0_private_key(eckey1))) 2946 goto err; 2947 2948 /* 2949 * retrieve bytes for pub1 for later 2950 * 2951 * We compute the pub key in the original group as we will later use it to 2952 * define a provider key in the built-in group. 2953 */ 2954 if (!TEST_true(EC_POINT_mul(group, Q1, priv1, NULL, NULL, ctx)) 2955 || !TEST_int_eq(EC_POINT_point2oct(group, Q1, 2956 POINT_CONVERSION_UNCOMPRESSED, 2957 NULL, 0, ctx), bsize) 2958 || !TEST_ptr(pub1 = OPENSSL_malloc(bsize)) 2959 || !TEST_int_eq(EC_POINT_point2oct(group, Q1, 2960 POINT_CONVERSION_UNCOMPRESSED, 2961 pub1, bsize, ctx), bsize)) 2962 goto err; 2963 2964 /* retrieve bytes for pub2 for later */ 2965 if (!TEST_ptr(Q = EC_KEY_get0_public_key(eckey2)) 2966 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q, 2967 POINT_CONVERSION_UNCOMPRESSED, 2968 NULL, 0, ctx), bsize) 2969 || !TEST_ptr(pub2 = OPENSSL_malloc(bsize)) 2970 || !TEST_int_eq(EC_POINT_point2oct(altgroup, Q, 2971 POINT_CONVERSION_UNCOMPRESSED, 2972 pub2, bsize, ctx), bsize)) 2973 goto err; 2974 2975 /* create two `EVP_PKEY`s from the `EC_KEY`s */ 2976 if (!TEST_ptr(pkey1 = EVP_PKEY_new()) 2977 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey1, eckey1), 1)) 2978 goto err; 2979 eckey1 = NULL; /* ownership passed to pkey1 */ 2980 if (!TEST_ptr(pkey2 = EVP_PKEY_new()) 2981 || !TEST_int_eq(EVP_PKEY_assign_EC_KEY(pkey2, eckey2), 1)) 2982 goto err; 2983 eckey2 = NULL; /* ownership passed to pkey2 */ 2984 2985 /* Compute keyexchange in both directions */ 2986 if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL)) 2987 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1) 2988 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx1, pkey2), 1) 2989 || !TEST_int_eq(EVP_PKEY_derive(pctx1, NULL, &sslen), 1) 2990 || !TEST_int_gt(bsize, sslen) 2991 || !TEST_int_eq(EVP_PKEY_derive(pctx1, buf1, &sslen), 1)) 2992 goto err; 2993 if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new(pkey2, NULL)) 2994 || !TEST_int_eq(EVP_PKEY_derive_init(pctx2), 1) 2995 || !TEST_int_eq(EVP_PKEY_derive_set_peer(pctx2, pkey1), 1) 2996 || !TEST_int_eq(EVP_PKEY_derive(pctx2, NULL, &t), 1) 2997 || !TEST_int_gt(bsize, t) 2998 || !TEST_int_le(sslen, t) 2999 || !TEST_int_eq(EVP_PKEY_derive(pctx2, buf2, &t), 1)) 3000 goto err; 3001 3002 /* Both sides should expect the same shared secret */ 3003 if (!TEST_mem_eq(buf1, sslen, buf2, t)) 3004 goto err; 3005 3006 /* Build parameters for provider-native keys */ 3007 if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new()) 3008 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld, 3009 OSSL_PKEY_PARAM_GROUP_NAME, 3010 curve_name, 0)) 3011 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld, 3012 OSSL_PKEY_PARAM_PUB_KEY, 3013 pub1, bsize)) 3014 || !TEST_true(OSSL_PARAM_BLD_push_BN(param_bld, 3015 OSSL_PKEY_PARAM_PRIV_KEY, 3016 priv1)) 3017 || !TEST_ptr(params1 = OSSL_PARAM_BLD_to_param(param_bld))) 3018 goto err; 3019 3020 OSSL_PARAM_BLD_free(param_bld); 3021 if (!TEST_ptr(param_bld = OSSL_PARAM_BLD_new()) 3022 || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(param_bld, 3023 OSSL_PKEY_PARAM_GROUP_NAME, 3024 curve_name, 0)) 3025 || !TEST_true(OSSL_PARAM_BLD_push_octet_string(param_bld, 3026 OSSL_PKEY_PARAM_PUB_KEY, 3027 pub2, bsize)) 3028 || !TEST_ptr(params2 = OSSL_PARAM_BLD_to_param(param_bld))) 3029 goto err; 3030 3031 /* create two new provider-native `EVP_PKEY`s */ 3032 EVP_PKEY_CTX_free(pctx2); 3033 if (!TEST_ptr(pctx2 = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) 3034 || !TEST_int_eq(EVP_PKEY_fromdata_init(pctx2), 1) 3035 || !TEST_int_eq(EVP_PKEY_fromdata(pctx2, &pkey1, EVP_PKEY_KEYPAIR, 3036 params1), 1) 3037 || !TEST_int_eq(EVP_PKEY_fromdata(pctx2, &pkey2, EVP_PKEY_PUBLIC_KEY, 3038 params2), 1)) 3039 goto err; 3040 3041 /* compute keyexchange once more using the provider keys */ 3042 EVP_PKEY_CTX_free(pctx1); 3043 if (!TEST_ptr(pctx1 = EVP_PKEY_CTX_new(pkey1, NULL)) 3044 || !TEST_int_eq(EVP_PKEY_derive_init(pctx1), 1) 3045 || !TEST_ptr(dctx = EVP_PKEY_CTX_dup(pctx1)) 3046 || !TEST_int_eq(EVP_PKEY_derive_set_peer_ex(dctx, pkey2, 1), 1) 3047 || !TEST_int_eq(EVP_PKEY_derive(dctx, NULL, &t), 1) 3048 || !TEST_int_gt(bsize, t) 3049 || !TEST_int_le(sslen, t) 3050 || !TEST_int_eq(EVP_PKEY_derive(dctx, buf1, &t), 1) 3051 /* compare with previous result */ 3052 || !TEST_mem_eq(buf1, t, buf2, sslen)) 3053 goto err; 3054 3055 ret = 1; 3056 3057 err: 3058 BN_CTX_end(ctx); 3059 BN_CTX_free(ctx); 3060 OSSL_PARAM_BLD_free(param_bld); 3061 OSSL_PARAM_free(params1); 3062 OSSL_PARAM_free(params2); 3063 EC_POINT_free(Q1); 3064 EC_POINT_free(Q2); 3065 EC_POINT_free(G2); 3066 EC_GROUP_free(group); 3067 EC_GROUP_free(altgroup); 3068 OPENSSL_free(buf1); 3069 OPENSSL_free(buf2); 3070 OPENSSL_free(pub1); 3071 OPENSSL_free(pub2); 3072 EC_KEY_free(eckey1); 3073 EC_KEY_free(eckey2); 3074 EVP_PKEY_free(pkey1); 3075 EVP_PKEY_free(pkey2); 3076 EVP_PKEY_CTX_free(pctx1); 3077 EVP_PKEY_CTX_free(pctx2); 3078 EVP_PKEY_CTX_free(dctx); 3079 3080 return ret; 3081 } 3082 3083 static int ec_d2i_publickey_test(void) 3084 { 3085 unsigned char buf[1000]; 3086 unsigned char *pubkey_enc = buf; 3087 const unsigned char *pk_enc = pubkey_enc; 3088 EVP_PKEY *gen_key = NULL, *decoded_key = NULL; 3089 EVP_PKEY_CTX *pctx = NULL; 3090 int pklen, ret = 0; 3091 OSSL_PARAM params[2]; 3092 3093 if (!TEST_ptr(gen_key = EVP_EC_gen("P-256"))) 3094 goto err; 3095 3096 if (!TEST_int_gt(pklen = i2d_PublicKey(gen_key, &pubkey_enc), 0)) 3097 goto err; 3098 3099 params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, 3100 "P-256", 0); 3101 params[1] = OSSL_PARAM_construct_end(); 3102 3103 if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) 3104 || !TEST_true(EVP_PKEY_fromdata_init(pctx)) 3105 || !TEST_true(EVP_PKEY_fromdata(pctx, &decoded_key, 3106 OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, 3107 params)) 3108 || !TEST_ptr(decoded_key) 3109 || !TEST_ptr(decoded_key = d2i_PublicKey(EVP_PKEY_EC, &decoded_key, 3110 &pk_enc, pklen))) 3111 goto err; 3112 3113 if (!TEST_true(EVP_PKEY_eq(gen_key, decoded_key))) 3114 goto err; 3115 ret = 1; 3116 3117 err: 3118 EVP_PKEY_CTX_free(pctx); 3119 EVP_PKEY_free(gen_key); 3120 EVP_PKEY_free(decoded_key); 3121 return ret; 3122 } 3123 3124 int setup_tests(void) 3125 { 3126 crv_len = EC_get_builtin_curves(NULL, 0); 3127 if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len)) 3128 || !TEST_true(EC_get_builtin_curves(curves, crv_len))) 3129 return 0; 3130 3131 ADD_TEST(parameter_test); 3132 ADD_TEST(ossl_parameter_test); 3133 ADD_TEST(cofactor_range_test); 3134 ADD_ALL_TESTS(cardinality_test, crv_len); 3135 ADD_TEST(prime_field_tests); 3136 #ifndef OPENSSL_NO_EC2M 3137 ADD_TEST(hybrid_point_encoding_test); 3138 ADD_TEST(char2_field_tests); 3139 ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests)); 3140 #endif 3141 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params)); 3142 ADD_ALL_TESTS(internal_curve_test, crv_len); 3143 ADD_ALL_TESTS(internal_curve_test_method, crv_len); 3144 ADD_TEST(group_field_test); 3145 ADD_ALL_TESTS(check_named_curve_test, crv_len); 3146 ADD_ALL_TESTS(check_named_curve_lookup_test, crv_len); 3147 ADD_ALL_TESTS(check_ec_key_field_public_range_test, crv_len); 3148 ADD_ALL_TESTS(check_named_curve_from_ecparameters, crv_len); 3149 ADD_ALL_TESTS(ec_point_hex2point_test, crv_len); 3150 ADD_ALL_TESTS(custom_generator_test, crv_len); 3151 ADD_ALL_TESTS(custom_params_test, crv_len); 3152 ADD_TEST(ec_d2i_publickey_test); 3153 return 1; 3154 } 3155 3156 void cleanup_tests(void) 3157 { 3158 OPENSSL_free(curves); 3159 } 3160