SM2 KAP (Key Agreement Protocol), not tested

This commit is contained in:
Zhi Guan
2016-04-07 22:15:41 +02:00
parent ef74cbd1e5
commit 5cc6cfdf22
55 changed files with 3803 additions and 1028 deletions

View File

@@ -72,6 +72,9 @@ extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
#ifndef OPENSSL_NO_SM2
extern const EVP_PKEY_ASN1_METHOD sm2_asn1_meth;
#endif
/* Keep this sorted in type order !! */
static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
@@ -91,6 +94,9 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
#endif
#ifndef OPENSSL_NO_EC
&eckey_asn1_meth,
#endif
#ifndef OPENSSL_NO_SM2
&sm2_asn1_meth,
#endif
&hmac_asn1_meth,
&cmac_asn1_meth,
@@ -159,6 +165,33 @@ static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
}
ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods)
/ sizeof(EVP_PKEY_ASN1_METHOD *));
#ifndef OPENSSL_NO_SM2
//FIXME: i dont know why sm2_asn1_meth can not be found
/*
{
int i;
for (i = 0;
i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++)
fprintf(stderr, "Number %d id=%d (%s)\n", i,
standard_methods[i]->pkey_id,
OBJ_nid2sn(standard_methods[i]->pkey_id));
}
*/
/*
fprintf(stderr, "%s:%d: type = %d, NID_sm2 = %d\n", __FILE__, __LINE__,
type, NID_sm2p256v1);
if (ret == NULL) {
fprintf(stderr, "shit, not found!");
}
*/
if (type == EVP_PKEY_SM2) {
return &sm2_asn1_meth;
}
#endif
if (!ret || !*ret)
return NULL;
return *ret;
@@ -200,6 +233,9 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
{
int i;
const EVP_PKEY_ASN1_METHOD *ameth;
printf("%s:%d: EVP_PKEY_asn1_find_str(%s)\n", __FILE__, __LINE__, str);
if (len == -1)
len = strlen(str);
if (pe) {

113
crypto/cbcmac/Makefile Normal file
View File

@@ -0,0 +1,113 @@
#
# OpenSSL/crypto/cbcmac/Makefile
#
DIR= cbcmac
TOP= ../..
CC= cc
INCLUDES=
CFLAG=-g
MAKEFILE= Makefile
AR= ar r
CFLAGS= $(INCLUDES) $(CFLAG)
GENERAL=Makefile
TEST=
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC=cbcmac.c cbcmac_ameth.c cbcmac_pmeth.c
LIBOBJ=cbcmac.o cbcmac_ameth.o cbcmac_pmeth.o
SRC= $(LIBSRC)
EXHEADER= cbcmac.h
HEADER= $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)
top:
(cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
all: lib
lib: $(LIBOBJ)
$(AR) $(LIB) $(LIBOBJ)
$(RANLIB) $(LIB) || echo Never mind.
@touch lib
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
links:
@$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
@$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
@$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
install:
@[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
@headerlist="$(EXHEADER)"; for i in $$headerlist ; \
do \
(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
done;
tags:
ctags $(SRC)
tests:
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
update: depend
depend:
@[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
dclean:
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
mv -f Makefile.new $(MAKEFILE)
clean:
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
# DO NOT DELETE THIS LINE -- make depend depends on it.
cm_ameth.o: ../../e_os.h ../../include/openssl/asn1.h
cm_ameth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
cm_ameth.o: ../../include/openssl/cmac.h ../../include/openssl/crypto.h
cm_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
cm_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cm_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cm_ameth.o: ../../include/openssl/opensslconf.h
cm_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cm_ameth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
cm_ameth.o: ../../include/openssl/symhacks.h ../asn1/asn1_locl.h ../cryptlib.h
cm_ameth.o: cm_ameth.c
cm_pmeth.o: ../../e_os.h ../../include/openssl/asn1.h
cm_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
cm_pmeth.o: ../../include/openssl/cmac.h ../../include/openssl/conf.h
cm_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
cm_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
cm_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
cm_pmeth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
cm_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
cm_pmeth.o: ../../include/openssl/opensslconf.h
cm_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cm_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h
cm_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
cm_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
cm_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h
cm_pmeth.o: ../cryptlib.h ../evp/evp_locl.h cm_pmeth.c
cmac.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h
cmac.o: ../../include/openssl/buffer.h ../../include/openssl/cmac.h
cmac.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
cmac.o: ../../include/openssl/err.h ../../include/openssl/evp.h
cmac.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
cmac.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
cmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
cmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
cmac.o: ../../include/openssl/symhacks.h ../cryptlib.h cmac.c

70
crypto/cbcmac/cbcmac.c Normal file
View File

@@ -0,0 +1,70 @@
#include <stdio.h>
struct CBCMAC_CTX_st {
EVP_CIPHER_CTX cipher_ctx;
unsigned char block[EVP_MAX_BLOCK_LENGTH];
unsigned char tmp_block[EVP_MAX_BLOCK_LENGTH];
};
CBCMAC *CBCMAC_CTX_new(void)
{
CBCMAC_CTX *ret;
if (!(ret = OPENSSL_malloc(*ret))) {
return NULL;
}
EVP_CIPHER_CTX_init(&ret->cipher_ctx);
return ret;
}
void CBCMAC_CTX_cleanup(CBCMAC_CTX *ctx)
{
EVP_CIPHER_CTX_cleanup(&ctx->cipher_ctx);
OPENSSL_cleanse(ctx->block, EVP_MAX_BLOCK_LENGTH);
OPENSSL_cleanse(ctx->tmp_block, EVP_MAX_BLOCK_LENGTH);
}
EVP_CIPHER_CTX *CBCMAC_CTX_get0_cipher_ctx(CBCMAC_CTX *ctx)
{
return &ctx->cipher_ctx;
}
void CBCMAC_CTX_free(CBCMAC_CTX *ctx)
{
if (ctx) {
CBCMAC_CTX_cleanup(ctx);
OPENSSL_free(ctx);
}
}
int CBCMAC_CTX_copy(CBCMAC_CTX *to, const CBCMAC_CTX *from)
{
return 0;
}
int CBCMAC_Init(CBCMAC_CTX *ctx, const void *key, size_t keylen,
const EVP_CIPHER *cipher, ENGINE *impl)
{
}
int CBCMAC_Update(CBCMAC_CTX *ctx, const void *data, size_t datalen)
{
}
int CBCMAC_Final(CBCMAC_CTX *ctx, unsigned char *out, size_t *outlen)
{
}
int CBCMAC_resume(CBCMAC_CTX *ctx)
{
}

79
crypto/cbcmac/cbcmac.h Normal file
View File

@@ -0,0 +1,79 @@
/* crypto/cbcmac/cbcmac.h */
/* ====================================================================
* Copyright (c) 2014 - 2015 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.
* ====================================================================
*
*/
#ifndef HEADER_CBCMAC_H
#define HEADER_CBCMAC_H
#include <openssl/evp.h>
#ifdef __cplusplus
extern "C" {
#endif
CBCMAC_CTX *CBCMAC_CTX_new(void);
void CBCMAC_CTX_cleanup(CBCMAC_CTX *ctx);
void CBCMAC_CTX_free(CBCMAC_CTX *ctx);
EVP_CIPHER_CTX *CBCMAC_CTX_get0_cipher_ctx(CBCMAC_CTX *ctx);
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);
int CBCMAC_Update(CBCMAC_CTX *ctx, const void *data, size_t datalen);
int CBCMAC_Final(CBCMAC_CTX *ctx, unsigned char *out, size_t *outlen);
int CBCMAC_resume(CBCMAC_CTX *ctx);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -641,6 +641,42 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
old_ec_priv_encode
};
#ifndef OPENSSL_NO_SM2
const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = {
EVP_PKEY_SM2,
EVP_PKEY_SM2,
0,
"SM2",
"GmSSL SM2 algorithm",
eckey_pub_decode,
eckey_pub_encode,
eckey_pub_cmp,
eckey_pub_print,
eckey_priv_decode,
eckey_priv_encode,
eckey_priv_print,
int_ec_size,
ec_bits,
eckey_param_decode,
eckey_param_encode,
ec_missing_parameters,
ec_copy_parameters,
ec_cmp_parameters,
eckey_param_print,
0,
int_ec_free,
ec_pkey_ctrl,
old_ec_priv_decode,
old_ec_priv_encode
};
#endif
#ifndef OPENSSL_NO_CMS
static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,

View File

@@ -2835,6 +2835,7 @@ static const struct {
}
};
#ifndef OPENSSL_NO_SM2
static const struct {
EC_CURVE_DATA h;
unsigned char data[0 + 32 * 6];
@@ -2870,6 +2871,7 @@ static const struct {
0x53, 0xBB, 0xF4, 0x09, 0x39, 0xD5, 0x41, 0x23
}
};
#endif
typedef struct _ec_list_element_st {
int nid;
@@ -3080,8 +3082,10 @@ static const ec_list_element curve_list[] = {
"RFC 5639 curve over a 512 bit prime field"},
{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,
"SM2 curve over a 256 bit prime field"},
#endif
};
#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element))

View File

@@ -499,9 +499,7 @@ static int pkey_ec_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
{
EC_KEY *ec_key = ctx->pkey->pkey.ec;
ECIES_PARAMS *param = ECIES_get_parameters(ec_key);
fprintf(stderr, "%s %s %d\n", __FUNCTION__, __FILE__, __LINE__);
OPENSSL_assert(param);
return ECIES_encrypt(out, outlen, param, in, inlen, ec_key);
}
@@ -510,7 +508,7 @@ static int pkey_ec_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
{
EC_KEY *ec_key = ctx->pkey->pkey.ec;
ECIES_PARAMS *param = ECIES_get_parameters(ec_key);
fprintf(stderr, "%s %s %d\n", __FUNCTION__, __FILE__, __LINE__);
OPENSSL_assert(param);
return ECIES_decrypt(out, outlen, param, in, inlen, ec_key);
}
#endif
@@ -564,6 +562,31 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
};
#ifndef OPENSSL_NO_SM2
static int pkey_sm2_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
EC_KEY *ec = NULL;
EC_PKEY_CTX *dctx = ctx->data;
if (ctx->pkey == NULL && dctx->gen_group == NULL) {
ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
if (!ec)
return 0;
EVP_PKEY_assign_SM2(pkey, ec);
if (ctx->pkey) {
/* Note: if error return, pkey is freed by parent routine */
if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
return 0;
} else {
if (!EC_KEY_set_group(ec, dctx->gen_group))
return 0;
}
return EC_KEY_generate_key(pkey->pkey.ec);
}
static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *dgst, size_t dgstlen)
{
@@ -611,7 +634,11 @@ static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outle
const EVP_MD *mac_md = ec_ctx->md;
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
return SM2_encrypt(kdf_md, mac_md, point_form, out, outlen, in, inlen, ec_key);
//FIXME: the ec_ctx is not work, no one init it
kdf_md = EVP_sm3();
mac_md = EVP_sm3();
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,
@@ -623,35 +650,55 @@ static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outle
const EVP_MD *mac_md = ec_ctx->md;
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
//FIXME: the ec_ctx is not work, no one init it
kdf_md = EVP_sm3();
mac_md = EVP_sm3();
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)
{
int ret;
int ret = 0;
EC_KEY *ec_key = pk_ctx->pkey->pkey.ec;
const EVP_MD *md = EVP_MD_CTX_md(md_ctx);
char *id;
unsigned char zid[EVP_MAX_MD_SIZE];
unsigned int zidlen = sizeof(zid);
EVP_PKEY_CTX *pctx;
fprintf(stderr, "%s() called\n", __FUNCTION__);
if (!(id = SM2_get_id(ec_key))) {
return 0;
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
id = "alice@pku.edu.cn";
//return 0;
}
//FIXME: check this function
if (!SM2_compute_id_digest(zid, &zidlen, md, id, strlen(zidlen), ec_key)) {
if (!SM2_compute_id_digest(zid, &zidlen, md, id, strlen(id), ec_key)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
return 0;
}
pctx = md_ctx->pctx;
md_ctx->pctx = NULL;
if (!EVP_DigestInit_ex(md_ctx, md, NULL)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
md_ctx->pctx = pctx;
if (!EVP_DigestUpdate(md_ctx, zid, zidlen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
EVP_MD_CTX_set_flags(md_ctx, EVP_MD_CTX_FLAG_NO_INIT);
ret = 1;
end:
return ret;
}
@@ -677,7 +724,7 @@ const EVP_PKEY_METHOD sm2_pkey_meth = {
0, /* paramgen_init */
pkey_ec_paramgen,
0, /* keygen_init */
pkey_ec_keygen,
pkey_sm2_keygen,
0, /* sign_init */
pkey_sm2_sign,
0, /* verify_init */

View File

@@ -10,7 +10,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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
@@ -61,393 +61,404 @@
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen,
const BIGNUM *, const BIGNUM *,
EC_KEY *eckey);
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp);
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey);
static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgstlen,
const BIGNUM *in_k, const BIGNUM *in_x, EC_KEY *ec_key);
static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp,
BIGNUM **xp);
static int sm2_do_verify(const unsigned char *dgst, int dgstlen,
const ECDSA_SIG *sig, EC_KEY *ec_key);
static ECDSA_METHOD openssl_sm2dsa_meth = {
"OpenSSL SM2DSA method",
sm2_do_sign,
sm2_sign_setup,
sm2_do_verify,
static ECDSA_METHOD openssl_ecdsa_meth = {
"OpenSSL ECDSA method",
ecdsa_do_sign,
ecdsa_sign_setup,
ecdsa_do_verify,
#if 0
NULL, /* init */
NULL, /* finish */
NULL, /* init */
NULL, /* finish */
#endif
0, /* flags */
NULL /* app_data */
0, /* flags */
NULL /* app_data */
};
const ECDSA_METHOD *ECDSA_OpenSSL(void)
{
return &openssl_sm2dsa_meth;
return &openssl_ecdsa_meth;
}
/* 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)
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp)
{
int ret = 0;
const EC_GROUP *ec_group;
BN_CTX *ctx = NULL;
BIGNUM *k = NULL;
BIGNUM *x = NULL;
BIGNUM *order = NULL;
EC_POINT *point=NULL;
BN_CTX *ctx = NULL;
BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
EC_POINT *tmp_point = NULL;
const EC_GROUP *group;
int ret = 0;
if (ec_key == NULL || (ec_group = EC_KEY_get0_group(ec_key)) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
return 0;
}
}
else {
ctx = ctx_in;
}
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
return 0;
}
} else
ctx = ctx_in;
k = BN_new();
x = BN_new();
order = BN_new();
k = BN_new(); /* this value is later returned in *kinvp */
r = BN_new(); /* this value is later returned in *rp */
order = BN_new();
X = BN_new();
if (!k || !r || !order || !X) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
goto err;
}
if ((tmp_point = EC_POINT_new(group)) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
if (!k || !x || !order) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
goto err;
}
do {
/* get random k */
do
if (!BN_rand_range(k, order)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
while (BN_is_zero(k)) ;
if (!EC_GROUP_get_order(ec_group, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
if ((point = EC_POINT_new(ec_group)) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
/*
* We do not want timing information to leak the length of k, so we
* compute G*k using an equivalent scalar of fixed bit-length.
*/
do {
/* get random k */
do {
if (!BN_rand_range(k, order)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,
ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
if (!BN_add(k, k, order))
goto err;
if (BN_num_bits(k) <= BN_num_bits(order))
if (!BN_add(k, k, order))
goto err;
} while (BN_is_zero(k));
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp
(group, tmp_point, X, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
}
#ifndef OPENSSL_NO_EC2M
else { /* NID_X9_62_characteristic_two_field */
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(ec_group, point, k, NULL, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GF2m(group,
tmp_point, X, NULL,
ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB);
goto err;
}
}
#endif
if (!BN_nnmod(r, X, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
}
while (BN_is_zero(r));
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(ec_group, point, x, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
goto err;
}
} else /* NID_X9_62_characteristic_two_field */ {
if (!EC_POINT_get_affine_coordinates_GF2m(ec_group, point, x, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB);
goto err;
}
}
/* compute the inverse of k */
if (EC_GROUP_get_mont_data(group) != NULL) {
/*
* We want inverse in constant time, therefore we utilize the fact
* order must be prime and use Fermats Little Theorem instead.
*/
if (!BN_set_word(X, 2)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_sub(X, order, X, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
BN_set_flags(X, BN_FLG_CONSTTIME);
if (!BN_mod_exp_mont_consttime
(k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
} else {
if (!BN_mod_inverse(k, k, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
}
if (!BN_nnmod(x, x, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB);
goto err;
}
} while (BN_is_zero(x));
/* clear old values if necessary */
if (*kp != NULL)
BN_clear_free(*kp);
if (*xp != NULL)
BN_clear_free(*xp);
/* save the pre-computed values */
*kp = k;
*xp = x;
ret = 1;
err:
if (!ret) {
if (k) BN_clear_free(k);
if (x) BN_clear_free(x);
}
if (ctx_in == NULL) BN_CTX_free(ctx);
if (order) BN_free(order);
if (point) EC_POINT_free(point);
return(ret);
/* clear old values if necessary */
if (*rp != NULL)
BN_clear_free(*rp);
if (*kinvp != NULL)
BN_clear_free(*kinvp);
/* save the pre-computed values */
*rp = r;
*kinvp = k;
ret = 1;
err:
if (!ret) {
if (k != NULL)
BN_clear_free(k);
if (r != NULL)
BN_clear_free(r);
}
if (ctx_in == NULL)
BN_CTX_free(ctx);
if (order != NULL)
BN_free(order);
if (tmp_point != NULL)
EC_POINT_free(tmp_point);
if (X)
BN_clear_free(X);
return (ret);
}
static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_k, const BIGNUM *in_x, EC_KEY *ec_key)
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_kinv, const BIGNUM *in_r,
EC_KEY *eckey)
{
int ok = 0;
ECDSA_SIG *ret = NULL;
ECDSA_DATA *ecdsa;
const EC_GROUP *ec_group;
const BIGNUM *priv_key;
const BIGNUM *ck;
BIGNUM *k = NULL;
BN_CTX *ctx = NULL;
BIGNUM *order = NULL;
BIGNUM *e = NULL;
BIGNUM *bn = NULL;
int i;
int ok = 0, i;
BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL;
const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
ECDSA_SIG *ret;
ECDSA_DATA *ecdsa;
const BIGNUM *priv_key;
ecdsa = ecdsa_check(ec_key);
ec_group = EC_KEY_get0_group(ec_key);
priv_key = EC_KEY_get0_private_key(ec_key);
if (!ec_group || !priv_key || !ecdsa) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
ecdsa = ecdsa_check(eckey);
group = EC_KEY_get0_group(eckey);
priv_key = EC_KEY_get0_private_key(eckey);
if (!(ret = ECDSA_SIG_new())) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
return NULL;
}
ctx = BN_CTX_new();
order = BN_new();
e = BN_new();
bn = BN_new();
if (!ctx || !order || !e || !bn) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_GROUP_get_order(ec_group, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
if (group == NULL || priv_key == NULL || ecdsa == NULL) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
/* convert dgst to e */
i = BN_num_bits(order);
if (8 * dgst_len > i) {
dgst_len = (i + 7)/8;
}
if (!BN_bin2bn(dgst, dgst_len, e)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if ((8 * dgst_len > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
ret = ECDSA_SIG_new();
if (!ret) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
return NULL;
}
s = ret->s;
do {
/* use or compute k and (kG).x */
if (!in_k || !in_x) {
if (!sm2_sign_setup(ec_key, ctx, &k, &ret->r)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
goto err;
}
ck = k;
} else {
ck = in_k;
if (!BN_copy(ret->r, in_x)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
/* 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;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
i = BN_num_bits(order);
/*
* Need to truncate digest if it is too long: first truncate whole bytes.
*/
if (8 * dgst_len > i)
dgst_len = (i + 7) / 8;
if (!BN_bin2bn(dgst, dgst_len, m)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
/* If still too long truncate remaining bits with a shift */
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
do {
if (in_kinv == NULL || in_r == NULL) {
if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB);
goto err;
}
ckinv = kinv;
} else {
ckinv = in_kinv;
if (BN_copy(ret->r, in_r) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
}
/* check r != 0 && r + k != n */
if (BN_is_zero(ret->r) || BN_is_zero(bn)) {
if (in_k && in_x) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
goto err;
} else
continue;
}
if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_add_quick(s, tmp, m, order)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (BN_is_zero(s)) {
/*
* if kinv and r have been supplied by the caller don't to
* generate new kinv and r values
*/
if (in_kinv != NULL && in_r != NULL) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,
ECDSA_R_NEED_NEW_SETUP_VALUES);
goto err;
}
} else
/* s != 0 => we have a valid signature */
break;
}
while (1);
/* s = ((1 + d)^-1 * (k - rd)) mod n */
if (!BN_one(bn)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_add(ret->s, priv_key, bn, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_inverse(ret->s, ret->s, order, ctx)) {
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;
}
if (!BN_mod_sub(bn, ck, bn, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(ret->s, ret->s, bn, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
/* check s != 0 */
if (BN_is_zero(ret->s)) {
if (in_k && in_x) {
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
goto err;
}
} else
break;
} while (1);
ok = 1;
err:
if (!ok) {
ECDSA_SIG_free(ret);
ret = NULL;
}
if (k) BN_free(k);
if (ctx) BN_CTX_free(ctx);
if (order) BN_free(order);
if (e) BN_free(e);
if (bn) BN_free(bn);
return ret;
ok = 1;
err:
if (!ok) {
ECDSA_SIG_free(ret);
ret = NULL;
}
if (ctx)
BN_CTX_free(ctx);
if (m)
BN_clear_free(m);
if (tmp)
BN_clear_free(tmp);
if (order)
BN_free(order);
if (kinv)
BN_clear_free(kinv);
return ret;
}
int sm2_do_verify(const unsigned char *dgst, int dgstlen,
const ECDSA_SIG *sig, EC_KEY *ec_key)
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey)
{
int ret = -1;
const EC_GROUP *ec_group;
const EC_POINT *pub_key;
EC_POINT *point = NULL;
BN_CTX *ctx = NULL;
BIGNUM *order = NULL;
BIGNUM *e = NULL;
BIGNUM *t = NULL;
int i;
int ret = -1, i;
BN_CTX *ctx;
BIGNUM *order, *u1, *u2, *m, *X;
EC_POINT *point = NULL;
const EC_GROUP *group;
const EC_POINT *pub_key;
if (!sig || !ec_key ||
!(ec_group = EC_KEY_get0_group(ec_key)) ||
!(pub_key = EC_KEY_get0_public_key(ec_key))) {
/* check input values */
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
return -1;
}
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
return -1;
}
ctx = BN_CTX_new();
if (!ctx) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
return -1;
}
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
u1 = BN_CTX_get(ctx);
u2 = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
if (!X) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
ctx = BN_CTX_new();
order = BN_new();
e = BN_new();
t = BN_new();
if (!EC_GROUP_get_order(group, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if (!ctx || !order || !e || !t) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_GROUP_get_order(ec_group, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
ret = 0; /* signature is invalid */
goto err;
}
/* calculate tmp1 = inv(S) mod order */
if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* digest -> m */
i = BN_num_bits(order);
/*
* Need to truncate digest if it is too long: first truncate whole bytes.
*/
if (8 * dgst_len > i)
dgst_len = (i + 7) / 8;
if (!BN_bin2bn(dgst, dgst_len, m)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* If still too long truncate remaining bits with a shift */
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* u1 = m * tmp mod order */
if (!BN_mod_mul(u1, m, u2, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* u2 = r * w mod q */
if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* check r, s in [1, n-1] and r + s != 0 (mod n) */
if (BN_is_zero(sig->r) ||
BN_is_negative(sig->r) ||
BN_ucmp(sig->r, order) >= 0 ||
BN_is_zero(sig->s) ||
BN_is_negative(sig->s) ||
BN_ucmp(sig->s, order) >= 0) {
if ((point = EC_POINT_new(group)) == NULL) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
}
#ifndef OPENSSL_NO_EC2M
else { /* NID_X9_62_characteristic_two_field */
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
ret = 0;
goto err;
}
/* check t = r + s != 0 */
if (!BN_mod_add(t, sig->r, sig->s, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
if (BN_is_zero(t)) {
ret = 0;
goto err;
}
/* convert digest to e */
i = BN_num_bits(order);
if (8 * dgstlen > i) {
dgstlen = (i + 7)/8;
}
if (!BN_bin2bn(dgst, dgstlen, e)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
if ((8 * dgstlen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* compute (x, y) = sG + tP, P is pub_key */
if (!(point = EC_POINT_new(ec_group))) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(ec_group, point, sig->s, pub_key, t, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(ec_group, point, t, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
} else /* NID_X9_62_characteristic_two_field */ {
if (!EC_POINT_get_affine_coordinates_GF2m(ec_group, point, t, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
}
if (!BN_nnmod(t, t, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* check (sG + tP).x + e == sig.r */
if (!BN_mod_add(t, t, e, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
ret = (BN_ucmp(t, sig->r) == 0);
err:
if (point) EC_POINT_free(point);
if (order) BN_free(order);
if (e) BN_free(e);
if (t) BN_free(t);
if (ctx) BN_CTX_free(ctx);
return ret;
if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
}
#endif
if (!BN_nnmod(u1, X, order, ctx)) {
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* if the signature is correct u1 is equal to sig->r */
ret = (BN_ucmp(u1, sig->r) == 0);
err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
if (point)
EC_POINT_free(point);
return ret;
}

View File

@@ -1,297 +0,0 @@
/* crypto/ecdsa/ecs_sm2.c */
#include "ecs_locl.h"
#include <openssl/err.h>
#include <openssl/obj_mac.h>
#include <openssl/bn.h>
static ECDSA_SIG *sm2dsa_do_sign(const unsigned char *dgst, int dlen, const BIGNUM *, const BIGNUM *, EC_KEY *eckey);
static int sm2dsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
static int sm2dsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, EC_KEY *eckey);
static ECDSA_METHOD sm2dsa_meth = {
"SM2 DSA method",
sm2_do_sign,
sm2_sign_setup,
sm2_do_verify,
#if 0
NULL, /* init */
NULL, /* finish */
#endif
0, /* flags */
NULL /* app_data */
};
const ECDSA_METHOD *ECDSA_SM2DSA(void)
{
return &openssl_ecdsa_meth;
}
static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
BIGNUM **rp)
{
return 1;
}
static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
{
int ok = 0, i;
BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
ECDSA_SIG *ret;
ECDSA_DATA *ecdsa;
const BIGNUM *priv_key;
ecdsa = ecdsa_check(eckey);
group = EC_KEY_get0_group(eckey);
priv_key = EC_KEY_get0_private_key(eckey);
if (group == NULL || priv_key == NULL || ecdsa == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
ret = ECDSA_SIG_new();
if (!ret)
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
return NULL;
}
s = ret->s;
if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
i = BN_num_bits(order);
/* Need to truncate digest if it is too long: first truncate whole
* bytes.
*/
if (8 * dgst_len > i)
dgst_len = (i + 7)/8;
if (!BN_bin2bn(dgst, dgst_len, m))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
/* If still too long truncate remaining bits with a shift */
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
do
{
if (in_kinv == NULL || in_r == NULL)
{
if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB);
goto err;
}
ckinv = kinv;
}
else
{
ckinv = in_kinv;
if (BN_copy(ret->r, in_r) == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_add_quick(s, tmp, m, order))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(s, s, ckinv, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
if (BN_is_zero(s))
{
/* if kinv and r have been supplied by the caller
* don't to generate new kinv and r values */
if (in_kinv != NULL && in_r != NULL)
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES);
goto err;
}
}
else
/* s != 0 => we have a valid signature */
break;
}
while (1);
ok = 1;
err:
if (!ok)
{
ECDSA_SIG_free(ret);
ret = NULL;
}
if (ctx)
BN_CTX_free(ctx);
if (m)
BN_clear_free(m);
if (tmp)
BN_clear_free(tmp);
if (order)
BN_free(order);
if (kinv)
BN_clear_free(kinv);
return ret;
}
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey)
{
int ret = -1, i;
BN_CTX *ctx;
BIGNUM *order, *u1, *u2, *m, *X;
EC_POINT *point = NULL;
const EC_GROUP *group;
const EC_POINT *pub_key;
/* check input values */
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS);
return -1;
}
ctx = BN_CTX_new();
if (!ctx)
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
return -1;
}
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
u1 = BN_CTX_get(ctx);
u2 = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
if (!X)
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0)
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE);
ret = 0; /* signature is invalid */
goto err;
}
/* calculate tmp1 = inv(S) mod order */
if (!BN_mod_inverse(u2, sig->s, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* digest -> m */
i = BN_num_bits(order);
/* Need to truncate digest if it is too long: first truncate whole
* bytes.
*/
if (8 * dgst_len > i)
dgst_len = (i + 7)/8;
if (!BN_bin2bn(dgst, dgst_len, m))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* If still too long truncate remaining bits with a shift */
if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* u1 = m * tmp mod order */
if (!BN_mod_mul(u1, m, u2, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* u2 = r * w mod q */
if (!BN_mod_mul(u2, sig->r, u2, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
if ((point = EC_POINT_new(group)) == NULL)
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
{
if (!EC_POINT_get_affine_coordinates_GFp(group,
point, X, NULL, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
}
else /* NID_X9_62_characteristic_two_field */
{
if (!EC_POINT_get_affine_coordinates_GF2m(group,
point, X, NULL, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
}
if (!BN_nnmod(u1, X, order, ctx))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
/* if the signature is correct u1 is equal to sig->r */
ret = (BN_ucmp(u1, sig->r) == 0);
err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
if (point)
EC_POINT_free(point);
return ret;
}

92
crypto/evp/a.c Normal file
View File

@@ -0,0 +1,92 @@
/* crypto/evp/e_sms4.c */
#include <stdio.h>
#include "../cryptlib.h"
#ifndef OPENSSL_NO_SMS4
#include <openssl/evp.h>
#include <openssl/objects.h>
#include "evp_locl.h"
#include <openssl/sms4.h>
#define SMS4_IV_LENGTH SMS4_BLOCK_SIZE
typedef struct {
sms4_key_t ks;
} EVP_SMS4_KEY;
static int sms4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
if (!enc) {
if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
enc = 1;
else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
enc = 1; //encrypt key == decrypt key
}
if (enc)
sms4_set_encrypt_key(ctx->cipher_data, key);
else sms4_set_decrypt_key(ctx->cipher_data, key);
return 1;
}
static int
sms4_cbc_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, const unsigned char *in, size_t inl)
{
while (inl >= ((size_t) 1 << (sizeof(long) * 8 - 2))) {
sms4_cbc_encrypt(in, out, (long)((size_t) 1 << (sizeof(long) * 8 - 2)), &((EVP_SMS4_KEY *) ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
inl -= ((size_t) 1 << (sizeof(long) * 8 - 2));
in += ((size_t) 1 << (sizeof(long) * 8 - 2));
out += ((size_t) 1 << (sizeof(long) * 8 - 2));
} if (inl)
sms4_cbc_encrypt(in, out, (long)inl, &((EVP_SMS4_KEY *) ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
return 1;
} static int sms4_cfb128_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, const unsigned char *in, size_t inl){
size_t chunk = ((size_t) 1 << (sizeof(long) * 8 - 2));
if (128 == 1)
chunk >>= 3;
if (inl < chunk)
chunk = inl;
while (inl && inl >= chunk) {
sms4_cfb128_encrypt(in, out, (long)((128 == 1) && !(ctx->flags & 0x2000) ? inl * 8 : inl), &((EVP_SMS4_KEY *) ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
inl -= chunk;
in += chunk;
out += chunk;
if (inl < chunk)
chunk = inl;
} return 1;
} static int sms4_ecb_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, const unsigned char *in, size_t inl){
size_t i , bl;
bl = ctx->cipher->block_size;
if (inl < bl)
return 1;
inl -= bl;
for (i = 0; i <= inl; i += bl)
sms4_ecb_encrypt(in + i, out + i, &((EVP_SMS4_KEY *) ctx->cipher_data)->ks, ctx->encrypt);
return 1;
} static int sms4_ofb_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out, const unsigned char *in, size_t inl){
while (inl >= ((size_t) 1 << (sizeof(long) * 8 - 2))) {
sms4_ofb128_encrypt(in, out, (long)((size_t) 1 << (sizeof(long) * 8 - 2)), &((EVP_SMS4_KEY *) ctx->cipher_data)->ks, ctx->iv, &ctx->num);
inl -= ((size_t) 1 << (sizeof(long) * 8 - 2));
in += ((size_t) 1 << (sizeof(long) * 8 - 2));
out += ((size_t) 1 << (sizeof(long) * 8 - 2));
} if (inl)
sms4_ofb128_encrypt(in, out, (long)inl, &((EVP_SMS4_KEY *) ctx->cipher_data)->ks, ctx->iv, &ctx->num);
return 1;
} static const EVP_CIPHER sms4_cbc = {978, 16, 16, 16, 0 | 0x2, sms4_init_key, sms4_cbc_cipher, ((void *)0), sizeof(EVP_SMS4_KEY), ((void *)0), ((void *)0), ((void *)0), ((void *)0)};
const EVP_CIPHER *EVP_sms4_cbc(void){
return &sms4_cbc;
} static const EVP_CIPHER sms4_cfb128 = {982, 1, 16, 16, 0 | 0x3, sms4_init_key, sms4_cfb128_cipher, ((void *)0), sizeof(EVP_SMS4_KEY), ((void *)0), ((void *)0), ((void *)0), ((void *)0)};
const EVP_CIPHER *EVP_sms4_cfb128(void){
return &sms4_cfb128;
} static const EVP_CIPHER sms4_ofb = {981, 1, 16, 16, 0 | 0x4, sms4_init_key, sms4_ofb_cipher, ((void *)0), sizeof(EVP_SMS4_KEY), ((void *)0), ((void *)0), ((void *)0), ((void *)0)};
const EVP_CIPHER *EVP_sms4_ofb(void){
return &sms4_ofb;
} static const EVP_CIPHER sms4_ecb = {977, 16, 16, 0, 0 | 0x1, sms4_init_key, sms4_ecb_cipher, ((void *)0), sizeof(EVP_SMS4_KEY), ((void *)0), ((void *)0), ((void *)0), ((void *)0)};
const EVP_CIPHER *
EVP_sms4_ecb(void)
{
return &sms4_ecb;
}
#endif

3
crypto/evp/a.c.BAK Normal file
View File

@@ -0,0 +1,3 @@
static int sms4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) {
while(inl>=((size_t)1<<(sizeof(long)*8-2))) { sms4_cbc_encrypt(in, out, (long)((size_t)1<<(sizeof(long)*8-2)), &((EVP_SMS4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); inl-=((size_t)1<<(sizeof(long)*8-2)); in +=((size_t)1<<(sizeof(long)*8-2)); out+=((size_t)1<<(sizeof(long)*8-2)); } if (inl) sms4_cbc_encrypt(in, out, (long)inl, &((EVP_SMS4_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt); return 1;} static int sms4_cfb128_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t chunk=((size_t)1<<(sizeof(long)*8-2)); if (128==1) chunk>>=3; if (inl<chunk) chunk=inl; while(inl && inl>=chunk) { sms4_cfb128_encrypt(in, out, (long)((128==1) && !(ctx->flags & 0x2000) ?inl*8:inl), &((EVP_SMS4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt); inl-=chunk; in +=chunk; out+=chunk; if(inl<chunk) chunk=inl; } return 1;} static int sms4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { size_t i, bl; bl = ctx->cipher->block_size; if(inl < bl) return 1; inl -= bl; for(i=0; i <= inl; i+=bl) sms4_ecb_encrypt(in + i, out + i, &((EVP_SMS4_KEY *)ctx->cipher_data)->ks, ctx->encrypt); return 1;} static int sms4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) { while(inl>=((size_t)1<<(sizeof(long)*8-2))) { sms4_ofb128_encrypt(in, out, (long)((size_t)1<<(sizeof(long)*8-2)), &((EVP_SMS4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); inl-=((size_t)1<<(sizeof(long)*8-2)); in +=((size_t)1<<(sizeof(long)*8-2)); out+=((size_t)1<<(sizeof(long)*8-2)); } if (inl) sms4_ofb128_encrypt(in, out, (long)inl, &((EVP_SMS4_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num); return 1;} static const EVP_CIPHER sms4_cbc = { 978, 16, 16, 16, 0 | 0x2, sms4_init_key, sms4_cbc_cipher, ((void*)0), sizeof(EVP_SMS4_KEY), ((void*)0), ((void*)0), ((void*)0), ((void*)0) }; const EVP_CIPHER *EVP_sms4_cbc(void) { return &sms4_cbc; } static const EVP_CIPHER sms4_cfb128 = { 982, 1, 16, 16, 0 | 0x3, sms4_init_key, sms4_cfb128_cipher, ((void*)0), sizeof(EVP_SMS4_KEY), ((void*)0), ((void*)0), ((void*)0), ((void*)0) }; const EVP_CIPHER *EVP_sms4_cfb128(void) { return &sms4_cfb128; } static const EVP_CIPHER sms4_ofb = { 981, 1, 16, 16, 0 | 0x4, sms4_init_key, sms4_ofb_cipher, ((void*)0), sizeof(EVP_SMS4_KEY), ((void*)0), ((void*)0), ((void*)0), ((void*)0) }; const EVP_CIPHER *EVP_sms4_ofb(void) { return &sms4_ofb; } static const EVP_CIPHER sms4_ecb = { 977, 16, 16, 0, 0 | 0x1, sms4_init_key, sms4_ecb_cipher, ((void*)0), sizeof(EVP_SMS4_KEY), ((void*)0), ((void*)0), ((void*)0), ((void*)0) }; const EVP_CIPHER *EVP_sms4_ecb(void) { return &sms4_ecb; }

View File

@@ -165,9 +165,9 @@ void OpenSSL_add_all_ciphers(void)
#ifndef OPENSSL_NO_SMS4
EVP_add_cipher(EVP_sms4_ecb());
//EVP_add_cipher(EVP_sms4_cfb128());
//EVP_add_cipher(EVP_sms4_ofb());
EVP_add_cipher(EVP_sms4_cbc());
EVP_add_cipher(EVP_sms4_ofb());
EVP_add_cipher(EVP_sms4_cfb128());
EVP_add_cipher_alias(SN_sms4_cbc,"SMS4");
EVP_add_cipher_alias(SN_sms4_cbc,"sms4");
#endif

View File

@@ -211,6 +211,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
type = ctx->digest;
}
#endif
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (ctx->digest != type) {
if (ctx->digest && ctx->digest->ctx_size)
OPENSSL_free(ctx->md_data);
@@ -218,6 +219,7 @@ 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) {
EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
return 0;
@@ -229,6 +231,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
#endif
if (ctx->pctx) {
int r;
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
if (r <= 0 && (r != -2))
@@ -245,6 +248,7 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
return 0;
}
#endif
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
return ctx->digest->init(ctx);
}

View File

@@ -8,30 +8,197 @@
#include "evp_locl.h"
#include <openssl/sms4.h>
static int sms4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv,int enc);
typedef struct
{
#define SMS4_IV_LENGTH SMS4_BLOCK_SIZE
typedef struct {
sms4_key_t ks;
} EVP_SMS4_KEY;
IMPLEMENT_BLOCK_CIPHER(sms4, ks, sms4, EVP_SMS4_KEY, NID_sms4,
16, 16, 16, 128, 0, sms4_init_key, 0, 0, 0, 0)
} EVP_SMS4_KEY;
static int sms4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
if(!enc) {
if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) enc = 1;
else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) enc = 1; //encrypt key == decrypt key
const unsigned char *iv, int enc)
{
if (!enc) {
if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE)
enc = 1;
else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE)
enc = 1; //encrypt key == decrypt key
}
if (enc)
sms4_set_encrypt_key(ctx->cipher_data, key);
else //ecb, cbc
sms4_set_decrypt_key(ctx->cipher_data, key);
else sms4_set_decrypt_key(ctx->cipher_data, key);
return 1;
}
IMPLEMENT_BLOCK_CIPHER(sms4, ks, sms4, EVP_SMS4_KEY, NID_sms4,
SMS4_BLOCK_SIZE, SMS4_KEY_LENGTH, SMS4_IV_LENGTH, 128, 0,
sms4_init_key, NULL, NULL, NULL, NULL)
#if 0
static int sms4_ctr_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out,
const unsigned char *in, size_t inlen)
{
unsigned int num = ctx->num;
EVP_SMS4_KEY *sms4 = (EVP_SMS4_KEY *)ctx->cipher_data;
CRYPTO_ctr128_encrypt_ctr32(in, out, inlen, &sms4->ks, ctx->iv, ctx->buf,
&num, sms4_ctr_encrypt);
ctx->num = (size_t)num;
return 1;
}
const EVP_CIPHER sms4_ctr = {
NID_sms4_ctr,
SMS4_BLOCK_SIZE,
SMS4_KEY_LENGTH,
SMS4_IV_LENGTH,
0,
sms4_init_key,
sms4_ctr_cipher,
NULL, /* cleanup() */
sizeof(EVP_SMS4_CTX),
NULL, /* set_asn1_parameters() */
NULL, /* get_asn1_parameters() */
NULL, /* ctrl() */
NULL /* app_data */
};
const EVP_CIPHER *EVP_sms4_ctr(void)
{
return &sms4_ctr;
}
static int sms4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
int mode;
mode = ctx->cipher->flags & EVP_CIPH_MODE;
if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) {
ret = sms4_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
sms4->block = (block128_f)sms4_decrypt;
sms4->stream.cbc = (mode == EVP_CIPH_CBC_MODE ?
(cbc128_f)sms4_cbc_encrypt : NULL);
} else {
ret = sms4_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
sms4->block = (block128_f)sms4_encrypt;
if (mode == EVP_CIPH_CBC_MODE) {
sms4->stream.cbc = (cbc128_f)sms4_cbc_encrypt;
} else if (mode == EVP_CIPH_CTR_MODE) {
sms4->stream.ctr = (ctr128_f)sms4_ctr32_encrypt_blocks;
} else {
sms4->stream.cbc = NULL;
}
}
if (ret < 0) {
return 0;
}
return 1;
}
typedef struct {
sms4_key_t ks;
int key_is_inited;
int iv_is_inited;
GCM128_CONTEXT gcm;
unsigned char *iv;
int ivlen;
int taglen;
int iv_gen;
ctr128_f ctr;
} EVP_SMS4_GCM_CTX;
static int sms4_gcm_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
{
switch (type) {
case EVP_CTRL_INIT:
case EVP_CTRL_GCM_SET_IVLEN:
case EVP_CTRL_GCM_SET_TAG:
case EVP_CTRL_GCM_GET_TAG:
case EVP_CTRL_GCM_SET_IV_FIXED:
case EVP_CTRL_GCM_IV_GEN:
case EVP_CTRL_GCM_SET_IV_INV:
case EVP_CTRL_COPY:
default:
return -1;
}
}
typedef struct {
union {
double align;
sms4_key_t ks;
} ks;
unsigned char *iv;
} EVP_SMS4_WRAP_CTX;
static int sms4_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
return -1;
}
static int sms4_wrap_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
const unsigned char *in, size_t inlen)
{
return -1;
}
#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \
| EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
| EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1)
const EVP_CIPHER sms4_wrap = {
NID_sms4_wrap,
SMS4_WRAP_BLOCK_SIZE,
SMS4_KEY_LENGTH,
SMS4_WRAP_IV_LENGTH,
WRAP_FLAGS,
sms4_wrap_init_key,
sms4_wrap_do_cipher,
NULL, /* cleanup() */
sizeof(EVP_SMS4_WRAP_CTX),
NULL, /* set_asn1_parameters() */
NULL, /* get_asn1_parameters() */
NULL, /* ctrl() */
NULL /* app_data */
};
const EVP_CIPHER *EVP_sms4_wrap(void)
{
return &sms4_wrap;
}
#endif
#endif

View File

@@ -657,6 +657,13 @@ int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
#ifndef OPENSSL_NO_GMSSL
int EVP_Encrypt_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outlen,
const unsigned char *in, int inlen);
int EVP_Decrypt_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outlen,
const unsigned char *in, int inlen);
#endif
int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
EVP_PKEY *pkey);
@@ -842,6 +849,11 @@ const EVP_CIPHER *EVP_sms4_ecb(void);
const EVP_CIPHER *EVP_sms4_cbc(void);
const EVP_CIPHER *EVP_sms4_cfb128(void);
const EVP_CIPHER *EVP_sms4_ofb128(void);
const EVP_CIPHER *EVP_sms4_ctr(void);
const EVP_CIPHER *EVP_sms4_ccm(void);
const EVP_CIPHER *EVP_sms4_gcm(void);
const EVP_CIPHER *EVP_sms4_xts(void);
const EVP_CIPHER *EVP_sms4_wrap(void);
#define EVP_sm4_ecb EVP_sms4_ecb
#define EVP_sm4_cbc EVP_sms4_cbc
#define EVP_sm4_cfb128 EVP_sms4_cfb128
@@ -1484,6 +1496,11 @@ void ERR_load_EVP_strings(void);
# define EVP_F_RC2_MAGIC_TO_METH 109
# define EVP_F_RC5_CTRL 125
# ifndef OPENSSL_NO_GMSSL
# define EVP_F_EVP_ENCRYPT_EX 200
# define EVP_F_EVP_DECRYPT_EX 201
# endif
/* Reason codes. */
# define EVP_R_AES_IV_SETUP_FAILED 162
# define EVP_R_AES_KEY_SETUP_FAILED 143

View File

@@ -664,3 +664,19 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
return 1;
}
#ifndef OPENSSL_NO_GMSSL
int EVP_Encrypt_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outlen,
const unsigned char *in, int inlen)
{
return 0;
}
int EVP_Decrypt_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outlen,
const unsigned char *in, int inlen)
{
return 1;
}
#endif /* GMSSL */

View File

@@ -152,6 +152,10 @@ static ERR_STRING_DATA EVP_str_functs[] = {
{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"},
{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
{ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"},
#ifndef OPENSSL_NO_GMSSL
{ERR_FUNC(EVP_F_EVP_ENCRYPT_EX), "EVP_Encrypt_ex"},
{ERR_FUNC(EVP_F_EVP_DECRYPT_EX), "EVP_Decrypt_ex"},
#endif
{0, NULL}
};

0
crypto/evp/m_sha3.c Normal file
View File

View File

@@ -87,6 +87,8 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
}
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (ver) {
if (ctx->pctx->pmeth->verifyctx_init) {
if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0)
@@ -102,12 +104,16 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
} else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
return 0;
}
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0)
return 0;
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (pctx)
*pctx = ctx->pctx;
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)
return 1;
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
if (!EVP_DigestInit_ex(ctx, type, e))
return 0;
return 1;

View File

@@ -7,21 +7,24 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/sm3.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
static int init(EVP_MD_CTX *ctx)
{ return sm3_init(ctx->md_data); }
{
return sm3_init(ctx->md_data);
}
static int update(EVP_MD_CTX *ctx, const void *data, size_t count)
{ return sm3_update(ctx->md_data, data, count); }
static int update(EVP_MD_CTX *ctx, const void *in, size_t inlen)
{
return sm3_update(ctx->md_data, in, inlen);
}
static int final(EVP_MD_CTX *ctx, unsigned char *md)
{ return sm3_final(ctx->md_data, md); }
static const EVP_MD sm3_md=
{
return sm3_final(ctx->md_data, md);
}
static const EVP_MD sm3_md = {
NID_sm3,
NID_sm2sign_with_sm3,
SM3_DIGEST_LENGTH,
@@ -33,11 +36,12 @@ static const EVP_MD sm3_md=
NULL,
EVP_PKEY_RSA_method,
SM3_BLOCK_SIZE,
sizeof(EVP_MD *)+sizeof(sm3_ctx_t),
sizeof(EVP_MD *) + sizeof(sm3_ctx_t),
};
const EVP_MD *EVP_sm3(void)
{
return(&sm3_md);
return &sm3_md;
}
#endif

View File

@@ -62,12 +62,12 @@
* [including the GNU Public Licence.]
*/
#define NUM_NID 1011
#define NUM_SN 995
#define NUM_LN 995
#define NUM_OBJ 934
#define NUM_NID 1031
#define NUM_SN 1009
#define NUM_LN 1009
#define NUM_OBJ 947
static const unsigned char lvalues[6560]={
static const unsigned char lvalues[6667]={
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */
@@ -966,8 +966,8 @@ static const unsigned char lvalues[6560]={
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x77, /* [6336] OBJ_sm2sign_with_sha256 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x01, /* [6344] OBJ_sms4_ecb */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x02, /* [6352] OBJ_sms4_cbc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04, /* [6360] OBJ_sms4_ofb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x03, /* [6368] OBJ_sms4_cfb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x03, /* [6360] OBJ_sms4_ofb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04, /* [6368] OBJ_sms4_cfb128 */
0x2B,0x81,0x04,0x01,0x07, /* [6376] OBJ_ecies_recommendedParameters */
0x2B,0x81,0x04,0x01,0x08, /* [6381] OBJ_ecies_specifiedParameters */
0x2B,0x81,0x04,0x01,0x11,0x00, /* [6386] OBJ_x9_63_kdf */
@@ -985,17 +985,30 @@ static const unsigned char lvalues[6560]={
0x2B,0x81,0x04,0x01,0x17, /* [6456] OBJ_hmac_half_ecies */
0x2B,0x81,0x04,0x01,0x18,0x00, /* [6461] OBJ_cmac_aes128_ecies */
0x2B,0x81,0x04,0x01,0x18,0x01, /* [6467] OBJ_cmac_aes192_ecies */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x81,0x48, /* [6473] OBJ_zuc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x65, /* [6481] OBJ_sm6 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x66, /* [6488] OBJ_sm1 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x67, /* [6495] OBJ_ssf33 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x69, /* [6502] OBJ_sm7 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x6A, /* [6509] OBJ_sm8 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x81,0x49, /* [6516] OBJ_sm5 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E, /* [6524] OBJ_sm9 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x01,/* [6532] OBJ_sm9sign */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x02,/* [6541] OBJ_sm9keyagreement */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x03,/* [6550] OBJ_sm9encrypt */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x86,0x20, /* [6473] OBJ_zuc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x69, /* [6481] OBJ_sm7 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x6A, /* [6488] OBJ_sm8 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x81,0x49, /* [6495] OBJ_sm5 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x01,/* [6503] OBJ_sm9sign */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x02,/* [6512] OBJ_sm9keyagreement */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E,0x03,/* [6521] OBJ_sm9encrypt */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x65,0x01, /* [6530] OBJ_sm6_ecb */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x65,0x02, /* [6538] OBJ_sm6_cbc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x65,0x03, /* [6546] OBJ_sm6_ofb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x65,0x04, /* [6554] OBJ_sm6_cfb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x66,0x01, /* [6562] OBJ_sm1_ecb */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x66,0x02, /* [6570] OBJ_sm1_cbc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x66,0x03, /* [6578] OBJ_sm1_ofb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x66,0x04, /* [6586] OBJ_sm1_cfb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x67,0x01, /* [6594] OBJ_ssf33_ecb */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x67,0x02, /* [6602] OBJ_ssf33_cbc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x67,0x03, /* [6610] OBJ_ssf33_ofb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04, /* [6618] OBJ_ssf33_cfb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2E, /* [6626] OBJ_id_sm9PublicKey */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x05, /* [6634] OBJ_sms4_ctr */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x06, /* [6642] OBJ_sms4_gcm */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x07, /* [6650] OBJ_sms4_ccm */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x08, /* [6658] OBJ_sms4_xts */
};
static const ASN1_OBJECT nid_objs[NUM_NID]={
@@ -2618,17 +2631,38 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={
{"cmac-aes192-ecies","cmac-aes192-ecies",NID_cmac_aes192_ecies,6,
&(lvalues[6467]),0},
{"ZUC","zuc",NID_zuc,8,&(lvalues[6473]),0},
{"SM6","sm6",NID_sm6,7,&(lvalues[6481]),0},
{"SM1","sm1",NID_sm1,7,&(lvalues[6488]),0},
{"SSF33","ssf33",NID_ssf33,7,&(lvalues[6495]),0},
{"SM7","sm7",NID_sm7,7,&(lvalues[6502]),0},
{"SM8","sm8",NID_sm8,7,&(lvalues[6509]),0},
{"SM5","sm5",NID_sm5,8,&(lvalues[6516]),0},
{"SM9","sm9",NID_sm9,8,&(lvalues[6524]),0},
{"sm9sign","sm9sign",NID_sm9sign,9,&(lvalues[6532]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{"NULL","NULL",NID_sm7,7,&(lvalues[6481]),0},
{"NULL","NULL",NID_sm8,7,&(lvalues[6488]),0},
{"SM5","sm5",NID_sm5,8,&(lvalues[6495]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{"sm9sign","sm9sign",NID_sm9sign,9,&(lvalues[6503]),0},
{"sm9keyagreement","sm9keyagreement",NID_sm9keyagreement,9,
&(lvalues[6541]),0},
{"sm9encrypt","sm9encrypt",NID_sm9encrypt,9,&(lvalues[6550]),0},
&(lvalues[6512]),0},
{"sm9encrypt","sm9encrypt",NID_sm9encrypt,9,&(lvalues[6521]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{"SM6-ECB","sm6-ecb",NID_sm6_ecb,8,&(lvalues[6530]),0},
{"SM6-CBC","sm6-cbc",NID_sm6_cbc,8,&(lvalues[6538]),0},
{"SM6-OFB","sm6-ofb",NID_sm6_ofb128,8,&(lvalues[6546]),0},
{"SM6-CFB","sm6-cfb",NID_sm6_cfb128,8,&(lvalues[6554]),0},
{"SM1-ECB","sm1-ecb",NID_sm1_ecb,8,&(lvalues[6562]),0},
{"SM1-CBC","sm1-cbc",NID_sm1_cbc,8,&(lvalues[6570]),0},
{"SM1-OFB","sm1-ofb",NID_sm1_ofb128,8,&(lvalues[6578]),0},
{"NULL","NULL",NID_sm1_cfb128,8,&(lvalues[6586]),0},
{"SSF33-ECB","ssf33-ecb",NID_ssf33_ecb,8,&(lvalues[6594]),0},
{"SSF33-CBC","ssf33-cbc",NID_ssf33_cbc,8,&(lvalues[6602]),0},
{"SSF33-OFB","ssf33-ofb",NID_ssf33_ofb128,8,&(lvalues[6610]),0},
{"SSF33-CFB","ssf33-cfb",NID_ssf33_cfb128,8,&(lvalues[6618]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{"id-sm9PublicKey","id-sm9PublicKey",NID_id_sm9PublicKey,8,
&(lvalues[6626]),0},
{"SMS4-CTR","sms4-ctr",NID_sms4_ctr,8,&(lvalues[6634]),0},
{"SMS4-GCM","sms4-gcm",NID_sms4_gcm,8,&(lvalues[6642]),0},
{"SMS4-CCM","sms4-ccm",NID_sms4_ccm,8,&(lvalues[6650]),0},
{"SMS4-XTS","sms4-xts",NID_sms4_xts,8,&(lvalues[6658]),0},
{"SM1-CFB","sm1-cfb",NID_sm1_cfb,0,NULL,0},
};
static const unsigned int sn_objs[NUM_SN]={
@@ -2747,6 +2781,9 @@ static const unsigned int sn_objs[NUM_SN]={
388, /* "Mail" */
393, /* "NULL" */
404, /* "NULL" */
1004, /* "NULL" */
1005, /* "NULL" */
1019, /* "NULL" */
57, /* "Netscape" */
366, /* "Nonce" */
17, /* "O" */
@@ -2814,24 +2851,34 @@ static const unsigned int sn_objs[NUM_SN]={
672, /* "SHA256" */
673, /* "SHA384" */
674, /* "SHA512" */
1002, /* "SM1" */
1017, /* "SM1-CBC" */
1030, /* "SM1-CFB" */
1016, /* "SM1-ECB" */
1018, /* "SM1-OFB" */
974, /* "SM2Sign-with-SHA1" */
975, /* "SM2Sign-with-SHA256" */
973, /* "SM2Sign-with-SM3" */
962, /* "SM3" */
1006, /* "SM5" */
1001, /* "SM6" */
1004, /* "SM7" */
1005, /* "SM8" */
1007, /* "SM9" */
1013, /* "SM6-CBC" */
1015, /* "SM6-CFB" */
1012, /* "SM6-ECB" */
1014, /* "SM6-OFB" */
188, /* "SMIME" */
167, /* "SMIME-CAPS" */
978, /* "SMS4-CBC" */
1028, /* "SMS4-CCM" */
982, /* "SMS4-CFB" */
1026, /* "SMS4-CTR" */
977, /* "SMS4-ECB" */
1027, /* "SMS4-GCM" */
981, /* "SMS4-OFB" */
1029, /* "SMS4-XTS" */
100, /* "SN" */
1003, /* "SSF33" */
1021, /* "SSF33-CBC" */
1023, /* "SSF33-CFB" */
1020, /* "SSF33-ECB" */
1022, /* "SSF33-OFB" */
16, /* "ST" */
143, /* "SXNetID" */
458, /* "UID" */
@@ -3191,6 +3238,7 @@ static const unsigned int sn_objs[NUM_SN]={
322, /* "id-regInfo-certReq" */
321, /* "id-regInfo-utf8Pairs" */
512, /* "id-set" */
1025, /* "id-sm9PublicKey" */
191, /* "id-smime-aa" */
215, /* "id-smime-aa-contentHint" */
218, /* "id-smime-aa-contentIdentifier" */
@@ -3700,6 +3748,9 @@ static const unsigned int ln_objs[NUM_LN]={
649, /* "Microsoft Universal Principal Name" */
393, /* "NULL" */
404, /* "NULL" */
1004, /* "NULL" */
1005, /* "NULL" */
1019, /* "NULL" */
72, /* "Netscape Base Url" */
76, /* "Netscape CA Policy Url" */
74, /* "Netscape CA Revocation Url" */
@@ -4157,6 +4208,7 @@ static const unsigned int ln_objs[NUM_LN]={
314, /* "id-regInfo" */
322, /* "id-regInfo-certReq" */
321, /* "id-regInfo-utf8Pairs" */
1025, /* "id-sm9PublicKey" */
191, /* "id-smime-aa" */
215, /* "id-smime-aa-contentHint" */
218, /* "id-smime-aa-contentIdentifier" */
@@ -4556,7 +4608,10 @@ static const unsigned int ln_objs[NUM_LN]={
454, /* "simpleSecurityObject" */
496, /* "singleLevelQuality" */
968, /* "sm" */
1002, /* "sm1" */
1017, /* "sm1-cbc" */
1030, /* "sm1-cfb" */
1016, /* "sm1-ecb" */
1018, /* "sm1-ofb" */
972, /* "sm2encrypt" */
971, /* "sm2keyagreement" */
958, /* "sm2p256v1" */
@@ -4566,18 +4621,25 @@ static const unsigned int ln_objs[NUM_LN]={
973, /* "sm2sign-with-sm3" */
962, /* "sm3" */
1006, /* "sm5" */
1001, /* "sm6" */
1004, /* "sm7" */
1005, /* "sm8" */
1007, /* "sm9" */
1013, /* "sm6-cbc" */
1015, /* "sm6-cfb" */
1012, /* "sm6-ecb" */
1014, /* "sm6-ofb" */
1010, /* "sm9encrypt" */
1009, /* "sm9keyagreement" */
1008, /* "sm9sign" */
978, /* "sms4-cbc" */
1028, /* "sms4-ccm" */
982, /* "sms4-cfb" */
1026, /* "sms4-ctr" */
977, /* "sms4-ecb" */
1027, /* "sms4-gcm" */
981, /* "sms4-ofb" */
1003, /* "ssf33" */
1029, /* "sms4-xts" */
1021, /* "ssf33-cbc" */
1023, /* "ssf33-cfb" */
1020, /* "ssf33-ecb" */
1022, /* "ssf33-ofb" */
16, /* "stateOrProvinceName" */
660, /* "streetAddress" */
498, /* "subtreeMaximumQuality" */
@@ -4988,9 +5050,6 @@ static const unsigned int obj_objs[NUM_OBJ]={
634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */
635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */
436, /* OBJ_ucl 0 9 2342 19200300 */
1001, /* OBJ_sm6 1 2 156 10197 1 101 */
1002, /* OBJ_sm1 1 2 156 10197 1 102 */
1003, /* OBJ_ssf33 1 2 156 10197 1 103 */
1004, /* OBJ_sm7 1 2 156 10197 1 105 */
1005, /* OBJ_sm8 1 2 156 10197 1 106 */
820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
@@ -5064,18 +5123,34 @@ static const unsigned int obj_objs[NUM_OBJ]={
768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */
759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */
437, /* OBJ_pilot 0 9 2342 19200300 100 */
1012, /* OBJ_sm6_ecb 1 2 156 10197 1 101 1 */
1013, /* OBJ_sm6_cbc 1 2 156 10197 1 101 2 */
1014, /* OBJ_sm6_ofb128 1 2 156 10197 1 101 3 */
1015, /* OBJ_sm6_cfb128 1 2 156 10197 1 101 4 */
1016, /* OBJ_sm1_ecb 1 2 156 10197 1 102 1 */
1017, /* OBJ_sm1_cbc 1 2 156 10197 1 102 2 */
1018, /* OBJ_sm1_ofb128 1 2 156 10197 1 102 3 */
1019, /* OBJ_sm1_cfb128 1 2 156 10197 1 102 4 */
1020, /* OBJ_ssf33_ecb 1 2 156 10197 1 103 1 */
1021, /* OBJ_ssf33_cbc 1 2 156 10197 1 103 2 */
1022, /* OBJ_ssf33_ofb128 1 2 156 10197 1 103 3 */
977, /* OBJ_sms4_ecb 1 2 156 10197 1 104 1 */
978, /* OBJ_sms4_cbc 1 2 156 10197 1 104 2 */
982, /* OBJ_sms4_cfb128 1 2 156 10197 1 104 3 */
981, /* OBJ_sms4_ofb128 1 2 156 10197 1 104 4 */
1000, /* OBJ_zuc 1 2 156 10197 1 200 */
981, /* OBJ_sms4_ofb128 1 2 156 10197 1 104 3 */
982, /* OBJ_sms4_cfb128 1 2 156 10197 1 104 4 */
1023, /* OBJ_ssf33_cfb128 1 2 156 10197 1 104 4 */
1026, /* OBJ_sms4_ctr 1 2 156 10197 1 104 5 */
1027, /* OBJ_sms4_gcm 1 2 156 10197 1 104 6 */
1028, /* OBJ_sms4_ccm 1 2 156 10197 1 104 7 */
1029, /* OBJ_sms4_xts 1 2 156 10197 1 104 8 */
1006, /* OBJ_sm5 1 2 156 10197 1 201 */
958, /* OBJ_sm2p256v1 1 2 156 10197 1 301 */
1007, /* OBJ_sm9 1 2 156 10197 1 302 */
1025, /* OBJ_id_sm9PublicKey 1 2 156 10197 1 302 */
962, /* OBJ_sm3 1 2 156 10197 1 401 */
973, /* OBJ_sm2sign_with_sm3 1 2 156 10197 1 501 */
974, /* OBJ_sm2sign_with_sha1 1 2 156 10197 1 502 */
975, /* OBJ_sm2sign_with_sha256 1 2 156 10197 1 503 */
1000, /* OBJ_zuc 1 2 156 10197 1 800 */
776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */
777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */
779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */

View File

@@ -4276,28 +4276,111 @@
#define NID_sm 968
#define OBJ_sm OBJ_oscca,1L
#define SN_sm6 "SM6"
#define LN_sm6 "sm6"
#define NID_sm6 1001
#define OBJ_sm6 OBJ_sm,101L
#define SN_sm6_ecb "SM6-ECB"
#define LN_sm6_ecb "sm6-ecb"
#define NID_sm6_ecb 1012
#define OBJ_sm6_ecb OBJ_sm,101L,1L
#define SN_sm1 "SM1"
#define LN_sm1 "sm1"
#define NID_sm1 1002
#define OBJ_sm1 OBJ_sm,102L
#define SN_sm6_cbc "SM6-CBC"
#define LN_sm6_cbc "sm6-cbc"
#define NID_sm6_cbc 1013
#define OBJ_sm6_cbc OBJ_sm,101L,2L
#define SN_ssf33 "SSF33"
#define LN_ssf33 "ssf33"
#define NID_ssf33 1003
#define OBJ_ssf33 OBJ_sm,103L
#define SN_sm6_ofb128 "SM6-OFB"
#define LN_sm6_ofb128 "sm6-ofb"
#define NID_sm6_ofb128 1014
#define OBJ_sm6_ofb128 OBJ_sm,101L,3L
#define SN_sm6_cfb128 "SM6-CFB"
#define LN_sm6_cfb128 "sm6-cfb"
#define NID_sm6_cfb128 1015
#define OBJ_sm6_cfb128 OBJ_sm,101L,4L
#define SN_sm1_ecb "SM1-ECB"
#define LN_sm1_ecb "sm1-ecb"
#define NID_sm1_ecb 1016
#define OBJ_sm1_ecb OBJ_sm,102L,1L
#define SN_sm1_cbc "SM1-CBC"
#define LN_sm1_cbc "sm1-cbc"
#define NID_sm1_cbc 1017
#define OBJ_sm1_cbc OBJ_sm,102L,2L
#define SN_sm1_ofb128 "SM1-OFB"
#define LN_sm1_ofb128 "sm1-ofb"
#define NID_sm1_ofb128 1018
#define OBJ_sm1_ofb128 OBJ_sm,102L,3L
#define NID_sm1_cfb128 1019
#define OBJ_sm1_cfb128 OBJ_sm,102L,4L
#define SN_sm1_cfb "SM1-CFB"
#define LN_sm1_cfb "sm1-cfb"
#define NID_sm1_cfb 1030
#define SN_ssf33_ecb "SSF33-ECB"
#define LN_ssf33_ecb "ssf33-ecb"
#define NID_ssf33_ecb 1020
#define OBJ_ssf33_ecb OBJ_sm,103L,1L
#define SN_ssf33_cbc "SSF33-CBC"
#define LN_ssf33_cbc "ssf33-cbc"
#define NID_ssf33_cbc 1021
#define OBJ_ssf33_cbc OBJ_sm,103L,2L
#define SN_ssf33_ofb128 "SSF33-OFB"
#define LN_ssf33_ofb128 "ssf33-ofb"
#define NID_ssf33_ofb128 1022
#define OBJ_ssf33_ofb128 OBJ_sm,103L,3L
#define SN_ssf33_cfb128 "SSF33-CFB"
#define LN_ssf33_cfb128 "ssf33-cfb"
#define NID_ssf33_cfb128 1023
#define OBJ_ssf33_cfb128 OBJ_sm,104L,4L
#define SN_sms4_ecb "SMS4-ECB"
#define LN_sms4_ecb "sms4-ecb"
#define NID_sms4_ecb 977
#define OBJ_sms4_ecb OBJ_sm,104L,1L
#define SN_sms4_cbc "SMS4-CBC"
#define LN_sms4_cbc "sms4-cbc"
#define NID_sms4_cbc 978
#define OBJ_sms4_cbc OBJ_sm,104L,2L
#define SN_sms4_ofb128 "SMS4-OFB"
#define LN_sms4_ofb128 "sms4-ofb"
#define NID_sms4_ofb128 981
#define OBJ_sms4_ofb128 OBJ_sm,104L,3L
#define SN_sms4_cfb128 "SMS4-CFB"
#define LN_sms4_cfb128 "sms4-cfb"
#define NID_sms4_cfb128 982
#define OBJ_sms4_cfb128 OBJ_sm,104L,4L
#define SN_sms4_ctr "SMS4-CTR"
#define LN_sms4_ctr "sms4-ctr"
#define NID_sms4_ctr 1026
#define OBJ_sms4_ctr OBJ_sm,104L,5L
#define SN_sms4_gcm "SMS4-GCM"
#define LN_sms4_gcm "sms4-gcm"
#define NID_sms4_gcm 1027
#define OBJ_sms4_gcm OBJ_sm,104L,6L
#define SN_sms4_ccm "SMS4-CCM"
#define LN_sms4_ccm "sms4-ccm"
#define NID_sms4_ccm 1028
#define OBJ_sms4_ccm OBJ_sm,104L,7L
#define SN_sms4_xts "SMS4-XTS"
#define LN_sms4_xts "sms4-xts"
#define NID_sms4_xts 1029
#define OBJ_sms4_xts OBJ_sm,104L,8L
#define SN_sm7 "SM7"
#define LN_sm7 "sm7"
#define NID_sm7 1004
#define OBJ_sm7 OBJ_sm,105L
#define SN_sm8 "SM8"
#define LN_sm8 "sm8"
#define NID_sm8 1005
#define OBJ_sm8 OBJ_sm,106L
@@ -4322,10 +4405,9 @@
#define NID_sm2encrypt 972
#define OBJ_sm2encrypt OBJ_sm,301L,3L
#define SN_sm9 "SM9"
#define LN_sm9 "sm9"
#define NID_sm9 1007
#define OBJ_sm9 OBJ_sm,302L
#define SN_id_sm9PublicKey "id-sm9PublicKey"
#define NID_id_sm9PublicKey 1025
#define OBJ_id_sm9PublicKey OBJ_sm,302L
#define SN_sm9sign "sm9sign"
#define NID_sm9sign 1008
@@ -4364,27 +4446,7 @@
#define NID_sm2sign_with_sha256 975
#define OBJ_sm2sign_with_sha256 OBJ_sm,503L
#define SN_sms4_ecb "SMS4-ECB"
#define LN_sms4_ecb "sms4-ecb"
#define NID_sms4_ecb 977
#define OBJ_sms4_ecb OBJ_sm,104L,1L
#define SN_sms4_cbc "SMS4-CBC"
#define LN_sms4_cbc "sms4-cbc"
#define NID_sms4_cbc 978
#define OBJ_sms4_cbc OBJ_sm,104L,2L
#define SN_sms4_cfb128 "SMS4-CFB"
#define LN_sms4_cfb128 "sms4-cfb"
#define NID_sms4_cfb128 982
#define OBJ_sms4_cfb128 OBJ_sm,104L,3L
#define SN_sms4_ofb128 "SMS4-OFB"
#define LN_sms4_ofb128 "sms4-ofb"
#define NID_sms4_ofb128 981
#define OBJ_sms4_ofb128 OBJ_sm,104L,4L
#define SN_zuc "ZUC"
#define LN_zuc "zuc"
#define NID_zuc 1000
#define OBJ_zuc OBJ_sm,200L
#define OBJ_zuc OBJ_sm,800L

View File

@@ -1008,3 +1008,23 @@ sm9 1007
sm9sign 1008
sm9keyagreement 1009
sm9encrypt 1010
sms4_cbc_hmac_sm3 1011
sm6_ecb 1012
sm6_cbc 1013
sm6_ofb128 1014
sm6_cfb128 1015
sm1_ecb 1016
sm1_cbc 1017
sm1_ofb128 1018
sm1_cfb128 1019
ssf33_ecb 1020
ssf33_cbc 1021
ssf33_ofb128 1022
ssf33_cfb128 1023
id_sm_PublicKey 1024
id_sm9PublicKey 1025
sms4_ctr 1026
sms4_gcm 1027
sms4_ccm 1028
sms4_xts 1029
sm1_cfb 1030

View File

@@ -1350,7 +1350,7 @@ secg-scheme 14 3 : dhSinglePass-cofactorDH-sha512kdf-scheme
1 3 6 1 4 1 311 60 2 1 3 : jurisdictionC : jurisdictionCountryName
# ECIES OID
# GmSSL SECG ECIES OID
!Alias secg_scheme certicom-arc 1
secg-scheme 7 : ecies-recommendedParameters
secg-scheme 8 : ecies-specifiedParameters
@@ -1370,29 +1370,58 @@ secg-scheme 23 : hmac-half-ecies
secg-scheme 24 0 : cmac-aes128-ecies
secg-scheme 24 1 : cmac-aes192-ecies
# SM: China National Cryptography Standards
member-body 156 : ISO-CN : ISO CN Member Body
ISO-CN 10197 : oscca
# GmSSL SM OID
member-body 156 : ISO-CN : ISO CN Member Body
ISO-CN 10197 : oscca
oscca 1 : sm
sm 101 : SM6 : sm6
sm 101 1 : SM6-ECB : sm6-ecb
sm 101 2 : SM6-CBC : sm6-cbc
!Cname sm6-ofb128
sm 101 3 : SM6-OFB : sm6-ofb
!Cname sm6-cfb128
sm 101 4 : SM6-CFB : sm6-cfb
sm 102 : SM1 : sm1
sm 102 1 : SM1-ECB : sm1-ecb
sm 102 2 : SM1-CBC : sm1-cbc
!Cname sm1-ofb128
sm 102 3 : SM1-OFB : sm1-ofb
!Cname sm1-cfb128
sm 102 4
: SM1-CFB : sm1-cfb
sm 103 : SSF33 : ssf33
sm 105 : SM7 : sm7
sm 106 : SM8 : sm8
sm 103 1 : SSF33-ECB : ssf33-ecb
sm 103 2 : SSF33-CBC : ssf33-cbc
!Cname ssf33-ofb128
sm 103 3 : SSF33-OFB : ssf33-ofb
!Cname ssf33-cfb128
sm 104 4 : SSF33-CFB : ssf33-cfb
sm 104 1 : SMS4-ECB : sms4-ecb
sm 104 2 : SMS4-CBC : sms4-cbc
!Cname sms4-ofb128
sm 104 3 : SMS4-OFB : sms4-ofb
!Cname sms4-cfb128
sm 104 4 : SMS4-CFB : sms4-cfb
sm 104 5 : SMS4-CTR : sms4-ctr
sm 104 6 : SMS4-GCM : sms4-gcm
sm 104 7 : SMS4-CCM : sms4-ccm
sm 104 8 : SMS4-XTS : sms4-xts
!Alias sm7 sm 105
!Alias sm8 sm 106
sm 201 : SM5 : sm5
# sm 301 : id-sm2PublicKey
sm 301 : sm2p256v1
sm 301 1 : sm2sign
sm 301 2 : sm2keyagreement
sm 301 3 : sm2encrypt
sm 302 : SM9 : sm9
sm 302 : id-sm9PublicKey
sm 302 1 : sm9sign
sm 302 2 : sm9keyagreement
sm 302 3 : sm9encrypt
@@ -1403,12 +1432,7 @@ sm 501 : SM2Sign-with-SM3 : sm2sign-with-sm3
sm 502 : SM2Sign-with-SHA1 : sm2sign-with-sha1
sm 503 : SM2Sign-with-SHA256 : sm2sign-with-sha256
sm 104 1 : SMS4-ECB : sms4-ecb
sm 104 2 : SMS4-CBC : sms4-cbc
!Cname sms4-cfb128
sm 104 3 : SMS4-CFB : sms4-cfb
!Cname sms4-ofb128
sm 104 4 : SMS4-OFB : sms4-ofb
# GmSSL ZUC OID
sm 800 : ZUC : zuc
sm 200 : ZUC : zuc

67
crypto/sm1/sm1.h Normal file
View File

@@ -0,0 +1,67 @@
/* crypto/sm1/sm1.h */
/* ====================================================================
* Copyright (c) 2014 - 2015 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.
* ====================================================================
*
*/
#ifndef HEADER_SM1_H
#define HEADER_SM1_H
#define SM1_KEY_LENGTH 16
#define SM1_BLOCK_SIZE 16
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -17,9 +17,9 @@ TEST=sm2test.c
APPS=
LIB=$(TOP)/libcrypto.a
LIBSRC= sm2_lib.c sm2_err.c sm2_sign.c sm2_enc.c
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
LIBOBJ= sm2_lib.o sm2_err.o sm2_sign.o sm2_enc.o sm2_kap.o
SRC= $(LIBSRC)

View File

@@ -83,7 +83,8 @@ typedef struct sm2_ciphertext_value_st {
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, const void *id, size_t idlen, EC_KEY *ec_key);
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,
@@ -128,6 +129,55 @@ int SM2_sign(int type, const unsigned char *dgst, int dgstlen,
int SM2_verify(int type, const unsigned char *dgst, int dgstlen,
const unsigned char *sig, int siglen, EC_KEY *ec_key);
typedef struct sm2_kap_ctx_st {
const EVP_MD *id_dgst_md;
const EVP_MD *kdf_md;
const EVP_MD *checksum_md;
point_conversion_form_t point_form;
KDF_FUNC kdf;
int is_initiator;
int do_checksum;
EC_KEY *ec_key;
unsigned char id_dgst[EVP_MAX_MD_SIZE];
unsigned int id_dgstlen;
EC_KEY *remote_pubkey;
unsigned char remote_id_dgst[EVP_MAX_MD_SIZE];
unsigned int remote_id_dgstlen;
const EC_GROUP *group;
BN_CTX *bn_ctx;
BIGNUM *order;
BIGNUM *two_pow_w;
BIGNUM *t;
EC_POINT *point;
unsigned char pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4];
unsigned char checksum[EVP_MAX_MD_SIZE];
} SM2_KAP_CTX;
int SM2_KAP_CTX_init_ex(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);
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,
unsigned char *checksum, size_t *checksumlen);
int SM2_KAP_final_check(SM2_KAP_CTX *ctx, const unsigned char *checksum,
size_t checksumlen);
void ERR_load_SM2_strings(void);
/* Function codes. */
@@ -143,14 +193,20 @@ void ERR_load_SM2_strings(void);
#define SM2_F_SM2_DO_DECRYPT 109
#define SM2_F_SM2_ENCRYPT 110
#define SM2_F_SM2_DECRYPT 111
#define SM2_SIGNATURE_SIZE 112
#define SM2_SIGN_SETUP 113
#define SM2_DO_SIGN_EX 114
#define SM2_DO_SIGN 115
#define SM2_DO_VERIFY 116
#define SM2_SIGN_EX 117
#define SM2_SIGN 118
#define SM2_VERIFY 119
#define SM2_F_SM2_SIGNATURE_SIZE 112
#define SM2_F_SM2_SIGN_SETUP 113
#define SM2_F_SM2_DO_SIGN_EX 114
#define SM2_F_SM2_DO_SIGN 115
#define SM2_F_SM2_DO_VERIFY 116
#define SM2_F_SM2_SIGN_EX 117
#define SM2_F_SM2_SIGN 118
#define SM2_F_SM2_VERIFY 119
#define SM2_F_SM2_KAP_CTX_INIT 120
#define SM2_F_SM2_KAP_CTX_CLEANUP 121
#define SM2_F_SM2_KAP_PREPARE 122
#define SM2_F_SM2_KAP_COMPUTE_KEY 123
#define SM2_F_SM2_KAP_FINAL_CHECK 124
/* Reason codes. */
#define SM2_R_BAD_DATA 100
@@ -162,6 +218,8 @@ void ERR_load_SM2_strings(void);
#define SM2_R_VERIFY_MAC_FAILED 106
#define SM2_R_ECDH_FAILED 107
#define SM2_R_BUFFER_TOO_SMALL 108
#define SM2_R_SM2_KAP_NOT_INITED 109
#define SM2_R_RANDOM_NUMBER_GENERATION_FAILED 110
#ifdef __cplusplus
}

37
crypto/sm2/sm2_asn1.c Normal file
View File

@@ -0,0 +1,37 @@
/*
* 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
}
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"
*/

View File

@@ -60,42 +60,6 @@
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECIES,0,reason)
#define SM2_F_SM2_SET_ID 100
#define SM2_F_SM2_GET_ID 101
#define SM2_F_SM2_COMPUTE_ID_DIGEST 102
#define SM2_F_SM2_CIPHERTEXT_VALUE_SIZE 103
#define SM2_F_SM2_CIPHERTEXT_VALUE_FREE 104
#define SM2_F_SM2_CIPHERTEXT_VALUE_ENCODE 105
#define SM2_F_SM2_CIPHERTEXT_VALUE_DECODE 106
#define SM2_F_SM2_CIPHERTEXT_VALUE_PRINT 107
#define SM2_F_SM2_DO_ENCRYPT 108
#define SM2_F_SM2_DO_DECRYPT 109
#define SM2_F_SM2_ENCRYPT 110
#define SM2_F_SM2_DECRYPT 111
#define SM2_SIGNATURE_SIZE 112
#define SM2_SIGN_SETUP 113
#define SM2_DO_SIGN_EX 114
#define SM2_DO_SIGN 115
#define SM2_DO_VERIFY 116
#define SM2_SIGN_EX 117
#define SM2_SIGN 118
#define SM2_VERIFY 119
static ERR_STRING_DATA SM2_str_functs[] = {
{ERR_FUNC(SM2_F_SM2_SET_ID), "SM2_SET_ID"},
{ERR_FUNC(SM2_F_SM2_GET_ID), "SM2_F_SM2_GET_ID"},
@@ -109,27 +73,34 @@ static ERR_STRING_DATA SM2_str_functs[] = {
{ERR_FUNC(SM2_F_SM2_DO_DECRYPT), "SM2_do_decrypt"},
{ERR_FUNC(SM2_F_SM2_ENCRYPT), "SM2_encrypt"},
{ERR_FUNC(SM2_F_SM2_DECRYPT), "SM2_decrypt"},
{ERR_FUNC(SM2_SIGNATURE_SIZE), "SM2_signature_size"},
{ERR_FUNC(SM2_SIGN_SETUP), "SM2_sign_setup"},
{ERR_FUNC(SM2_DO_SIGN_EX), "SM2_do_sign_ex"},
{ERR_FUNC(SM2_DO_SIGN), "SM2_do_sign"},
{ERR_FUNC(SM2_DO_VERIFY), "SM2_do_verify"},
{ERR_FUNC(SM2_SIGN_EX), "SM2_sign_ex"},
{ERR_FUNC(SM2_SIGN), "SM2_sign"},
{ERR_FUNC(SM2_VERIFY), "SM2_verify"},
{ERR_FUNC(SM2_F_SM2_SIGNATURE_SIZE), "SM2_signature_size"},
{ERR_FUNC(SM2_F_SM2_SIGN_SETUP), "SM2_sign_setup"},
{ERR_FUNC(SM2_F_SM2_DO_SIGN_EX), "SM2_do_sign_ex"},
{ERR_FUNC(SM2_F_SM2_DO_SIGN), "SM2_do_sign"},
{ERR_FUNC(SM2_F_SM2_DO_VERIFY), "SM2_do_verify"},
{ERR_FUNC(SM2_F_SM2_SIGN_EX), "SM2_sign_ex"},
{ERR_FUNC(SM2_F_SM2_SIGN), "SM2_sign"},
{ERR_FUNC(SM2_F_SM2_VERIFY), "SM2_verify"},
{ERR_FUNC(SM2_F_SM2_KAP_CTX_INIT), "SM2_KAP_CTX_init"},
{ERR_FUNC(SM2_F_SM2_KAP_CTX_CLEANUP), "SM2_KAP_CTX_cleanup"},
{ERR_FUNC(SM2_F_SM2_KAP_PREPARE), "SM2_KAP_prepare"},
{ERR_FUNC(SM2_F_SM2_KAP_COMPUTE_KEY), "SM2_KAP_compute_key"},
{ERR_FUNC(SM2_F_SM2_KAP_FINAL_CHECK), "SM2_KAP_final_check"},
{0,NULL}
};
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_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_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

@@ -48,3 +48,504 @@
* ====================================================================
*
*/
#include <string.h>
#include <openssl/kdf.h>
#include "sm2.h"
int SM2_KAP_CTX_init_ex(SM2_KAP_CTX *ctx, EC_KEY *ec_key,
EC_KEY *remote_pubkey, int is_initiator, int do_checksum)
{
int ret = 0;
int w;
memset(ctx, 0, sizeof(*ctx));
ctx->id_dgst_md = EVP_sm3();
ctx->kdf_md = EVP_sm3();
ctx->checksum_md = EVP_sm3();
ctx->point_form = POINT_CONVERSION_COMPRESSED;
if (!(ctx->kdf = KDF_get_x9_63(ctx->kdf_md))) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
ctx->is_initiator = is_initiator;
ctx->do_checksum = do_checksum;
if (EC_GROUP_cmp(EC_KEY_get0_group(ec_key),
EC_KEY_get0_group(remote_pubkey), NULL) != 0) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
if (!SM2_compute_id_digest(ctx->id_dgst, &ctx->id_dgstlen,
ctx->id_dgst_md, ec_key)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
if (!(ctx->ec_key = EC_KEY_dup(ec_key))) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, ERR_R_EC_LIB);
goto end;
}
if (!SM2_compute_id_digest(ctx->remote_id_dgst, &ctx->remote_id_dgstlen,
ctx->id_dgst_md, remote_pubkey)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
if (!(ctx->remote_pubkey = EC_KEY_dup(remote_pubkey))) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
ctx->group = EC_KEY_get0_group(ec_key);
ctx->bn_ctx = BN_CTX_new();
ctx->order = BN_new();
ctx->two_pow_w = BN_new();
ctx->t = BN_new();
if (!ctx->bn_ctx || !ctx->order || !ctx->two_pow_w || !ctx->t) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, ERR_R_BN_LIB);
goto end;
}
if (!EC_GROUP_get_order(EC_KEY_get0_group(ec_key), ctx->order, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, ERR_R_EC_LIB);
goto end;
}
w = (EC_GROUP_get_degree(ctx->group) + 1)/2 - 1;
if (!BN_one(ctx->two_pow_w)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, ERR_R_BN_LIB);
goto end;
}
if (!BN_lshift(ctx->two_pow_w, ctx->two_pow_w, w)) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, ERR_R_BN_LIB);
goto end;
}
if (!(ctx->point = EC_POINT_new(ctx->group))) {
SM2err(SM2_F_SM2_KAP_CTX_INIT, ERR_R_EC_LIB);
goto end;
}
ret = 1;
end:
if (!ret) SM2_KAP_CTX_cleanup(ctx);
return ret;
}
void SM2_KAP_CTX_cleanup(SM2_KAP_CTX *ctx)
{
if (ctx->ec_key) EC_KEY_free(ctx->ec_key);
if (ctx->remote_pubkey) EC_KEY_free(ctx->remote_pubkey);
if (ctx->bn_ctx) BN_CTX_free(ctx->bn_ctx);
if (ctx->two_pow_w) BN_free(ctx->two_pow_w);
if (ctx->order) BN_free(ctx->order);
if (ctx->point) EC_POINT_free(ctx->point);
if (ctx->t) BN_free(ctx->t);
memset(ctx, 0, sizeof(*ctx));
}
int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,
size_t ephem_point_len)
{
int ret = 0;
const BIGNUM *prikey;
BIGNUM *h = NULL;
BIGNUM *r = NULL;
BIGNUM *x = NULL;
if (!(prikey = EC_KEY_get0_private_key(ctx->ec_key))) {
SM2err(SM2_F_SM2_KAP_PREPARE, SM2_R_SM2_KAP_NOT_INITED);
return 0;
}
h = BN_new();
r = BN_new();
x = BN_new();
if (!h || !r || !x) {
SM2err(SM2_F_SM2_KAP_PREPARE, 0);
goto end;
}
/*
* r = rand(1, n)
* R = rG = (x, y)
*/
do {
if (!BN_rand_range(r, ctx->order)) {
SM2err(SM2_F_SM2_KAP_PREPARE, SM2_R_RANDOM_NUMBER_GENERATION_FAILED);
goto end;
}
} 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);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(ctx->group, ctx->point, x, NULL, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto end;
}
}
/*
* w = ceil(keybits / 2) - 1
* x = 2^w + (x and (2^w - 1)) = 2^w + (x mod 2^w)
* t = (d + x * r) mod n
* t = (h * t) mod n
*/
if (!ctx->t) {
SM2err(SM2_F_SM2_KAP_PREPARE, SM2_R_SM2_KAP_NOT_INITED);
goto end;
}
if (!BN_nnmod(x, x, ctx->two_pow_w, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_add(x, x, ctx->two_pow_w)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_mul(ctx->t, x, r, ctx->order, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_add(ctx->t, ctx->t, prikey, ctx->order, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!EC_GROUP_get_cofactor(ctx->group, h, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto end;
}
if (!BN_mul(ctx->t, ctx->t, h, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
/* encode R = (x, y) for output and local buffer */
ret = EC_POINT_point2oct(ctx->group, ctx->point, ctx->point_form,
ephem_point, ephem_point_len, ctx->bn_ctx);
memcpy(ctx->pt_buf, ephem_point, ret);
end:
if (h) BN_free(h);
if (r) BN_free(r);
if (x) BN_free(x);
return ret;
}
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,
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 dgst[EVP_MAX_MD_SIZE];
unsigned int dgstlen;
unsigned int len, bnlen;
EVP_MD_CTX_init(&md_ctx);
if (!(x = BN_new())) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
/*
* decode point R = (x, y), encode (x, y)
* x = 2^w + (x and (2^w - 1)) = 2^w + (x mod 2^w), w = ceil(keybits / 2) - 1
* U = ht * (P + x * R)
* check U != O
*/
if (!EC_POINT_oct2point(ctx->group, ctx->point,
remote_point, remote_point_len, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
if (!(len = EC_POINT_point2oct(ctx->group, ctx->point, POINT_CONVERSION_UNCOMPRESSED,
remote_pt_buf, sizeof(remote_pt_buf), ctx->bn_ctx))) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
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_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(ctx->group, ctx->point, x, NULL, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
}
/* x = 2^w + (x and (2^w - 1)) = 2^w + (x mod 2^w) */
if (!BN_nnmod(x, x, ctx->two_pow_w, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_BN_LIB);
goto end;
}
if (!BN_add(x, x, ctx->two_pow_w)) {
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;
}
if (!EC_POINT_add(ctx->group, ctx->point, ctx->point,
EC_KEY_get0_public_key(ctx->remote_pubkey), ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
if (!EC_POINT_mul(ctx->group, ctx->point, NULL, ctx->point, ctx->t, ctx->bn_ctx)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
if (!EC_POINT_is_at_infinity(ctx->group, ctx->point)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
/* encode U, append with ZA, ZB */
if (!(len = EC_POINT_point2oct(ctx->group, ctx->point, POINT_CONVERSION_UNCOMPRESSED,
share_pt_buf, sizeof(share_pt_buf), ctx->bn_ctx))) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
if (ctx->is_initiator) {
memcpy(share_pt_buf + len, ctx->id_dgst, ctx->id_dgstlen);
len += ctx->id_dgstlen;
memcpy(share_pt_buf + len, ctx->remote_id_dgst, ctx->remote_id_dgstlen);
len += ctx->remote_id_dgstlen;
} else {
memcpy(share_pt_buf + len, ctx->remote_id_dgst, ctx->remote_id_dgstlen);
len += ctx->remote_id_dgstlen;
memcpy(share_pt_buf + len, ctx->id_dgst, ctx->id_dgstlen);
len += ctx->id_dgstlen;
}
/* key = KDF(xu, yu, ZA, ZB) */
if (!ctx->kdf(share_pt_buf, len, key, keylen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
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))
*/
if (!EVP_DigestInit_ex(&md_ctx, ctx->checksum_md, NULL)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
bnlen = BN_num_bytes(ctx->order);
if (!EVP_DigestUpdate(&md_ctx, share_pt_buf + 1, bnlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (ctx->is_initiator) {
if (!EVP_DigestUpdate(&md_ctx, ctx->id_dgst, ctx->id_dgstlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
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;
}
if (!EVP_DigestUpdate(&md_ctx, ctx->pt_buf + 1, bnlen * 2)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, remote_pt_buf + 1, bnlen * 2)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
} 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;
}
if (!EVP_DigestUpdate(&md_ctx, ctx->id_dgst, ctx->id_dgstlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, remote_pt_buf + 1, bnlen * 2)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, ctx->pt_buf + 1, bnlen * 2)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
}
if (!EVP_DigestFinal_ex(&md_ctx, dgst, &dgstlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
/* S1 = SB = Hash(0x02, yu, dgst) */
if (!EVP_DigestInit_ex(&md_ctx, ctx->checksum_md, NULL)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, "\0x02", 1)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, share_pt_buf + 1 + bnlen, bnlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, dgst, dgstlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
/* output S1 to local buffer or SB to output */
if (ctx->is_initiator) {
if (!EVP_DigestFinal_ex(&md_ctx, ctx->checksum, &len)) {
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);
goto end;
}
*checksumlen = len;
}
/* generate checksum SA or S2 start with 0x03
* SA = S2 = Hash(0x03, yu, dgst)
*/
if (!EVP_DigestInit_ex(&md_ctx, ctx->checksum_md, NULL)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, "\0x03", 1)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, share_pt_buf + 1 + bnlen, bnlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(&md_ctx, dgst, dgstlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (ctx->is_initiator) {
if (!EVP_DigestFinal_ex(&md_ctx, checksum, &len)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
*checksumlen = len;
} else {
if (!EVP_DigestFinal_ex(&md_ctx, ctx->checksum, &len)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
}
}
ret = 1;
end:
EVP_MD_CTX_cleanup(&md_ctx);
if (x) BN_free(x);
return 0;
}
int SM2_KAP_final_check(SM2_KAP_CTX *ctx, const unsigned char *checksum,
size_t checksumlen)
{
if (ctx->do_checksum) {
if (checksumlen != EVP_MD_size(ctx->checksum_md)) {
SM2err(SM2_F_SM2_KAP_FINAL_CHECK, 0);
return 0;
}
if (memcmp(ctx->checksum, checksum, checksumlen)) {
SM2err(SM2_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
return 0;
}
}
return 1;
}

View File

@@ -185,18 +185,25 @@ err:
}
int SM2_compute_id_digest(unsigned char *dgst, unsigned int *dgstlen,
const EVP_MD *md, const void *id, size_t idlen, EC_KEY *ec_key)
const EVP_MD *md, EC_KEY *ec_key)
{
int ret = 0;
EVP_MD_CTX *md_ctx = NULL;
unsigned char pkdata[EC_MAX_NBYTES * 6];
uint16_t idbits = idlen * 8;
uint16_t idbits;
int pkdatalen;
char *id = NULL;
if ((pkdatalen = sm2_get_public_key_data(pkdata, ec_key)) < 0) {
goto err;
}
if (!(id = SM2_get_id(ec_key))) {
goto err;
}
idbits = strlen(id) * 8;
if (!(md_ctx = EVP_MD_CTX_create())) {
goto err;
}
@@ -206,7 +213,7 @@ int SM2_compute_id_digest(unsigned char *dgst, unsigned int *dgstlen,
if (!EVP_DigestUpdate(md_ctx, &idbits, sizeof(idbits))) {
goto err;
}
if (!EVP_DigestUpdate(md_ctx, id, idlen)) {
if (!EVP_DigestUpdate(md_ctx, id, strlen(id))) {
goto err;
}
if (!EVP_DigestUpdate(md_ctx, pkdata, pkdatalen)) {

View File

@@ -88,6 +88,58 @@ static int test_sm2_enc(void)
return 0;
}
static int test_sm2_kap(void)
{
int rv = 0;
int curve_name = NID_sm2p256v1;
EC_KEY *eckey1 = NULL;
EC_KEY *eckey2 = NULL;
SM2_KAP_CTX ctx1;
SM2_KAP_CTX ctx2;
eckey1 = EC_KEY_new_by_curve_name(curve_name);
OPENSSL_assert(eckey1 != NULL);
eckey2 = EC_KEY_new_by_curve_name(curve_name);
OPENSSL_assert(eckey2 != NULL);
rv = EC_KEY_generate_key(eckey1);
OPENSSL_assert(rv == 1);
rv = EC_KEY_generate_key(eckey2);
OPENSSL_assert(rv == 1);
rv = SM2_set_id(eckey1, "Alice");
OPENSSL_assert(rv == 1);
rv = SM2_set_id(eckey2, "Bob");
OPENSSL_assert(rv == 1);
rv = SM2_KAP_init();
OPENSSL_assert(rv == 1);
rv = SM2_KAP_prepare(&ctx1);
OPENSSL_assert(rv == 1);
rv = SM2_KAP_prepare(&ctx2);
OPENSSL_assert(rv == 1);
rv = SM2_KAP_compute_key(&ctx1);
OPENSSL_assert(rv == 1);
rv = SM2_KAP_compute_key(&ctx2);
OPENSSL_assert(rv == 1);
rv = SM2_KAP_final_check(&ctx1);
OPENSSL_assert(rv == 1);
rv = SM2_KAP_final_check(&ctx2);
OPENSSL_assert(rv == 1);
return 0;
}
int main(int argc, char **argv)
{

View File

@@ -239,9 +239,9 @@ void sms4_set_decrypt_key(sms4_key_t *key, const unsigned char *user_key)
ROUND_(X1, X2, X3, X4, X0, CK31, rk[0]);
}
void sms4_encrypt(const unsigned char *in, unsigned char *out, sms4_key_t *key)
void sms4_encrypt(const unsigned char *in, unsigned char *out, const sms4_key_t *key)
{
uint32_t *rk = key->rk;
const uint32_t *rk = key->rk;
uint32_t X0, X1, X2, X3, X4;
X0 = GETU32(in );

View File

@@ -59,7 +59,6 @@
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include "openssl/modes.h"
#ifdef __cplusplus
@@ -72,22 +71,26 @@ typedef struct {
void sms4_set_encrypt_key(sms4_key_t *key, const unsigned char *user_key);
void sms4_set_decrypt_key(sms4_key_t *key, const unsigned char *user_key);
void sms4_encrypt(const unsigned char *in, unsigned char *out, sms4_key_t *key);
void sms4_ecb_encrypt(const unsigned char *in, unsigned char *out, sms4_key_t *key, int enc);
void sms4_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len,
sms4_key_t *key, unsigned char *ivec, int encrypt);
void sms4_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, sms4_key_t *key,
unsigned char *ivec, int *num, int encrypt);
void sms4_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const sms4_key_t *key,
unsigned char ivec[SMS4_BLOCK_SIZE],
int *num);
void sms4_encrypt(const unsigned char *in, unsigned char *out, const sms4_key_t *key);
#define sms4_decrypt(in,out,key) sms4_encrypt(in,out,key)
void sms4_ecb_encrypt(const unsigned char *in, unsigned char *out,
const sms4_key_t *key, int enc);
void sms4_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const sms4_key_t *key, unsigned char *iv, int enc);
void sms4_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const sms4_key_t *key, unsigned char *iv, int *num, int enc);
void sms4_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const sms4_key_t *key, unsigned char *iv, int *num);
void sms4_ctr128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const sms4_key_t *key, unsigned char *iv,
unsigned char ecount_buf[SMS4_BLOCK_SIZE], unsigned int *num);
int sms4_wrap_key(sms4_key_t *key, const unsigned char *iv,
unsigned char *out, const unsigned char *in, unsigned int inlen);
int sms4_unwrap_key(sms4_key_t *key, const unsigned char *iv,
unsigned char *out, const unsigned char *in, unsigned int inlen);
#ifdef __cplusplus
}
#endif

View File

@@ -49,20 +49,14 @@
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sms4.h"
#include <openssl/sms4.h>
#include <openssl/modes.h>
void sms4_cbc_encrypt(const unsigned char *in, unsigned char *out,
size_t len, sms4_key_t *key,
unsigned char *ivec, int encrypt)
size_t len, const sms4_key_t *key, unsigned char *iv, int enc)
{
if(encrypt)
CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)sms4_encrypt);
else
CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)sms4_encrypt);
if (enc)
CRYPTO_cbc128_encrypt(in, out, len, key, iv, (block128_f)sms4_encrypt);
else CRYPTO_cbc128_decrypt(in, out, len, key, iv, (block128_f)sms4_encrypt);
}

View File

@@ -49,26 +49,12 @@
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sms4.h"
#ifndef MODES_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
#include <assert.h>
/* The input and output encrypted as though 128bit cfb mode is being
* used. The extra state information to record how much of the
* 128bit block we have used is contained in *num;
*/
#include <openssl/sms4.h>
#include <openssl/modes.h>
void sms4_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, sms4_key_t *key,
unsigned char *ivec, int *num, int encrypt) {
CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,encrypt,(block128_f)sms4_encrypt);
size_t len, const sms4_key_t *key, unsigned char *iv, int *num, int enc)
{
CRYPTO_cfb128_encrypt(in, out, len, key, iv, num, enc, (block128_f)sms4_encrypt);
}

63
crypto/sms4/sms4_ctr.c Normal file
View File

@@ -0,0 +1,63 @@
/* crypto/sms4/sms4_cbc.c */
/* ====================================================================
* Copyright (c) 2014 - 2015 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 <openssl/sms4.h>
#include <openssl/modes.h>
void sms4_ctr128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const sms4_key_t *key, unsigned char *iv,
unsigned char ecount_buf[SMS4_BLOCK_SIZE], unsigned int *num)
{
/* this should be replaced with a parallelized version */
CRYPTO_ctr128_encrypt(in, out, len, key, iv, ecount_buf, num, (block128_f)sms4_encrypt);
}

View File

@@ -50,18 +50,14 @@
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sms4.h"
#include <assert.h>
#include <openssl/sms4.h>
#include <openssl/modes.h>
void sms4_ecb_encrypt(const unsigned char *in, unsigned char *out, sms4_key_t *key, int encrypt) {
assert(in && out && key);
if(encrypt)
sms4_encrypt(in, out, key);
else
sms4_decrypt(in, out, key);
void sms4_ecb_encrypt(const unsigned char *in, unsigned char *out,
const sms4_key_t *key, int enc)
{
if (enc)
sms4_encrypt(in, out, key);
else sms4_decrypt(in, out, key);
}
//sms4_decrypt = sms4_encrypt, but the key is in reverse order

View File

@@ -49,26 +49,13 @@
*
*/
#include <openssl/sms4.h>
#include <openssl/modes.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sms4.h"
#ifndef MODES_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
#include <assert.h>
void sms4_ofb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const sms4_key_t *key,
unsigned char ivec[SMS4_BLOCK_SIZE],
int *num)
size_t len, const sms4_key_t *key, unsigned char *iv, int *num)
{
CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)sms4_encrypt);
CRYPTO_ofb128_encrypt(in, out, len, key, iv, num, (block128_f)sms4_encrypt);
}
//cprefix##_ofb##cbits##_encrypt

68
crypto/sms4/sms4_wrap.c Normal file
View File

@@ -0,0 +1,68 @@
/* crypto/sms4/sms4_cbc.c */
/* ====================================================================
* Copyright (c) 2014 - 2015 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 "cryptlib.h"
#include <openssl/sms4.h>
#include <openssl/modes.h>
int sms4_wrap_key(sms4_key_t *key, const unsigned char *iv,
unsigned char *out, const unsigned char *in, unsigned int inlen)
{
return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f)sms4_encrypt);
}
int sms4_unwrap_key(sms4_key_t *key, const unsigned char *iv,
unsigned char *out, const unsigned char *in, unsigned int inlen)
{
return CRYPTO_128_unwrap(key, iv, out, in, inlen, (block128_f)sms4_decrypt);
}

67
crypto/ssf33/ssf33.h Normal file
View File

@@ -0,0 +1,67 @@
/* crypto/ssf33/ssf33.h */
/* ====================================================================
* Copyright (c) 2014 - 2015 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.
* ====================================================================
*
*/
#ifndef HEADER_SSF33_H
#define HEADER_SSF33_H
#define SSF33_KEY_LENGTH 16
#define SSF33_BLOCK_SIZE 16
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -91,6 +91,10 @@
# include <openssl/ecdh.h>
# endif
# ifndef OPENSSL_NO_SM2
# include <openssl/sm2.h>
# endif
# ifndef OPENSSL_NO_DEPRECATED
# ifndef OPENSSL_NO_RSA
# include <openssl/rsa.h>

View File

@@ -90,6 +90,11 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
case EVP_PKEY_EC:
ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
break;
#ifndef OPENSSL_NO_SM2
case EVP_PKEY_SM2:
ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH;
break;
#endif
case EVP_PKEY_DH:
ret = EVP_PK_DH | EVP_PKT_EXCH;
break;
@@ -116,6 +121,9 @@ int X509_certificate_type(X509 *x, EVP_PKEY *pkey)
case NID_X9_62_id_ecPublicKey:
ret |= EVP_PKS_EC;
break;
#ifndef OPENSSL_NO_SM2
/* what to do ? */
#endif
default:
break;
}