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

@@ -4,7 +4,7 @@
## Makefile for OpenSSL
##
VERSION=1.0.2d
VERSION=1.0.2d-fips
MAJOR=1
MINOR=0.2
SHLIB_VERSION_NUMBER=1.0.0
@@ -151,7 +151,7 @@ SDIRS= \
buffer bio stack lhash rand err \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
cms pqueue ts srp cmac \
sm3 sms4 zuc cpk ecies sm2
sm2 sm3 sms4 ecies zuc
# keep in mind that the above list is adjusted by ./Configure
# according to no-xxx arguments...

View File

@@ -4,7 +4,7 @@
## Makefile for OpenSSL
##
VERSION=1.0.2d
VERSION=1.0.2d-fips
MAJOR=1
MINOR=0.2
SHLIB_VERSION_NUMBER=1.0.0
@@ -67,9 +67,9 @@ EX_LIBS=
EXE_EXT=
ARFLAGS=
AR= ar $(ARFLAGS) r
RANLIB= /opt/local/bin/ranlib
RANLIB= /usr/bin/ranlib
NM= nm
PERL= /opt/local/bin/perl5
PERL= /usr/bin/perl
TAR= tar
TARFLAGS= --no-recursion
MAKEDEPPROG=makedepend
@@ -151,7 +151,7 @@ SDIRS= \
buffer bio stack lhash rand err \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
cms pqueue ts srp cmac \
sm3 sms4 zuc cpk ecies sm2
sm2 sm3 sms4 ecies
# keep in mind that the above list is adjusted by ./Configure
# according to no-xxx arguments...

View File

@@ -149,7 +149,7 @@ SDIRS= \
buffer bio stack lhash rand err \
evp asn1 pem x509 x509v3 conf txt_db pkcs7 pkcs12 comp ocsp ui krb5 \
cms pqueue ts jpake srp store cmac \
sm3 sms4 zuc cpk ecies sm2
sm2 sm3 sms4 ecies zuc
# keep in mind that the above list is adjusted by ./Configure
# according to no-xxx arguments...

View File

@@ -0,0 +1,6 @@
/*
*
* gmssl cpkparam
*/

Binary file not shown.

View File

@@ -1,69 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <openssl/evp.h>
#include <openssl/ecdsa.h>
#include <openssl/objects.h>
int main(int argc, char **argv)
{
char *prog = basename(argv[0]);
EC_GROUP *ec_group = NULL;
EC_KEY *ec_key = NULL;
BN_CTX *ctx = BN_CTX_new();
const char *id = "Alice@YAHOO.COM";
unsigned char za[32];
BIGNUM *k = NULL;
BIGNUM *x = NULL;
ECDSA_SIG *sig = NULL;
unsigned char dgst[20] = "abc";
int ret;
if (!(ec_group = EC_GROUP_new_by_curve_name(NID_sm2t257v1))) {
fprintf(stderr, "%s: no such curve\n", prog);
return -1;
}
if (!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) {
fprintf(stderr, "%s: %s %d\n", prog, __FUNCTION__, __LINE__);
return -1;
}
if (!EC_KEY_generate_key(ec_key)) {
ERR_print_errors_fp(stderr);
return -1;
}
if ((ret = EC_KEY_compute_za(za, EVP_sha256(), id, strlen(id), ec_key)) < 0) {
ERR_print_errors_fp(stderr);
return -1;
}
printf("Za length = %d\n", ret);
if (!(sig = ECDSA_do_sign(dgst, sizeof(dgst), ec_key))) {
ERR_print_errors_fp(stderr);
return -1;
}
if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) {
ERR_print_errors_fp(stderr);
return -1;
}
printf("result = %d\n", ret);
if (!ECDSA_sign_setup(ec_key, ctx, &k, &x)) {
ERR_print_errors_fp(stderr);
return -1;
}
if (!(sig = ECDSA_do_sign_ex(dgst, sizeof(dgst), k, x, ec_key))) {
ERR_print_errors_fp(stderr);
return -1;
}
if ((ret = ECDSA_do_verify(dgst, sizeof(dgst), sig, ec_key)) < 0) {
ERR_print_errors_fp(stderr);
return -1;
}
printf("result = %d\n", ret);
return 0;
}

View File

@@ -1,7 +1,3 @@
#include <stdio.h>
@@ -54,17 +50,21 @@ int CBCMAC_CTX_copy(CBCMAC_CTX *to, const CBCMAC_CTX *from)
int CBCMAC_Init(CBCMAC_CTX *ctx, const void *key, size_t keylen,
const EVP_CIPHER *cipher, ENGINE *impl)
{
return 0;
}
int CBCMAC_Update(CBCMAC_CTX *ctx, const void *data, size_t datalen)
{
return 0;
}
int CBCMAC_Final(CBCMAC_CTX *ctx, unsigned char *out, size_t *outlen)
{
return 0;
}
int CBCMAC_resume(CBCMAC_CTX *ctx)
{
return 0;
}

View File

@@ -48,7 +48,11 @@
* ====================================================================
*
*/
/* Note:
* 1. CBC-MAC should be only used for fixed-length message
* 2. the message length should be multiple of block size
* 3. the implementation do not add padding
*/
#ifndef HEADER_CBCMAC_H
#define HEADER_CBCMAC_H

View File

@@ -1224,11 +1224,25 @@ void ERR_load_EC_strings(void);
# define EC_F_PKEY_EC_SIGN 218
# ifndef OPENSSL_NO_GMSSL
# define EC_F_PKEY_EC_ENCRYPT 300
# define EC_F_PKEY_EC_DECRYPT 301
# define EC_F_PKEY_SM2_SIGN 302
# define EC_F_PKEY_SM2_ENCRYPT 303
# define EC_F_PKEY_SM2_DECRYPT 304
# define EC_F_PKEY_EC_ENCRYPT 300
# define EC_F_PKEY_EC_DECRYPT 301
# define EC_F_PKEY_SM2_INIT 302
# define EC_F_PKEY_SM2_COPY 303
# define EC_F_PKEY_SM2_CLEANUP 304
# define EC_F_PKEY_SM2_PARAMGEN 305
# define EC_F_PKEY_SM2_KEYGEN 306
# define EC_F_PKEY_SM2_SIGN 307
# define EC_F_PKEY_SM2_VERIFY 308
# define EC_F_PKEY_SM2_SIGNCTX_INIT 309
# define EC_F_PKEY_SM2_SIGNCTX 310
# define EC_F_PKEY_SM2_VERIFYCTX_INIT 311
# define EC_F_PKEY_SM2_VERIFYCTX 312
# define EC_F_PKEY_SM2_ENCRYPT 313
# define EC_F_PKEY_SM2_DECRYPT 314
# define EC_F_PKEY_SM2_DERIVE_INIT 315
# define EC_F_PKEY_SM2_DERIVE 316
# define EC_F_PKEY_SM2_CTRL 317
# define EC_F_PKEY_SM2_CTRL_STR 318
# endif
/* Reason codes. */

View File

@@ -625,7 +625,97 @@ static int pkey_sm2_verify(EVP_PKEY_CTX *ctx,
return SM2_verify(type, dgst, dgstlen, sig, siglen, ec_key);
}
static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
static int pkey_sm2_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
int ret = 0;
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
const EVP_MD *md = EVP_sm3();
unsigned char zid[EVP_MAX_MD_SIZE];
unsigned int zidlen;
if (!SM2_compute_id_digest(md, zid, &zidlen, ec_key)) {
ECerr(EC_F_PKEY_SM2_SIGNCTX_INIT, ERR_R_SM2_LIB);
return 0;
}
if (!mctx->update(mctx, zid, zidlen)) {
ECerr(EC_F_PKEY_SM2_SIGNCTX_INIT, ERR_R_EVP_LIB);
return 0;
}
return 1;
}
static int pkey_sm2_signctx(EVP_PKEY_CTX *ctx,
unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx)
{
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
unsigned char dgst[EVP_MAX_MD_SIZE];
unsigned int dgstlen;
int type = NID_undef;
if (!sig) {
*siglen = SM2_signature_size(ec_key);
return 1;
}
if (*siglen < (size_t)SM2_signature_size(ec_key)) {
ECerr(EC_F_PKEY_SM2_SIGNCTX, EC_R_BUFFER_TOO_SMALL);
return 0;
}
if (!EVP_DigestFinal_ex(mctx, dgst, &dgstlen)) {
ECerr(EC_F_PKEY_SM2_SIGNCTX, ERR_R_EVP_LIB);
return 0;
}
return SM2_sign(type, dgst, dgstlen, sig, &siglen, ec_key);
}
static int pkey_sm2_verifyctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
{
int ret = 0;
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
const EVP_MD *md = EVP_sm3();
unsigned char zid[EVP_MAX_MD_SIZE];
unsigned int zidlen;
// FIXME: we need to get md from somewhere
if (!SM2_compute_id_digest(md, zid, &zidlen, ec_key)) {
goto end;
}
if (!mctx->update(mctx, zid, zidlen)) {
goto end;
}
ret = 1;
end:
return 0;
}
static int pkey_sm2_verifyctx(EVP_PKEY_CTX *ctx,
const unsigned char *sig, int siglen, EVP_MD_CTX *mctx)
{
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
int type = ec_ctx->md ? EVP_MD_type(ec_ctx->md) : NID_sm3;
/*
if (!EVP_DigestFinal_ex(mctx, dgst, &dgstlen)) {
goto end;
}
return SM2_verify(type, dgst, dgstlen, sig, siglen, ec_key);
*/
return 0;
}
static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
EC_PKEY_CTX *ec_ctx = ctx->data;
@@ -641,7 +731,8 @@ static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outle
return SM2_encrypt(kdf_md, mac_md, point_form, in, inlen, out, outlen, ec_key);
}
static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
EC_PKEY_CTX *ec_ctx = ctx->data;
@@ -654,7 +745,8 @@ static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outle
kdf_md = EVP_sm3();
mac_md = EVP_sm3();
return SM2_decrypt(kdf_md, mac_md, point_form, in, inlen, out, outlen, ec_key);
return SM2_decrypt(kdf_md, mac_md, point_form,
in, inlen, out, outlen, ec_key);
}
static int pkey_sm2_ctrl_digestinit(EVP_PKEY_CTX *pk_ctx, EVP_MD_CTX *md_ctx)
@@ -679,7 +771,7 @@ static int pkey_sm2_ctrl_digestinit(EVP_PKEY_CTX *pk_ctx, EVP_MD_CTX *md_ctx)
*/
//FIXME: check this function
if (!SM2_compute_id_digest(zid, &zidlen, md, ec_key)) {
if (!SM2_compute_id_digest(md, zid, &zidlen, ec_key)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
return 0;
}
@@ -706,6 +798,16 @@ end:
return ret;
}
static int pkey_sm2_derive_init(EVP_PKEY_CTX *ctx)
{
return 0;
}
static int pkey_sm2_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
return 0;
}
static int pkey_sm2_ctrl(EVP_PKEY_CTX *pk_ctx, int type, int p1, void *p2)
{
switch (type) {
@@ -720,34 +822,30 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *pk_ctx, int type, int p1, void *p2)
const EVP_PKEY_METHOD sm2_pkey_meth = {
EVP_PKEY_SM2,
0, /* flags */
0,
pkey_ec_init,
pkey_ec_copy,
pkey_ec_cleanup,
0, /* paramgen_init */
pkey_ec_paramgen,
0, /* keygen_init */
pkey_sm2_keygen,
0, /* sign_init */
pkey_sm2_sign,
0, /* verify_init */
pkey_sm2_verify,
0, /* verify_recover_init */
0, /* verify_recover */
0, /* signctx_init */
0, /* signctx */
0, /* verifyctx_init */
0, /* verifyctx */
0, /* encrypt_init */
pkey_sm2_encrypt,
0, /* decrypt_init */
pkey_sm2_decrypt,
0, /* derive_init */
#ifndef OPENSSL_NO_ECDH
pkey_ec_kdf_derive,
#else
0,
#endif
pkey_ec_paramgen,
0,
pkey_sm2_keygen,
0,
pkey_sm2_sign,
0,
pkey_sm2_verify,
0,
0,
pkey_sm2_signctx_init,
pkey_sm2_signctx,
pkey_sm2_verifyctx_init,
pkey_sm2_verifyctx,
0,
pkey_sm2_encrypt,
0,
pkey_sm2_decrypt,
pkey_sm2_derive_init,
pkey_sm2_derive,
pkey_sm2_ctrl,
pkey_ec_ctrl_str
};

File diff suppressed because it is too large Load Diff

View File

@@ -177,7 +177,7 @@ void OpenSSL_add_all_ciphers(void)
#endif
#ifndef OPENSSL_NO_ZUC
EVP_add_cipher(EVP_zuc());
EVP_add_cipher(EVP_zuc());
#endif
#ifndef OPENSSL_NO_AES

View File

@@ -219,8 +219,8 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
ctx->update = type->update;
ctx->md_data = OPENSSL_malloc(type->ctx_size);
//fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (ctx->md_data == NULL) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
return 0;
}

View File

@@ -23,6 +23,11 @@ static int zuc_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
return 1;
}
/*
* FIXME:
* evp_enc.c assert block_size in {1, 8, 16}, 4 not ok!
*/
static const EVP_CIPHER zuc_cipher = {
NID_zuc, /* nid */
4, /* block_size */

View File

@@ -210,6 +210,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
#endif
/* we assume block size is a power of 2 in *cryptUpdate */
OPENSSL_assert(ctx->cipher->block_size == 1
#ifndef OPENSSL_NO_GMSSL
|| ctx->cipher->block_size == 4
#endif
|| ctx->cipher->block_size == 8
|| ctx->cipher->block_size == 16);

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

View File

@@ -209,6 +209,7 @@ void ZUC_set_key(ZUC_KEY *key, const unsigned char *k, const unsigned char *iv)
void ZUC_encrypt(ZUC_KEY *key, size_t inlen, const unsigned char *in, unsigned char *out)
{
#if 0
uint32_t word;
int n = key->buf_index;
@@ -244,5 +245,6 @@ void ZUC_encrypt(ZUC_KEY *key, size_t inlen, const unsigned char *in, unsigned c
key->buf_index = n;
return;
#endif
}

72
demos/gmssl/sm2.c Normal file
View File

@@ -0,0 +1,72 @@
/* demo/gmssl/sm2.c */
/* ====================================================================
* 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
* 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 <strings.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/engine.h>
#include <openssl/sm2.h>
int main()
{
ENGINE *engine = NULL;
EVP_PKEY_CTX *pkctx;
pkctx = EVP_PKEY_CTX_new_id(id, engine);
}

111
demos/gmssl/sms4enc.c Normal file
View File

@@ -0,0 +1,111 @@
/* demo/gmssl/sms4enc.c */
/* ====================================================================
* Copyright (c) 2014 - 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 <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
int main(int argc, char **argv)
{
int ret = -1;
FILE *fp = stdin;
unsigned char key[32];
unsigned char buf[1024];
int len;
const EVP_MD *md;
HMAC_CTX hmctx;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int maclen, i;
if (argc == 2) {
if (!(fp = fopen(argv[1], "r"))) {
fprintf(stderr, "open file %s failed\n", argv[1]);
return -1;
}
}
HMAC_CTX_init(&hmctx);
RAND_bytes(key, sizeof(key));
OpenSSL_add_all_digests();
if (!(md = EVP_get_digestbyname("sm3"))) {
ERR_print_errors_fp(stderr);
goto end;
}
if (!EVP_DigestSignInit()) {
goto end;
}
while ((len = fread(buf, 1, sizeof(buf), fp))) {
EVP_DigestSignUpdate(&hmctx, buf, len);
}
if (!EVP_DigestSignFinal()) {
goto end;
}
for (i = 0; i < maclen; i++) {
printf("%02x", mac[i]);
}
printf("\n");
ret = 0;
end:
fclose(fp);
EVP_cleanup();
return ret;
}

Binary file not shown.

1
include/openssl/cbcmac.h Symbolic link
View File

@@ -0,0 +1 @@
../../crypto/cbcmac/cbcmac.h

1
include/openssl/ffx.h Symbolic link
View File

@@ -0,0 +1 @@
../../crypto/ffx/ffx.h

54
test/p Normal file
View File

@@ -0,0 +1,54 @@
#!/bin/sh
testsrc=testenc
test=./p
cmd="../util/shlib_wrap.sh ../apps/openssl"
cat $testsrc >$test;
echo cat
$cmd enc < $test > $test.cipher
$cmd enc < $test.cipher >$test.clear
cmp $test $test.clear
if [ $? != 0 ]
then
exit 1
else
/bin/rm $test.cipher $test.clear
fi
echo base64
$cmd enc -a -e < $test > $test.cipher
$cmd enc -a -d < $test.cipher >$test.clear
cmp $test $test.clear
if [ $? != 0 ]
then
exit 1
else
/bin/rm $test.cipher $test.clear
fi
for i in `$cmd list-cipher-commands`
do
echo $i
$cmd $i -bufsize 113 -e -k test < $test > $test.$i.cipher
$cmd $i -bufsize 157 -d -k test < $test.$i.cipher >$test.$i.clear
cmp $test $test.$i.clear
if [ $? != 0 ]
then
exit 1
else
/bin/rm $test.$i.cipher $test.$i.clear
fi
echo $i base64
$cmd $i -bufsize 113 -a -e -k test < $test > $test.$i.cipher
$cmd $i -bufsize 157 -a -d -k test < $test.$i.cipher >$test.$i.clear
cmp $test $test.$i.clear
if [ $? != 0 ]
then
exit 1
else
/bin/rm $test.$i.cipher $test.$i.clear
fi
done
rm -f $test

BIN
test/p.zuc.cipher Normal file

Binary file not shown.

BIN
test/p.zuc.clear Normal file

Binary file not shown.