sm2 test vector

This commit is contained in:
Zhi Guan
2016-05-02 17:56:14 +02:00
parent d8072491bc
commit addcac4896
34 changed files with 1245 additions and 3023 deletions

View File

@@ -17,9 +17,8 @@ TEST=sm2test.c
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= sm2_lib.c sm2_err.c sm2_sign.c sm2_enc.c sm2_kap.c
LIBOBJ= sm2_lib.o sm2_err.o sm2_sign.o sm2_enc.o sm2_kap.o
LIBSRC= sm2_lib.c sm2_asn1.c sm2_err.c sm2_sign.c sm2_enc.c sm2_kap.c
LIBOBJ= sm2_lib.o sm2_asn1.o sm2_err.o sm2_sign.o sm2_enc.o sm2_kap.o
SRC= $(LIBSRC)

View File

@@ -67,10 +67,16 @@ extern "C" {
#define SM2_MAX_ID_BITS 65535
#define SM2_MAX_ID_LENGTH 8191
#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8)
#define SM2_DEFAULT_ID "1234567812345678"
#define SM2_DEFAULT_POINT_CONVERSION_FORM POINT_CONVERSION_UNCOMPRESSED
char *SM2_get0_id(EC_KEY *ec_key);
int SM2_set_id(EC_KEY *ec_key, const char *id);
int SM2_compute_id_digest(const EVP_MD *md, unsigned char *dgst,
unsigned int *dgstlen, EC_KEY *ec_key);
typedef struct sm2_ciphertext_value_st {
EC_POINT *ephem_point;
@@ -80,13 +86,6 @@ typedef struct sm2_ciphertext_value_st {
unsigned int mactag_size;
} SM2_CIPHERTEXT_VALUE;
char *SM2_get_id(EC_KEY *ec_key);
int SM2_set_id(EC_KEY *ec_key, const char *id);
int SM2_compute_id_digest(unsigned char *dgst, unsigned int *dgstlen,
const EVP_MD *md, EC_KEY *ec_key);
int SM2_CIPHERTEXT_VALUE_size(const EC_GROUP *ec_group,
point_conversion_form_t point_form, size_t mlen,
const EVP_MD *mac_md);
@@ -97,13 +96,19 @@ int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(const EC_GROUP *ec_group,
point_conversion_form_t point_form, const EVP_MD *mac_md,
const unsigned char *buf, size_t buflen);
int i2d_SM2_CIPHERTEXT_VALUE(const SM2_CIPHERTEXT_VALUE *c, unsigned char **out);
SM2_CIPHERTEXT_VALUE *d2i_SM2_CIPHERTEXT_VALUE(SM2_CIPHERTEXT_VALUE **c,
const unsigned char **in, long len);
int SM2_CIPHERTEXT_VALUE_print(BIO *out, const EC_GROUP *ec_group,
const SM2_CIPHERTEXT_VALUE *cv, int indent, unsigned long flags);
/* FIXME: we should provide optional return value */
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen,
EC_KEY *ec_key);
int SM2_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form,
const unsigned char *in, size_t inlen,
@@ -114,6 +119,12 @@ int SM2_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_compute_message_digest(const EVP_MD *id_md, const EVP_MD *msg_md,
const void *msg, size_t msglen, unsigned char *dgst,
unsigned int *dgstlen, EC_KEY *ec_key);
#define SM2_signature_size(ec_key) ECDSA_size(ec_key)
int SM2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx, BIGNUM **a, BIGNUM **b);
ECDSA_SIG *SM2_do_sign_ex(const unsigned char *dgst, int dgstlen,
@@ -127,6 +138,9 @@ int SM2_sign_ex(int type, const unsigned char *dgst, int dgstlen,
const BIGNUM *k, const BIGNUM *x, EC_KEY *ec_key);
int SM2_sign(int type, const unsigned char *dgst, int dgstlen,
unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
#define SM2_VERIFY_SUCCESS 1
#define SM2_VERIFY_FAILED 0
#define SM2_VERIFY_INNER_ERROR -1
int SM2_verify(int type, const unsigned char *dgst, int dgstlen,
const unsigned char *sig, int siglen, EC_KEY *ec_key);
@@ -165,13 +179,13 @@ typedef struct sm2_kap_ctx_st {
int SM2_KAP_CTX_init_ex(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
int SM2_KAP_CTX_init(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
EC_KEY *remote_pubkey, int is_initiator, int do_checksum);
void SM2_KAP_CTX_cleanup(SM2_KAP_CTX *ctx);
int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,
size_t ephem_point_len);
size_t *ephem_point_len);
int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_ephem_point,
size_t remote_ephem_point_len, unsigned char *key, size_t *keylen,
size_t remote_ephem_point_len, unsigned char *key, size_t keylen,
unsigned char *checksum, size_t *checksumlen);
int SM2_KAP_final_check(SM2_KAP_CTX *ctx, const unsigned char *checksum,
size_t checksumlen);

View File

@@ -1,41 +1,130 @@
/* crypto/sm2/sm2_asn1.c */
/* ====================================================================
* Copyright (c) 2007 - 2016 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 <string.h>
#include <openssl/err.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/obj_mac.h>
#include <openssl/sm2.h>
/*
* from GM/T 0009-2012
* "SM2 Cryptography Algorithm Application Specification"
*
SM2PrivateKey ::= INTEGER
SM2PublicKey ::= BIT STRING
SM2CiphertextValue ::= SEQUENCE {
XCoordinate INTEGER,
YCoordinate INTEGER,
Hash OCTET STRING SIZE(32),
Ciphertext OCTET STRING
}
SM2PrivateKey ::= INTEGER
SM2Signature ::= SEQUENCE {
R INTEGER,
S INTEGER,
}
SM2PublicKey ::= BIT STRING
SM2EnvelopedKey ::= SEQUENCE {
symAlgID AlgorithmIdentifier,
symEncryptedKey SM2CiphertextValue,
sm2PublicKey SM2PublicKey,
sm2EncryptedPrivateKey BIT STRING
}
SM2CiphertextValue ::= SEQUENCE {
XCoordinate INTEGER,
YCoordinate INTEGER,
Hash OCTET STRING SIZE(32),
Ciphertext OCTET STRING
}
ZID = SM3(nbits(ID)||ID||a||b||xG||yG||xA||yA)
Default ID = "1234567812345678"
SM2Signature ::= SEQUENCE {
R INTEGER,
S INTEGER,
}
SM2EnvelopedKey ::= SEQUENCE {
symAlgID AlgorithmIdentifier,
symEncryptedKey SM2CiphertextValue,
sm2PublicKey SM2PublicKey,
sm2EncryptedPrivateKey BIT STRING
}
ZID = SM3(nbits(ID)||ID||a||b||xG||yG||xA||yA)
Default ID = "1234567812345678"
*/
typedef struct SM2CiphertextValue_st {
ASN1_INTEGER *xCoordinate;
ASN1_INTEGER *yCoordinate;
ASN1_OCTET_STRING *hash;
ASN1_OCTET_STRING *ciphertext;
} SM2CiphertextValue;
ASN1_SEQUENCE(SM2CiphertextValue) = {
ASN1_SIMPLE(SM2CiphertextValue, xCoordinate, ASN1_INTEGER),
ASN1_SIMPLE(SM2CiphertextValue, yCoordinate, ASN1_INTEGER),
ASN1_SIMPLE(SM2CiphertextValue, hash, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM2CiphertextValue, ciphertext, ASN1_OCTET_STRING),
} ASN1_SEQUENCE_END(SM2CiphertextValue)
IMPLEMENT_ASN1_FUNCTIONS(SM2CiphertextValue)
IMPLEMENT_ASN1_DUP_FUNCTION(SM2CiphertextValue)
int i2d_SM2_CIPHERTEXT_VALUE(const SM2_CIPHERTEXT_VALUE *c, unsigned char **out)
{
SM2CiphertextValue *asn1 = NULL;
/*
asn1 = SM2CiphertextValue_new();
asn1->xCoordinate = BN_to_ASN1_INTEGER(x, NULL);
asn1->yCoordinate = BN_to_ASN1_INTEGER(y, NULL);
*/
return 0;
}
SM2_CIPHERTEXT_VALUE *d2i_SM2_CIPHERTEXT_VALUE(SM2_CIPHERTEXT_VALUE **c,
const unsigned char **in, long len)
{
return NULL;
}

View File

@@ -330,7 +330,9 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
goto end;
}
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
OPENSSL_assert(nbytes == BN_num_bytes(n));
//OPENSSL_assert(nbytes == BN_num_bytes(n));
#if 0
/* check sm2 curve and md is 256 bits */
@@ -345,6 +347,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
do {
BN_rand_range(k, n);
} while (BN_is_zero(k));
/* A2: C1 = [k]G = (x1, y1) */
if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) {
@@ -358,7 +361,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
if (EC_POINT_is_at_infinity(ec_group, point)) {
goto end;
}
/* A4: compute ECDH [k]P_B = (x2, y2) */
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
goto end;
@@ -368,11 +371,10 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
goto end;
}
OPENSSL_assert(len == nbytes * 2 + 1);
/* A5: t = KDF(x2 || y2, klen) */
kdf(buf + 1, len - 1, cv->ciphertext, &cv->ciphertext_size);
for (i = 0; i < cv->ciphertext_size; i++) {
if (cv->ciphertext[i]) {
break;
@@ -391,7 +393,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
for (i = 0; i < inlen; i++) {
cv->ciphertext[i] ^= in[i];
}
/* A7: C3 = Hash(x2 || M || y2) */
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
goto end;
@@ -409,6 +411,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
goto end;
}
ok = 1;
end:
@@ -525,7 +528,7 @@ int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
goto end;
}
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
OPENSSL_assert(nbytes == BN_num_bytes(n));
//OPENSSL_assert(nbytes == BN_num_bytes(n));
#if 0
/* check sm2 curve and md is 256 bits */

View File

@@ -90,16 +90,16 @@ static ERR_STRING_DATA SM2_str_functs[] = {
};
static ERR_STRING_DATA SM2_str_reasons[] = {
{ERR_REASON(SM2_R_BAD_DATA), "bad data"},
{ERR_REASON(SM2_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"},
{ERR_REASON(SM2_R_ENCRYPT_FAILED), "encrypt failed"},
{ERR_REASON(SM2_R_DECRYPT_FAILED), "decrypt failed"},
{ERR_REASON(SM2_R_UNKNOWN_MAC_TYPE), "unknown MAC type"},
{ERR_REASON(SM2_R_GEN_MAC_FAILED), "MAC generation failed"},
{ERR_REASON(SM2_R_VERIFY_MAC_FAILED), "MAC verification failed"},
{ERR_REASON(SM2_R_ECDH_FAILED), "ECDH failed"},
{ERR_REASON(SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
{ERR_REASON(SM2_R_SM2_KAP_NOT_INITED), "KAP not inited"},
{ERR_REASON(SM2_R_BAD_DATA), "bad data"},
{ERR_REASON(SM2_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"},
{ERR_REASON(SM2_R_ENCRYPT_FAILED), "encrypt failed"},
{ERR_REASON(SM2_R_DECRYPT_FAILED), "decrypt failed"},
{ERR_REASON(SM2_R_UNKNOWN_MAC_TYPE), "unknown MAC type"},
{ERR_REASON(SM2_R_GEN_MAC_FAILED), "MAC generation failed"},
{ERR_REASON(SM2_R_VERIFY_MAC_FAILED), "MAC verification failed"},
{ERR_REASON(SM2_R_ECDH_FAILED), "ECDH failed"},
{ERR_REASON(SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
{ERR_REASON(SM2_R_SM2_KAP_NOT_INITED), "KAP not inited"},
{ERR_REASON(SM2_R_RANDOM_NUMBER_GENERATION_FAILED), "random number generation failed"},
{0,NULL}
};

View File

@@ -53,7 +53,7 @@
#include <openssl/kdf.h>
#include "sm2.h"
int SM2_KAP_CTX_init_ex(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
int SM2_KAP_CTX_init(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
EC_KEY *remote_pubkey, int is_initiator, int do_checksum)
{
int ret = 0;
@@ -64,7 +64,7 @@ int SM2_KAP_CTX_init_ex(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
ctx->id_dgst_md = EVP_sm3();
ctx->kdf_md = EVP_sm3();
ctx->checksum_md = EVP_sm3();
ctx->point_form = POINT_CONVERSION_COMPRESSED;
ctx->point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
if (!(ctx->kdf = KDF_get_x9_63(ctx->kdf_md))) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
@@ -80,8 +80,8 @@ int SM2_KAP_CTX_init_ex(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
goto end;
}
if (!SM2_compute_id_digest(ctx->id_dgst, &ctx->id_dgstlen,
ctx->id_dgst_md, ec_key)) {
if (!SM2_compute_id_digest(ctx->id_dgst_md, ctx->id_dgst,
&ctx->id_dgstlen, ec_key)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
@@ -91,8 +91,8 @@ int SM2_KAP_CTX_init_ex(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
goto end;
}
if (!SM2_compute_id_digest(ctx->remote_id_dgst, &ctx->remote_id_dgstlen,
ctx->id_dgst_md, remote_pubkey)) {
if (!SM2_compute_id_digest(ctx->id_dgst_md, ctx->remote_id_dgst,
&ctx->remote_id_dgstlen, remote_pubkey)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
@@ -118,7 +118,7 @@ int SM2_KAP_CTX_init_ex(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
goto end;
}
w = (EC_GROUP_get_degree(ctx->group) + 1)/2 - 1;
w = (BN_num_bits(ctx->order) + 1)/2 - 1;
if (!BN_one(ctx->two_pow_w)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, ERR_R_BN_LIB);
@@ -155,8 +155,10 @@ void SM2_KAP_CTX_cleanup(SM2_KAP_CTX *ctx)
memset(ctx, 0, sizeof(*ctx));
}
/* FIXME: ephem_point_len should be both input and output */
int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,
size_t ephem_point_len)
size_t *ephem_point_len)
{
int ret = 0;
const BIGNUM *prikey;
@@ -191,11 +193,13 @@ int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,
} while (BN_is_zero(r));
if (!EC_POINT_mul(ctx->group, ctx->point, r, NULL, NULL, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ctx->group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(ctx->group, ctx->point, x, NULL, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
@@ -252,11 +256,13 @@ int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,
/* encode R = (x, y) for output and local buffer */
// FIXME: ret is size_t and ret is the output length
ret = EC_POINT_point2oct(ctx->group, ctx->point, ctx->point_form,
ephem_point, ephem_point_len, ctx->bn_ctx);
ephem_point, *ephem_point_len, ctx->bn_ctx);
memcpy(ctx->pt_buf, ephem_point, ret);
*ephem_point_len = ret;
ret = 1;
end:
if (h) BN_free(h);
@@ -267,19 +273,21 @@ end:
}
int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
size_t remote_point_len, unsigned char *key, size_t *keylen,
size_t remote_point_len, unsigned char *key, size_t keylen,
unsigned char *checksum, size_t *checksumlen)
{
int ret = 0;
EVP_MD_CTX md_ctx;
BIGNUM *x = NULL;
unsigned char share_pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4 + EVP_MAX_MD_SIZE * 2];
unsigned char remote_pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4];
unsigned char share_pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4 + EVP_MAX_MD_SIZE * 2 + 100];
unsigned char remote_pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4 + 111];
unsigned char dgst[EVP_MAX_MD_SIZE];
unsigned int dgstlen;
unsigned int len, bnlen;
size_t klen = keylen;
EVP_MD_CTX_init(&md_ctx);
if (!(x = BN_new())) {
@@ -329,14 +337,16 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_BN_LIB);
goto end;
}
/*
if (!BN_mod_mul(x, x, ctx->t, ctx->order, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_BN_LIB);
goto end;
}
*/
/* U = ht * (P + x * R), check U != O */
if (!EC_POINT_mul(ctx->group, ctx->point, NULL, ctx->point, x, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
@@ -352,8 +362,8 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
if (!EC_POINT_is_at_infinity(ctx->group, ctx->point)) {
if (EC_POINT_is_at_infinity(ctx->group, ctx->point)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
@@ -380,12 +390,13 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
/* key = KDF(xu, yu, ZA, ZB) */
if (!ctx->kdf(share_pt_buf, len, key, keylen)) {
if (!ctx->kdf(share_pt_buf + 1, len - 1, key, &klen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
if (!ctx->do_checksum) {
if (ctx->do_checksum) {
/* generate checksum S1 or SB start with 0x02
* S1 = SB = Hash(0x02, yu, Hash(xu, ZA, ZB, x1, y1, x2, y2))
@@ -403,7 +414,8 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
}
if (ctx->is_initiator) {
/* update ZA,ZB,x1,y1,x2,y2 */
if (!EVP_DigestUpdate(&md_ctx, ctx->id_dgst, ctx->id_dgstlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
@@ -422,6 +434,7 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
}
} else {
if (!EVP_DigestUpdate(&md_ctx, ctx->remote_id_dgst, ctx->remote_id_dgstlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
@@ -444,6 +457,8 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
/* now dgst == H(xu,ZA,ZB,x1,y1,x2,y2)
*/
/* S1 = SB = Hash(0x02, yu, dgst) */
@@ -452,7 +467,7 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, "\0x02", 1)) {
if (!EVP_DigestUpdate(&md_ctx, "\x02", 1)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
@@ -473,6 +488,7 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
} else {
if (!EVP_DigestFinal_ex(&md_ctx, checksum, &len)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
@@ -490,7 +506,7 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, "\0x03", 1)) {
if (!EVP_DigestUpdate(&md_ctx, "\x03", 1)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
@@ -519,6 +535,7 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
}
}
}
ret = 1;
@@ -526,7 +543,7 @@ int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
end:
EVP_MD_CTX_cleanup(&md_ctx);
if (x) BN_free(x);
return 0;
return ret;
}
int SM2_KAP_final_check(SM2_KAP_CTX *ctx, const unsigned char *checksum,

View File

@@ -65,14 +65,16 @@
#define EC_MAX_NBYTES ((OPENSSL_ECC_MAX_FIELD_BITS + 7)/8)
#define SM2_DEFAULT_ID "1234567812345678"
static void *sm2_data_dup(void *data) {
return OPENSSL_strdup((const char *)data);
if (data)
return OPENSSL_strdup((const char *)data);
else return NULL;
}
static void sm2_data_free(void *data) {
return OPENSSL_free(data);
if (data)
OPENSSL_free(data);
}
int SM2_set_id(EC_KEY *ec_key, const char *id)
@@ -80,28 +82,33 @@ int SM2_set_id(EC_KEY *ec_key, const char *id)
char *pid;
if (strlen(id) > SM2_MAX_ID_LENGTH) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
return 0;
}
if ((pid = EC_KEY_get_key_method_data(ec_key, sm2_data_dup,
sm2_data_free, sm2_data_free)) != NULL) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
return 0;
}
if (!(pid = OPENSSL_strdup(id))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
return 0;
}
if (!EC_KEY_insert_key_method_data(ec_key, pid, sm2_data_dup,
if (EC_KEY_insert_key_method_data(ec_key, pid, sm2_data_dup,
sm2_data_free, sm2_data_free)) {
OPENSSL_free(pid);
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
//ERR_print_errors_fp(stderr);
//OPENSSL_free(pid);
return 0;
}
return 1;
}
char *SM2_get_id(EC_KEY *ec_key)
char *SM2_get0_id(EC_KEY *ec_key)
{
return (char *)EC_KEY_get_key_method_data(ec_key, sm2_data_dup,
sm2_data_free, sm2_data_free);
@@ -110,12 +117,12 @@ char *SM2_get_id(EC_KEY *ec_key)
/*
* pkdata = a || b || G.x || G.y || P.x || P.y
*/
static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
{
int ret = -1;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
const EC_POINT *point;
int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
int nbytes;
unsigned char oct[EC_MAX_NBYTES * 2 + 1];
BN_CTX *bn_ctx = NULL;
BIGNUM *p = NULL;
@@ -123,12 +130,12 @@ static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
BIGNUM *y = NULL;
size_t len;
OPENSSL_assert(ec_key);
OPENSSL_assert(nbytes == 256/8);
if (!buf) {
return (nbytes * 6);
unsigned char *pbuf = buf;
if (!ec_key || !buf) {
return 0;
}
nbytes = (EC_GROUP_get_degree(EC_KEY_get0_group(ec_key)) + 7)/8;
bzero(buf, nbytes * 6);
bn_ctx = BN_CTX_new();
@@ -139,44 +146,54 @@ static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
goto err;
}
/* get curve coefficients a, b */
if (!EC_GROUP_get_curve_GFp(ec_group, p, x, y, bn_ctx)) {
goto err;
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) {
if (!EC_GROUP_get_curve_GFp(ec_group, p, x, y, bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto err;
}
} else {
if (!EC_GROUP_get_curve_GF2m(ec_group, p, x, y, bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto err;
}
}
buf += nbytes;
if (!BN_bn2bin(x, buf - BN_num_bytes(x))) {
goto err;
}
BN_bn2bin(x, buf - BN_num_bytes(x));
buf += nbytes;
if (!BN_bn2bin(y, buf - BN_num_bytes(y))) {
goto err;
}
BN_bn2bin(y, buf - BN_num_bytes(y));
/* get curve generator coordinates */
if (!(point = EC_GROUP_get0_generator(ec_group))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
if (!(len = EC_POINT_point2oct(ec_group, point,
POINT_CONVERSION_UNCOMPRESSED, oct, sizeof(oct), bn_ctx))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
OPENSSL_assert(len == 32 * 2 + 1);
//OPENSSL_assert(len == 32 * 2 + 1);
memcpy(buf, oct + 1, len - 1);
buf += len - 1;
/* get pub_key coorindates */
if (!(point = EC_KEY_get0_public_key(ec_key))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
if (!(len = EC_POINT_point2oct(ec_group, point,
POINT_CONVERSION_UNCOMPRESSED, oct, sizeof(oct), bn_ctx))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
OPENSSL_assert(len == 32 * 2 + 1);
//OPENSSL_assert(len == 32 * 2 + 1);
memcpy(buf, oct + 1, len - 1);
buf += len - 1;
ret = (nbytes * 6);
err:
if (bn_ctx) BN_CTX_free(bn_ctx);
if (p) BN_free(p);
@@ -187,42 +204,53 @@ err:
}
//TODO: review this function again.
int SM2_compute_id_digest(unsigned char *dgst, unsigned int *dgstlen,
const EVP_MD *md, EC_KEY *ec_key)
int SM2_compute_id_digest(const EVP_MD *md, unsigned char *dgst,
unsigned int *dgstlen, EC_KEY *ec_key)
{
int ret = 0;
EVP_MD_CTX *md_ctx = NULL;
unsigned char pkdata[EC_MAX_NBYTES * 6];
uint16_t idbits;
unsigned char idbits[2];
int pkdatalen;
char *id = NULL;
char *id;
if ((pkdatalen = sm2_get_public_key_data(pkdata, ec_key)) < 0) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
if (!(id = SM2_get_id(ec_key))) {
id = SM2_DEFAULT_ID;
if (!(id = SM2_get0_id(ec_key))) {
id = SM2_DEFAULT_ID;
}
idbits = strlen(id) * 8;
idbits[0] = ((strlen(id) * 8) >> 8) % 256;
idbits[1] = (strlen(id) * 8) % 256;
if (!(md_ctx = EVP_MD_CTX_create())) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
if (!EVP_DigestInit_ex(md_ctx, md, NULL)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
ERR_print_errors_fp(stderr);
goto err;
}
if (!EVP_DigestUpdate(md_ctx, &idbits, sizeof(idbits))) {
if (!EVP_DigestUpdate(md_ctx, idbits, sizeof(idbits))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
if (!EVP_DigestUpdate(md_ctx, id, strlen(id))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
if (!EVP_DigestUpdate(md_ctx, pkdata, pkdatalen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
if (!EVP_DigestFinal(md_ctx, dgst, dgstlen)) {
if (!EVP_DigestFinal_ex(md_ctx, dgst, dgstlen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto err;
}
@@ -233,3 +261,40 @@ err:
return ret;
}
int SM2_compute_message_digest(const EVP_MD *id_md, const EVP_MD *msg_md,
const void *msg, size_t msglen, unsigned char *dgst,
unsigned int *dgstlen, EC_KEY *ec_key)
{
int ret = 0;
EVP_MD_CTX md_ctx;
unsigned char buf[EVP_MAX_MD_SIZE];
unsigned int len;
EVP_MD_CTX_init(&md_ctx);
if (!EVP_DigestInit_ex(&md_ctx, msg_md, NULL)) {
goto err;
}
if (!SM2_compute_id_digest(id_md, buf, &len, ec_key)) {
goto err;
}
if (!EVP_DigestUpdate(&md_ctx, buf, len)) {
goto err;
}
if (!EVP_DigestUpdate(&md_ctx, msg, msglen)) {
goto err;
}
if (!EVP_DigestFinal_ex(&md_ctx, dgst, &dgstlen)) {
goto err;
}
ret = 1;
err:
EVP_MD_CTX_cleanup(&md_ctx);
return ret;
}

View File

@@ -1,6 +1,6 @@
/* crypto/sm2/sm2_locl.h */
/* ====================================================================
* Copyright (c) 2015 The GmSSL Project. All rights reserved.
* Copyright (c) 2015-2016 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
@@ -58,15 +58,16 @@
extern "C" {
#endif
typedef struct sm2_data_st {
int (*init)(EC_KEY *);
ENGINE *engine;
int flags;
const ECDSA_METHOD *sign_meth;
const ECDH_METHOD *kap_meth; /* FIXME: SM2 KAP is different from ECDH */
CRYPTO_EX_DATA ex_data;
} SM2_DATA;
struct sm2sign_method {
const char *name;
SM2_SIG *(*sm2_do_sign)(const unsigned char *dgst, int dgstlen);
int (*sm2_sign_setup)(void);
int (*sm2_do_verify)(void);
int flag;
void *app_data;
};
SM2_DATA *sm2_check(EC_KEY *eckey);
#ifdef __cplusplus

View File

@@ -58,7 +58,6 @@
#include <openssl/rand.h>
#include <openssl/sm2.h>
//FIXME: ECDSAerr()
/* k in [1, n-1], (x, y) = kG */
static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **xp)
@@ -69,7 +68,7 @@ static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **
BIGNUM *k = NULL;
BIGNUM *x = NULL;
BIGNUM *order = NULL;
EC_POINT *point=NULL;
EC_POINT *point = NULL;
if (ec_key == NULL || (ec_group = EC_KEY_get0_group(ec_key)) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
@@ -89,7 +88,6 @@ static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **
k = BN_new();
x = BN_new();
order = BN_new();
if (!k || !x || !order) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
goto err;
@@ -133,7 +131,8 @@ static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **
goto err;
}
}
//FIXME: do we need this?
if (!BN_nnmod(x, x, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
@@ -206,17 +205,22 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgst_len,
/* convert dgst to e */
i = BN_num_bits(order);
#if 0
if (8 * dgst_len > i) {
dgst_len = (i + 7)/8;
}
#endif
if (!BN_bin2bn(dgst, dgst_len, e)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
#if 0
if ((8 * dgst_len > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
#endif
do {
/* use or compute k and (kG).x */
@@ -234,11 +238,14 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgst_len,
}
}
/* r = e + x (mod n) */
if (!BN_mod_add(ret->r, ret->r, e, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_add(bn, ret->r, ck, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
@@ -266,6 +273,7 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgst_len,
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(bn, ret->r, priv_key, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
@@ -309,7 +317,7 @@ err:
int sm2_do_verify(const unsigned char *dgst, int dgstlen,
const ECDSA_SIG *sig, EC_KEY *ec_key)
{
int ret = -1;
int ret = SM2_VERIFY_INNER_ERROR;
const EC_GROUP *ec_group;
const EC_POINT *pub_key;
EC_POINT *point = NULL;
@@ -366,17 +374,21 @@ int sm2_do_verify(const unsigned char *dgst, int dgstlen,
/* convert digest to e */
i = BN_num_bits(order);
#if 0
if (8 * dgstlen > i) {
dgstlen = (i + 7)/8;
}
#endif
if (!BN_bin2bn(dgst, dgstlen, e)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
#if 0
if ((8 * dgstlen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
#endif
/* compute (x, y) = sG + tP, P is pub_key */
if (!(point = EC_POINT_new(ec_group))) {
@@ -408,8 +420,12 @@ int sm2_do_verify(const unsigned char *dgst, int dgstlen,
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
ret = (BN_ucmp(t, sig->r) == 0);
if (BN_ucmp(t, sig->r) == 0) {
ret = SM2_VERIFY_SUCCESS;
} else {
ret = SM2_VERIFY_FAILED;
}
err:
if (point) EC_POINT_free(point);
if (order) BN_free(order);

File diff suppressed because it is too large Load Diff