sm2.cpp 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  1. #include "stdafx.h"
  2. #include "sm2.h"
  3. #include "kdf.h"
  4. #include "public.h"
  5. static const char rnd_seed[] = "string to make the random number generator think it has entropy";
  6. //#pragma comment(lib,"libeay32.lib")
  7. BN_CTX *ctx = NULL;
  8. EC_GROUP *group;
  9. void BNPrintf(BIGNUM* bn)
  10. {
  11. char *p=NULL;
  12. p=BN_bn2hex(bn);
  13. printf("%s",p);
  14. OPENSSL_free(p);
  15. }
  16. int sm2_init()
  17. {
  18. BIGNUM *p, *a, *b;
  19. BIGNUM *x, *y, *z;
  20. EC_POINT *P, *Q;
  21. //CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0);
  22. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
  23. ERR_load_crypto_strings();
  24. RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */
  25. /*
  26. 素数p:FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF
  27. 系数a:FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC
  28. 系数b:28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93
  29. 基点G:
  30. xG:32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7
  31. yG:BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0
  32. 阶n:FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123
  33. */
  34. ctx = BN_CTX_new();
  35. if (!ctx) ABORT;
  36. /* Curve SM2 (Chinese National Algorithm) */
  37. //http://www.oscca.gov.cn/News/201012/News_1197.htm
  38. p = BN_new();
  39. a = BN_new();
  40. b = BN_new();
  41. if (!p || !a || !b) ABORT;
  42. group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use EC_GROUP_new_curve_GFp
  43. * so that the library gets to choose the EC_METHOD */
  44. if (!group) ABORT;
  45. if (!BN_hex2bn(&p, "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"))ABORT;//8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3")) ABORT;
  46. if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
  47. if (!BN_hex2bn(&a, "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC"))ABORT;//787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498")) ABORT;
  48. if (!BN_hex2bn(&b, "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93"))ABORT;//63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A")) ABORT;
  49. if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) ABORT;
  50. P = EC_POINT_new(group);
  51. Q = EC_POINT_new(group);
  52. if (!P || !Q) ABORT;
  53. x = BN_new();
  54. y = BN_new();
  55. z = BN_new();
  56. if (!x || !y || !z) ABORT;
  57. if (!BN_hex2bn(&x, "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"))ABORT;//421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D")) ABORT;
  58. if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT;
  59. if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT;
  60. if (!BN_hex2bn(&z, "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"))ABORT;//8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7")) ABORT;
  61. if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT;
  62. if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT;
  63. /* G_y value taken from the standard: */
  64. if (!BN_hex2bn(&z, "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"))ABORT;//0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2")) ABORT;
  65. if (0 != BN_cmp(y, z)) ABORT;
  66. if (EC_GROUP_get_degree(group) != 256) ABORT;
  67. if (!EC_GROUP_get_order(group, z, ctx)) ABORT;
  68. if (!EC_GROUP_precompute_mult(group, ctx)) ABORT;
  69. if (!EC_POINT_mul(group, Q, z, NULL, NULL, ctx)) ABORT;
  70. if (!EC_POINT_is_at_infinity(group, Q)) ABORT;
  71. EC_POINT_free(P);
  72. EC_POINT_free(Q);
  73. return 0;
  74. }
  75. EC_KEY* sm2_generate_key()
  76. {
  77. EC_KEY *tmpKey = NULL;
  78. if ((tmpKey = EC_KEY_new()) == NULL)
  79. return NULL;
  80. if (EC_KEY_set_group(tmpKey, group) == 0)
  81. {
  82. fprintf(stdout," failed\n");
  83. return NULL;
  84. }
  85. if(EC_KEY_generate_key(tmpKey)!=1)
  86. {
  87. printf("EC_KEY_generate_key err.\n");
  88. return NULL;
  89. }
  90. /* 检查密钥 */
  91. if(EC_KEY_check_key(tmpKey)!=1)
  92. {
  93. printf("check key err.\n");
  94. return NULL;
  95. }
  96. return tmpKey;
  97. }
  98. 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)
  99. {
  100. BN_CTX *ctx;
  101. EC_POINT *tmp=NULL;
  102. BIGNUM *x=NULL, *y=NULL, *order=NULL,*z=NULL;
  103. const BIGNUM *priv_key;
  104. const EC_GROUP* group;
  105. EC_POINT *ret= NULL;
  106. /* size_t buflen, len;*/
  107. unsigned char *buf=NULL;
  108. int i, j;
  109. //char *p=NULL;
  110. BIGNUM *x1,*x2,*t,*h;
  111. if ((ctx = BN_CTX_new()) == NULL) goto err;
  112. BN_CTX_start(ctx);
  113. x = BN_CTX_get(ctx);
  114. y = BN_CTX_get(ctx);
  115. order = BN_CTX_get(ctx);
  116. z = BN_CTX_get(ctx);
  117. x1 = BN_CTX_get(ctx);
  118. x2 = BN_CTX_get(ctx);
  119. t = BN_CTX_get(ctx);
  120. h = BN_CTX_get(ctx);
  121. priv_key = EC_KEY_get0_private_key(a_eckey);
  122. if (priv_key == NULL)
  123. {
  124. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_NO_PRIVATE_VALUE);
  125. goto err;
  126. }
  127. group = EC_KEY_get0_group(a_eckey);
  128. if ((tmp=EC_POINT_new(group)) == NULL)
  129. {
  130. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
  131. goto err;
  132. }
  133. if (!EC_POINT_mul(group, tmp, a_r, NULL, NULL, ctx))
  134. {
  135. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  136. goto err;
  137. }
  138. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  139. {
  140. if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx))
  141. {
  142. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  143. goto err;
  144. }
  145. }
  146. else
  147. {
  148. if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, NULL, ctx))
  149. {
  150. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  151. goto err;
  152. }
  153. }
  154. if (!EC_GROUP_get_order(group, order, ctx))
  155. {
  156. ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
  157. goto err;
  158. }
  159. i = BN_num_bits(order);
  160. j = i/2 -1;
  161. BN_mask_bits(x,j);
  162. BN_set_word(y,2);
  163. BN_set_word(z,j);
  164. BN_exp(y,y,z,ctx);
  165. BN_add(x1,x,y);
  166. BN_mod_mul(t,x1,a_r,order,ctx);
  167. BN_mod_add_quick(t,t,priv_key,order);
  168. //
  169. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  170. {
  171. if (!EC_POINT_get_affine_coordinates_GFp(group, b_pub_key_r, x, NULL, ctx))
  172. {
  173. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  174. goto err;
  175. }
  176. }
  177. else
  178. {
  179. if (!EC_POINT_get_affine_coordinates_GF2m(group, b_pub_key_r, x, NULL, ctx))
  180. {
  181. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  182. goto err;
  183. }
  184. }
  185. i = BN_num_bits(order);
  186. j = i/2 -1;
  187. BN_mask_bits(x,j);
  188. BN_set_word(y,2);
  189. BN_set_word(z,j);
  190. BN_exp(y,y,z,ctx);
  191. BN_add(x2,x,y);
  192. //x2*Rb+Pb;
  193. if (!EC_POINT_mul(group, tmp, NULL,b_pub_key_r,x2,ctx) )
  194. {
  195. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  196. goto err;
  197. }
  198. if ((ret=EC_POINT_new(group)) == NULL)
  199. {
  200. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ERR_R_MALLOC_FAILURE);
  201. goto err;
  202. }
  203. if (!EC_POINT_add(group, ret, b_pub_key, tmp, ctx))
  204. {
  205. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  206. goto err;
  207. }
  208. if (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx))
  209. {
  210. goto err;
  211. }
  212. if(!EC_GROUP_get_cofactor(group, h, ctx))
  213. {
  214. goto err;
  215. }
  216. BN_mul(t,t,h,ctx);
  217. //h*t*(x2*Rb+Pb)
  218. if (!EC_POINT_mul(group, ret, NULL,ret,t,ctx) )
  219. {
  220. goto err;
  221. }
  222. if (!EC_POINT_get_affine_coordinates_GFp(group,ret, x, y, ctx))
  223. {
  224. goto err;
  225. }
  226. err:
  227. if (tmp) EC_POINT_free(tmp);
  228. if (ctx) BN_CTX_end(ctx);
  229. if (ctx) BN_CTX_free(ctx);
  230. if (buf) OPENSSL_free(buf);
  231. return(ret);
  232. }
  233. 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)
  234. {
  235. EC_POINT *dhpoint = NULL;
  236. BN_CTX * ctx;
  237. BIGNUM *x, *y,*z;
  238. int ret = 0;
  239. unsigned char in[256],SB[33],tmp[33]={0};
  240. int inlen;
  241. int len;
  242. ctx = BN_CTX_new();
  243. x = BN_new();
  244. y = BN_new();
  245. z = BN_new();
  246. if (!x || !y ||!z) goto err;
  247. z = (BIGNUM*)EC_KEY_get0_private_key(RB);
  248. dhpoint = sm2_compute_key(RA,PA,z,B);
  249. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  250. {
  251. if (!EC_POINT_get_affine_coordinates_GFp(group,dhpoint, x, y, ctx))
  252. {
  253. fprintf(stdout, " failed\n");
  254. goto err;
  255. }
  256. }
  257. else
  258. {
  259. if (!EC_POINT_get_affine_coordinates_GF2m(group,dhpoint, x, y, ctx))
  260. {
  261. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  262. goto err;
  263. }
  264. }
  265. fprintf(stdout, "\nTesting DH Point\n Xv = 0x");
  266. BNPrintf(x);
  267. fprintf(stdout, "\n Yv = 0x");
  268. BNPrintf( y);
  269. fprintf(stdout, "\n");
  270. len = BN_bn2bin(x,in);
  271. inlen =BN_bn2bin(y,in+len);
  272. inlen = inlen + len;
  273. memcpy(in+inlen,ZA,32);
  274. inlen +=32;
  275. memcpy(in+inlen,ZB,32);
  276. inlen +=32;
  277. ret = sm3_kdf(in,inlen,keylen,outkey);
  278. //计算可选项 Hash(0x02||yv||Hash(xv||ZA||ZB||x1||y1||x2||y2));
  279. BN_bn2bin(y,tmp);
  280. memset(in,0,sizeof(in));
  281. len = BN_bn2bin(x,in);
  282. memcpy(in+len,ZA,32);
  283. len +=32;
  284. memcpy(in+len,ZB,32);
  285. len +=32;
  286. inlen = len;
  287. if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field)
  288. {
  289. if (!EC_POINT_get_affine_coordinates_GFp(group,RA, x, y, ctx))
  290. {
  291. fprintf(stdout, " failed\n");
  292. goto err;
  293. }
  294. }
  295. else
  296. {
  297. if (!EC_POINT_get_affine_coordinates_GF2m(group,RA, x, y, ctx))
  298. {
  299. ECDHerr(ECDH_F_ECDH_COMPUTE_KEY,ECDH_R_POINT_ARITHMETIC_FAILURE);
  300. goto err;
  301. }
  302. }
  303. len = BN_bn2bin(x,in+inlen);
  304. inlen +=len;
  305. len =BN_bn2bin(y,in+inlen);
  306. inlen += len;
  307. len = ecKey2str(RB,in+inlen);
  308. inlen += len;
  309. sm3(in,inlen,SB);
  310. memset(in,0,sizeof(in));
  311. in[0] = 0x02;
  312. memcpy(in+1,tmp,32);
  313. memcpy(in+33,SB,32);
  314. sm3(in,65,SB);
  315. memcpy(outkey+keylen,SB,32);
  316. //ret = 1;
  317. err:
  318. EC_POINT_free(dhpoint);
  319. BN_CTX_free(ctx);
  320. return ret;
  321. return 0;
  322. }
  323. int sm2_end()
  324. {
  325. EC_GROUP_free(group);
  326. BN_CTX_free(ctx);
  327. CRYPTO_cleanup_all_ex_data();
  328. ERR_free_strings();
  329. ERR_remove_state(0);
  330. //CRYPTO_mem_leaks_fp(stderr);
  331. return 0;
  332. }
  333. int ecKey2str(EC_KEY*k,unsigned char*pubkey)
  334. {
  335. EC_POINT *point;
  336. BIGNUM *x,*y;
  337. int ilen = 0,tolen=0;
  338. unsigned char to[512] = {0};
  339. x = BN_new();
  340. y = BN_new();
  341. point = (EC_POINT *)EC_KEY_get0_public_key(k);
  342. if (!EC_POINT_get_affine_coordinates_GFp(group,point, x, y, ctx)) ABORT;
  343. tolen = BN_bn2bin(x,to);
  344. memcpy(pubkey,to,tolen);
  345. ilen += tolen;
  346. tolen = BN_bn2bin(y,to);
  347. memcpy(pubkey+ilen,to,tolen);
  348. ilen +=tolen;
  349. return ilen;
  350. }
  351. int pubkey2ecPoint(char*pubkey,EC_POINT**k)
  352. {
  353. char tmp[65] = {0};
  354. BIGNUM *x,*y;
  355. x = BN_new();
  356. y = BN_new();
  357. memcpy(tmp,pubkey,64);
  358. if(!BN_hex2bn(&x,(const char*)tmp))ABORT;
  359. memcpy(tmp,pubkey+64,64);
  360. if(!BN_hex2bn(&y,(const char*)tmp))ABORT;
  361. if(!EC_POINT_set_affine_coordinates_GFp(group,*k,x,y,ctx))ABORT;
  362. return 0;
  363. }
  364. /*
  365. random_k :随机数k,Ascii码表示的16进制字符串如:4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F
  366. ecpoint_PBx:公钥的x值:435B39CCA8F3B508C1488AFC67BE491A0F7BA07E581A0E4849A5CF70628A7E0A
  367. ecpont_PBy:公钥的y值:75DDBA78F15FEECB4C7895E2C1CDF5FE01DEBB2CDBADF45399CCF77BBA076A42
  368. M:要加密的信息,原文,不处理
  369. encdata:加密后的返回值,已转为Ascii码形式
  370. 返回值:加密返回的字符串长度
  371. */
  372. int sm2_encrypt(char*random_k,char*ecpoint_PBx,char*ecpoint_PBy,const char *M,unsigned char mdatalen,char*encdata)
  373. /*
  374. 新国密密文格式加密
  375. */
  376. {
  377. int len,inlen,encLen = 0,mLen = 0;
  378. unsigned char in[512],outkey[256]={0},C2[256]={0};
  379. BIGNUM *x,*y,*k;
  380. EC_POINT *C1,*P,*PB;
  381. unsigned char C3[256] = {0};
  382. unsigned char tsm2data[256];
  383. mLen = mdatalen;
  384. sm2_init();
  385. x = BN_new();
  386. y = BN_new();
  387. k = BN_new();
  388. C1 = EC_POINT_new(group);
  389. PB = EC_POINT_new(group);
  390. P = EC_POINT_new(group);
  391. if(!BN_hex2bn(&k,random_k))ABORT;//随机数k
  392. if(!EC_POINT_mul(group,C1,k,NULL,NULL,ctx))ABORT;
  393. if(!EC_POINT_get_affine_coordinates_GFp(group,C1,x,y,ctx))ABORT;
  394. /*
  395. printf("C1=[k]G:\r\n");
  396. BNPrintf(x);
  397. BNPrintf(y);
  398. */
  399. encdata[0] = 0x04;
  400. encLen = 1;
  401. memset(encdata+1,0,64);
  402. len = BN_bn2bin(x,tsm2data);
  403. memcpy(encdata+33-len,tsm2data,len);
  404. len=32;
  405. inlen = BN_bn2bin(y,tsm2data);
  406. memcpy(encdata+65-inlen,tsm2data,inlen);
  407. inlen=32;
  408. encLen += len + inlen;
  409. if(!BN_hex2bn(&x,ecpoint_PBx))ABORT;//xB
  410. if(!BN_hex2bn(&y,ecpoint_PBy))ABORT;//yB
  411. if(!EC_POINT_set_affine_coordinates_GFp(group,PB,x,y,ctx))ABORT;
  412. if(!EC_POINT_mul(group,P,NULL,PB,k,ctx))ABORT;
  413. if(!EC_POINT_get_affine_coordinates_GFp(group,P,x,y,ctx))ABORT;
  414. /*
  415. printf("P=[k]PB:\r\n");
  416. BNPrintf(x);
  417. BNPrintf(y);
  418. */
  419. memset(in,0,64);
  420. len = BN_bn2bin(x,tsm2data);
  421. memcpy(in+32-len,tsm2data,len);
  422. len=32;
  423. inlen =BN_bn2bin(y,tsm2data);
  424. memcpy(in+64-inlen,tsm2data,inlen);
  425. inlen = 64;
  426. sm3_kdf(in,inlen,mLen,outkey);
  427. for(len=0;len<mLen;len++)
  428. {
  429. // printf("%02X ",outkey[len]);
  430. C2[len] = M[len]^outkey[len];
  431. }
  432. memcpy(encdata+encLen,C2,mLen);
  433. encLen +=mLen;
  434. memset(in,0,32);
  435. len = BN_bn2bin(x,tsm2data);
  436. memcpy(in+32-len,tsm2data,len);
  437. len=32;
  438. memcpy(in+len,M,mdatalen);
  439. len +=mdatalen;
  440. memset(in+len,0,32);
  441. inlen =BN_bn2bin(y,tsm2data);
  442. memcpy(in+len+32-inlen,tsm2data,inlen);
  443. inlen=32;
  444. inlen +=len;
  445. sm3(in,inlen,C3);
  446. memcpy(encdata+encLen,C3,32);
  447. encLen +=32;
  448. ConvAscii((unsigned char*)encdata,(char*)in,encLen);
  449. memcpy(encdata,in,encLen*2);
  450. encdata[encLen*2]=0x00;
  451. sm2_end();
  452. return encLen*2;
  453. }
  454. /*
  455. random_k :随机数k,Ascii码表示的16进制字符串如:4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F
  456. ecpoint_PBx:公钥的x值:435B39CCA8F3B508C1488AFC67BE491A0F7BA07E581A0E4849A5CF70628A7E0A
  457. ecpont_PBy:公钥的y值:75DDBA78F15FEECB4C7895E2C1CDF5FE01DEBB2CDBADF45399CCF77BBA076A42
  458. M:要加密的信息,原文,不处理
  459. encdata:加密后的返回值,已转为Ascii码形式
  460. 返回值:加密返回的字符串长度
  461. */
  462. int sm2_encrypt_new(char*random_k,char*ecpoint_PBx,char*ecpoint_PBy,const char *M,unsigned char mdatalen,char*encdata)
  463. /*
  464. 新国密密文格式加密
  465. */
  466. {
  467. int len,inlen,encLen = 0,mLen = 0;
  468. unsigned char in[512],outkey[256]={0},C2[256]={0};
  469. unsigned char tsm2data[256];
  470. BIGNUM *x,*y,*k;
  471. EC_POINT *C1,*P,*PB;
  472. unsigned char C3[256] = {0};
  473. mLen = mdatalen;
  474. sm2_init();
  475. x = BN_new();
  476. y = BN_new();
  477. k = BN_new();
  478. C1 = EC_POINT_new(group);
  479. PB = EC_POINT_new(group);
  480. P = EC_POINT_new(group);
  481. if (!BN_hex2bn(&k, random_k)) {
  482. printf("BN_hex2bn failed, abort!\n");
  483. ABORT;//???k
  484. }
  485. if (!EC_POINT_mul(group, C1, k, NULL, NULL, ctx)) {
  486. printf("EC_POINT_mul failed, abort!\n");
  487. ABORT;
  488. }
  489. if (!EC_POINT_get_affine_coordinates_GFp(group, C1, x, y, ctx)) {
  490. printf("EC_POINT_get_affine_coordinates_GFp failed, abort!\n");
  491. ABORT;
  492. }
  493. encLen = 0;
  494. memset(encdata,0,64);
  495. len = BN_bn2bin(x,tsm2data);
  496. memcpy(encdata+32-len,tsm2data,len);
  497. len=32;
  498. inlen = BN_bn2bin(y,tsm2data);
  499. memcpy(encdata+64-inlen,tsm2data,inlen);
  500. inlen=32;
  501. encLen += len + inlen;
  502. if (!BN_hex2bn(&x, ecpoint_PBx)) {
  503. printf("BN_hex2bn for x failed, abort!\n");
  504. ABORT;
  505. }
  506. if (!BN_hex2bn(&y, ecpoint_PBy)) {
  507. printf("BN_hex2bn for y failed, abort!\n");
  508. ABORT;
  509. }
  510. if (!EC_POINT_set_affine_coordinates_GFp(group, PB, x, y, ctx)) {
  511. printf("EC_POINT_set_affine_coordinates_GFp for PB failed, abort!\n");
  512. ABORT;
  513. }
  514. if (!EC_POINT_mul(group, P, NULL, PB, k, ctx)) {
  515. printf("EC_POINT_mul failed, abort!\n");
  516. ABORT;
  517. }
  518. if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) {
  519. printf("EC_POINT_get_affine_coordinates_GFp for P failed, abort!\n");
  520. ABORT;
  521. }
  522. /*
  523. printf("P=[k]PB:\r\n");
  524. BNPrintf(x);
  525. BNPrintf(y);
  526. */
  527. memset(in,0,64);
  528. len = BN_bn2bin(x,tsm2data);
  529. memcpy(in+32-len,tsm2data,len);
  530. len=32;
  531. inlen =BN_bn2bin(y,tsm2data);
  532. memcpy(in+64-inlen,tsm2data,inlen);
  533. inlen = 64;
  534. sm3_kdf(in,inlen,mLen,outkey);
  535. for(len=0;len<mLen;len++)
  536. {
  537. // printf("%02X ",outkey[len]);
  538. C2[len] = M[len]^outkey[len];
  539. }
  540. memcpy(encdata+encLen+32,C2,mLen);
  541. memset(in,0,32);
  542. len = BN_bn2bin(x,tsm2data);
  543. memcpy(in+32-len,tsm2data,len);
  544. len=32;
  545. memcpy(in+len,M,mdatalen);
  546. len +=mdatalen;
  547. memset(in+len,0,32);
  548. inlen =BN_bn2bin(y,tsm2data);
  549. memcpy(in+len+32-inlen,tsm2data,inlen);
  550. inlen=32;
  551. inlen +=len;
  552. sm3(in,inlen,C3);
  553. memcpy(encdata+encLen,C3,32);
  554. encLen +=mLen;
  555. encLen +=32;
  556. ConvAscii((unsigned char*)encdata,(char*)in,encLen);
  557. memcpy(encdata,in,encLen*2);
  558. encdata[encLen*2]=0x00;
  559. sm2_end();
  560. return encLen*2;
  561. }
  562. /*
  563. decdata:Ascii码表示的16进制字符串,sm2_encrypt的返回值字符串,Ascii码的16进制形式
  564. dB:B的私钥,如1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0
  565. M:解密后的值,没有编码
  566. 返回值:>0 M的长度
  567. =0 解密失败
  568. */
  569. int sm2_decrypt(const char*decdata,const char*dB,char*M)
  570. /*
  571. 旧国密密文格式解密
  572. */
  573. {
  574. int len,inlen,mLen = 0;
  575. unsigned char in[256],outkey[256]={0};
  576. unsigned char C2[256]={0},C3[256]={0};
  577. char xstr[65]={0},ystr[65]={0};
  578. unsigned char tsm2data[256];
  579. EC_POINT *C1,*S,*P;
  580. BIGNUM *x,*y,*h;
  581. x = BN_new();
  582. y = BN_new();
  583. h = BN_new();
  584. sm2_init();
  585. C1 = EC_POINT_new(group);
  586. S = EC_POINT_new(group);
  587. P = EC_POINT_new(group);
  588. memcpy(xstr,decdata+2,64);
  589. memcpy(ystr,decdata+66,64);
  590. len = strlen(decdata);
  591. mLen = len - 130 - 64;
  592. AsciiToHex((char*)decdata+130,C2,64);
  593. AsciiToHex((char*)decdata+len-64,C3,64);
  594. mLen /=2;
  595. /*
  596. memcpy(C2,decdata+130,mLen);
  597. memcpy(C3,decdata+len-64,64);
  598. */
  599. if (!BN_hex2bn(&x, xstr)) {
  600. printf("BN_hex2bn for x failed, abort!\n");
  601. ABORT;
  602. }
  603. if (!BN_hex2bn(&y, ystr)) {
  604. printf("BN_hex2bn for y failed, abort!\n");
  605. ABORT;
  606. }
  607. if (!EC_POINT_set_affine_coordinates_GFp(group, C1, x, y, ctx)) {
  608. printf("EC_POINT_set_affine_coordinates_GFp for C1 for y failed, abort!\n");
  609. ABORT;
  610. }
  611. /*
  612. printf("C1:\r\n");
  613. BNPrintf(x);
  614. printf("\r\n");
  615. BNPrintf(y);
  616. printf("\r\n");
  617. */
  618. if (!EC_POINT_is_on_curve(group, C1, ctx)) {
  619. printf("EC_POINT_is_on_curve failed, abort!\n");
  620. ABORT;
  621. }
  622. if (!EC_GROUP_get_cofactor(group, h, ctx)) {
  623. printf("EC_GROUP_get_cofactor failed, abort!\n");
  624. ABORT;
  625. }
  626. if (!EC_POINT_mul(group, S, NULL, C1, h, ctx)) {
  627. printf("EC_POINT_mul failed, abort!\n");
  628. ABORT;
  629. }
  630. if(EC_POINT_is_at_infinity(group,S)) //S是无穷远点
  631. {
  632. printf("EC_POINT_is_at_infinity failed, abort!\n");
  633. ABORT;
  634. }
  635. if (!BN_hex2bn(&x, dB)) {
  636. printf("BN_hex2bn failed, abort!\n");
  637. ABORT;
  638. }
  639. if (!EC_POINT_mul(group, P, NULL, C1, x, ctx)) {
  640. printf("EC_POINT_mul failed, abort!\n");
  641. ABORT;
  642. }
  643. if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) {
  644. printf("EC_POINT_get_affine_coordinates_GFp for P failed, abort!\n");
  645. ABORT;
  646. }
  647. /*
  648. printf("P=[dB]C1:\r\n");
  649. BNPrintf(x);
  650. printf("\r\n");
  651. BNPrintf(y);
  652. printf("\r\n");
  653. */
  654. memset(in,0,64);
  655. len = BN_bn2bin(x,tsm2data);
  656. memcpy(in+32-len,tsm2data,len);
  657. len=32;
  658. inlen =BN_bn2bin(y,tsm2data);
  659. memcpy(in+64-inlen,tsm2data,inlen);
  660. inlen = 64;
  661. sm3_kdf(in,inlen,mLen,outkey);
  662. for(len=0;len<mLen;len++)
  663. {
  664. M[len] = C2[len]^outkey[len];
  665. }
  666. M[mLen] = 0x00;
  667. memset(in,0,32);
  668. len = BN_bn2bin(x,tsm2data);
  669. memcpy(in+32-len,tsm2data,len);
  670. len=32;
  671. memcpy(in+len,M,mLen);
  672. len +=mLen;
  673. memset(in+len,0,32);
  674. inlen =BN_bn2bin(y,tsm2data);
  675. memcpy(in+len+32-inlen,tsm2data,inlen);
  676. inlen=32;
  677. inlen +=len;
  678. sm3(in,inlen,C2);
  679. sm2_end();
  680. if(memcmp(C2,C3,32)==0)
  681. {
  682. return mLen;
  683. }
  684. else
  685. {
  686. return 0;
  687. }
  688. }
  689. /*
  690. decdata:Ascii码表示的16进制字符串,sm2_encrypt的返回值字符串,Ascii码的16进制形式
  691. dB:B的私钥,如1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0
  692. M:解密后的值,没有编码
  693. 返回值:>0 M的长度
  694. =0 解密失败
  695. */
  696. int sm2_decrypt_new(const char*decdata,const char*dB,char*M)
  697. /*
  698. 新国密密文格式解密
  699. */
  700. {
  701. int len,inlen,mLen = 0;
  702. unsigned char in[256],outkey[256]={0};
  703. unsigned char C2[256]={0},C3[256]={0};
  704. unsigned char tsm2data[256];
  705. char xstr[65]={0},ystr[65]={0};
  706. EC_POINT *C1,*S,*P;
  707. BIGNUM *x,*y,*h;
  708. x = BN_new();
  709. y = BN_new();
  710. h = BN_new();
  711. sm2_init();
  712. C1 = EC_POINT_new(group);
  713. S = EC_POINT_new(group);
  714. P = EC_POINT_new(group);
  715. memcpy(xstr,decdata,64);
  716. memcpy(ystr,decdata+64,64);
  717. len = strlen(decdata);
  718. mLen = len - 128 - 64;
  719. AsciiToHex((char*)decdata+128,C3,64);
  720. AsciiToHex((char*)decdata+128+64,C2,mLen);
  721. mLen /=2;
  722. /*
  723. memcpy(C2,decdata+130,mLen);
  724. memcpy(C3,decdata+len-64,64);
  725. */
  726. if(!BN_hex2bn(&x,xstr))ABORT;
  727. if(!BN_hex2bn(&y,ystr))ABORT;
  728. if(!EC_POINT_set_affine_coordinates_GFp(group,C1,x,y,ctx))ABORT;
  729. /*
  730. printf("C1:\r\n");
  731. BNPrintf(x);
  732. printf("\r\n");
  733. BNPrintf(y);
  734. printf("\r\n");
  735. */
  736. if(!EC_POINT_is_on_curve(group,C1,ctx))ABORT;
  737. if(!EC_GROUP_get_cofactor(group,h,ctx))ABORT;
  738. if(!EC_POINT_mul(group,S,NULL,C1,h,ctx))ABORT;
  739. if(EC_POINT_is_at_infinity(group,S))ABORT; //S是无穷远点
  740. if(!BN_hex2bn(&x,dB))ABORT;
  741. if(!EC_POINT_mul(group,P,NULL,C1,x,ctx))ABORT;
  742. if(!EC_POINT_get_affine_coordinates_GFp(group,P,x,y,ctx))ABORT;
  743. /*
  744. printf("P=[dB]C1:\r\n");
  745. BNPrintf(x);
  746. printf("\r\n");
  747. BNPrintf(y);
  748. printf("\r\n");
  749. */
  750. memset(in,0,64);
  751. len = BN_bn2bin(x,tsm2data);
  752. memcpy(in+32-len,tsm2data,len);
  753. len=32;
  754. inlen =BN_bn2bin(y,tsm2data);
  755. memcpy(in+64-inlen,tsm2data,inlen);
  756. inlen = 64;
  757. sm3_kdf(in,inlen,mLen,outkey);
  758. for(len=0;len<mLen;len++)
  759. {
  760. M[len] = C2[len]^outkey[len];
  761. }
  762. M[mLen] = 0x00;
  763. memset(in,0,32);
  764. len = BN_bn2bin(x,tsm2data);
  765. memcpy(in+32-len,tsm2data,len);
  766. len=32;
  767. memcpy(in+len,M,mLen);
  768. len +=mLen;
  769. memset(in+len,0,32);
  770. inlen =BN_bn2bin(y,tsm2data);
  771. memcpy(in+len+32-inlen,tsm2data,inlen);
  772. inlen=32;
  773. inlen +=len;
  774. sm3(in,inlen,C2);
  775. sm2_end();
  776. if(memcmp(C2,C3,32)==0)
  777. {
  778. return mLen;
  779. }
  780. else
  781. {
  782. return 0;
  783. }
  784. }
  785. int main11()
  786. {
  787. EC_KEY *B = NULL,*RB = NULL;
  788. EC_POINT *PA,*RA,*PB,*PRB;
  789. BIGNUM *x,*y;
  790. unsigned char outkey[32] = {0};
  791. unsigned char ZA[33]={0},ZB[33]={0};
  792. unsigned char pubkey[130]={0};
  793. int i;
  794. x = BN_new();
  795. y = BN_new();
  796. sm2_init();
  797. PA = EC_POINT_new(group);
  798. RA = EC_POINT_new(group);
  799. /* 指定私钥dB和rB */
  800. PB = EC_POINT_new(group);
  801. PRB = EC_POINT_new(group);
  802. if ((B = EC_KEY_new()) == NULL)
  803. return 1;
  804. if (EC_KEY_set_group(B, group) == 0)
  805. {
  806. fprintf(stdout," failed\n");
  807. return 1;
  808. }
  809. if ((RB = EC_KEY_new()) == NULL)
  810. return 1;
  811. if (EC_KEY_set_group(RB, group) == 0)
  812. {
  813. fprintf(stdout," failed\n");
  814. return 1;
  815. }
  816. if (!BN_hex2bn(&x, "785129917D45A9EA5437A59356B82338EAADDA6CEB199088F14AE10DEFA229B5"))ABORT;//6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE")) ABORT;
  817. if (!EC_POINT_mul(group,PB, x, NULL, NULL, ctx)) ABORT;
  818. EC_KEY_set_private_key(B,x);
  819. EC_KEY_set_public_key(B, PB);
  820. if (!BN_hex2bn(&x, "7E07124814B309489125EAED101113164EBF0F3458C5BD88335C1F9D596243D6"))ABORT;//6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE")) ABORT;
  821. if (!EC_POINT_mul(group,PRB, x, NULL, NULL, ctx)) ABORT;
  822. EC_KEY_set_private_key(RB,x);
  823. EC_KEY_set_public_key(RB, PRB);
  824. //*/
  825. //随机产生dB和rB
  826. // B = sm2_generate_key();
  827. // RB = sm2_generate_key();
  828. ecKey2str(B,pubkey);
  829. if(!PA || !RA)
  830. return 1;
  831. if(!BN_hex2bn(&x,"160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C94232"))ABORT;
  832. if(!BN_hex2bn(&y,"4A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F"))ABORT;
  833. if(!EC_POINT_set_affine_coordinates_GFp(group,PA,x,y,ctx))ABORT;
  834. // pubkey2ecPoint("160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C942324A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F",&PA);
  835. if(!BN_hex2bn(&x,"64ced1bdBC99D590049B434D0FD73428CF608A5DB8FE5CE07F15026940BAE40E"))ABORT;
  836. if(!BN_hex2bn(&y,"376629C7AB21E7DB260922499DDB118F07CE8EAAE3E7720AFEF6A5CC062070C0"))ABORT;
  837. if(!EC_POINT_set_affine_coordinates_GFp(group,RA,x,y,ctx))ABORT;
  838. 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);
  839. 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);
  840. sm2_exchange_key(B,RB,PA,RA,ZA,ZB,outkey,16);
  841. fprintf(stdout,"\nExchange key --KDF(Xv||Yv)-- :");
  842. for(i=0; i<16; i++)
  843. printf("%02X",outkey[i]);
  844. printf("\n");
  845. sm2_end();
  846. return 0;
  847. }