new modules

This commit is contained in:
Zhi Guan
2015-10-05 15:34:54 +08:00
parent 8afb3ef97b
commit 254a1266d6
49 changed files with 4895 additions and 187 deletions

79
crypto/sm2/Makefile Normal file
View 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
View 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
View 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
View 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
View 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;
}