1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved 4e1051a39Sopenharmony_ci * 5e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 6e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 7e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 8e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 9e1051a39Sopenharmony_ci */ 10e1051a39Sopenharmony_ci 11e1051a39Sopenharmony_ci/* 12e1051a39Sopenharmony_ci * ECDSA low level APIs are deprecated for public use, but still ok for 13e1051a39Sopenharmony_ci * internal use. 14e1051a39Sopenharmony_ci */ 15e1051a39Sopenharmony_ci#include "internal/deprecated.h" 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include <openssl/err.h> 18e1051a39Sopenharmony_ci#include <openssl/symhacks.h> 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ci#include "ec_local.h" 21e1051a39Sopenharmony_ci 22e1051a39Sopenharmony_ciint ossl_ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, 23e1051a39Sopenharmony_ci EC_POINT *point, 24e1051a39Sopenharmony_ci const BIGNUM *x_, int y_bit, 25e1051a39Sopenharmony_ci BN_CTX *ctx) 26e1051a39Sopenharmony_ci{ 27e1051a39Sopenharmony_ci BN_CTX *new_ctx = NULL; 28e1051a39Sopenharmony_ci BIGNUM *tmp1, *tmp2, *x, *y; 29e1051a39Sopenharmony_ci int ret = 0; 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_ci if (ctx == NULL) { 32e1051a39Sopenharmony_ci ctx = new_ctx = BN_CTX_new_ex(group->libctx); 33e1051a39Sopenharmony_ci if (ctx == NULL) 34e1051a39Sopenharmony_ci return 0; 35e1051a39Sopenharmony_ci } 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ci y_bit = (y_bit != 0); 38e1051a39Sopenharmony_ci 39e1051a39Sopenharmony_ci BN_CTX_start(ctx); 40e1051a39Sopenharmony_ci tmp1 = BN_CTX_get(ctx); 41e1051a39Sopenharmony_ci tmp2 = BN_CTX_get(ctx); 42e1051a39Sopenharmony_ci x = BN_CTX_get(ctx); 43e1051a39Sopenharmony_ci y = BN_CTX_get(ctx); 44e1051a39Sopenharmony_ci if (y == NULL) 45e1051a39Sopenharmony_ci goto err; 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci /*- 48e1051a39Sopenharmony_ci * Recover y. We have a Weierstrass equation 49e1051a39Sopenharmony_ci * y^2 = x^3 + a*x + b, 50e1051a39Sopenharmony_ci * so y is one of the square roots of x^3 + a*x + b. 51e1051a39Sopenharmony_ci */ 52e1051a39Sopenharmony_ci 53e1051a39Sopenharmony_ci /* tmp1 := x^3 */ 54e1051a39Sopenharmony_ci if (!BN_nnmod(x, x_, group->field, ctx)) 55e1051a39Sopenharmony_ci goto err; 56e1051a39Sopenharmony_ci if (group->meth->field_decode == 0) { 57e1051a39Sopenharmony_ci /* field_{sqr,mul} work on standard representation */ 58e1051a39Sopenharmony_ci if (!group->meth->field_sqr(group, tmp2, x_, ctx)) 59e1051a39Sopenharmony_ci goto err; 60e1051a39Sopenharmony_ci if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) 61e1051a39Sopenharmony_ci goto err; 62e1051a39Sopenharmony_ci } else { 63e1051a39Sopenharmony_ci if (!BN_mod_sqr(tmp2, x_, group->field, ctx)) 64e1051a39Sopenharmony_ci goto err; 65e1051a39Sopenharmony_ci if (!BN_mod_mul(tmp1, tmp2, x_, group->field, ctx)) 66e1051a39Sopenharmony_ci goto err; 67e1051a39Sopenharmony_ci } 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci /* tmp1 := tmp1 + a*x */ 70e1051a39Sopenharmony_ci if (group->a_is_minus3) { 71e1051a39Sopenharmony_ci if (!BN_mod_lshift1_quick(tmp2, x, group->field)) 72e1051a39Sopenharmony_ci goto err; 73e1051a39Sopenharmony_ci if (!BN_mod_add_quick(tmp2, tmp2, x, group->field)) 74e1051a39Sopenharmony_ci goto err; 75e1051a39Sopenharmony_ci if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, group->field)) 76e1051a39Sopenharmony_ci goto err; 77e1051a39Sopenharmony_ci } else { 78e1051a39Sopenharmony_ci if (group->meth->field_decode) { 79e1051a39Sopenharmony_ci if (!group->meth->field_decode(group, tmp2, group->a, ctx)) 80e1051a39Sopenharmony_ci goto err; 81e1051a39Sopenharmony_ci if (!BN_mod_mul(tmp2, tmp2, x, group->field, ctx)) 82e1051a39Sopenharmony_ci goto err; 83e1051a39Sopenharmony_ci } else { 84e1051a39Sopenharmony_ci /* field_mul works on standard representation */ 85e1051a39Sopenharmony_ci if (!group->meth->field_mul(group, tmp2, group->a, x, ctx)) 86e1051a39Sopenharmony_ci goto err; 87e1051a39Sopenharmony_ci } 88e1051a39Sopenharmony_ci 89e1051a39Sopenharmony_ci if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field)) 90e1051a39Sopenharmony_ci goto err; 91e1051a39Sopenharmony_ci } 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ci /* tmp1 := tmp1 + b */ 94e1051a39Sopenharmony_ci if (group->meth->field_decode) { 95e1051a39Sopenharmony_ci if (!group->meth->field_decode(group, tmp2, group->b, ctx)) 96e1051a39Sopenharmony_ci goto err; 97e1051a39Sopenharmony_ci if (!BN_mod_add_quick(tmp1, tmp1, tmp2, group->field)) 98e1051a39Sopenharmony_ci goto err; 99e1051a39Sopenharmony_ci } else { 100e1051a39Sopenharmony_ci if (!BN_mod_add_quick(tmp1, tmp1, group->b, group->field)) 101e1051a39Sopenharmony_ci goto err; 102e1051a39Sopenharmony_ci } 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci ERR_set_mark(); 105e1051a39Sopenharmony_ci if (!BN_mod_sqrt(y, tmp1, group->field, ctx)) { 106e1051a39Sopenharmony_ci#ifndef FIPS_MODULE 107e1051a39Sopenharmony_ci unsigned long err = ERR_peek_last_error(); 108e1051a39Sopenharmony_ci 109e1051a39Sopenharmony_ci if (ERR_GET_LIB(err) == ERR_LIB_BN 110e1051a39Sopenharmony_ci && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { 111e1051a39Sopenharmony_ci ERR_pop_to_mark(); 112e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT); 113e1051a39Sopenharmony_ci } else 114e1051a39Sopenharmony_ci#endif 115e1051a39Sopenharmony_ci { 116e1051a39Sopenharmony_ci ERR_clear_last_mark(); 117e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 118e1051a39Sopenharmony_ci } 119e1051a39Sopenharmony_ci goto err; 120e1051a39Sopenharmony_ci } 121e1051a39Sopenharmony_ci ERR_clear_last_mark(); 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci if (y_bit != BN_is_odd(y)) { 124e1051a39Sopenharmony_ci if (BN_is_zero(y)) { 125e1051a39Sopenharmony_ci int kron; 126e1051a39Sopenharmony_ci 127e1051a39Sopenharmony_ci kron = BN_kronecker(x, group->field, ctx); 128e1051a39Sopenharmony_ci if (kron == -2) 129e1051a39Sopenharmony_ci goto err; 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ci if (kron == 1) 132e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSION_BIT); 133e1051a39Sopenharmony_ci else 134e1051a39Sopenharmony_ci /* 135e1051a39Sopenharmony_ci * BN_mod_sqrt() should have caught this error (not a square) 136e1051a39Sopenharmony_ci */ 137e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT); 138e1051a39Sopenharmony_ci goto err; 139e1051a39Sopenharmony_ci } 140e1051a39Sopenharmony_ci if (!BN_usub(y, group->field, y)) 141e1051a39Sopenharmony_ci goto err; 142e1051a39Sopenharmony_ci } 143e1051a39Sopenharmony_ci if (y_bit != BN_is_odd(y)) { 144e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); 145e1051a39Sopenharmony_ci goto err; 146e1051a39Sopenharmony_ci } 147e1051a39Sopenharmony_ci 148e1051a39Sopenharmony_ci if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) 149e1051a39Sopenharmony_ci goto err; 150e1051a39Sopenharmony_ci 151e1051a39Sopenharmony_ci ret = 1; 152e1051a39Sopenharmony_ci 153e1051a39Sopenharmony_ci err: 154e1051a39Sopenharmony_ci BN_CTX_end(ctx); 155e1051a39Sopenharmony_ci BN_CTX_free(new_ctx); 156e1051a39Sopenharmony_ci return ret; 157e1051a39Sopenharmony_ci} 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_cisize_t ossl_ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, 160e1051a39Sopenharmony_ci point_conversion_form_t form, 161e1051a39Sopenharmony_ci unsigned char *buf, size_t len, BN_CTX *ctx) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci size_t ret; 164e1051a39Sopenharmony_ci BN_CTX *new_ctx = NULL; 165e1051a39Sopenharmony_ci int used_ctx = 0; 166e1051a39Sopenharmony_ci BIGNUM *x, *y; 167e1051a39Sopenharmony_ci size_t field_len, i, skip; 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci if ((form != POINT_CONVERSION_COMPRESSED) 170e1051a39Sopenharmony_ci && (form != POINT_CONVERSION_UNCOMPRESSED) 171e1051a39Sopenharmony_ci && (form != POINT_CONVERSION_HYBRID)) { 172e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); 173e1051a39Sopenharmony_ci goto err; 174e1051a39Sopenharmony_ci } 175e1051a39Sopenharmony_ci 176e1051a39Sopenharmony_ci if (EC_POINT_is_at_infinity(group, point)) { 177e1051a39Sopenharmony_ci /* encodes to a single 0 octet */ 178e1051a39Sopenharmony_ci if (buf != NULL) { 179e1051a39Sopenharmony_ci if (len < 1) { 180e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 181e1051a39Sopenharmony_ci return 0; 182e1051a39Sopenharmony_ci } 183e1051a39Sopenharmony_ci buf[0] = 0; 184e1051a39Sopenharmony_ci } 185e1051a39Sopenharmony_ci return 1; 186e1051a39Sopenharmony_ci } 187e1051a39Sopenharmony_ci 188e1051a39Sopenharmony_ci /* ret := required output buffer length */ 189e1051a39Sopenharmony_ci field_len = BN_num_bytes(group->field); 190e1051a39Sopenharmony_ci ret = 191e1051a39Sopenharmony_ci (form == 192e1051a39Sopenharmony_ci POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; 193e1051a39Sopenharmony_ci 194e1051a39Sopenharmony_ci /* if 'buf' is NULL, just return required length */ 195e1051a39Sopenharmony_ci if (buf != NULL) { 196e1051a39Sopenharmony_ci if (len < ret) { 197e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 198e1051a39Sopenharmony_ci goto err; 199e1051a39Sopenharmony_ci } 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci if (ctx == NULL) { 202e1051a39Sopenharmony_ci ctx = new_ctx = BN_CTX_new_ex(group->libctx); 203e1051a39Sopenharmony_ci if (ctx == NULL) 204e1051a39Sopenharmony_ci return 0; 205e1051a39Sopenharmony_ci } 206e1051a39Sopenharmony_ci 207e1051a39Sopenharmony_ci BN_CTX_start(ctx); 208e1051a39Sopenharmony_ci used_ctx = 1; 209e1051a39Sopenharmony_ci x = BN_CTX_get(ctx); 210e1051a39Sopenharmony_ci y = BN_CTX_get(ctx); 211e1051a39Sopenharmony_ci if (y == NULL) 212e1051a39Sopenharmony_ci goto err; 213e1051a39Sopenharmony_ci 214e1051a39Sopenharmony_ci if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx)) 215e1051a39Sopenharmony_ci goto err; 216e1051a39Sopenharmony_ci 217e1051a39Sopenharmony_ci if ((form == POINT_CONVERSION_COMPRESSED 218e1051a39Sopenharmony_ci || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) 219e1051a39Sopenharmony_ci buf[0] = form + 1; 220e1051a39Sopenharmony_ci else 221e1051a39Sopenharmony_ci buf[0] = form; 222e1051a39Sopenharmony_ci 223e1051a39Sopenharmony_ci i = 1; 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci skip = field_len - BN_num_bytes(x); 226e1051a39Sopenharmony_ci if (skip > field_len) { 227e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); 228e1051a39Sopenharmony_ci goto err; 229e1051a39Sopenharmony_ci } 230e1051a39Sopenharmony_ci while (skip > 0) { 231e1051a39Sopenharmony_ci buf[i++] = 0; 232e1051a39Sopenharmony_ci skip--; 233e1051a39Sopenharmony_ci } 234e1051a39Sopenharmony_ci skip = BN_bn2bin(x, buf + i); 235e1051a39Sopenharmony_ci i += skip; 236e1051a39Sopenharmony_ci if (i != 1 + field_len) { 237e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); 238e1051a39Sopenharmony_ci goto err; 239e1051a39Sopenharmony_ci } 240e1051a39Sopenharmony_ci 241e1051a39Sopenharmony_ci if (form == POINT_CONVERSION_UNCOMPRESSED 242e1051a39Sopenharmony_ci || form == POINT_CONVERSION_HYBRID) { 243e1051a39Sopenharmony_ci skip = field_len - BN_num_bytes(y); 244e1051a39Sopenharmony_ci if (skip > field_len) { 245e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); 246e1051a39Sopenharmony_ci goto err; 247e1051a39Sopenharmony_ci } 248e1051a39Sopenharmony_ci while (skip > 0) { 249e1051a39Sopenharmony_ci buf[i++] = 0; 250e1051a39Sopenharmony_ci skip--; 251e1051a39Sopenharmony_ci } 252e1051a39Sopenharmony_ci skip = BN_bn2bin(y, buf + i); 253e1051a39Sopenharmony_ci i += skip; 254e1051a39Sopenharmony_ci } 255e1051a39Sopenharmony_ci 256e1051a39Sopenharmony_ci if (i != ret) { 257e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR); 258e1051a39Sopenharmony_ci goto err; 259e1051a39Sopenharmony_ci } 260e1051a39Sopenharmony_ci } 261e1051a39Sopenharmony_ci 262e1051a39Sopenharmony_ci if (used_ctx) 263e1051a39Sopenharmony_ci BN_CTX_end(ctx); 264e1051a39Sopenharmony_ci BN_CTX_free(new_ctx); 265e1051a39Sopenharmony_ci return ret; 266e1051a39Sopenharmony_ci 267e1051a39Sopenharmony_ci err: 268e1051a39Sopenharmony_ci if (used_ctx) 269e1051a39Sopenharmony_ci BN_CTX_end(ctx); 270e1051a39Sopenharmony_ci BN_CTX_free(new_ctx); 271e1051a39Sopenharmony_ci return 0; 272e1051a39Sopenharmony_ci} 273e1051a39Sopenharmony_ci 274e1051a39Sopenharmony_ciint ossl_ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, 275e1051a39Sopenharmony_ci const unsigned char *buf, size_t len, 276e1051a39Sopenharmony_ci BN_CTX *ctx) 277e1051a39Sopenharmony_ci{ 278e1051a39Sopenharmony_ci point_conversion_form_t form; 279e1051a39Sopenharmony_ci int y_bit; 280e1051a39Sopenharmony_ci BN_CTX *new_ctx = NULL; 281e1051a39Sopenharmony_ci BIGNUM *x, *y; 282e1051a39Sopenharmony_ci size_t field_len, enc_len; 283e1051a39Sopenharmony_ci int ret = 0; 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_ci if (len == 0) { 286e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL); 287e1051a39Sopenharmony_ci return 0; 288e1051a39Sopenharmony_ci } 289e1051a39Sopenharmony_ci form = buf[0]; 290e1051a39Sopenharmony_ci y_bit = form & 1; 291e1051a39Sopenharmony_ci form = form & ~1U; 292e1051a39Sopenharmony_ci if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) 293e1051a39Sopenharmony_ci && (form != POINT_CONVERSION_UNCOMPRESSED) 294e1051a39Sopenharmony_ci && (form != POINT_CONVERSION_HYBRID)) { 295e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 296e1051a39Sopenharmony_ci return 0; 297e1051a39Sopenharmony_ci } 298e1051a39Sopenharmony_ci if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { 299e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 300e1051a39Sopenharmony_ci return 0; 301e1051a39Sopenharmony_ci } 302e1051a39Sopenharmony_ci 303e1051a39Sopenharmony_ci if (form == 0) { 304e1051a39Sopenharmony_ci if (len != 1) { 305e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 306e1051a39Sopenharmony_ci return 0; 307e1051a39Sopenharmony_ci } 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_ci return EC_POINT_set_to_infinity(group, point); 310e1051a39Sopenharmony_ci } 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci field_len = BN_num_bytes(group->field); 313e1051a39Sopenharmony_ci enc_len = 314e1051a39Sopenharmony_ci (form == 315e1051a39Sopenharmony_ci POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; 316e1051a39Sopenharmony_ci 317e1051a39Sopenharmony_ci if (len != enc_len) { 318e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 319e1051a39Sopenharmony_ci return 0; 320e1051a39Sopenharmony_ci } 321e1051a39Sopenharmony_ci 322e1051a39Sopenharmony_ci if (ctx == NULL) { 323e1051a39Sopenharmony_ci ctx = new_ctx = BN_CTX_new_ex(group->libctx); 324e1051a39Sopenharmony_ci if (ctx == NULL) 325e1051a39Sopenharmony_ci return 0; 326e1051a39Sopenharmony_ci } 327e1051a39Sopenharmony_ci 328e1051a39Sopenharmony_ci BN_CTX_start(ctx); 329e1051a39Sopenharmony_ci x = BN_CTX_get(ctx); 330e1051a39Sopenharmony_ci y = BN_CTX_get(ctx); 331e1051a39Sopenharmony_ci if (y == NULL) 332e1051a39Sopenharmony_ci goto err; 333e1051a39Sopenharmony_ci 334e1051a39Sopenharmony_ci if (!BN_bin2bn(buf + 1, field_len, x)) 335e1051a39Sopenharmony_ci goto err; 336e1051a39Sopenharmony_ci if (BN_ucmp(x, group->field) >= 0) { 337e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 338e1051a39Sopenharmony_ci goto err; 339e1051a39Sopenharmony_ci } 340e1051a39Sopenharmony_ci 341e1051a39Sopenharmony_ci if (form == POINT_CONVERSION_COMPRESSED) { 342e1051a39Sopenharmony_ci if (!EC_POINT_set_compressed_coordinates(group, point, x, y_bit, ctx)) 343e1051a39Sopenharmony_ci goto err; 344e1051a39Sopenharmony_ci } else { 345e1051a39Sopenharmony_ci if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) 346e1051a39Sopenharmony_ci goto err; 347e1051a39Sopenharmony_ci if (BN_ucmp(y, group->field) >= 0) { 348e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 349e1051a39Sopenharmony_ci goto err; 350e1051a39Sopenharmony_ci } 351e1051a39Sopenharmony_ci if (form == POINT_CONVERSION_HYBRID) { 352e1051a39Sopenharmony_ci if (y_bit != BN_is_odd(y)) { 353e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); 354e1051a39Sopenharmony_ci goto err; 355e1051a39Sopenharmony_ci } 356e1051a39Sopenharmony_ci } 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ci /* 359e1051a39Sopenharmony_ci * EC_POINT_set_affine_coordinates is responsible for checking that 360e1051a39Sopenharmony_ci * the point is on the curve. 361e1051a39Sopenharmony_ci */ 362e1051a39Sopenharmony_ci if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx)) 363e1051a39Sopenharmony_ci goto err; 364e1051a39Sopenharmony_ci } 365e1051a39Sopenharmony_ci 366e1051a39Sopenharmony_ci ret = 1; 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci err: 369e1051a39Sopenharmony_ci BN_CTX_end(ctx); 370e1051a39Sopenharmony_ci BN_CTX_free(new_ctx); 371e1051a39Sopenharmony_ci return ret; 372e1051a39Sopenharmony_ci} 373