mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-27 15:43:42 +08:00
first step of v2 final release
This commit is contained in:
@@ -6,6 +6,7 @@ SOURCE[../../libcrypto]=\
|
||||
ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c \
|
||||
ecp_oct.c ec2_oct.c ec_oct.c ec_kmeth.c ecdh_ossl.c ecdh_kdf.c \
|
||||
ecdsa_ossl.c ecdsa_sign.c ecdsa_vrf.c curve25519.c ecx_meth.c \
|
||||
ec_ctrl.c \
|
||||
{- $target{ec_asm_src} -}
|
||||
|
||||
GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl $(PERLASM_SCHEME) $(CFLAGS) $(LIB_CFLAGS) $(PROCESSOR)
|
||||
|
||||
@@ -809,7 +809,7 @@ static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
|
||||
goto err;
|
||||
if (kdf_md == NULL) {
|
||||
/* Fixme later for better MD */
|
||||
kdf_md = EVP_sha1();
|
||||
kdf_md = EVP_get_default_digest();
|
||||
if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
567
crypto/ec/ec_bssl_asn1.c
Normal file
567
crypto/ec/ec_bssl_asn1.c
Normal file
@@ -0,0 +1,567 @@
|
||||
/* Written by Nils Larsch for the OpenSSL project. */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com). */
|
||||
|
||||
#include <openssl/ec.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/mem.h>
|
||||
#include <openssl/nid.h>
|
||||
|
||||
#include "../bytestring/internal.h"
|
||||
#include "../internal.h"
|
||||
#include <openssl/e_os2.h>
|
||||
#include "ec_lcl.h"
|
||||
|
||||
static const uint8_t kParametersTag =
|
||||
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0;
|
||||
static const uint8_t kPublicKeyTag =
|
||||
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1;
|
||||
|
||||
EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) {
|
||||
CBS ec_private_key, private_key;
|
||||
uint64_t version;
|
||||
if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_asn1_uint64(&ec_private_key, &version) ||
|
||||
version != 1 ||
|
||||
!CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse the optional parameters field. */
|
||||
EC_GROUP *inner_group = NULL;
|
||||
EC_KEY *ret = NULL;
|
||||
if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) {
|
||||
/* Per SEC 1, as an alternative to omitting it, one is allowed to specify
|
||||
* this field and put in a NULL to mean inheriting this value. This was
|
||||
* omitted in a previous version of this logic without problems, so leave it
|
||||
* unimplemented. */
|
||||
CBS child;
|
||||
if (!CBS_get_asn1(&ec_private_key, &child, kParametersTag)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
inner_group = EC_KEY_parse_parameters(&child);
|
||||
if (inner_group == NULL) {
|
||||
goto err;
|
||||
}
|
||||
if (group == NULL) {
|
||||
group = inner_group;
|
||||
} else if (EC_GROUP_cmp(group, inner_group, NULL) != 0) {
|
||||
/* If a group was supplied externally, it must match. */
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH);
|
||||
goto err;
|
||||
}
|
||||
if (CBS_len(&child) != 0) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (group == NULL) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = EC_KEY_new();
|
||||
if (ret == NULL || !EC_KEY_set_group(ret, group)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Although RFC 5915 specifies the length of the key, OpenSSL historically
|
||||
* got this wrong, so accept any length. See upstream's
|
||||
* 30cd4ff294252c4b6a4b69cbef6a5b4117705d22. */
|
||||
ret->priv_key =
|
||||
BN_bin2bn(CBS_data(&private_key), CBS_len(&private_key), NULL);
|
||||
ret->pub_key = EC_POINT_new(group);
|
||||
if (ret->priv_key == NULL || ret->pub_key == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (BN_cmp(ret->priv_key, EC_GROUP_get0_order(group)) >= 0) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (CBS_peek_asn1_tag(&ec_private_key, kPublicKeyTag)) {
|
||||
CBS child, public_key;
|
||||
uint8_t padding;
|
||||
if (!CBS_get_asn1(&ec_private_key, &child, kPublicKeyTag) ||
|
||||
!CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
|
||||
/* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
|
||||
* encoded as a BIT STRING with bits ordered as in the DER encoding. */
|
||||
!CBS_get_u8(&public_key, &padding) ||
|
||||
padding != 0 ||
|
||||
/* Explicitly check |public_key| is non-empty to save the conversion
|
||||
* form later. */
|
||||
CBS_len(&public_key) == 0 ||
|
||||
!EC_POINT_oct2point(group, ret->pub_key, CBS_data(&public_key),
|
||||
CBS_len(&public_key), NULL) ||
|
||||
CBS_len(&child) != 0) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Save the point conversion form.
|
||||
* TODO(davidben): Consider removing this. */
|
||||
ret->conv_form =
|
||||
(point_conversion_form_t)(CBS_data(&public_key)[0] & ~0x01);
|
||||
} else {
|
||||
/* Compute the public key instead. */
|
||||
if (!EC_POINT_mul(group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
/* Remember the original private-key-only encoding.
|
||||
* TODO(davidben): Consider removing this. */
|
||||
ret->enc_flag |= EC_PKEY_NO_PUBKEY;
|
||||
}
|
||||
|
||||
if (CBS_len(&ec_private_key) != 0) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Ensure the resulting key is valid. */
|
||||
if (!EC_KEY_check_key(ret)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
EC_GROUP_free(inner_group);
|
||||
return ret;
|
||||
|
||||
err:
|
||||
EC_KEY_free(ret);
|
||||
EC_GROUP_free(inner_group);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key,
|
||||
unsigned enc_flags) {
|
||||
if (key == NULL || key->group == NULL || key->priv_key == NULL) {
|
||||
//OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBB ec_private_key, private_key;
|
||||
if (!CBB_add_asn1(cbb, &ec_private_key, CBS_ASN1_SEQUENCE) ||
|
||||
!CBB_add_asn1_uint64(&ec_private_key, 1 /* version */) ||
|
||||
!CBB_add_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING) ||
|
||||
!BN_bn2cbb_padded(&private_key,
|
||||
BN_num_bytes(EC_GROUP_get0_order(key->group)),
|
||||
key->priv_key)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(enc_flags & EC_PKEY_NO_PARAMETERS)) {
|
||||
CBB child;
|
||||
if (!CBB_add_asn1(&ec_private_key, &child, kParametersTag) ||
|
||||
!EC_KEY_marshal_curve_name(&child, key->group) ||
|
||||
!CBB_flush(&ec_private_key)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO(fork): replace this flexibility with sensible default? */
|
||||
if (!(enc_flags & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
|
||||
CBB child, public_key;
|
||||
if (!CBB_add_asn1(&ec_private_key, &child, kPublicKeyTag) ||
|
||||
!CBB_add_asn1(&child, &public_key, CBS_ASN1_BITSTRING) ||
|
||||
/* As in a SubjectPublicKeyInfo, the byte-encoded public key is then
|
||||
* encoded as a BIT STRING with bits ordered as in the DER encoding. */
|
||||
!CBB_add_u8(&public_key, 0 /* padding */) ||
|
||||
!EC_POINT_point2cbb(&public_key, key->group, key->pub_key,
|
||||
key->conv_form, NULL) ||
|
||||
!CBB_flush(&ec_private_key)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!CBB_flush(cbb)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* is_unsigned_integer returns one if |cbs| is a valid unsigned DER INTEGER and
|
||||
* zero otherwise. */
|
||||
static int is_unsigned_integer(const CBS *cbs) {
|
||||
if (CBS_len(cbs) == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t byte = CBS_data(cbs)[0];
|
||||
if ((byte & 0x80) ||
|
||||
(byte == 0 && CBS_len(cbs) > 1 && (CBS_data(cbs)[1] & 0x80) == 0)) {
|
||||
/* Negative or not minimally-encoded. */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* kPrimeFieldOID is the encoding of 1.2.840.10045.1.1. */
|
||||
static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01};
|
||||
|
||||
static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a,
|
||||
CBS *out_b, CBS *out_base_x,
|
||||
CBS *out_base_y, CBS *out_order) {
|
||||
/* See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an
|
||||
* ECParameters while RFC 5480 calls it a SpecifiedECDomain. */
|
||||
CBS params, field_id, field_type, curve, base;
|
||||
uint64_t version;
|
||||
if (!CBS_get_asn1(in, ¶ms, CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_asn1_uint64(¶ms, &version) ||
|
||||
version != 1 ||
|
||||
!CBS_get_asn1(¶ms, &field_id, CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) ||
|
||||
CBS_len(&field_type) != sizeof(kPrimeField) ||
|
||||
OPENSSL_memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != 0 ||
|
||||
!CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) ||
|
||||
!is_unsigned_integer(out_prime) ||
|
||||
CBS_len(&field_id) != 0 ||
|
||||
!CBS_get_asn1(¶ms, &curve, CBS_ASN1_SEQUENCE) ||
|
||||
!CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) ||
|
||||
!CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) ||
|
||||
/* |curve| has an optional BIT STRING seed which we ignore. */
|
||||
!CBS_get_asn1(¶ms, &base, CBS_ASN1_OCTETSTRING) ||
|
||||
!CBS_get_asn1(¶ms, out_order, CBS_ASN1_INTEGER) ||
|
||||
!is_unsigned_integer(out_order)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* |params| has an optional cofactor which we ignore. With the optional seed
|
||||
* in |curve|, a group already has arbitrarily many encodings. Parse enough to
|
||||
* uniquely determine the curve. */
|
||||
|
||||
/* Require that the base point use uncompressed form. */
|
||||
uint8_t form;
|
||||
if (!CBS_get_u8(&base, &form) || form != POINT_CONVERSION_UNCOMPRESSED) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (CBS_len(&base) % 2 != 0) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
size_t field_len = CBS_len(&base) / 2;
|
||||
CBS_init(out_base_x, CBS_data(&base), field_len);
|
||||
CBS_init(out_base_y, CBS_data(&base) + field_len, field_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* integers_equal returns one if |a| and |b| are equal, up to leading zeros, and
|
||||
* zero otherwise. */
|
||||
static int integers_equal(const CBS *a, const uint8_t *b, size_t b_len) {
|
||||
/* Remove leading zeros from |a| and |b|. */
|
||||
CBS a_copy = *a;
|
||||
while (CBS_len(&a_copy) > 0 && CBS_data(&a_copy)[0] == 0) {
|
||||
CBS_skip(&a_copy, 1);
|
||||
}
|
||||
while (b_len > 0 && b[0] == 0) {
|
||||
b++;
|
||||
b_len--;
|
||||
}
|
||||
return CBS_mem_equal(&a_copy, b, b_len);
|
||||
}
|
||||
|
||||
#if 0
|
||||
EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) {
|
||||
CBS named_curve;
|
||||
if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for a matching curve. */
|
||||
const struct built_in_curves *const curves = OPENSSL_built_in_curves();
|
||||
for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
|
||||
const struct built_in_curve *curve = &curves->curves[i];
|
||||
if (CBS_len(&named_curve) == curve->oid_len &&
|
||||
OPENSSL_memcmp(CBS_data(&named_curve), curve->oid, curve->oid_len) ==
|
||||
0) {
|
||||
return EC_GROUP_new_by_curve_name(curve->nid);
|
||||
}
|
||||
}
|
||||
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) {
|
||||
int nid = EC_GROUP_get_curve_name(group);
|
||||
if (nid == NID_undef) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct built_in_curves *const curves = OPENSSL_built_in_curves();
|
||||
for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
|
||||
const struct built_in_curve *curve = &curves->curves[i];
|
||||
if (curve->nid == nid) {
|
||||
CBB child;
|
||||
return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) &&
|
||||
CBB_add_bytes(&child, curve->oid, curve->oid_len) &&
|
||||
CBB_flush(cbb);
|
||||
}
|
||||
}
|
||||
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) {
|
||||
if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) {
|
||||
return EC_KEY_parse_curve_name(cbs);
|
||||
}
|
||||
|
||||
/* OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions
|
||||
* of named curves.
|
||||
*
|
||||
* TODO(davidben): Remove support for this. */
|
||||
CBS prime, a, b, base_x, base_y, order;
|
||||
if (!parse_explicit_prime_curve(cbs, &prime, &a, &b, &base_x, &base_y,
|
||||
&order)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Look for a matching prime curve. */
|
||||
const struct built_in_curves *const curves = OPENSSL_built_in_curves();
|
||||
for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) {
|
||||
const struct built_in_curve *curve = &curves->curves[i];
|
||||
const unsigned param_len = curve->data->param_len;
|
||||
/* |curve->data->data| is ordered p, a, b, x, y, order, each component
|
||||
* zero-padded up to the field length. Although SEC 1 states that the
|
||||
* Field-Element-to-Octet-String conversion also pads, OpenSSL mis-encodes
|
||||
* |a| and |b|, so this comparison must allow omitting leading zeros. (This
|
||||
* is relevant for P-521 whose |b| has a leading 0.) */
|
||||
if (integers_equal(&prime, curve->data->data, param_len) &&
|
||||
integers_equal(&a, curve->data->data + param_len, param_len) &&
|
||||
integers_equal(&b, curve->data->data + param_len * 2, param_len) &&
|
||||
integers_equal(&base_x, curve->data->data + param_len * 3, param_len) &&
|
||||
integers_equal(&base_y, curve->data->data + param_len * 4, param_len) &&
|
||||
integers_equal(&order, curve->data->data + param_len * 5, param_len)) {
|
||||
return EC_GROUP_new_by_curve_name(curve->nid);
|
||||
}
|
||||
}
|
||||
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point,
|
||||
point_conversion_form_t form, BN_CTX *ctx) {
|
||||
size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx);
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t *p;
|
||||
return CBB_add_space(out, &p, len) &&
|
||||
EC_POINT_point2oct(group, point, form, p, len, ctx) == len;
|
||||
}
|
||||
|
||||
EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) {
|
||||
/* This function treats its |out| parameter differently from other |d2i|
|
||||
* functions. If supplied, take the group from |*out|. */
|
||||
const EC_GROUP *group = NULL;
|
||||
if (out != NULL && *out != NULL) {
|
||||
group = EC_KEY_get0_group(*out);
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
//OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, *inp, (size_t)len);
|
||||
EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group);
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (out != NULL) {
|
||||
EC_KEY_free(*out);
|
||||
*out = ret;
|
||||
}
|
||||
*inp = CBS_data(&cbs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
|
||||
CBB cbb;
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) {
|
||||
CBB_cleanup(&cbb);
|
||||
return -1;
|
||||
}
|
||||
return CBB_finish_i2d(&cbb, outp);
|
||||
}
|
||||
|
||||
EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) {
|
||||
if (len < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, *inp, (size_t)len);
|
||||
EC_GROUP *group = EC_KEY_parse_parameters(&cbs);
|
||||
if (group == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_KEY *ret = EC_KEY_new();
|
||||
if (ret == NULL || !EC_KEY_set_group(ret, group)) {
|
||||
EC_GROUP_free(group);
|
||||
EC_KEY_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
EC_GROUP_free(group);
|
||||
|
||||
if (out_key != NULL) {
|
||||
EC_KEY_free(*out_key);
|
||||
*out_key = ret;
|
||||
}
|
||||
*inp = CBS_data(&cbs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
|
||||
if (key == NULL || key->group == NULL) {
|
||||
//OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CBB cbb;
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!EC_KEY_marshal_curve_name(&cbb, key->group)) {
|
||||
CBB_cleanup(&cbb);
|
||||
return -1;
|
||||
}
|
||||
return CBB_finish_i2d(&cbb, outp);
|
||||
}
|
||||
#endif
|
||||
|
||||
EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) {
|
||||
EC_KEY *ret = NULL;
|
||||
|
||||
if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
|
||||
//OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
ret = *keyp;
|
||||
if (ret->pub_key == NULL &&
|
||||
(ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
|
||||
// OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
|
||||
//OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
|
||||
return NULL;
|
||||
}
|
||||
/* save the point conversion form */
|
||||
ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01);
|
||||
*inp += len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
|
||||
size_t buf_len = 0;
|
||||
int new_buffer = 0;
|
||||
|
||||
if (key == NULL) {
|
||||
//OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
|
||||
0, NULL);
|
||||
|
||||
if (outp == NULL || buf_len == 0) {
|
||||
/* out == NULL => just return the length of the octet string */
|
||||
return buf_len;
|
||||
}
|
||||
|
||||
if (*outp == NULL) {
|
||||
*outp = OPENSSL_malloc(buf_len);
|
||||
if (*outp == NULL) {
|
||||
//OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
new_buffer = 1;
|
||||
}
|
||||
if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
|
||||
buf_len, NULL)) {
|
||||
//OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
|
||||
if (new_buffer) {
|
||||
OPENSSL_free(*outp);
|
||||
*outp = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!new_buffer) {
|
||||
*outp += buf_len;
|
||||
}
|
||||
return buf_len;
|
||||
}
|
||||
138
crypto/ec/ec_ctrl.c
Normal file
138
crypto/ec/ec_ctrl.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - 2017 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
|
||||
#ifdef OPENSSL_NO_MACRO
|
||||
int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
|
||||
EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN,
|
||||
EVP_PKEY_CTRL_EC_PARAM_ENC, param_enc, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx, int co_mode)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_ECDH_COFACTOR, co_mode, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_cofactor_mode(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_kdf_type(EVP_PKEY_CTX *ctx, int kdf)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_kdf_type(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)md);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_kdf_md(EVP_PKEY_CTX *ctx, const EVP_MD **pmd)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)pmd);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int len)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_ecdh_kdf_outlen(EVP_PKEY_CTX *ctx, int *plen)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, (void *)plen);
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_set0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char *der, int len)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_EC_KDF_UKM, len, (void *)der)
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get0_ecdh_kdf_ukm(EVP_PKEY_CTX *ctx, unsigned char **pder)
|
||||
{
|
||||
return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC,
|
||||
EVP_PKEY_OP_DERIVE,
|
||||
EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)pder)
|
||||
}
|
||||
#endif
|
||||
@@ -24,7 +24,6 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"},
|
||||
{ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"},
|
||||
{ERR_FUNC(EC_F_D2I_SM2_CIPHERTEXT_VALUE), "d2i_SM2_CIPHERTEXT_VALUE"},
|
||||
{ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "do_EC_KEY_print"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ecdh_cms_decrypt"},
|
||||
{ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ecdh_cms_set_shared_info"},
|
||||
@@ -54,7 +53,6 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "eckey_pub_decode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "eckey_pub_encode"},
|
||||
{ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "eckey_type2param"},
|
||||
{ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"},
|
||||
{ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"},
|
||||
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"},
|
||||
{ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"},
|
||||
@@ -160,10 +158,8 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_NEW_METHOD), "EC_KEY_new_method"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_OCT2PRIV), "EC_KEY_oct2priv"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_PRIV2OCT), "EC_KEY_priv2oct"},
|
||||
{ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES),
|
||||
@@ -210,7 +206,6 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"},
|
||||
{ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"},
|
||||
{ERR_FUNC(EC_F_I2D_SM2_CIPHERTEXT_VALUE), "i2d_SM2_CIPHERTEXT_VALUE"},
|
||||
{ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"},
|
||||
{ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "nistp224_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "nistp256_pre_comp_new"},
|
||||
@@ -229,37 +224,14 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "pkey_ec_keygen"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "pkey_ec_paramgen"},
|
||||
{ERR_FUNC(EC_F_PKEY_EC_SIGN), "pkey_ec_sign"},
|
||||
{ERR_FUNC(EC_F_SM2_CIPHERTEXT_VALUE_DECODE),
|
||||
"SM2_CIPHERTEXT_VALUE_decode"},
|
||||
{ERR_FUNC(EC_F_SM2_CIPHERTEXT_VALUE_ENCODE),
|
||||
"SM2_CIPHERTEXT_VALUE_encode"},
|
||||
{ERR_FUNC(EC_F_SM2_CIPHERTEXT_VALUE_GET_ECIES_CIPHERTEXT_VALUE),
|
||||
"SM2_CIPHERTEXT_VALUE_get_ECIES_CIPHERTEXT_VALUE"},
|
||||
{ERR_FUNC(EC_F_SM2_CIPHERTEXT_VALUE_NEW), "SM2_CIPHERTEXT_VALUE_new"},
|
||||
{ERR_FUNC(EC_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECIES_CIPHERTEXT_VALUE),
|
||||
"SM2_CIPHERTEXT_VALUE_new_from_ECIES_CIPHERTEXT_VALUE"},
|
||||
{ERR_FUNC(EC_F_SM2_CIPHERTEXT_VALUE_SET_ECIES_CIPHERTEXT_VALUE),
|
||||
"SM2_CIPHERTEXT_VALUE_set_ECIES_CIPHERTEXT_VALUE"},
|
||||
{ERR_FUNC(EC_F_SM2_CIPHERTEXT_VALUE_SIZE), "SM2_CIPHERTEXT_VALUE_size"},
|
||||
{ERR_FUNC(EC_F_SM2_COMPUTE_ID_DIGEST), "SM2_compute_id_digest"},
|
||||
{ERR_FUNC(EC_F_SM2_COMPUTE_MESSAGE_DIGEST), "SM2_compute_message_digest"},
|
||||
{ERR_FUNC(EC_F_SM2_DECRYPT), "SM2_decrypt"},
|
||||
{ERR_FUNC(EC_F_SM2_DO_DECRYPT), "SM2_do_decrypt"},
|
||||
{ERR_FUNC(EC_F_SM2_DO_ENCRYPT), "SM2_do_encrypt"},
|
||||
{ERR_FUNC(EC_F_SM2_DO_SIGN), "SM2_do_sign"},
|
||||
{ERR_FUNC(EC_F_SM2_DO_VERIFY), "SM2_do_verify"},
|
||||
{ERR_FUNC(EC_F_SM2_ENCRYPT), "SM2_encrypt"},
|
||||
{ERR_FUNC(EC_F_SM2_ENC_PARAMS_DUP), "SM2_ENC_PARAMS_dup"},
|
||||
{ERR_FUNC(EC_F_SM2_ENC_PARAMS_INIT_WITH_RECOMMENDED),
|
||||
"SM2_ENC_PARAMS_init_with_recommended"},
|
||||
{ERR_FUNC(EC_F_SM2_ENC_PARAMS_NEW), "SM2_ENC_PARAMS_new"},
|
||||
{ERR_FUNC(EC_F_SM2_ENC_PARAMS_SET_TYPE), "SM2_ENC_PARAMS_set_type"},
|
||||
{ERR_FUNC(EC_F_SM2_GET_PUBLIC_KEY_DATA), "SM2_get_public_key_data"},
|
||||
{ERR_FUNC(EC_F_SM2_KAP_COMPUTE_KEY), "SM2_KAP_compute_key"},
|
||||
{ERR_FUNC(EC_F_SM2_KAP_CTX_INIT), "SM2_KAP_CTX_init"},
|
||||
{ERR_FUNC(EC_F_SM2_KAP_FINAL_CHECK), "SM2_KAP_final_check"},
|
||||
{ERR_FUNC(EC_F_SM2_KAP_PREPARE), "SM2_KAP_prepare"},
|
||||
{ERR_FUNC(EC_F_SM2_SIGN_SETUP), "SM2_sign_setup"},
|
||||
{ERR_FUNC(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK),
|
||||
"type1curve_eval_line_textbook"},
|
||||
{ERR_FUNC(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK),
|
||||
@@ -273,7 +245,6 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_BAD_SIGNATURE), "bad signature"},
|
||||
{ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"},
|
||||
{ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_REASON(EC_R_CIPHERTEXT_ENCODE_FAILED), "ciphertext encode failed"},
|
||||
{ERR_REASON(EC_R_CMAC_FINAL_FAILURE), "cmac final failure"},
|
||||
{ERR_REASON(EC_R_CMAC_INIT_FAILURE), "cmac init failure"},
|
||||
{ERR_REASON(EC_R_CMAC_UPDATE_FAILURE), "cmac update failure"},
|
||||
@@ -292,22 +263,16 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_ECIES_DECRYPT_FAILED), "ecies decrypt failed"},
|
||||
{ERR_REASON(EC_R_ECIES_DECRYPT_INIT_FAILURE),
|
||||
"ecies decrypt init failure"},
|
||||
{ERR_REASON(EC_R_ECIES_DECRYPT_WITH_RECOMMENDED_FAILED),
|
||||
"ecies decrypt with recommended failed"},
|
||||
{ERR_REASON(EC_R_ECIES_ENCRYPT_FAILED), "ecies encrypt failed"},
|
||||
{ERR_REASON(EC_R_ECIES_ENCRYPT_WITH_RECOMMENDED_FAILED),
|
||||
"ecies encrypt with recommended failed"},
|
||||
{ERR_REASON(EC_R_ECIES_VERIFY_MAC_FAILURE), "ecies verify mac failure"},
|
||||
{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
|
||||
"ec group new by name failure"},
|
||||
{ERR_REASON(EC_R_ENCODE_ERROR), "encode error"},
|
||||
{ERR_REASON(EC_R_ENCRYPT_FAILED), "encrypt failed"},
|
||||
{ERR_REASON(EC_R_ENCRYPT_FAILURE), "encrypt failure"},
|
||||
{ERR_REASON(EC_R_ERROR), "error"},
|
||||
{ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
|
||||
{ERR_REASON(EC_R_GEN_MAC_FAILED), "gen mac failed"},
|
||||
{ERR_REASON(EC_R_GET_CIPHERTEXT_SIZE_FAILED),
|
||||
"get ciphertext size failed"},
|
||||
{ERR_REASON(EC_R_GET_KDF_FAILED), "get kdf failed"},
|
||||
{ERR_REASON(EC_R_GET_PUBLIC_KEY_DATA_FAILURE),
|
||||
"get public key data failure"},
|
||||
{ERR_REASON(EC_R_GET_TYPE1CURVE_ZETA_FAILURE),
|
||||
@@ -315,11 +280,11 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
|
||||
{ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE),
|
||||
"group2pkparameters failure"},
|
||||
{ERR_REASON(EC_R_GROUP_MISMATCH), "group mismatch"},
|
||||
{ERR_REASON(EC_R_HMAC_FAILURE), "hmac failure"},
|
||||
{ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE),
|
||||
"i2d ecpkparameters failure"},
|
||||
{ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"},
|
||||
{ERR_REASON(EC_R_INNOR_ERROR), "innor error"},
|
||||
{ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"},
|
||||
{ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"},
|
||||
{ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"},
|
||||
@@ -330,7 +295,8 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_INVALID_ECIES_CIPHERTEXT), "invalid ecies ciphertext"},
|
||||
{ERR_REASON(EC_R_INVALID_ECIES_PARAMETERS), "invalid ecies parameters"},
|
||||
{ERR_REASON(EC_R_INVALID_ECIES_PARAMS), "invalid ecies params"},
|
||||
{ERR_REASON(EC_R_INVALID_EC_KEY), "invalid ec key"},
|
||||
{ERR_REASON(EC_R_INVALID_EC_ENCRYPT_PARAM), "invalid ec encrypt param"},
|
||||
{ERR_REASON(EC_R_INVALID_EC_SCHEME), "invalid ec scheme"},
|
||||
{ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
|
||||
{ERR_REASON(EC_R_INVALID_ENC_PARAM), "invalid enc param"},
|
||||
{ERR_REASON(EC_R_INVALID_ENC_TYPE), "invalid enc type"},
|
||||
@@ -346,6 +312,7 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_INVALID_PEER_KEY), "invalid peer key"},
|
||||
{ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"},
|
||||
{ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"},
|
||||
{ERR_REASON(EC_R_INVALID_SIGNER_ID), "invalid signer id"},
|
||||
{ERR_REASON(EC_R_INVALID_SM2_ID), "invalid sm2 id"},
|
||||
{ERR_REASON(EC_R_INVALID_SM2_KAP_CHECKSUM_LENGTH),
|
||||
"invalid sm2 kap checksum length"},
|
||||
@@ -357,37 +324,28 @@ static ERR_STRING_DATA EC_str_reasons[] = {
|
||||
{ERR_REASON(EC_R_INVLID_TYPE1CURVE), "invlid type1curve"},
|
||||
{ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
|
||||
{ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"},
|
||||
{ERR_REASON(EC_R_MALLOC_FAILED), "malloc failed"},
|
||||
{ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"},
|
||||
{ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"},
|
||||
{ERR_REASON(EC_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
|
||||
{ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"},
|
||||
{ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a nist prime"},
|
||||
{ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"},
|
||||
{ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"},
|
||||
{ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"},
|
||||
{ERR_REASON(EC_R_NO_PRIVATE_VALUE), "no private value"},
|
||||
{ERR_REASON(EC_R_NULL_ARGUMENT), "null argument"},
|
||||
{ERR_REASON(EC_R_OCT2POINT_FAILED), "oct2point failed"},
|
||||
{ERR_REASON(EC_R_OPERATION_NOT_SUPPORTED), "operation not supported"},
|
||||
{ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"},
|
||||
{ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"},
|
||||
{ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE),
|
||||
"pkparameters2group failure"},
|
||||
{ERR_REASON(EC_R_POINT2OCT_FAILED), "point2oct failed"},
|
||||
{ERR_REASON(EC_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"},
|
||||
{ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"},
|
||||
{ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"},
|
||||
{ERR_REASON(EC_R_POINT_NEW_FAILED), "point new failed"},
|
||||
{ERR_REASON(EC_R_RANDOM_NUMBER_GENERATION_FAILED),
|
||||
"random number generation failed"},
|
||||
{ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"},
|
||||
{ERR_REASON(EC_R_SLOT_FULL), "slot full"},
|
||||
{ERR_REASON(EC_R_SM2_DECRYPT_FAILED), "sm2 decrypt failed"},
|
||||
{ERR_REASON(EC_R_SM2_DECRYPT_WITH_RECOMMENDED_FAILED),
|
||||
"sm2 decrypt with recommended failed"},
|
||||
{ERR_REASON(EC_R_SM2_ENCRYPT_FAILED), "sm2 encrypt failed"},
|
||||
{ERR_REASON(EC_R_SM2_ENCRYPT_WITH_RECOMMENDED_FAILED),
|
||||
"sm2 encrypt with recommended failed"},
|
||||
{ERR_REASON(EC_R_SM2_KAP_NOT_INITED), "sm2 kap not inited"},
|
||||
{ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"},
|
||||
{ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"},
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <openssl/ecies.h>
|
||||
#endif
|
||||
|
||||
#include "e_os.h"
|
||||
#include "../../e_os.h"
|
||||
|
||||
#if defined(__SUNPRO_C)
|
||||
# if __SUNPRO_C >= 0x520
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
@@ -17,6 +18,7 @@
|
||||
#include "internal/evp_int.h"
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
# include <openssl/sm2.h>
|
||||
# include <openssl/sm3.h>
|
||||
#endif
|
||||
|
||||
/* EC pkey context structure */
|
||||
@@ -40,10 +42,10 @@ typedef struct {
|
||||
/* KDF output length */
|
||||
size_t kdf_outlen;
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
int sign_type;
|
||||
int exch_type;
|
||||
int enc_type;
|
||||
int enc_param;
|
||||
int ec_scheme;
|
||||
char *signer_id;
|
||||
unsigned char *signer_zid;
|
||||
int ec_encrypt_param;
|
||||
#endif
|
||||
} EC_PKEY_CTX;
|
||||
|
||||
@@ -58,10 +60,10 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx)
|
||||
dctx->cofactor_mode = -1;
|
||||
dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
dctx->sign_type = NID_secg_scheme;
|
||||
dctx->exch_type = NID_secg_scheme;
|
||||
dctx->enc_type = NID_secg_scheme;
|
||||
dctx->enc_param = NID_sm3;
|
||||
dctx->ec_scheme = NID_sm_scheme;
|
||||
dctx->signer_id = NULL;
|
||||
dctx->signer_zid = NULL;
|
||||
dctx->ec_encrypt_param = NID_sm3;
|
||||
#endif
|
||||
ctx->data = dctx;
|
||||
return 1;
|
||||
@@ -97,10 +99,14 @@ static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
|
||||
dctx->kdf_ukm = NULL;
|
||||
dctx->kdf_ukmlen = sctx->kdf_ukmlen;
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
dctx->sign_type = sctx->sign_type;
|
||||
dctx->exch_type = sctx->exch_type;
|
||||
dctx->enc_type = sctx->enc_type;
|
||||
dctx->enc_param = sctx->enc_param;
|
||||
dctx->ec_scheme = sctx->ec_scheme;
|
||||
if (sctx->signer_id) {
|
||||
dctx->signer_id = OPENSSL_strdup(sctx->signer_id);
|
||||
if (!dctx->signer_id)
|
||||
return 0;
|
||||
}
|
||||
dctx->signer_zid = NULL;
|
||||
dctx->ec_encrypt_param = sctx->ec_encrypt_param;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@@ -113,6 +119,10 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
|
||||
EC_KEY_free(dctx->co_key);
|
||||
OPENSSL_free(dctx->kdf_ukm);
|
||||
OPENSSL_free(dctx);
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
OPENSSL_free(dctx->signer_id);
|
||||
OPENSSL_free(dctx->signer_zid);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +148,7 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||
type = NID_sha1;
|
||||
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
if (dctx->sign_type == NID_sm_scheme)
|
||||
if (dctx->ec_scheme == NID_sm_scheme)
|
||||
ret = SM2_sign(NID_undef, tbs, tbslen, sig, &sltmp, ec);
|
||||
else
|
||||
#endif
|
||||
@@ -165,7 +175,7 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
|
||||
type = NID_sha1;
|
||||
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
if (dctx->sign_type == NID_sm_scheme)
|
||||
if (dctx->ec_scheme == NID_sm_scheme)
|
||||
ret = SM2_verify(NID_undef, tbs, tbslen, sig, siglen, ec);
|
||||
else
|
||||
#endif
|
||||
@@ -182,15 +192,15 @@ static int pkey_ec_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
|
||||
switch (dctx->enc_type) {
|
||||
switch (dctx->ec_scheme) {
|
||||
case NID_sm_scheme:
|
||||
if (!SM2_encrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
|
||||
if (!SM2_encrypt(dctx->ec_encrypt_param, in, inlen, out, outlen, ec_key)) {
|
||||
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_SM2_ENCRYPT_FAILED);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case NID_secg_scheme:
|
||||
if (!ECIES_encrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
|
||||
if (!ECIES_encrypt(dctx->ec_encrypt_param, in, inlen, out, outlen, ec_key)) {
|
||||
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_ECIES_ENCRYPT_FAILED);
|
||||
return 0;
|
||||
}
|
||||
@@ -209,15 +219,15 @@ static int pkey_ec_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
|
||||
switch (dctx->enc_type) {
|
||||
switch (dctx->ec_scheme) {
|
||||
case NID_sm_scheme:
|
||||
if (!SM2_decrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
|
||||
if (!SM2_decrypt(dctx->ec_encrypt_param, in, inlen, out, outlen, ec_key)) {
|
||||
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_SM2_DECRYPT_FAILED);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case NID_secg_scheme:
|
||||
if (!ECIES_decrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
|
||||
if (!ECIES_decrypt(dctx->ec_encrypt_param, in, inlen, out, outlen, ec_key)) {
|
||||
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_ECIES_DECRYPT_FAILED);
|
||||
return 0;
|
||||
}
|
||||
@@ -264,9 +274,12 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
outlen = *keylen;
|
||||
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
if (dctx->exch_type == NID_sm_scheme)
|
||||
|
||||
/*
|
||||
if (dctx->ec_scheme == NID_sm_scheme)
|
||||
ret = SM2_compute_key(key, outlen, pubkey, eckey, 0);
|
||||
else
|
||||
*/
|
||||
#endif
|
||||
|
||||
ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0);
|
||||
@@ -378,40 +391,83 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||
return 1;
|
||||
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
case EVP_PKEY_CTRL_EC_SIGN_TYPE:
|
||||
if (p1 == -2)
|
||||
return dctx->sign_type;
|
||||
if (p1 != NID_secg_scheme && p1 != NID_sm_scheme)
|
||||
case EVP_PKEY_CTRL_EC_SCHEME:
|
||||
if (p1 == -2) {
|
||||
return dctx->ec_scheme;
|
||||
}
|
||||
if (p1 != NID_secg_scheme && p1 != NID_sm_scheme) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_EC_SCHEME);
|
||||
return 0;
|
||||
}
|
||||
dctx->ec_scheme = p1;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_SIGNER_ID:
|
||||
if (!p2 || !strlen((char *)p2) || strlen((char *)p2) > SM2_MAX_ID_LENGTH) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_SIGNER_ID);
|
||||
return 0;
|
||||
} else {
|
||||
char *id = NULL;
|
||||
if (!(id = OPENSSL_strdup((char *)p2))) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (dctx->signer_id)
|
||||
OPENSSL_free(dctx->signer_id);
|
||||
dctx->signer_id = id;
|
||||
if (dctx->ec_scheme == NID_sm_scheme) {
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
unsigned char zid[SM3_DIGEST_LENGTH];
|
||||
size_t zidlen = SM3_DIGEST_LENGTH;
|
||||
if (!SM2_compute_id_digest(EVP_sm3(), dctx->signer_id,
|
||||
strlen(dctx->signer_id), zid, &zidlen, ec_key)) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, ERR_R_SM2_LIB);
|
||||
return 0;
|
||||
}
|
||||
if (!dctx->signer_zid) {
|
||||
if (!(dctx->signer_zid = OPENSSL_malloc(zidlen))) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
memcpy(dctx->signer_zid, zid, zidlen);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_SIGNER_ID:
|
||||
*(const char **)p2 = dctx->signer_id;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_SIGNER_ZID:
|
||||
if (dctx->ec_scheme != NID_sm_scheme) {
|
||||
*(const unsigned char **)p2 = NULL;
|
||||
return -2;
|
||||
dctx->sign_type = p1;
|
||||
}
|
||||
if (!dctx->signer_zid) {
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
unsigned char *zid;
|
||||
size_t zidlen = SM3_DIGEST_LENGTH;
|
||||
if (!(zid = OPENSSL_malloc(zidlen))) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!SM2_compute_id_digest(EVP_sm3(), SM2_DEFAULT_ID,
|
||||
SM2_DEFAULT_ID_LENGTH, zid, &zidlen, ec_key)) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL, ERR_R_SM2_LIB);
|
||||
OPENSSL_free(zid);
|
||||
return 0;
|
||||
}
|
||||
dctx->signer_zid = zid;
|
||||
}
|
||||
*(const unsigned char **)p2 = dctx->signer_zid;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_EC_SIGN_TYPE:
|
||||
*(int *)p2 = dctx->sign_type;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_ENC_TYPE:
|
||||
if (p1 == -2)
|
||||
return dctx->enc_type;
|
||||
if (p1 != NID_secg_scheme && p1 != NID_sm_scheme)
|
||||
return -2;
|
||||
dctx->enc_type = p1;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_EC_ENC_TYPE:
|
||||
*(int *)p2 = dctx->enc_type;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_EC_DH_TYPE:
|
||||
if (p1 == -2)
|
||||
return dctx->exch_type;
|
||||
if (p1 != NID_secg_scheme && p1 != NID_sm_scheme)
|
||||
return -2;
|
||||
dctx->exch_type = p1;
|
||||
return 1;
|
||||
|
||||
case EVP_PKEY_CTRL_GET_EC_DH_TYPE:
|
||||
*(int *)p2 = dctx->exch_type;
|
||||
case EVP_PKEY_CTRL_EC_ENCRYPT_PARAM:
|
||||
if (p1 == -2) {
|
||||
return dctx->ec_encrypt_param;
|
||||
}
|
||||
dctx->ec_encrypt_param = p1;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
@@ -495,34 +551,24 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
}
|
||||
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
} else if (!strcmp(type, "signer")) {
|
||||
} else if (!strcmp(type, "ec_sign_algor")) {
|
||||
int sign_type;
|
||||
if (!strcmp(value, "ecdsa"))
|
||||
sign_type = NID_secg_scheme;
|
||||
} else if (!strcmp(type, "ec_scheme")) {
|
||||
int scheme;
|
||||
if (!strcmp(value, "secg"))
|
||||
scheme = NID_secg_scheme;
|
||||
else if (!strcmp(value, "sm2"))
|
||||
sign_type = NID_sm_scheme;
|
||||
scheme = NID_sm_scheme;
|
||||
else
|
||||
return -2;
|
||||
return EVP_PKEY_CTX_set_ec_sign_type(ctx, sign_type);
|
||||
} else if (!strcmp(type, "ec_encrypt_algor")) {
|
||||
int enc_type;
|
||||
if (!strcmp(value, "ecies"))
|
||||
enc_type = NID_secg_scheme;
|
||||
else if (!strcmp(value, "sm2"))
|
||||
enc_type = NID_sm_scheme;
|
||||
else
|
||||
return -2;
|
||||
return EVP_PKEY_CTX_set_ec_enc_type(ctx, enc_type);
|
||||
} else if (!strcmp(type, "ec_derive_algor")) {
|
||||
int dh_type;
|
||||
if (!strcmp(value, "ecdh"))
|
||||
dh_type = NID_secg_scheme;
|
||||
else if (!strcmp(value, "sm2"))
|
||||
dh_type = NID_sm_scheme;
|
||||
else
|
||||
return -2;
|
||||
return EVP_PKEY_CTX_set_ec_dh_type(ctx, dh_type);
|
||||
return EVP_PKEY_CTX_set_ec_scheme(ctx, scheme);
|
||||
} else if (!strcmp(type, "signer_id")) {
|
||||
return EVP_PKEY_CTX_set_signer_id(ctx, value);
|
||||
} else if (!strcmp(type, "ec_encrypt_param")) {
|
||||
int encrypt_param;
|
||||
if (!(encrypt_param = OBJ_txt2nid(value))) {
|
||||
ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_EC_ENCRYPT_PARAM);
|
||||
return 0;
|
||||
}
|
||||
return EVP_PKEY_CTX_set_ec_encrypt_param(ctx, encrypt_param);
|
||||
#endif
|
||||
} else if (strcmp(type, "ec_param_enc") == 0) {
|
||||
int param_enc;
|
||||
|
||||
157
crypto/ec/ecdsa_bssl.c
Normal file
157
crypto/ec/ecdsa_bssl.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com). */
|
||||
|
||||
#include <openssl/ecdsa.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/bytestring.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/mem.h>
|
||||
|
||||
#include "../bytestring/internal.h"
|
||||
#include "../ec/ec_lcl.h"
|
||||
#include "../internal.h"
|
||||
|
||||
|
||||
ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) {
|
||||
ECDSA_SIG *ret = ECDSA_SIG_new();
|
||||
if (ret == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
CBS child;
|
||||
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
|
||||
!BN_parse_asn1_unsigned(&child, ret->r) ||
|
||||
!BN_parse_asn1_unsigned(&child, ret->s) ||
|
||||
CBS_len(&child) != 0) {
|
||||
//OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
|
||||
ECDSA_SIG_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) {
|
||||
CBS cbs;
|
||||
CBS_init(&cbs, in, in_len);
|
||||
ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs);
|
||||
if (ret == NULL || CBS_len(&cbs) != 0) {
|
||||
//OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
|
||||
ECDSA_SIG_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) {
|
||||
CBB child;
|
||||
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
|
||||
!BN_marshal_asn1(&child, sig->r) ||
|
||||
!BN_marshal_asn1(&child, sig->s) ||
|
||||
!CBB_flush(cbb)) {
|
||||
//OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len,
|
||||
const ECDSA_SIG *sig) {
|
||||
CBB cbb;
|
||||
CBB_zero(&cbb);
|
||||
if (!CBB_init(&cbb, 0) ||
|
||||
!ECDSA_SIG_marshal(&cbb, sig) ||
|
||||
!CBB_finish(&cbb, out_bytes, out_len)) {
|
||||
//OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
|
||||
CBB_cleanup(&cbb);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* der_len_len returns the number of bytes needed to represent a length of |len|
|
||||
* in DER. */
|
||||
static size_t der_len_len(size_t len) {
|
||||
if (len < 0x80) {
|
||||
return 1;
|
||||
}
|
||||
size_t ret = 1;
|
||||
while (len > 0) {
|
||||
ret++;
|
||||
len >>= 8;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t ECDSA_SIG_max_len(size_t order_len) {
|
||||
/* Compute the maximum length of an |order_len| byte integer. Defensively
|
||||
* assume that the leading 0x00 is included. */
|
||||
size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len;
|
||||
if (integer_len < order_len) {
|
||||
return 0;
|
||||
}
|
||||
/* An ECDSA signature is two INTEGERs. */
|
||||
size_t value_len = 2 * integer_len;
|
||||
if (value_len < integer_len) {
|
||||
return 0;
|
||||
}
|
||||
/* Add the header. */
|
||||
size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len;
|
||||
if (ret < value_len) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user