1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * ECDSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include "ec_local.h" 17e1051a39Sopenharmony_ci#include <openssl/err.h> 18e1051a39Sopenharmony_ci 19e1051a39Sopenharmony_ciint EC_GROUP_check_named_curve(const EC_GROUP *group, int nist_only, 20e1051a39Sopenharmony_ci BN_CTX *ctx) 21e1051a39Sopenharmony_ci{ 22e1051a39Sopenharmony_ci int nid; 23e1051a39Sopenharmony_ci BN_CTX *new_ctx = NULL; 24e1051a39Sopenharmony_ci 25e1051a39Sopenharmony_ci if (group == NULL) { 26e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 27e1051a39Sopenharmony_ci return NID_undef; 28e1051a39Sopenharmony_ci } 29e1051a39Sopenharmony_ci 30e1051a39Sopenharmony_ci if (ctx == NULL) { 31e1051a39Sopenharmony_ci ctx = new_ctx = BN_CTX_new_ex(NULL); 32e1051a39Sopenharmony_ci if (ctx == NULL) { 33e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 34e1051a39Sopenharmony_ci return NID_undef; 35e1051a39Sopenharmony_ci } 36e1051a39Sopenharmony_ci } 37e1051a39Sopenharmony_ci 38e1051a39Sopenharmony_ci nid = ossl_ec_curve_nid_from_params(group, ctx); 39e1051a39Sopenharmony_ci if (nid > 0 && nist_only && EC_curve_nid2nist(nid) == NULL) 40e1051a39Sopenharmony_ci nid = NID_undef; 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci BN_CTX_free(new_ctx); 43e1051a39Sopenharmony_ci return nid; 44e1051a39Sopenharmony_ci} 45e1051a39Sopenharmony_ci 46e1051a39Sopenharmony_ciint EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) 47e1051a39Sopenharmony_ci{ 48e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 49e1051a39Sopenharmony_ci /* 50e1051a39Sopenharmony_ci * ECC domain parameter validation. 51e1051a39Sopenharmony_ci * See SP800-56A R3 5.5.2 "Assurances of Domain-Parameter Validity" Part 1b. 52e1051a39Sopenharmony_ci */ 53e1051a39Sopenharmony_ci return EC_GROUP_check_named_curve(group, 1, ctx) >= 0 ? 1 : 0; 54e1051a39Sopenharmony_ci#else 55e1051a39Sopenharmony_ci int ret = 0; 56e1051a39Sopenharmony_ci const BIGNUM *order; 57e1051a39Sopenharmony_ci BN_CTX *new_ctx = NULL; 58e1051a39Sopenharmony_ci EC_POINT *point = NULL; 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_ci if (group == NULL || group->meth == NULL) { 61e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 62e1051a39Sopenharmony_ci return 0; 63e1051a39Sopenharmony_ci } 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci /* Custom curves assumed to be correct */ 66e1051a39Sopenharmony_ci if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0) 67e1051a39Sopenharmony_ci return 1; 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci if (ctx == NULL) { 70e1051a39Sopenharmony_ci ctx = new_ctx = BN_CTX_new(); 71e1051a39Sopenharmony_ci if (ctx == NULL) { 72e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 73e1051a39Sopenharmony_ci goto err; 74e1051a39Sopenharmony_ci } 75e1051a39Sopenharmony_ci } 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_ci /* check the discriminant */ 78e1051a39Sopenharmony_ci if (!EC_GROUP_check_discriminant(group, ctx)) { 79e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_DISCRIMINANT_IS_ZERO); 80e1051a39Sopenharmony_ci goto err; 81e1051a39Sopenharmony_ci } 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci /* check the generator */ 84e1051a39Sopenharmony_ci if (group->generator == NULL) { 85e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR); 86e1051a39Sopenharmony_ci goto err; 87e1051a39Sopenharmony_ci } 88e1051a39Sopenharmony_ci if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { 89e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE); 90e1051a39Sopenharmony_ci goto err; 91e1051a39Sopenharmony_ci } 92e1051a39Sopenharmony_ci 93e1051a39Sopenharmony_ci /* check the order of the generator */ 94e1051a39Sopenharmony_ci if ((point = EC_POINT_new(group)) == NULL) 95e1051a39Sopenharmony_ci goto err; 96e1051a39Sopenharmony_ci order = EC_GROUP_get0_order(group); 97e1051a39Sopenharmony_ci if (order == NULL) 98e1051a39Sopenharmony_ci goto err; 99e1051a39Sopenharmony_ci if (BN_is_zero(order)) { 100e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_UNDEFINED_ORDER); 101e1051a39Sopenharmony_ci goto err; 102e1051a39Sopenharmony_ci } 103e1051a39Sopenharmony_ci 104e1051a39Sopenharmony_ci if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) 105e1051a39Sopenharmony_ci goto err; 106e1051a39Sopenharmony_ci if (!EC_POINT_is_at_infinity(group, point)) { 107e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); 108e1051a39Sopenharmony_ci goto err; 109e1051a39Sopenharmony_ci } 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci ret = 1; 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci err: 114e1051a39Sopenharmony_ci BN_CTX_free(new_ctx); 115e1051a39Sopenharmony_ci EC_POINT_free(point); 116e1051a39Sopenharmony_ci return ret; 117e1051a39Sopenharmony_ci#endif /* FIPS_MODULE */ 118e1051a39Sopenharmony_ci} 119