/*
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/*
* ECDSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include "internal/cryptlib.h"
#include <string.h>
#include "ec_local.h"
#include "internal/refcount.h"
#include <openssl/err.h>
#include <openssl/engine.h>
#include <openssl/self_test.h>
#include "crypto/bn.h"
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
void *cbarg);
#ifndef FIPS_MODE
EC_KEY *EC_KEY_new(void)
{
return ec_key_new_method_int(NULL, NULL);
}
#endif
EC_KEY *EC_KEY_new_ex(OPENSSL_CTX *ctx)
{
return ec_key_new_method_int(ctx, NULL);
}
EC_KEY *EC_KEY_new_by_curve_name_ex(OPENSSL_CTX *ctx, int nid)
{
EC_KEY *ret = EC_KEY_new_ex(ctx);
if (ret == NULL)
return NULL;
ret->group = EC_GROUP_new_by_curve_name_ex(ctx, nid);
if (ret->group == NULL) {
EC_KEY_free(ret);
return NULL;
}
if (ret->meth->set_group != NULL
&& ret->meth->set_group(ret, ret->group) == 0) {
EC_KEY_free(ret);
return NULL;
}
return ret;
}
#ifndef FIPS_MODE
EC_KEY *EC_KEY_new_by_curve_name(int nid)
{
return EC_KEY_new_by_curve_name_ex(NULL, nid);
}
#endif
void EC_KEY_free(EC_KEY *r)
{
int i;
if (r == NULL)
return;
CRYPTO_DOWN_REF(&r->references, &i, r->lock);
REF_PRINT_COUNT("EC_KEY", r);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
if (r->meth != NULL && r->meth->finish != NULL)
r->meth->finish(r);
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
ENGINE_finish(r->engine);
#endif
if (r->group && r->group->meth->keyfinish)
r->group->meth->keyfinish(r);
#ifndef FIPS_MODE
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EC_KEY, r, &r->ex_data);
#endif
CRYPTO_THREAD_lock_free(r->lock);
EC_GROUP_free(r->group);
EC_POINT_free(r->pub_key);
BN_clear_free(r->priv_key);
OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
}
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
{
if (dest == NULL || src == NULL) {
ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (src->meth != dest->meth) {
if (dest->meth->finish != NULL)
dest->meth->finish(dest);
if (dest->group && dest->group->meth->keyfinish)
dest->group->meth->keyfinish(dest);
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
if (ENGINE_finish(dest->engine) == 0)
return 0;
dest->engine = NULL;
#endif
}
dest->libctx = src->libctx;
/* copy the parameters */
if (src->group != NULL) {
const EC_METHOD *meth = EC_GROUP_method_of(src->group);
/* clear the old group */
EC_GROUP_free(dest->group);
dest->group = EC_GROUP_new_ex(src->libctx, meth);
if (dest->group == NULL)
return NULL;
if (!EC_GROUP_copy(dest->group, src->group))
return NULL;
/* copy the public key */
if (src->pub_key != NULL) {
EC_POINT_free(dest->pub_key);
dest->pub_key = EC_POINT_new(src->group);
if (dest->pub_key == NULL)
return NULL;