mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-07 21:53:41 +08:00
new modules
This commit is contained in:
79
crypto/sm2/Makefile
Normal file
79
crypto/sm2/Makefile
Normal file
@@ -0,0 +1,79 @@
|
||||
#
|
||||
# crypto/ecies/Makefile
|
||||
#
|
||||
|
||||
DIR= sm2
|
||||
TOP= ../..
|
||||
CC= cc
|
||||
INCLUDES= -I.. -I$(TOP) -I../../include
|
||||
CFLAG=-g -Wall
|
||||
MAKEFILE= Makefile
|
||||
AR= ar r
|
||||
|
||||
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||
|
||||
GENERAL=Makefile
|
||||
TEST=sm2test.c
|
||||
APPS=
|
||||
|
||||
LIB=$(TOP)/libcrypto.a
|
||||
LIBSRC= sm2_dgst.c sm2_enc.c
|
||||
|
||||
LIBOBJ= sm2_dgst.o sm2_enc.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
EXHEADER= sm2_enc.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 */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
170
crypto/sm2/sm2_dgst.c
Normal file
170
crypto/sm2/sm2_dgst.c
Normal file
@@ -0,0 +1,170 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
|
||||
#define EC_MAX_NBYTES ((OPENSSL_ECC_MAX_FIELD_BITS + 7)/8)
|
||||
|
||||
/*
|
||||
* pkdata = a || b || G.x || G.y || P.x || P.y
|
||||
*/
|
||||
static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
|
||||
{
|
||||
int ret = -1;
|
||||
int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
const EC_POINT *point;
|
||||
unsigned char oct[EC_MAX_NBYTES * 2 + 1];
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *p = NULL;
|
||||
BIGNUM *x = NULL;
|
||||
BIGNUM *y = NULL;
|
||||
|
||||
OPENSSL_assert(ec_key);
|
||||
OPENSSL_assert(nbytes == 256/8);
|
||||
|
||||
if (!buf) {
|
||||
return (nbytes * 6);
|
||||
}
|
||||
bzero(buf, nbytes * 6);
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
p = BN_new();
|
||||
x = BN_new();
|
||||
y = BN_new();
|
||||
if (!ctx || !p || !x || !y) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* get curve coefficients a, b */
|
||||
if (!EC_GROUP_get_curve_GFp(ec_group, p, x, y, ctx)) {
|
||||
goto err;
|
||||
}
|
||||
buf += nbytes;
|
||||
if (!BN_bn2bin(x, buf - BN_num_bytes(x))) {
|
||||
goto err;
|
||||
}
|
||||
buf += nbytes;
|
||||
if (!BN_bn2bin(y, buf - BN_num_bytes(y))) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* get curve generator coordinates */
|
||||
if (!(point = EC_GROUP_get0_generator(ec_group))) {
|
||||
goto err;
|
||||
}
|
||||
if (!(len = EC_POINT_point2oct(ec_group, point,
|
||||
POINT_CONVERSION_UNCOMPRESSED, oct, sizeof(oct), bn_ctx))) {
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_assert(len == 32 * 2 + 1);
|
||||
memcpy(buf, oct + 1, len - 1);
|
||||
buf += len - 1;
|
||||
|
||||
/* get pub_key coorindates */
|
||||
if (!(point = EC_KEY_get0_public_key(ec_key))) {
|
||||
goto err;
|
||||
}
|
||||
if (!(len = EC_POINT_point2oct(ec_group, point,
|
||||
POINT_CONVERSION_UNCOMPRESSED, oct, sizeof(oct), bn_ctx))) {
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_assert(len == 32 * 2 + 1);
|
||||
memcpy(buf, oct + 1, len - 1);
|
||||
buf += len - 1;
|
||||
|
||||
ret = (nbytes * 6);
|
||||
err:
|
||||
if (ctx) BN_CTX_free(ctx);
|
||||
if (p) BN_free(p);
|
||||
if (x) BN_free(x);
|
||||
if (y) BN_free(y);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SM2_compute_za(unsigned char *za, const EVP_MD *md,
|
||||
const void *id, size_t idlen, EC_KEY *ec_key)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
unsigned char pkdata[EC_MAX_NBYTES * 6];
|
||||
uint16_t idbits;
|
||||
int len;
|
||||
idbits = cpu_to_be16(idlen * 8);
|
||||
|
||||
if ((pkdatalen = sm2_get_public_key_data(pkdata, ec_key)) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(ctx = EVP_MD_CTX_create())) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestInit_ex(ctx, md, NULL)) {
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, &idbits, sizeof(idbits))) {
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, id, idlen)) {
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, pkdata, pkdatalen)) {
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestFinal(ctx, za, &zalen)) {
|
||||
}
|
||||
|
||||
ret = SM3_DIGEST_LENGTH;
|
||||
|
||||
err:
|
||||
if (ctx) EVP_MD_CTX_destroy(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SM2_compute_digest(unsigned char *dgst, unsigned int *dgstlen,
|
||||
const EVP_MD *za_md, const void *id, size_t idlen, EC_KEY *ec_key,
|
||||
const EVP_MD *msg_md, const void *msg, size_t msglen)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned char za[EVP_MAX_MD_SIZE];
|
||||
int zalen;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
|
||||
/* compute Za */
|
||||
if (idlen > SM2_MAX_ID_LENGTH) {
|
||||
goto err;
|
||||
}
|
||||
if ((zalen = SM2_compute_za(za, za_md, id, idlen, ec_key)) < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* compute digest */
|
||||
if (!(ctx = EVP_MD_CTX_create())) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestInit_ex(ctx, msg_md, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, za, zalen)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(ctx, msg, msglen)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(ctx, dgst, dgstlen)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
if (ctx) EVP_MD_CTX_destroy(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
284
crypto/sm2/sm2_enc.c
Normal file
284
crypto/sm2/sm2_enc.c
Normal file
@@ -0,0 +1,284 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <strings.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <oepnssl/kdf.h>
|
||||
#include "sm2_enc.h"
|
||||
|
||||
void SM2_CIPEHRTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv)
|
||||
{
|
||||
if (cv->ephem_point) EC_POINT_free(cv->ephem_point);
|
||||
if (cv->ciphertext) OPENSSL_free(cv->ciphertext);
|
||||
bzero(cv, sizeof(SM2_CIPHERTEXT_VALUE));
|
||||
OPENSSL_free(cv);
|
||||
}
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
const void *in, size_t inlen, const EC_KEY *ec_key);
|
||||
{
|
||||
int ok = 0;
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key);
|
||||
KDF_FUNC kdf = KDF_get_x9_63(kdf_md);
|
||||
EC_POINT *point = NULL;
|
||||
BIGNUM *n = NULL;
|
||||
BIGNUM *h = NULL;
|
||||
BIGNUM *k = NULL;
|
||||
BN_CTX *bn_ctx = NULL;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
|
||||
int nbytes;
|
||||
int i;
|
||||
|
||||
if (!ec_group || !pub_key) {
|
||||
goto err;
|
||||
}
|
||||
if (!kdf) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* init ciphertext_value */
|
||||
if (!(cv = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
|
||||
goto err;
|
||||
}
|
||||
bzero(cv, sizeof(SM2_CIPHERTEXT_VALUE));
|
||||
cv->ephem_point = EC_POINT_new(ec_group);
|
||||
cv->ciphertext = OPENSSL_malloc(inlen);
|
||||
cv->ciphertext_size = inlen;
|
||||
if (!cv->ephem_point || !cv->ciphertext) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
point = EC_POINT_new(ec_group);
|
||||
n = BN_new();
|
||||
h = BN_new();
|
||||
k = BN_new();
|
||||
bn_ctx = BN_CTX_new();
|
||||
md_ctx = EVP_MD_CTX_create();
|
||||
if (!point || !n || !h || !k || !bn_ctx || !md_ctx) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* init ec domain parameters */
|
||||
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
nbytes = (EC_GROPU_get_degree(ec_group) + 7) / 8;
|
||||
OPENSSL_assert(nbytes == BN_num_bytes(n));
|
||||
|
||||
/* check sm2 curve and md is 256 bits */
|
||||
OPENSSL_assert(nbytes == 32);
|
||||
OPENSSL_assert(EVP_MD_size(kdf_md) == 32);
|
||||
OPENSSL_assert(EVP_MD_size(mac_md) == 32);
|
||||
|
||||
do
|
||||
{
|
||||
/* A1: rand k in [1, n-1] */
|
||||
do {
|
||||
BN_rand_range(k, n);
|
||||
} while (BN_is_zero(k));
|
||||
|
||||
/* A2: C1 = [k]G = (x1, y1) */
|
||||
if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* A3: check [h]P_B != O */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_is_at_infinity(ec_group, point)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* A4: compute ECDH [k]P_B = (x2, y2) */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (!(len = EC_POINT_point2oct(ec_group, point,
|
||||
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_assert(len == nbytes * 2 + 1);
|
||||
|
||||
/* A5: t = KDF(x2 || y2, klen) */
|
||||
kdf(buf - 1, len - 1, cv->ciphertext, &cv->ciphertext_size);
|
||||
|
||||
for (i = 0; i < cv->ciphertext_size; i++) {
|
||||
if (cv->ciphertext[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == cv->ciphertext_size) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
} while (1);
|
||||
|
||||
|
||||
/* A6: C2 = M xor t */
|
||||
for (i = 0; i < inlen; i++) {
|
||||
cv->ciphertext[i] ^= in[i];
|
||||
}
|
||||
|
||||
/* A7: C3 = Hash(x2 || M || y2) */
|
||||
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, in, inlen)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(md_ctx, cv->mactag, &cv->mactag_size)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
|
||||
err:
|
||||
if (!ok && cv) {
|
||||
SM2_CIPHERTEXT_VALUE_free(cv);
|
||||
cv = NULL;
|
||||
}
|
||||
|
||||
if (n) BN_free(n);
|
||||
if (h) BN_free(h);
|
||||
if (k) BN_free(k);
|
||||
if (bn_ctx) BN_CTX_free(bn_ctx);
|
||||
if (md_ctx) EVP_MD_CTX_destroy(md_ctx);
|
||||
|
||||
return cv;
|
||||
}
|
||||
|
||||
|
||||
int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
|
||||
{
|
||||
int ret = 0
|
||||
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
|
||||
const BIGNUM *pri_key = EC_KEY_get0_private_key(ec_key);
|
||||
KDF_FUNC kdf = KDF_get_x9_63(kdf_md);
|
||||
EC_POINT *point = NULL;
|
||||
BIGNUM *n = NULL;
|
||||
BIGNUM *h = NULL;
|
||||
BN_CTX *bn_ctx = NULL;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
|
||||
unsigned char mac[EVP_MAX_MD_SIZE];
|
||||
int nbytes;
|
||||
int i;
|
||||
|
||||
if (!ec_group || !pub_key) {
|
||||
goto err;
|
||||
}
|
||||
if (!kdf) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!out) {
|
||||
*outlen = cv->ciphertext_size;
|
||||
return 1;
|
||||
}
|
||||
if (*outlen < cv->ciphertext_size) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* init vars */
|
||||
point = EC_POINT_new(ec_group);
|
||||
n = BN_new();
|
||||
h = BN_new();
|
||||
bn_ctx = BN_CTX_new();
|
||||
md_ctx = EVP_MD_CTX_create();
|
||||
if (!point || !n || !h || !bn_ctx || !md_ctx) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* init ec domain parameters */
|
||||
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
nbytes = (EC_GROPU_get_degree(ec_group) + 7) / 8;
|
||||
OPENSSL_assert(nbytes == BN_num_bytes(n));
|
||||
|
||||
/* check sm2 curve and md is 256 bits */
|
||||
OPENSSL_assert(nbytes == 32);
|
||||
OPENSSL_assert(EVP_MD_size(kdf_md) == 32);
|
||||
OPENSSL_assert(EVP_MD_size(mac_md) == 32);
|
||||
|
||||
/* B2: check [h]C1 != O */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, h, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (EC_POINT_is_at_infinity(ec_group, point)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* B3: compute ECDH [d]C1 = (x2, y2) */
|
||||
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, pri_key, bn_ctx)) {
|
||||
goto err;
|
||||
}
|
||||
if (!(len = EC_POINT_point2oct(ec_group, point,
|
||||
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* B4: compute t = KDF(x2 || y2, clen) */
|
||||
kdf(buf - 1, len - 1, out, outlen);
|
||||
|
||||
|
||||
/* B5: compute M = C2 xor t */
|
||||
for (i = 0; i < cv->ciphertext_size; i++) {
|
||||
out[i] ^= cv->ciphertext[i];
|
||||
}
|
||||
|
||||
/* B6: check Hash(x2 || M || y2) == C3 */
|
||||
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, out, *outlen)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
|
||||
goto err;
|
||||
}
|
||||
if (cv->mactag_size != maclen || memcmp(cv->mactag, mac, maclen)) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
err:
|
||||
if (point) EC_POINT_free(point);
|
||||
if (n) BN_free(n);
|
||||
if (h) BN_free(h);
|
||||
if (bn_ctx) BN_CTX_free(bn_ctx);
|
||||
if (md_ctx) EVP_MD_CTX_destroy(md_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
59
crypto/sm2/sm2_enc.h
Normal file
59
crypto/sm2/sm2_enc.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef HEADER_SM2_ENC_H
|
||||
#define HEADER_SM2_ENC_H
|
||||
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct sm2_ciphertext_value_st {
|
||||
EC_POINT *ephem_point;
|
||||
unsigned char *ciphertext;
|
||||
size_t ciphertext_size;
|
||||
unsigned char mactag[EVP_MAX_MD_SIZE];
|
||||
size_t mactag_size;
|
||||
} SM2_CIPHERTEXT_VALUE;
|
||||
|
||||
|
||||
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
const void *in, size_t inlen, const EC_KEY *pub_key);
|
||||
|
||||
int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
|
||||
const EVP_MD *kdf_md, const EVP_MD *mac_md,
|
||||
unsigned char *out, size_t *outlen, EC_KEY *pri_key);
|
||||
|
||||
void SM2_CIPHERTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv);
|
||||
|
||||
|
||||
void ERR_load_SM2_strings(void);
|
||||
|
||||
/* Error codes for the ECIES functions. */
|
||||
|
||||
/* Function codes. */
|
||||
#define SM2_F_SM2_DO_ENCRYPT 100
|
||||
#define SM2_F_SM2_DO_DECRYPT 101
|
||||
#define SM2_F_SM2_CIPHERTEXT_VALUE_FREE 102
|
||||
|
||||
/* Reason codes. */
|
||||
#define SM2_R_BAD_DATA 100
|
||||
#define SM2_R_UNKNOWN_CIPHER_TYPE 101
|
||||
#define SM2_R_ENCRYPT_FAILED 102
|
||||
#define SM2_R_DECRYPT_FAILED 103
|
||||
#define SM2_R_UNKNOWN_MAC_TYPE 104
|
||||
#define SM2_R_GEN_MAC_FAILED 105
|
||||
#define SM2_R_VERIFY_MAC_FAILED 106
|
||||
#define SM2_R_ECDH_FAILED 107
|
||||
#define SM2_R_BUFFER_TOO_SMALL 108
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
114
crypto/sm2/sm2test.c
Normal file
114
crypto/sm2/sm2test.c
Normal file
@@ -0,0 +1,114 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include "sm2.h"
|
||||
#include "sm3.h"
|
||||
|
||||
void SM2PKE_test3()
|
||||
{
|
||||
/* test3 params */
|
||||
const char *p = "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3";
|
||||
const char *a = "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498";
|
||||
const char *b = "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A";
|
||||
const char *xG = "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D";
|
||||
const char *yG = "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2";
|
||||
const char *n = "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7";
|
||||
const char *dB = "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0";
|
||||
const char *xB = "435B39CCA8F3B508C1488AFC67BE491A0F7BA07E581A0E4849A5CF70628A7E0A";
|
||||
const char *yB = "75DDBA78F15FEECB4C7895E2C1CDF5FE01DEBB2CDBADF45399CCF77BBA076A42";
|
||||
|
||||
BIGNUM *bn_p = BN_new();
|
||||
BN_hex2bn(&bn_p, p);
|
||||
BIGNUM *bn_a = BN_new();
|
||||
BN_hex2bn(&bn_a, a);
|
||||
BIGNUM *bn_b = BN_new();
|
||||
BN_hex2bn(&bn_b, b);
|
||||
BIGNUM *bn_xG = BN_new();
|
||||
BN_hex2bn(&bn_xG, xG);
|
||||
BIGNUM *bn_yG = BN_new();
|
||||
BN_hex2bn(&bn_yG, yG);
|
||||
BIGNUM *bn_n = BN_new();
|
||||
BN_hex2bn(&bn_n, n);
|
||||
BIGNUM *bn_dB = BN_new();
|
||||
BN_hex2bn(&bn_dB, dB);
|
||||
BIGNUM *bn_xB = BN_new();
|
||||
BN_hex2bn(&bn_xB, xB);
|
||||
BIGNUM *bn_yB = BN_new();
|
||||
BN_hex2bn(&bn_yB, yB);
|
||||
|
||||
BN_CTX *bn_ctx = BN_CTX_new();
|
||||
EC_GROUP *ec_group = EC_GROUP_new(EC_GFp_mont_method());
|
||||
EC_GROUP_set_curve_GFp(ec_group, bn_p, bn_a, bn_b, bn_ctx);
|
||||
|
||||
EC_POINT *G = EC_POINT_new(ec_group);
|
||||
EC_POINT_set_affine_coordinates_GFp(ec_group, G, bn_xG, bn_yG, bn_ctx);
|
||||
BIGNUM *bn_h = BN_new(); /* cofactor h = #E(Fp) / n */
|
||||
BN_div(bn_h, NULL, bn_p, bn_n, bn_ctx);
|
||||
EC_GROUP_set_generator(ec_group, G, bn_n, bn_h);
|
||||
|
||||
EC_POINT *PB = EC_POINT_new(ec_group);
|
||||
EC_POINT_set_affine_coordinates_GFp(ec_group, PB, bn_xB, bn_yB, bn_ctx);
|
||||
EC_KEY *ec_key_B = EC_KEY_new();
|
||||
EC_KEY_set_group(ec_key_B, ec_group);
|
||||
EC_KEY_set_private_key(ec_key_B, bn_dB);
|
||||
EC_KEY_set_public_key(ec_key_B, PB);
|
||||
|
||||
BN_free(bn_p);
|
||||
BN_free(bn_a);
|
||||
BN_free(bn_b);
|
||||
BN_free(bn_n);
|
||||
BN_free(bn_xG);
|
||||
BN_free(bn_yG);
|
||||
BN_free(bn_dB);
|
||||
BN_free(bn_xB);
|
||||
BN_free(bn_yB);
|
||||
BN_free(bn_h);
|
||||
BN_CTX_free(bn_ctx);
|
||||
EC_POINT_free(G);
|
||||
EC_POINT_free(PB);
|
||||
EC_GROUP_free(ec_group);
|
||||
|
||||
char *M = "encryption standard";
|
||||
char *ctest = "04245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF17F6252"
|
||||
"E776CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A24B84400F01"
|
||||
"B8650053A89B41C418B0C3AAD00D886C002864679C3D7360C30156FAB7C80A02"
|
||||
"76712DA9D8094A634B766D3A285E07480653426D";
|
||||
BIGNUM *ct = BN_new();
|
||||
BN_hex2bn(&ct, ctest);
|
||||
unsigned char ct2bin[116];
|
||||
BN_bn2bin(ct, ct2bin);
|
||||
BN_free(ct);
|
||||
|
||||
int mlen = strlen(M);
|
||||
int c1len = PRIME_SIZE / 8 * 2 + 1;
|
||||
int clen = c1len + mlen + HASH_V / 8;
|
||||
|
||||
unsigned char *C = malloc(sizeof(unsigned char) * clen);
|
||||
sm2_pke_encrypt(C, M, mlen, ec_key_B);
|
||||
if (memcmp(C, ct2bin, clen) == 0)
|
||||
printf("sm2_pke_encrypt passed.\n");
|
||||
else
|
||||
printf("sm2_pke_encrypt failed.\n");
|
||||
free(C);
|
||||
|
||||
int m1len = clen - c1len - HASH_V / 8;
|
||||
unsigned char *M1bin = malloc(sizeof(unsigned char) * m1len);
|
||||
sm2_pke_decrypt((char *)ct2bin, M1bin, m1len, ec_key_B);
|
||||
if (memcmp(M1bin, M, m1len) == 0)
|
||||
printf("sm2_pke_decrypt passed.\n");
|
||||
else
|
||||
printf("sm2_pke_decrypt failed.\n");
|
||||
free(M1bin);
|
||||
|
||||
EC_KEY_free(ec_key_B);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SM2PKE_test3();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user