1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042 |
- #include "stdafx.h"
- #include "sm2.h"
- #include "kdf.h"
- #include "public.h"
- static const char rnd_seed[] = "string to make the random number generator think it has entropy";
- //#pragma comment(lib,"libeay32.lib")
- BN_CTX *ctx = NULL;
- EC_GROUP *group;
- void BNPrintf(BIGNUM* bn)
- {
- char *p=NULL;
- p=BN_bn2hex(bn);
- printf("%s",p);
- OPENSSL_free(p);
- }
- int sm2_init()
- {
- BIGNUM *p, *a, *b;
- BIGNUM *x, *y, *z;
- EC_POINT *P, *Q;
-
- //CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
- CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
- ERR_load_crypto_strings();
- RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
- /*
- 素数p:FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF
- 系数a:FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC
- 系数b:28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93
- 基点G:
- xG:32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7
- yG:BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0
-
- 阶n:FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123
- */
-
- ctx = BN_CTX_new();
- if (!ctx) ABORT;
- /* Curve SM2 (Chinese National Algorithm) */
- //http://www.oscca.gov.cn/News/201012/News_1197.htm
- p = BN_new();
- a = BN_new();
- b = BN_new();
- if (!p || !a || !b) ABORT;
- group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
- * so that the library gets to choose the EC_METHOD */
- if (!group) ABORT;
-
- if (!BN_hex2bn(&p, "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"))ABORT;//8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3")) ABORT;
- if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
- if (!BN_hex2bn(&a, "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC"))ABORT;//787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498")) ABORT;
- if (!BN_hex2bn(&b, "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93"))ABORT;//63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A")) ABORT;
- if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
- P = EC_POINT_new(group);
- Q = EC_POINT_new(group);
- if (!P || !Q) ABORT;
- x = BN_new();
- y = BN_new();
- z = BN_new();
- if (!x || !y || !z) ABORT;
- if (!BN_hex2bn(&x, "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"))ABORT;//421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D")) ABORT;
- if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
- if (!BN_hex2bn(&z, "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"))ABORT;//8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7")) ABORT;
- if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
-
- if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
- /* G_y value taken from the standard: */
- if (!BN_hex2bn(&z, "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"))ABORT;//0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2")) ABORT;
- if (0 != BN_cmp(y, z)) ABORT;
-
- if (EC_GROUP_get_degree(group) != 256) ABORT;
- if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
- if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
- if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
- if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
-
- EC_POINT_free(P);
- EC_POINT_free(Q);
-
- return 0;
- }
- EC_KEY* sm2_generate_key()
- {
- EC_KEY *tmpKey = NULL;
- if ((tmpKey = EC_KEY_new()) == NULL)
- return NULL;
- if (EC_KEY_set_group(tmpKey, group) == 0)
- {
- fprintf(stdout," failed\n");
- return NULL;
- }
- if(EC_KEY_generate_key(tmpKey)!=1)
- {
- printf("EC_KEY_generate_key err.\n");
- return NULL;
- }
- /* 检查密钥 */
- if(EC_KEY_check_key(tmpKey)!=1)
- {
- printf("check key err.\n");
- return NULL;
- }
- return tmpKey;
- }
- EC_POINT *sm2_compute_key(const EC_POINT *b_pub_key_r, const EC_POINT *b_pub_key, const BIGNUM *a_r,EC_KEY *a_eckey)
- {
- BN_CTX *ctx;
- EC_POINT *tmp=NULL;
- BIGNUM *x=NULL, *y=NULL, *order=NULL,*z=NULL;
- const BIGNUM *priv_key;
- const EC_GROUP* group;
- EC_POINT *ret= NULL;
- /* size_t buflen, len;*/
- unsigned char *buf=NULL;
- int i, j;
- //char *p=NULL;
- BIGNUM *x1,*x2,*t,*h;
- if ((ctx = BN_CTX_new()) == NULL) goto err;
- BN_CTX_start(ctx);
- x = BN_CTX_get(ctx);
- y = BN_CTX_get(ctx);
- order = BN_CTX_get(ctx);
- z = BN_CTX_get(ctx);
- x1 = BN_CTX_get(ctx);
- x2 = BN_CTX_get(ctx);
- t = BN_CTX_get(ctx);
- h = BN_CTX_get(ctx);
-
- priv_key = EC_KEY_get0_private_key(a_eckey);
- if (priv_key == NULL)
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
- goto err;
- }
- group = EC_KEY_get0_group(a_eckey);
- if ((tmp=EC_POINT_new(group)) == NULL)
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!EC_POINT_mul(group, tmp, a_r, NULL, NULL, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- 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, x, NULL, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- goto err;
- }
- }
- else
- {
- if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, NULL, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_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);
- j = i/2 -1;
- BN_mask_bits(x,j);
- BN_set_word(y,2);
- BN_set_word(z,j);
- BN_exp(y,y,z,ctx);
- BN_add(x1,x,y);
- BN_mod_mul(t,x1,a_r,order,ctx);
- BN_mod_add_quick(t,t,priv_key,order);
- //
-
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
- {
- if (!EC_POINT_get_affine_coordinates_GFp(group, b_pub_key_r, x, NULL, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- goto err;
- }
- }
- else
- {
- if (!EC_POINT_get_affine_coordinates_GF2m(group, b_pub_key_r, x, NULL, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- goto err;
- }
- }
- i = BN_num_bits(order);
- j = i/2 -1;
- BN_mask_bits(x,j);
- BN_set_word(y,2);
- BN_set_word(z,j);
- BN_exp(y,y,z,ctx);
- BN_add(x2,x,y);
-
- //x2*Rb+Pb;
- if (!EC_POINT_mul(group, tmp, NULL,b_pub_key_r,x2,ctx) )
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- goto err;
- }
- if ((ret=EC_POINT_new(group)) == NULL)
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!EC_POINT_add(group, ret, b_pub_key, tmp, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- goto err;
- }
- if (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx))
- {
- goto err;
- }
- if(!EC_GROUP_get_cofactor(group, h, ctx))
- {
- goto err;
- }
- BN_mul(t,t,h,ctx);
- //h*t*(x2*Rb+Pb)
- if (!EC_POINT_mul(group, ret, NULL,ret,t,ctx) )
- {
- goto err;
- }
- if (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx))
- {
- goto err;
- }
-
- err:
- if (tmp) EC_POINT_free(tmp);
- if (ctx) BN_CTX_end(ctx);
- if (ctx) BN_CTX_free(ctx);
- if (buf) OPENSSL_free(buf);
- return(ret);
- }
- int sm2_exchange_key(EC_KEY*B,EC_KEY*RB,EC_POINT*PA,EC_POINT*RA,unsigned char*ZA,unsigned char *ZB,unsigned char *outkey,size_t keylen)
- {
- EC_POINT *dhpoint = NULL;
- BN_CTX * ctx;
- BIGNUM *x, *y,*z;
- int ret = 0;
- unsigned char in[256],SB[33],tmp[33]={0};
- int inlen;
- int len;
- ctx = BN_CTX_new();
- x = BN_new();
- y = BN_new();
- z = BN_new();
- if (!x || !y ||!z) goto err;
-
- z = (BIGNUM*)EC_KEY_get0_private_key(RB);
- dhpoint = sm2_compute_key(RA,PA,z,B);
-
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
- {
- if (!EC_POINT_get_affine_coordinates_GFp(group,dhpoint, x, y, ctx))
- {
- fprintf(stdout, " failed\n");
- goto err;
- }
- }
- else
- {
- if (!EC_POINT_get_affine_coordinates_GF2m(group,dhpoint, x, y, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- goto err;
- }
- }
-
- fprintf(stdout, "\nTesting DH Point\n Xv = 0x");
- BNPrintf(x);
- fprintf(stdout, "\n Yv = 0x");
- BNPrintf( y);
- fprintf(stdout, "\n");
-
- len = BN_bn2bin(x,in);
- inlen =BN_bn2bin(y,in+len);
- inlen = inlen + len;
- memcpy(in+inlen,ZA,32);
- inlen +=32;
- memcpy(in+inlen,ZB,32);
- inlen +=32;
-
- ret = sm3_kdf(in,inlen,keylen,outkey);
- //计算可选项 Hash(0x02||yv||Hash(xv||ZA||ZB||x1||y1||x2||y2));
- BN_bn2bin(y,tmp);
- memset(in,0,sizeof(in));
- len = BN_bn2bin(x,in);
- memcpy(in+len,ZA,32);
- len +=32;
- memcpy(in+len,ZB,32);
- len +=32;
- inlen = len;
- if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
- {
- if (!EC_POINT_get_affine_coordinates_GFp(group,RA, x, y, ctx))
- {
- fprintf(stdout, " failed\n");
- goto err;
- }
- }
- else
- {
- if (!EC_POINT_get_affine_coordinates_GF2m(group,RA, x, y, ctx))
- {
- ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
- goto err;
- }
- }
- len = BN_bn2bin(x,in+inlen);
- inlen +=len;
- len =BN_bn2bin(y,in+inlen);
- inlen += len;
- len = ecKey2str(RB,in+inlen);
- inlen += len;
- sm3(in,inlen,SB);
- memset(in,0,sizeof(in));
- in[0] = 0x02;
- memcpy(in+1,tmp,32);
- memcpy(in+33,SB,32);
- sm3(in,65,SB);
- memcpy(outkey+keylen,SB,32);
- //ret = 1;
- err:
- EC_POINT_free(dhpoint);
- BN_CTX_free(ctx);
-
- return ret;
- return 0;
- }
- int sm2_end()
- {
- EC_GROUP_free(group);
- BN_CTX_free(ctx);
- CRYPTO_cleanup_all_ex_data();
- ERR_free_strings();
- ERR_remove_state(0);
- //CRYPTO_mem_leaks_fp(stderr);
- return 0;
- }
- int ecKey2str(EC_KEY*k,unsigned char*pubkey)
- {
- EC_POINT *point;
- BIGNUM *x,*y;
- int ilen = 0,tolen=0;
- unsigned char to[512] = {0};
- x = BN_new();
- y = BN_new();
- point = (EC_POINT *)EC_KEY_get0_public_key(k);
- if (!EC_POINT_get_affine_coordinates_GFp(group,point, x, y, ctx)) ABORT;
- tolen = BN_bn2bin(x,to);
- memcpy(pubkey,to,tolen);
- ilen += tolen;
- tolen = BN_bn2bin(y,to);
- memcpy(pubkey+ilen,to,tolen);
- ilen +=tolen;
- return ilen;
- }
- int pubkey2ecPoint(char*pubkey,EC_POINT**k)
- {
- char tmp[65] = {0};
- BIGNUM *x,*y;
- x = BN_new();
- y = BN_new();
- memcpy(tmp,pubkey,64);
- if(!BN_hex2bn(&x,(const char*)tmp))ABORT;
- memcpy(tmp,pubkey+64,64);
- if(!BN_hex2bn(&y,(const char*)tmp))ABORT;
- if(!EC_POINT_set_affine_coordinates_GFp(group,*k,x,y,ctx))ABORT;
- return 0;
- }
- /*
- random_k :随机数k,Ascii码表示的16进制字符串如:4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F
- ecpoint_PBx:公钥的x值:435B39CCA8F3B508C1488AFC67BE491A0F7BA07E581A0E4849A5CF70628A7E0A
- ecpont_PBy:公钥的y值:75DDBA78F15FEECB4C7895E2C1CDF5FE01DEBB2CDBADF45399CCF77BBA076A42
- M:要加密的信息,原文,不处理
- encdata:加密后的返回值,已转为Ascii码形式
- 返回值:加密返回的字符串长度
- */
- int sm2_encrypt(char*random_k,char*ecpoint_PBx,char*ecpoint_PBy,const char *M,unsigned char mdatalen,char*encdata)
- /*
- 新国密密文格式加密
- */
- {
- int len,inlen,encLen = 0,mLen = 0;
- unsigned char in[512],outkey[256]={0},C2[256]={0};
- BIGNUM *x,*y,*k;
- EC_POINT *C1,*P,*PB;
- unsigned char C3[256] = {0};
- unsigned char tsm2data[256];
- mLen = mdatalen;
- sm2_init();
-
- x = BN_new();
- y = BN_new();
- k = BN_new();
-
- C1 = EC_POINT_new(group);
-
- PB = EC_POINT_new(group);
-
- P = EC_POINT_new(group);
-
- if(!BN_hex2bn(&k,random_k))ABORT;//随机数k
-
- if(!EC_POINT_mul(group,C1,k,NULL,NULL,ctx))ABORT;
-
- if(!EC_POINT_get_affine_coordinates_GFp(group,C1,x,y,ctx))ABORT;
- /*
- printf("C1=[k]G:\r\n");
- BNPrintf(x);
- BNPrintf(y);
- */
- encdata[0] = 0x04;
- encLen = 1;
-
- memset(encdata+1,0,64);
- len = BN_bn2bin(x,tsm2data);
- memcpy(encdata+33-len,tsm2data,len);
- len=32;
- inlen = BN_bn2bin(y,tsm2data);
- memcpy(encdata+65-inlen,tsm2data,inlen);
- inlen=32;
- encLen += len + inlen;
-
- if(!BN_hex2bn(&x,ecpoint_PBx))ABORT;//xB
- if(!BN_hex2bn(&y,ecpoint_PBy))ABORT;//yB
-
- if(!EC_POINT_set_affine_coordinates_GFp(group,PB,x,y,ctx))ABORT;
-
- if(!EC_POINT_mul(group,P,NULL,PB,k,ctx))ABORT;
-
- if(!EC_POINT_get_affine_coordinates_GFp(group,P,x,y,ctx))ABORT;
- /*
- printf("P=[k]PB:\r\n");
- BNPrintf(x);
- BNPrintf(y);
- */
- memset(in,0,64);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+64-inlen,tsm2data,inlen);
- inlen = 64;
-
-
- sm3_kdf(in,inlen,mLen,outkey);
-
- for(len=0;len<mLen;len++)
- {
- // printf("%02X ",outkey[len]);
- C2[len] = M[len]^outkey[len];
- }
-
- memcpy(encdata+encLen,C2,mLen);
- encLen +=mLen;
-
- memset(in,0,32);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
- memcpy(in+len,M,mdatalen);
- len +=mdatalen;
- memset(in+len,0,32);
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+len+32-inlen,tsm2data,inlen);
- inlen=32;
- inlen +=len;
-
- sm3(in,inlen,C3);
- memcpy(encdata+encLen,C3,32);
- encLen +=32;
- ConvAscii((unsigned char*)encdata,(char*)in,encLen);
- memcpy(encdata,in,encLen*2);
- encdata[encLen*2]=0x00;
- sm2_end();
- return encLen*2;
- }
- /*
- random_k :随机数k,Ascii码表示的16进制字符串如:4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F
- ecpoint_PBx:公钥的x值:435B39CCA8F3B508C1488AFC67BE491A0F7BA07E581A0E4849A5CF70628A7E0A
- ecpont_PBy:公钥的y值:75DDBA78F15FEECB4C7895E2C1CDF5FE01DEBB2CDBADF45399CCF77BBA076A42
- M:要加密的信息,原文,不处理
- encdata:加密后的返回值,已转为Ascii码形式
- 返回值:加密返回的字符串长度
- */
- int sm2_encrypt_new(char*random_k,char*ecpoint_PBx,char*ecpoint_PBy,const char *M,unsigned char mdatalen,char*encdata)
- /*
- 新国密密文格式加密
- */
- {
- int len,inlen,encLen = 0,mLen = 0;
- unsigned char in[512],outkey[256]={0},C2[256]={0};
- unsigned char tsm2data[256];
- BIGNUM *x,*y,*k;
- EC_POINT *C1,*P,*PB;
- unsigned char C3[256] = {0};
-
- mLen = mdatalen;
- sm2_init();
-
- x = BN_new();
- y = BN_new();
- k = BN_new();
-
- C1 = EC_POINT_new(group);
-
- PB = EC_POINT_new(group);
-
- P = EC_POINT_new(group);
-
- if (!BN_hex2bn(&k, random_k)) {
- printf("BN_hex2bn failed, abort!\n");
- ABORT;//???k
- }
-
-
- if (!EC_POINT_mul(group, C1, k, NULL, NULL, ctx)) {
- printf("EC_POINT_mul failed, abort!\n");
- ABORT;
- }
-
- if (!EC_POINT_get_affine_coordinates_GFp(group, C1, x, y, ctx)) {
- printf("EC_POINT_get_affine_coordinates_GFp failed, abort!\n");
- ABORT;
- }
-
- encLen = 0;
- memset(encdata,0,64);
- len = BN_bn2bin(x,tsm2data);
- memcpy(encdata+32-len,tsm2data,len);
- len=32;
- inlen = BN_bn2bin(y,tsm2data);
- memcpy(encdata+64-inlen,tsm2data,inlen);
- inlen=32;
- encLen += len + inlen;
-
- if (!BN_hex2bn(&x, ecpoint_PBx)) {
- printf("BN_hex2bn for x failed, abort!\n");
- ABORT;
- }
- if (!BN_hex2bn(&y, ecpoint_PBy)) {
- printf("BN_hex2bn for y failed, abort!\n");
- ABORT;
- }
-
- if (!EC_POINT_set_affine_coordinates_GFp(group, PB, x, y, ctx)) {
- printf("EC_POINT_set_affine_coordinates_GFp for PB failed, abort!\n");
- ABORT;
- }
-
- if (!EC_POINT_mul(group, P, NULL, PB, k, ctx)) {
- printf("EC_POINT_mul failed, abort!\n");
- ABORT;
- }
-
- if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) {
- printf("EC_POINT_get_affine_coordinates_GFp for P failed, abort!\n");
- ABORT;
- }
- /*
- printf("P=[k]PB:\r\n");
- BNPrintf(x);
- BNPrintf(y);
- */
- memset(in,0,64);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+64-inlen,tsm2data,inlen);
- inlen = 64;
-
-
- sm3_kdf(in,inlen,mLen,outkey);
-
- for(len=0;len<mLen;len++)
- {
- // printf("%02X ",outkey[len]);
- C2[len] = M[len]^outkey[len];
- }
-
- memcpy(encdata+encLen+32,C2,mLen);
-
- memset(in,0,32);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
- memcpy(in+len,M,mdatalen);
- len +=mdatalen;
- memset(in+len,0,32);
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+len+32-inlen,tsm2data,inlen);
- inlen=32;
- inlen +=len;
-
- sm3(in,inlen,C3);
- memcpy(encdata+encLen,C3,32);
- encLen +=mLen;
- encLen +=32;
- ConvAscii((unsigned char*)encdata,(char*)in,encLen);
- memcpy(encdata,in,encLen*2);
- encdata[encLen*2]=0x00;
- sm2_end();
- return encLen*2;
- }
- /*
- decdata:Ascii码表示的16进制字符串,sm2_encrypt的返回值字符串,Ascii码的16进制形式
- dB:B的私钥,如1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0
- M:解密后的值,没有编码
- 返回值:>0 M的长度
- =0 解密失败
- */
- int sm2_decrypt(const char*decdata,const char*dB,char*M)
- /*
- 旧国密密文格式解密
- */
- {
- int len,inlen,mLen = 0;
- unsigned char in[256],outkey[256]={0};
- unsigned char C2[256]={0},C3[256]={0};
- char xstr[65]={0},ystr[65]={0};
- unsigned char tsm2data[256];
- EC_POINT *C1,*S,*P;
- BIGNUM *x,*y,*h;
- x = BN_new();
- y = BN_new();
- h = BN_new();
- sm2_init();
-
- C1 = EC_POINT_new(group);
- S = EC_POINT_new(group);
- P = EC_POINT_new(group);
- memcpy(xstr,decdata+2,64);
- memcpy(ystr,decdata+66,64);
- len = strlen(decdata);
- mLen = len - 130 - 64;
- AsciiToHex((char*)decdata+130,C2,64);
- AsciiToHex((char*)decdata+len-64,C3,64);
- mLen /=2;
- /*
- memcpy(C2,decdata+130,mLen);
- memcpy(C3,decdata+len-64,64);
- */
- if (!BN_hex2bn(&x, xstr)) {
- printf("BN_hex2bn for x failed, abort!\n");
- ABORT;
- }
- if (!BN_hex2bn(&y, ystr)) {
- printf("BN_hex2bn for y failed, abort!\n");
- ABORT;
- }
- if (!EC_POINT_set_affine_coordinates_GFp(group, C1, x, y, ctx)) {
- printf("EC_POINT_set_affine_coordinates_GFp for C1 for y failed, abort!\n");
- ABORT;
- }
- /*
- printf("C1:\r\n");
- BNPrintf(x);
- printf("\r\n");
- BNPrintf(y);
- printf("\r\n");
- */
- if (!EC_POINT_is_on_curve(group, C1, ctx)) {
- printf("EC_POINT_is_on_curve failed, abort!\n");
- ABORT;
- }
-
- if (!EC_GROUP_get_cofactor(group, h, ctx)) {
- printf("EC_GROUP_get_cofactor failed, abort!\n");
- ABORT;
- }
- if (!EC_POINT_mul(group, S, NULL, C1, h, ctx)) {
- printf("EC_POINT_mul failed, abort!\n");
- ABORT;
- }
- if(EC_POINT_is_at_infinity(group,S)) //S是无穷远点
- {
- printf("EC_POINT_is_at_infinity failed, abort!\n");
- ABORT;
- }
- if (!BN_hex2bn(&x, dB)) {
- printf("BN_hex2bn failed, abort!\n");
- ABORT;
- }
- if (!EC_POINT_mul(group, P, NULL, C1, x, ctx)) {
- printf("EC_POINT_mul failed, abort!\n");
- ABORT;
- }
- if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) {
- printf("EC_POINT_get_affine_coordinates_GFp for P failed, abort!\n");
- ABORT;
- }
- /*
- printf("P=[dB]C1:\r\n");
- BNPrintf(x);
- printf("\r\n");
- BNPrintf(y);
- printf("\r\n");
- */
- memset(in,0,64);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+64-inlen,tsm2data,inlen);
- inlen = 64;
-
-
- sm3_kdf(in,inlen,mLen,outkey);
-
-
- for(len=0;len<mLen;len++)
- {
- M[len] = C2[len]^outkey[len];
- }
- M[mLen] = 0x00;
-
- memset(in,0,32);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
-
- memcpy(in+len,M,mLen);
- len +=mLen;
- memset(in+len,0,32);
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+len+32-inlen,tsm2data,inlen);
- inlen=32;
- inlen +=len;
- sm3(in,inlen,C2);
- sm2_end();
- if(memcmp(C2,C3,32)==0)
- {
- return mLen;
- }
- else
- {
- return 0;
- }
- }
- /*
- decdata:Ascii码表示的16进制字符串,sm2_encrypt的返回值字符串,Ascii码的16进制形式
- dB:B的私钥,如1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0
- M:解密后的值,没有编码
- 返回值:>0 M的长度
- =0 解密失败
- */
- int sm2_decrypt_new(const char*decdata,const char*dB,char*M)
- /*
- 新国密密文格式解密
- */
- {
- int len,inlen,mLen = 0;
- unsigned char in[256],outkey[256]={0};
- unsigned char C2[256]={0},C3[256]={0};
- unsigned char tsm2data[256];
- char xstr[65]={0},ystr[65]={0};
- EC_POINT *C1,*S,*P;
- BIGNUM *x,*y,*h;
- x = BN_new();
- y = BN_new();
- h = BN_new();
- sm2_init();
-
- C1 = EC_POINT_new(group);
- S = EC_POINT_new(group);
- P = EC_POINT_new(group);
- memcpy(xstr,decdata,64);
- memcpy(ystr,decdata+64,64);
- len = strlen(decdata);
- mLen = len - 128 - 64;
- AsciiToHex((char*)decdata+128,C3,64);
- AsciiToHex((char*)decdata+128+64,C2,mLen);
- mLen /=2;
- /*
- memcpy(C2,decdata+130,mLen);
- memcpy(C3,decdata+len-64,64);
- */
- if(!BN_hex2bn(&x,xstr))ABORT;
- if(!BN_hex2bn(&y,ystr))ABORT;
- if(!EC_POINT_set_affine_coordinates_GFp(group,C1,x,y,ctx))ABORT;
- /*
- printf("C1:\r\n");
- BNPrintf(x);
- printf("\r\n");
- BNPrintf(y);
- printf("\r\n");
- */
- if(!EC_POINT_is_on_curve(group,C1,ctx))ABORT;
-
- if(!EC_GROUP_get_cofactor(group,h,ctx))ABORT;
- if(!EC_POINT_mul(group,S,NULL,C1,h,ctx))ABORT;
- if(EC_POINT_is_at_infinity(group,S))ABORT; //S是无穷远点
- if(!BN_hex2bn(&x,dB))ABORT;
- if(!EC_POINT_mul(group,P,NULL,C1,x,ctx))ABORT;
- if(!EC_POINT_get_affine_coordinates_GFp(group,P,x,y,ctx))ABORT;
- /*
- printf("P=[dB]C1:\r\n");
- BNPrintf(x);
- printf("\r\n");
- BNPrintf(y);
- printf("\r\n");
- */
- memset(in,0,64);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+64-inlen,tsm2data,inlen);
- inlen = 64;
-
-
- sm3_kdf(in,inlen,mLen,outkey);
-
-
- for(len=0;len<mLen;len++)
- {
- M[len] = C2[len]^outkey[len];
- }
- M[mLen] = 0x00;
-
- memset(in,0,32);
- len = BN_bn2bin(x,tsm2data);
- memcpy(in+32-len,tsm2data,len);
- len=32;
-
- memcpy(in+len,M,mLen);
- len +=mLen;
- memset(in+len,0,32);
- inlen =BN_bn2bin(y,tsm2data);
- memcpy(in+len+32-inlen,tsm2data,inlen);
- inlen=32;
- inlen +=len;
-
- sm3(in,inlen,C2);
- sm2_end();
- if(memcmp(C2,C3,32)==0)
- {
- return mLen;
- }
- else
- {
- return 0;
- }
- }
- int main11()
- {
- EC_KEY *B = NULL,*RB = NULL;
- EC_POINT *PA,*RA,*PB,*PRB;
- BIGNUM *x,*y;
- unsigned char outkey[32] = {0};
- unsigned char ZA[33]={0},ZB[33]={0};
- unsigned char pubkey[130]={0};
- int i;
-
- x = BN_new();
- y = BN_new();
- sm2_init();
-
- PA = EC_POINT_new(group);
-
- RA = EC_POINT_new(group);
- /* 指定私钥dB和rB */
- PB = EC_POINT_new(group);
-
- PRB = EC_POINT_new(group);
- if ((B = EC_KEY_new()) == NULL)
- return 1;
- if (EC_KEY_set_group(B, group) == 0)
- {
- fprintf(stdout," failed\n");
- return 1;
- }
-
- if ((RB = EC_KEY_new()) == NULL)
- return 1;
- if (EC_KEY_set_group(RB, group) == 0)
- {
- fprintf(stdout," failed\n");
- return 1;
- }
- if (!BN_hex2bn(&x, "785129917D45A9EA5437A59356B82338EAADDA6CEB199088F14AE10DEFA229B5"))ABORT;//6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE")) ABORT;
- if (!EC_POINT_mul(group,PB, x, NULL, NULL, ctx)) ABORT;
-
- EC_KEY_set_private_key(B,x);
- EC_KEY_set_public_key(B, PB);
-
- if (!BN_hex2bn(&x, "7E07124814B309489125EAED101113164EBF0F3458C5BD88335C1F9D596243D6"))ABORT;//6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE")) ABORT;
- if (!EC_POINT_mul(group,PRB, x, NULL, NULL, ctx)) ABORT;
- EC_KEY_set_private_key(RB,x);
- EC_KEY_set_public_key(RB, PRB);
- //*/
- //随机产生dB和rB
- // B = sm2_generate_key();
-
- // RB = sm2_generate_key();
- ecKey2str(B,pubkey);
- if(!PA || !RA)
- return 1;
- if(!BN_hex2bn(&x,"160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C94232"))ABORT;
- if(!BN_hex2bn(&y,"4A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F"))ABORT;
- if(!EC_POINT_set_affine_coordinates_GFp(group,PA,x,y,ctx))ABORT;
- // pubkey2ecPoint("160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C942324A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F",&PA);
- if(!BN_hex2bn(&x,"64ced1bdBC99D590049B434D0FD73428CF608A5DB8FE5CE07F15026940BAE40E"))ABORT;
- if(!BN_hex2bn(&y,"376629C7AB21E7DB260922499DDB118F07CE8EAAE3E7720AFEF6A5CC062070C0"))ABORT;
- if(!EC_POINT_set_affine_coordinates_GFp(group,RA,x,y,ctx))ABORT;
- memcpy(ZA,"\x3B\x85\xA5\x71\x79\xE1\x1E\x7E\x51\x3A\xA6\x22\x99\x1F\x2C\xA7\x4D\x18\x07\xA0\xBD\x4D\x4B\x38\xF9\x09\x87\xA1\x7A\xC2\x45\xB1",32);
- memcpy(ZB,"\x79\xC9\x88\xD6\x32\x29\xD9\x7E\xF1\x9F\xE0\x2C\xA1\x05\x6E\x01\xE6\xA7\x41\x1E\xD2\x46\x94\xAA\x8F\x83\x4F\x4A\x4A\xB0\x22\xF7",32);
- sm2_exchange_key(B,RB,PA,RA,ZA,ZB,outkey,16);
- fprintf(stdout,"\nExchange key --KDF(Xv||Yv)-- :");
- for(i=0; i<16; i++)
- printf("%02X",outkey[i]);
- printf("\n");
- sm2_end();
- return 0;
- }
|