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