mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-20 12:17:13 +08:00
Optimize sm2p256v1 curve for Intel processors
This update is part of the GmSSL Turbo project. This work is supported by the National Key Research and Development Program of China NO.2018YFB0803601 and Intel.
This commit is contained in:
@@ -138,7 +138,7 @@
|
||||
template => 1,
|
||||
cpuid_asm_src => "x86cpuid.s",
|
||||
bn_asm_src => "bn-586.s co-586.s x86-mont.s x86-gf2m.s",
|
||||
ec_asm_src => "ecp_nistz256.c ecp_nistz256-x86.s",
|
||||
ec_asm_src => "ecp_nistz256.c ecp_nistz256-x86.s ecp_sm2z256.c ecp_sm2z256-x86.s",
|
||||
des_asm_src => "des-586.s crypt586.s",
|
||||
aes_asm_src => "aes-586.s vpaes-x86.s aesni-x86.s",
|
||||
bf_asm_src => "bf-586.s",
|
||||
@@ -165,7 +165,7 @@
|
||||
template => 1,
|
||||
cpuid_asm_src => "x86_64cpuid.s",
|
||||
bn_asm_src => "asm/x86_64-gcc.c x86_64-mont.s x86_64-mont5.s x86_64-gf2m.s rsaz_exp.c rsaz-x86_64.s rsaz-avx2.s",
|
||||
ec_asm_src => "ecp_nistz256.c ecp_nistz256-x86_64.s",
|
||||
ec_asm_src => "ecp_nistz256.c ecp_nistz256-x86_64.s ecp_sm2z256.c ecp_sm2z256-x86_64.s",
|
||||
aes_asm_src => "aes-x86_64.s vpaes-x86_64.s bsaes-x86_64.s aesni-x86_64.s aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s",
|
||||
md5_asm_src => "md5-x86_64.s",
|
||||
sha1_asm_src => "sha1-x86_64.s sha256-x86_64.s sha512-x86_64.s sha1-mb-x86_64.s sha256-mb-x86_64.s",
|
||||
|
||||
3181
crypto/ec/asm/ecp_sm2z256-x86_64.pl
Executable file
3181
crypto/ec/asm/ecp_sm2z256-x86_64.pl
Executable file
File diff suppressed because it is too large
Load Diff
@@ -22,7 +22,11 @@ INCLUDE[ecp_nistz256-armv4.o]=..
|
||||
GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl $(PERLASM_SCHEME)
|
||||
INCLUDE[ecp_nistz256-armv8.o]=..
|
||||
|
||||
GENERATE[ecp_sm2z256-x86_64.s]=asm/ecp_sm2z256-x86_64.pl $(PERLASM_SCHEME)
|
||||
|
||||
BEGINRAW[Makefile]
|
||||
{- $builddir -}/ecp_nistz256-%.S: {- $sourcedir -}/asm/ecp_nistz256-%.pl
|
||||
CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
|
||||
{- $builddir -}/ecp_sm2z256-%.S: {- $sourcedir -}/asm/ecp_sm2z256-%.pl
|
||||
CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
|
||||
ENDRAW[Makefile]
|
||||
|
||||
@@ -1,567 +0,0 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2014 - 2016 The GmSSL Project. All rights reserved.
|
||||
* Copyright (c) 2014 - 2018 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
|
||||
@@ -3090,7 +3090,14 @@ static const ec_list_element curve_list[] = {
|
||||
{NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0,
|
||||
"RFC 5639 curve over a 512 bit prime field"},
|
||||
#ifndef OPENSSL_NO_SM2
|
||||
{NID_sm2p256v1, &_EC_SM2_PRIME_256V1.h, 0,
|
||||
{NID_sm2p256v1, &_EC_SM2_PRIME_256V1.h,
|
||||
# if defined(ECP_NISTZ256_ASM)
|
||||
EC_GFp_sm2z256_method,
|
||||
# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
|
||||
EC_GFp_sm2p256_method,
|
||||
# else
|
||||
0,
|
||||
# endif
|
||||
"SM2 curve over a 256 bit prime field"},
|
||||
{NID_wapip192v1, &_EC_WAPI_PRIME_192V1.h, 0,
|
||||
"WAPI curve over a 192 bit prime field"},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -62,6 +62,12 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"},
|
||||
{ERR_FUNC(EC_F_ECP_SM2Z256_GET_AFFINE), "ecp_sm2z256_get_affine"},
|
||||
{ERR_FUNC(EC_F_ECP_SM2Z256_MULT_PRECOMPUTE),
|
||||
"ecp_sm2z256_mult_precompute"},
|
||||
{ERR_FUNC(EC_F_ECP_SM2Z256_POINTS_MUL), "ecp_sm2z256_points_mul"},
|
||||
{ERR_FUNC(EC_F_ECP_SM2Z256_PRE_COMP_NEW), "ecp_sm2z256_pre_comp_new"},
|
||||
{ERR_FUNC(EC_F_ECP_SM2Z256_WINDOWED_MUL), "ecp_sm2z256_windowed_mul"},
|
||||
{ERR_FUNC(EC_F_ECX_KEY_OP), "ecx_key_op"},
|
||||
{ERR_FUNC(EC_F_ECX_PRIV_ENCODE), "ecx_priv_encode"},
|
||||
{ERR_FUNC(EC_F_ECX_PUB_ENCODE), "ecx_pub_encode"},
|
||||
@@ -123,6 +129,11 @@ static ERR_STRING_DATA EC_str_functs[] = {
|
||||
"ec_GFp_simple_point_set_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES),
|
||||
"ec_GFp_simple_set_compressed_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SM2P256_GROUP_SET_CURVE),
|
||||
"ec_GFp_sm2p256_group_set_curve"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SM2P256_POINTS_MUL), "ec_GFp_sm2p256_points_mul"},
|
||||
{ERR_FUNC(EC_F_EC_GFP_SM2P256_POINT_GET_AFFINE_COORDINATES),
|
||||
"ec_GFp_sm2p256_point_get_affine_coordinates"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"},
|
||||
{ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT),
|
||||
"EC_GROUP_check_discriminant"},
|
||||
@@ -224,6 +235,7 @@ 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_SM2P256_PRE_COMP_NEW), "sm2p256_pre_comp_new"},
|
||||
{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_DO_ENCRYPT), "SM2_do_encrypt"},
|
||||
|
||||
@@ -181,6 +181,8 @@ typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP;
|
||||
typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP;
|
||||
typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP;
|
||||
typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP;
|
||||
typedef struct sm2p256_pre_comp_st SM2P256_PRE_COMP;
|
||||
typedef struct sm2z256_pre_comp_st SM2Z256_PRE_COMP;
|
||||
typedef struct ec_pre_comp_st EC_PRE_COMP;
|
||||
|
||||
struct ec_group_st {
|
||||
@@ -239,6 +241,8 @@ struct ec_group_st {
|
||||
enum {
|
||||
PCT_none,
|
||||
PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256,
|
||||
//PCT_sm2p256,
|
||||
PCT_sm2z256,
|
||||
PCT_ec
|
||||
} pre_comp_type;
|
||||
union {
|
||||
@@ -246,6 +250,8 @@ struct ec_group_st {
|
||||
NISTP256_PRE_COMP *nistp256;
|
||||
NISTP521_PRE_COMP *nistp521;
|
||||
NISTZ256_PRE_COMP *nistz256;
|
||||
SM2P256_PRE_COMP *sm2p256;
|
||||
SM2Z256_PRE_COMP *sm2z256;
|
||||
EC_PRE_COMP *ec;
|
||||
} pre_comp;
|
||||
};
|
||||
@@ -288,7 +294,8 @@ NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
|
||||
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
|
||||
NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
|
||||
NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *);
|
||||
NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
|
||||
SM2P256_PRE_COMP *EC_sm2p256_pre_comp_dup(SM2P256_PRE_COMP *);
|
||||
SM2Z256_PRE_COMP *EC_sm2z256_pre_comp_dup(SM2Z256_PRE_COMP *);
|
||||
EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *);
|
||||
|
||||
void EC_pre_comp_free(EC_GROUP *group);
|
||||
@@ -296,6 +303,8 @@ void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *);
|
||||
void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *);
|
||||
void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *);
|
||||
void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *);
|
||||
void EC_sm2p256_pre_comp_free(SM2P256_PRE_COMP *);
|
||||
void EC_sm2z256_pre_comp_free(SM2Z256_PRE_COMP *);
|
||||
void EC_ec_pre_comp_free(EC_PRE_COMP *);
|
||||
|
||||
/*
|
||||
@@ -508,6 +517,26 @@ int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
|
||||
int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
/* method functions in ecp_sm2p256.c */
|
||||
int ec_GFp_sm2p256_group_init(EC_GROUP *group);
|
||||
int ec_GFp_sm2p256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
|
||||
const BIGNUM *a, const BIGNUM *n,
|
||||
BN_CTX *);
|
||||
int ec_GFp_sm2p256_point_get_affine_coordinates(const EC_GROUP *group,
|
||||
const EC_POINT *point,
|
||||
BIGNUM *x, BIGNUM *y,
|
||||
BN_CTX *ctx);
|
||||
int ec_GFp_sm2p256_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[], const BIGNUM *scalars[],
|
||||
BN_CTX *);
|
||||
int ec_GFp_sm2p256_points_mul(const EC_GROUP *group, EC_POINT *r,
|
||||
const BIGNUM *scalar, size_t num,
|
||||
const EC_POINT *points[],
|
||||
const BIGNUM *scalars[], BN_CTX *ctx);
|
||||
int ec_GFp_sm2p256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
|
||||
int ec_GFp_sm2p256_have_precompute_mult(const EC_GROUP *group);
|
||||
|
||||
/* utility functions in ecp_nistputil.c */
|
||||
void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array,
|
||||
size_t felem_size,
|
||||
@@ -546,6 +575,7 @@ int ec_group_simple_order_bits(const EC_GROUP *group);
|
||||
* \return EC_METHOD object
|
||||
*/
|
||||
const EC_METHOD *EC_GFp_nistz256_method(void);
|
||||
const EC_METHOD *EC_GFp_sm2z256_method(void);
|
||||
#endif
|
||||
|
||||
size_t ec_key_simple_priv2oct(const EC_KEY *eckey,
|
||||
|
||||
1617
crypto/ec/ecp_sm2z256.c
Normal file
1617
crypto/ec/ecp_sm2z256.c
Normal file
File diff suppressed because it is too large
Load Diff
9628
crypto/ec/ecp_sm2z256_table.c
Normal file
9628
crypto/ec/ecp_sm2z256_table.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -94,6 +94,10 @@ const EC_METHOD *EC_GFp_nistp256_method(void);
|
||||
* \return EC_METHOD object
|
||||
*/
|
||||
const EC_METHOD *EC_GFp_nistp521_method(void);
|
||||
|
||||
# ifndef OPENSSL_NO_SM2
|
||||
const EC_METHOD *EC_GFp_sm2p256_method(void);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef OPENSSL_NO_EC2M
|
||||
@@ -1408,6 +1412,11 @@ int ERR_load_EC_strings(void);
|
||||
# define EC_F_ECP_NISTZ256_POINTS_MUL 137
|
||||
# define EC_F_ECP_NISTZ256_PRE_COMP_NEW 138
|
||||
# define EC_F_ECP_NISTZ256_WINDOWED_MUL 139
|
||||
# define EC_F_ECP_SM2Z256_GET_AFFINE 278
|
||||
# define EC_F_ECP_SM2Z256_MULT_PRECOMPUTE 279
|
||||
# define EC_F_ECP_SM2Z256_POINTS_MUL 280
|
||||
# define EC_F_ECP_SM2Z256_PRE_COMP_NEW 281
|
||||
# define EC_F_ECP_SM2Z256_WINDOWED_MUL 282
|
||||
# define EC_F_ECX_KEY_OP 140
|
||||
# define EC_F_ECX_PRIV_ENCODE 141
|
||||
# define EC_F_ECX_PUB_ENCODE 142
|
||||
@@ -1448,6 +1457,9 @@ int ERR_load_EC_strings(void);
|
||||
# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 177
|
||||
# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 178
|
||||
# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 179
|
||||
# define EC_F_EC_GFP_SM2P256_GROUP_SET_CURVE 274
|
||||
# define EC_F_EC_GFP_SM2P256_POINTS_MUL 275
|
||||
# define EC_F_EC_GFP_SM2P256_POINT_GET_AFFINE_COORDINATES 276
|
||||
# define EC_F_EC_GROUP_CHECK 180
|
||||
# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 181
|
||||
# define EC_F_EC_GROUP_COPY 182
|
||||
@@ -1531,6 +1543,7 @@ int ERR_load_EC_strings(void);
|
||||
# define EC_F_PKEY_EC_KEYGEN 260
|
||||
# define EC_F_PKEY_EC_PARAMGEN 261
|
||||
# define EC_F_PKEY_EC_SIGN 262
|
||||
# define EC_F_SM2P256_PRE_COMP_NEW 277
|
||||
# define EC_F_SM2_COMPUTE_ID_DIGEST 263
|
||||
# define EC_F_SM2_COMPUTE_MESSAGE_DIGEST 264
|
||||
# define EC_F_SM2_DO_ENCRYPT 265
|
||||
|
||||
@@ -41,9 +41,9 @@ extern "C" {
|
||||
*/
|
||||
# define OPENSSL_VERSION_NUMBER 0x1010004fL
|
||||
# ifdef OPENSSL_FIPS
|
||||
# define OPENSSL_VERSION_TEXT "GmSSL 2.3.1 - OpenSSL 1.1.0d-fips 30 Mar 2018"
|
||||
# define OPENSSL_VERSION_TEXT "GmSSL 2.3.2 - OpenSSL 1.1.0d-fips 7 Sep 2018"
|
||||
# else
|
||||
# define OPENSSL_VERSION_TEXT "GmSSL 2.3.1 - OpenSSL 1.1.0d 30 Mar 2018"
|
||||
# define OPENSSL_VERSION_TEXT "GmSSL 2.3.2 - OpenSSL 1.1.0d 7 Sep 2018"
|
||||
# endif
|
||||
|
||||
/*-
|
||||
|
||||
Reference in New Issue
Block a user