sm2.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  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))ABORT;//???k
  482. if(!EC_POINT_mul(group,C1,k,NULL,NULL,ctx))ABORT;
  483. if(!EC_POINT_get_affine_coordinates_GFp(group,C1,x,y,ctx))ABORT;
  484. encLen = 0;
  485. memset(encdata,0,64);
  486. len = BN_bn2bin(x,tsm2data);
  487. memcpy(encdata+32-len,tsm2data,len);
  488. len=32;
  489. inlen = BN_bn2bin(y,tsm2data);
  490. memcpy(encdata+64-inlen,tsm2data,inlen);
  491. inlen=32;
  492. encLen += len + inlen;
  493. if(!BN_hex2bn(&x,ecpoint_PBx))ABORT;//xB
  494. if(!BN_hex2bn(&y,ecpoint_PBy))ABORT;//yB
  495. if(!EC_POINT_set_affine_coordinates_GFp(group,PB,x,y,ctx))ABORT;
  496. if(!EC_POINT_mul(group,P,NULL,PB,k,ctx))ABORT;
  497. if(!EC_POINT_get_affine_coordinates_GFp(group,P,x,y,ctx))ABORT;
  498. /*
  499. printf("P=[k]PB:\r\n");
  500. BNPrintf(x);
  501. BNPrintf(y);
  502. */
  503. memset(in,0,64);
  504. len = BN_bn2bin(x,tsm2data);
  505. memcpy(in+32-len,tsm2data,len);
  506. len=32;
  507. inlen =BN_bn2bin(y,tsm2data);
  508. memcpy(in+64-inlen,tsm2data,inlen);
  509. inlen = 64;
  510. sm3_kdf(in,inlen,mLen,outkey);
  511. for(len=0;len<mLen;len++)
  512. {
  513. // printf("%02X ",outkey[len]);
  514. C2[len] = M[len]^outkey[len];
  515. }
  516. memcpy(encdata+encLen+32,C2,mLen);
  517. memset(in,0,32);
  518. len = BN_bn2bin(x,tsm2data);
  519. memcpy(in+32-len,tsm2data,len);
  520. len=32;
  521. memcpy(in+len,M,mdatalen);
  522. len +=mdatalen;
  523. memset(in+len,0,32);
  524. inlen =BN_bn2bin(y,tsm2data);
  525. memcpy(in+len+32-inlen,tsm2data,inlen);
  526. inlen=32;
  527. inlen +=len;
  528. sm3(in,inlen,C3);
  529. memcpy(encdata+encLen,C3,32);
  530. encLen +=mLen;
  531. encLen +=32;
  532. ConvAscii((unsigned char*)encdata,(char*)in,encLen);
  533. memcpy(encdata,in,encLen*2);
  534. encdata[encLen*2]=0x00;
  535. sm2_end();
  536. return encLen*2;
  537. }
  538. /*
  539. decdata:Ascii码表示的16进制字符串,sm2_encrypt的返回值字符串,Ascii码的16进制形式
  540. dB:B的私钥,如1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0
  541. M:解密后的值,没有编码
  542. 返回值:>0 M的长度
  543. =0 解密失败
  544. */
  545. int sm2_decrypt(const char*decdata,const char*dB,char*M)
  546. /*
  547. 旧国密密文格式解密
  548. */
  549. {
  550. int len,inlen,mLen = 0;
  551. unsigned char in[256],outkey[256]={0};
  552. unsigned char C2[256]={0},C3[256]={0};
  553. char xstr[65]={0},ystr[65]={0};
  554. unsigned char tsm2data[256];
  555. EC_POINT *C1,*S,*P;
  556. BIGNUM *x,*y,*h;
  557. x = BN_new();
  558. y = BN_new();
  559. h = BN_new();
  560. sm2_init();
  561. C1 = EC_POINT_new(group);
  562. S = EC_POINT_new(group);
  563. P = EC_POINT_new(group);
  564. memcpy(xstr,decdata+2,64);
  565. memcpy(ystr,decdata+66,64);
  566. len = strlen(decdata);
  567. mLen = len - 130 - 64;
  568. AsciiToHex((char*)decdata+130,C2,64);
  569. AsciiToHex((char*)decdata+len-64,C3,64);
  570. mLen /=2;
  571. /*
  572. memcpy(C2,decdata+130,mLen);
  573. memcpy(C3,decdata+len-64,64);
  574. */
  575. if(!BN_hex2bn(&x,xstr))ABORT;
  576. if(!BN_hex2bn(&y,ystr))ABORT;
  577. if(!EC_POINT_set_affine_coordinates_GFp(group,C1,x,y,ctx))ABORT;
  578. /*
  579. printf("C1:\r\n");
  580. BNPrintf(x);
  581. printf("\r\n");
  582. BNPrintf(y);
  583. printf("\r\n");
  584. */
  585. if(!EC_POINT_is_on_curve(group,C1,ctx))ABORT;
  586. if(!EC_GROUP_get_cofactor(group,h,ctx))ABORT;
  587. if(!EC_POINT_mul(group,S,NULL,C1,h,ctx))ABORT;
  588. if(EC_POINT_is_at_infinity(group,S))ABORT; //S是无穷远点
  589. if(!BN_hex2bn(&x,dB))ABORT;
  590. if(!EC_POINT_mul(group,P,NULL,C1,x,ctx))ABORT;
  591. if(!EC_POINT_get_affine_coordinates_GFp(group,P,x,y,ctx))ABORT;
  592. /*
  593. printf("P=[dB]C1:\r\n");
  594. BNPrintf(x);
  595. printf("\r\n");
  596. BNPrintf(y);
  597. printf("\r\n");
  598. */
  599. memset(in,0,64);
  600. len = BN_bn2bin(x,tsm2data);
  601. memcpy(in+32-len,tsm2data,len);
  602. len=32;
  603. inlen =BN_bn2bin(y,tsm2data);
  604. memcpy(in+64-inlen,tsm2data,inlen);
  605. inlen = 64;
  606. sm3_kdf(in,inlen,mLen,outkey);
  607. for(len=0;len<mLen;len++)
  608. {
  609. M[len] = C2[len]^outkey[len];
  610. }
  611. M[mLen] = 0x00;
  612. memset(in,0,32);
  613. len = BN_bn2bin(x,tsm2data);
  614. memcpy(in+32-len,tsm2data,len);
  615. len=32;
  616. memcpy(in+len,M,mLen);
  617. len +=mLen;
  618. memset(in+len,0,32);
  619. inlen =BN_bn2bin(y,tsm2data);
  620. memcpy(in+len+32-inlen,tsm2data,inlen);
  621. inlen=32;
  622. inlen +=len;
  623. sm3(in,inlen,C2);
  624. sm2_end();
  625. if(memcmp(C2,C3,32)==0)
  626. {
  627. return mLen;
  628. }
  629. else
  630. {
  631. return 0;
  632. }
  633. }
  634. /*
  635. decdata:Ascii码表示的16进制字符串,sm2_encrypt的返回值字符串,Ascii码的16进制形式
  636. dB:B的私钥,如1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0
  637. M:解密后的值,没有编码
  638. 返回值:>0 M的长度
  639. =0 解密失败
  640. */
  641. int sm2_decrypt_new(const char*decdata,const char*dB,char*M)
  642. /*
  643. 新国密密文格式解密
  644. */
  645. {
  646. int len,inlen,mLen = 0;
  647. unsigned char in[256],outkey[256]={0};
  648. unsigned char C2[256]={0},C3[256]={0};
  649. unsigned char tsm2data[256];
  650. char xstr[65]={0},ystr[65]={0};
  651. EC_POINT *C1,*S,*P;
  652. BIGNUM *x,*y,*h;
  653. x = BN_new();
  654. y = BN_new();
  655. h = BN_new();
  656. sm2_init();
  657. C1 = EC_POINT_new(group);
  658. S = EC_POINT_new(group);
  659. P = EC_POINT_new(group);
  660. memcpy(xstr,decdata,64);
  661. memcpy(ystr,decdata+64,64);
  662. len = strlen(decdata);
  663. mLen = len - 128 - 64;
  664. AsciiToHex((char*)decdata+128,C3,64);
  665. AsciiToHex((char*)decdata+128+64,C2,mLen);
  666. mLen /=2;
  667. /*
  668. memcpy(C2,decdata+130,mLen);
  669. memcpy(C3,decdata+len-64,64);
  670. */
  671. if(!BN_hex2bn(&x,xstr))ABORT;
  672. if(!BN_hex2bn(&y,ystr))ABORT;
  673. if(!EC_POINT_set_affine_coordinates_GFp(group,C1,x,y,ctx))ABORT;
  674. /*
  675. printf("C1:\r\n");
  676. BNPrintf(x);
  677. printf("\r\n");
  678. BNPrintf(y);
  679. printf("\r\n");
  680. */
  681. if(!EC_POINT_is_on_curve(group,C1,ctx))ABORT;
  682. if(!EC_GROUP_get_cofactor(group,h,ctx))ABORT;
  683. if(!EC_POINT_mul(group,S,NULL,C1,h,ctx))ABORT;
  684. if(EC_POINT_is_at_infinity(group,S))ABORT; //S是无穷远点
  685. if(!BN_hex2bn(&x,dB))ABORT;
  686. if(!EC_POINT_mul(group,P,NULL,C1,x,ctx))ABORT;
  687. if(!EC_POINT_get_affine_coordinates_GFp(group,P,x,y,ctx))ABORT;
  688. /*
  689. printf("P=[dB]C1:\r\n");
  690. BNPrintf(x);
  691. printf("\r\n");
  692. BNPrintf(y);
  693. printf("\r\n");
  694. */
  695. memset(in,0,64);
  696. len = BN_bn2bin(x,tsm2data);
  697. memcpy(in+32-len,tsm2data,len);
  698. len=32;
  699. inlen =BN_bn2bin(y,tsm2data);
  700. memcpy(in+64-inlen,tsm2data,inlen);
  701. inlen = 64;
  702. sm3_kdf(in,inlen,mLen,outkey);
  703. for(len=0;len<mLen;len++)
  704. {
  705. M[len] = C2[len]^outkey[len];
  706. }
  707. M[mLen] = 0x00;
  708. memset(in,0,32);
  709. len = BN_bn2bin(x,tsm2data);
  710. memcpy(in+32-len,tsm2data,len);
  711. len=32;
  712. memcpy(in+len,M,mLen);
  713. len +=mLen;
  714. memset(in+len,0,32);
  715. inlen =BN_bn2bin(y,tsm2data);
  716. memcpy(in+len+32-inlen,tsm2data,inlen);
  717. inlen=32;
  718. inlen +=len;
  719. sm3(in,inlen,C2);
  720. sm2_end();
  721. if(memcmp(C2,C3,32)==0)
  722. {
  723. return mLen;
  724. }
  725. else
  726. {
  727. return 0;
  728. }
  729. }
  730. int main11()
  731. {
  732. EC_KEY *B = NULL,*RB = NULL;
  733. EC_POINT *PA,*RA,*PB,*PRB;
  734. BIGNUM *x,*y;
  735. unsigned char outkey[32] = {0};
  736. unsigned char ZA[33]={0},ZB[33]={0};
  737. unsigned char pubkey[130]={0};
  738. int i;
  739. x = BN_new();
  740. y = BN_new();
  741. sm2_init();
  742. PA = EC_POINT_new(group);
  743. RA = EC_POINT_new(group);
  744. /* 指定私钥dB和rB */
  745. PB = EC_POINT_new(group);
  746. PRB = EC_POINT_new(group);
  747. if ((B = EC_KEY_new()) == NULL)
  748. return 1;
  749. if (EC_KEY_set_group(B, group) == 0)
  750. {
  751. fprintf(stdout," failed\n");
  752. return 1;
  753. }
  754. if ((RB = EC_KEY_new()) == NULL)
  755. return 1;
  756. if (EC_KEY_set_group(RB, group) == 0)
  757. {
  758. fprintf(stdout," failed\n");
  759. return 1;
  760. }
  761. if (!BN_hex2bn(&x, "785129917D45A9EA5437A59356B82338EAADDA6CEB199088F14AE10DEFA229B5"))ABORT;//6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE")) ABORT;
  762. if (!EC_POINT_mul(group,PB, x, NULL, NULL, ctx)) ABORT;
  763. EC_KEY_set_private_key(B,x);
  764. EC_KEY_set_public_key(B, PB);
  765. if (!BN_hex2bn(&x, "7E07124814B309489125EAED101113164EBF0F3458C5BD88335C1F9D596243D6"))ABORT;//6FCBA2EF9AE0AB902BC3BDE3FF915D44BA4CC78F88E2F8E7F8996D3B8CCEEDEE")) ABORT;
  766. if (!EC_POINT_mul(group,PRB, x, NULL, NULL, ctx)) ABORT;
  767. EC_KEY_set_private_key(RB,x);
  768. EC_KEY_set_public_key(RB, PRB);
  769. //*/
  770. //随机产生dB和rB
  771. // B = sm2_generate_key();
  772. // RB = sm2_generate_key();
  773. ecKey2str(B,pubkey);
  774. if(!PA || !RA)
  775. return 1;
  776. if(!BN_hex2bn(&x,"160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C94232"))ABORT;
  777. if(!BN_hex2bn(&y,"4A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F"))ABORT;
  778. if(!EC_POINT_set_affine_coordinates_GFp(group,PA,x,y,ctx))ABORT;
  779. // pubkey2ecPoint("160E12897DF4EDB61DD812FEB96748FBD3CCF4FFE26AA6F6DB9540AF49C942324A7DAD08BB9A459531694BEB20AA489D6649975E1BFCF8C4741B78B4B223007F",&PA);
  780. if(!BN_hex2bn(&x,"64ced1bdBC99D590049B434D0FD73428CF608A5DB8FE5CE07F15026940BAE40E"))ABORT;
  781. if(!BN_hex2bn(&y,"376629C7AB21E7DB260922499DDB118F07CE8EAAE3E7720AFEF6A5CC062070C0"))ABORT;
  782. if(!EC_POINT_set_affine_coordinates_GFp(group,RA,x,y,ctx))ABORT;
  783. 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);
  784. 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);
  785. sm2_exchange_key(B,RB,PA,RA,ZA,ZB,outkey,16);
  786. fprintf(stdout,"\nExchange key --KDF(Xv||Yv)-- :");
  787. for(i=0; i<16; i++)
  788. printf("%02X",outkey[i]);
  789. printf("\n");
  790. sm2_end();
  791. return 0;
  792. }