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