luat_lib_gmssl.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. /*
  2. @module gmssl
  3. @summary 国密算法
  4. @version 1.1
  5. @date 2023.03.02
  6. @author chenxudong1208
  7. @demo gmssl
  8. @tag LUAT_USE_GMSSL
  9. */
  10. #include "luat_base.h"
  11. #include "luat_mem.h"
  12. #include "luat_str.h"
  13. #include <time.h>
  14. #include "luat_zbuff.h"
  15. #include "gmssl/sm2.h"
  16. #include "gmssl/sm3.h"
  17. #include "gmssl/sm4.h"
  18. // #include "mbedtls/hmac_drbg.h"
  19. #define LUAT_LOG_TAG "sm"
  20. #include "luat_log.h"
  21. #define SM3_DIGEST_LENGTH 32
  22. #define SM4_BLOCK_LEN 16
  23. #define SM2_STR_LEN 300
  24. #define HEX_CODE 16
  25. extern void luat_str_fromhex(const char* str, size_t len, char* buff);
  26. static void DeletePaddingBuf(luaL_Buffer *B, const char *pPadding, size_t nBufLen, uint8_t *pBuf, uint8_t pPaddLen)
  27. {
  28. uint8_t nPadLen;
  29. if((strcmp(pPadding, "PKCS5")==0) || (strcmp(pPadding, "PKCS7")==0))
  30. {
  31. nPadLen = *(pBuf+nBufLen-1);
  32. //printf("aes DeletePaddingBuf length=%d\n", nPadLen);
  33. if((pPaddLen-nPadLen) >= 0)
  34. {
  35. luaL_addlstring(B, (char*)pBuf, nBufLen-nPadLen);
  36. }
  37. }
  38. else if(strcmp(pPadding, "ZERO")==0)
  39. {
  40. uint8_t *pEnd = pBuf+nBufLen-1;
  41. nPadLen = 0;
  42. while(1)
  43. {
  44. if(*pEnd == 0)
  45. {
  46. nPadLen++;
  47. if(nPadLen == pPaddLen)
  48. {
  49. break;
  50. }
  51. pEnd--;
  52. }
  53. else
  54. {
  55. break;
  56. }
  57. }
  58. //printf("aes DeletePaddingBuf length=%d\n", nPadLen);
  59. if((pPaddLen-nPadLen) >= 0)
  60. {
  61. luaL_addlstring(B, (char*)pBuf, nBufLen-nPadLen);
  62. }
  63. }
  64. else
  65. {
  66. luaL_addlstring(B, (char*)pBuf, nBufLen);
  67. }
  68. }
  69. /*
  70. sm2算法加密
  71. @api sm.sm2encrypt(pkx,pky,data, mode, mode2)
  72. @string 公钥x,必选. HEX字符串
  73. @string 公钥y,必选. HEX字符串
  74. @string 待计算的数据,必选,最长32字节, 非HEX字符串
  75. @boolean 输出模式,默认false. false-GMSSL默认格式DER, true-网站兼容模式
  76. @boolean 标准版本,默认false. false-C1C3C2新国际, true-C1C2C3老国际
  77. @return string 加密后的字符串, 原样输出,未经HEX转换. 若加密失败会返回nil或空字符串
  78. @usage
  79. -- 提示 mode/mode2 参数是 2023.10.17 新增
  80. -- 由于SM2在各平台的实现都有差异,用法务必参考demo
  81. */
  82. static int l_sm2_encrypt(lua_State *L)
  83. {
  84. // size_t randLen = 0;
  85. size_t pkxLen = 0;
  86. size_t pkyLen = 0;
  87. size_t pBufLen = 0;
  88. const char *pkx = lua_tolstring(L, 1,&pkxLen);
  89. const char *pky = lua_tolstring(L, 2,&pkyLen);
  90. const char *pBuf = lua_tolstring(L, 3,&pBufLen);
  91. int ret = 0;
  92. //检查参数合法性
  93. if((pkxLen!=64))
  94. {
  95. LLOGE("invalid pkx password length=%d", pkxLen);
  96. return 0;
  97. }
  98. if((pkyLen!=64))
  99. {
  100. LLOGE("invalid pky password length=%d", pkyLen);
  101. return 0;
  102. }
  103. if (pBufLen > SM2_MAX_PLAINTEXT_SIZE) {
  104. LLOGD("data too large max %d but %d", SM2_MAX_PLAINTEXT_SIZE, pBufLen);
  105. return 0;
  106. }
  107. int mode = 0;
  108. if (lua_isboolean(L, 4)) {
  109. mode = lua_toboolean(L, 4);
  110. }
  111. int mode2 = 0;
  112. if (lua_isboolean(L, 5)) {
  113. mode2 = lua_toboolean(L, 5);
  114. }
  115. SM2_KEY sm2 = {0};
  116. SM2_POINT point = {0};
  117. luat_str_fromhex(pkx, 64, (char*)point.x);
  118. luat_str_fromhex(pky, 64, (char*)point.y);
  119. ret = sm2_key_set_public_key(&sm2, (const SM2_POINT*)&point);
  120. if (ret != 1) {
  121. LLOGD("sm2_key_set_public_key %d", ret);
  122. return 0;
  123. }
  124. uint8_t out[SM2_MAX_CIPHERTEXT_SIZE] = {0};
  125. size_t olen = 0;
  126. if (mode == 1) {
  127. SM2_CIPHERTEXT C = {0};
  128. ret = sm2_do_encrypt(&sm2, (const uint8_t *)pBuf, pBufLen, &C);
  129. if (ret == 1) {
  130. if (mode2 == 0) {
  131. memcpy(out, &C.point.x, 32);
  132. memcpy(out + 32, &C.point.y, 32);
  133. memcpy(out + 64, C.hash, 32);
  134. memcpy(out + 96, C.ciphertext, C.ciphertext_size);
  135. olen = 96 + C.ciphertext_size;
  136. }
  137. else {
  138. out[0] = 0x04;
  139. memcpy(out + 1, &C.point.x, 32);
  140. memcpy(out + 32 + 1, &C.point.y, 32);
  141. memcpy(out + 64 + 1, C.ciphertext, C.ciphertext_size);
  142. memcpy(out + 64 + C.ciphertext_size + 1, C.hash, 32);
  143. olen = 96 + C.ciphertext_size + 1;
  144. }
  145. }
  146. }
  147. else {
  148. ret = sm2_encrypt(&sm2, (const uint8_t *)pBuf, pBufLen, out, &olen);
  149. }
  150. if (ret != 1) {
  151. LLOGD("sm2_encrypt ret %d", ret);
  152. return 0;
  153. }
  154. lua_pushlstring(L, (char*)out, olen);
  155. return 1;
  156. }
  157. /*
  158. sm2算法解密
  159. @api sm.sm2decrypt(private,data,mode,mode2)
  160. @string 私钥,必选,HEX字符串
  161. @string 待计算的数据,必选,原始数据,非HEX字符串
  162. @boolean 输出模式,默认false. false-GMSSL默认格式DER, true-网站兼容模式
  163. @boolean 标准版本,默认false. false-C1C3C2新国际, true-C1C2C3老国际
  164. @return string 解密后的字符串,未经HEX转换.若解密失败会返回nil或空字符串
  165. @usage
  166. -- 提示 mode/mode2 参数是 2023.10.17 新增
  167. -- 由于SM2在各平台的实现都有差异,用法务必参考demo
  168. */
  169. static int l_sm2_decrypt(lua_State *L)
  170. {
  171. size_t privateLen = 0;
  172. size_t pBufLen = 0;
  173. const char *private = lua_tolstring(L, 1,&privateLen);
  174. const char *pBuf = lua_tolstring(L, 2,&pBufLen);
  175. int ret = 0;
  176. int mode = 0;
  177. if (lua_isboolean(L, 3)) {
  178. mode = lua_toboolean(L, 3);
  179. }
  180. int mode2 = 0;
  181. if (lua_isboolean(L, 4)) {
  182. mode2 = lua_toboolean(L, 4);
  183. }
  184. //检查参数合法性
  185. if((privateLen!=64))
  186. {
  187. LLOGE("invalid private password length=%d", privateLen);
  188. return 0;
  189. }
  190. if (pBufLen < 97) {
  191. LLOGE("待数据太短,应该要97字节以上");
  192. return 0;
  193. }
  194. SM2_KEY sm2 = {0};
  195. char out[512] = {0};
  196. size_t olen = 0;
  197. luat_str_fromhex(private, 64, (char*)sm2.private_key);
  198. if (mode) {
  199. // LLOGD("网站兼容模式");
  200. SM2_CIPHERTEXT C = {0};
  201. if (mode2 == 0) {
  202. // LLOGD("C1C3C2");
  203. C.ciphertext_size = (uint8_t)(pBufLen - 96);
  204. // LLOGD("pBufLen %d ciphertext_size %d", pBufLen, C.ciphertext_size);
  205. memcpy(&C.point.x, pBuf, 32);
  206. memcpy(&C.point.y, pBuf + 32, 32);
  207. memcpy(C.hash, pBuf + 64, 32);
  208. memcpy(C.ciphertext, pBuf + 96, C.ciphertext_size);
  209. }
  210. else {
  211. // LLOGD("C1C2C3");
  212. pBuf ++;
  213. pBufLen --;
  214. C.ciphertext_size = (uint8_t)(pBufLen - 96);
  215. // LLOGD("pBufLen %d ciphertext_size %d", pBufLen, C.ciphertext_size);
  216. memcpy(&C.point.x, pBuf, 32);
  217. memcpy(&C.point.y, pBuf + 32, 32);
  218. memcpy(C.ciphertext, pBuf + 64, C.ciphertext_size);
  219. memcpy(C.hash, pBuf + 64 + C.ciphertext_size, 32);
  220. }
  221. ret = sm2_do_decrypt(&sm2, &C, (uint8_t *)out, &olen);
  222. }
  223. else {
  224. // LLOGD("GMSSL默认模式");
  225. ret = sm2_decrypt(&sm2, (uint8_t*)pBuf, pBufLen, (uint8_t*)out, &olen);
  226. }
  227. if (ret != 1) {
  228. LLOGD("sm2_decrypt ret %d", ret);
  229. return 0;
  230. }
  231. lua_pushlstring(L, (char*)out, olen);
  232. return 1;
  233. }
  234. /*
  235. sm3算法,算HASH值
  236. @api sm.sm3(data)
  237. @string 待计算的数据,必选
  238. @return string 对应的hash值
  239. @usage
  240. local encodeStr = gmssl.sm3("lqlq666lqlq946")
  241. log.info("testsm.sm3update",string.toHex(encodeStr))
  242. */
  243. static int l_sm3_update(lua_State *L)
  244. {
  245. size_t inputLen = 0;
  246. uint8_t dgst[SM3_DIGEST_LENGTH];
  247. const char *inputData = lua_tolstring(L,1,&inputLen);
  248. sm3_digest((uint8_t*)inputData, inputLen, dgst);
  249. lua_pushlstring(L, (char*)dgst, SM3_DIGEST_LENGTH);
  250. return 1;
  251. }
  252. /*
  253. sm3算法,算HASH值,但带HMAC
  254. @api sm.sm3hmac(data, key)
  255. @string 待计算的数据,必选
  256. @string 密钥
  257. @return string 对应的hash值
  258. @usage
  259. local encodeStr = gmssl.sm3hmac("lqlq666lqlq946", "123")
  260. log.info("testsm.sm3update",string.toHex(encodeStr))
  261. */
  262. static int l_sm3hmac_update(lua_State *L)
  263. {
  264. size_t inputLen = 0;
  265. size_t keyLen = 0;
  266. uint8_t dgst[SM3_DIGEST_LENGTH];
  267. const char *inputData = lua_tolstring(L, 1, &inputLen);
  268. const char *keyData = lua_tolstring(L, 2, &keyLen);
  269. sm3_hmac((uint8_t*)keyData, keyLen, (uint8_t*)inputData, inputLen, dgst);
  270. lua_pushlstring(L, (char*)dgst, SM3_DIGEST_LENGTH);
  271. return 1;
  272. }
  273. /*
  274. SM4加密算法
  275. @api gmssl.sm4encrypt(mode,padding,originStr,password)
  276. @string 加密模式, CBC或ECB
  277. @string 填充方式, NONE/ZERO/PKCS5/PKCS7
  278. @string 加密的字符串
  279. @string 密钥
  280. @string 偏移量
  281. @return string 加密后的数据
  282. @usage
  283. local originStr = "SM4 ECB ZeroPadding test"
  284. --加密模式:ECB;填充方式:ZeroPadding;密钥:1234567890123456;密钥长度:128 bit
  285. local encodeStr = gmssl.sm4encrypt("ECB","ZERO",originStr,"1234567890123456")
  286. print(originStr,"encrypt",string.toHex(encodeStr))
  287. log.info("testsm.decrypt",gmssl.sm4decrypt("ECB","ZERO",encodeStr,"1234567890123456"))
  288. originStr = "SM4 ECB Pkcs5Padding test"
  289. --加密模式:ECB;填充方式:Pkcs5Padding;密钥:1234567890123456;密钥长度:128 bit
  290. encodeStr = gmssl.sm4encrypt("ECB","PKCS5",originStr,"1234567890123456")
  291. print(originStr,"encrypt",string.toHex(encodeStr))
  292. log.info("testsm.decrypt",gmssl.sm4decrypt("ECB","PKCS5",encodeStr,"1234567890123456"))
  293. originStr = "SM4 CBC Pkcs5Padding test"
  294. --加密模式:CBC;填充方式:Pkcs5Padding;密钥:1234567890123456;密钥长度:256 bit;偏移量:1234567890666666
  295. encodeStr = gmssl.sm4encrypt("CBC","PKCS5",originStr,"1234567890123456","1234567890666666")
  296. print(originStr,"encrypt",string.toHex(encodeStr))
  297. log.info("testsm.decrypt",gmssl.sm4decrypt("CBC","PKCS5",encodeStr,"1234567890123456","1234567890666666"))
  298. */
  299. static int l_sm4_encrypt(lua_State *L)
  300. {
  301. const char *pMode = luaL_checkstring(L, 1);
  302. const char *pPadding = luaL_checkstring(L, 2);
  303. size_t nBufLen = 0;
  304. const char *pBuf = lua_tolstring(L, 3, &nBufLen);
  305. size_t nPswdLen = 0;
  306. const char *pPassword = lua_tolstring(L, 4, &nPswdLen);
  307. size_t nIVLen = 0;
  308. const char *pIV = lua_tolstring(L, 5, &nIVLen);
  309. int nPadLen = SM4_BLOCK_LEN-(nBufLen%SM4_BLOCK_LEN);
  310. uint8_t pPadBuf[SM4_BLOCK_LEN] = {0};
  311. uint8_t *pInBuf = NULL;
  312. //检查参数合法性
  313. if((nPswdLen!=16))
  314. {
  315. return luaL_error(L, "invalid password length=%d, only support 128bit Password", nPswdLen);
  316. }
  317. if((strcmp(pMode, "ECB")!=0) && (strcmp(pMode, "CBC")!=0))
  318. {
  319. return luaL_error(L, "invalid mode=%s, only support ECB,CBC", pMode);
  320. }
  321. if((strcmp(pPadding, "NONE")!=0) && (strcmp(pPadding, "PKCS5")!=0) && (strcmp(pPadding, "PKCS7")!=0) && (strcmp((char*)pPadding, "ZERO")!=0))
  322. {
  323. return luaL_error(L, "invalid padding=%s, only support NONE,PKCS5,PKCS7,ZERO", pPadding);
  324. }
  325. if(((strcmp(pMode, "CBC")==0)) && (nIVLen!=16))
  326. {
  327. return luaL_error(L, "invalid iv length=%d, only support 128bit IV", nIVLen);
  328. }
  329. //构造填充数据
  330. if((strcmp(pPadding, "PKCS5")==0) || (strcmp(pPadding, "PKCS7")==0))
  331. {
  332. memset(pPadBuf, nPadLen, sizeof(pPadBuf));
  333. }
  334. else if(strcmp(pPadding, "ZERO")==0)
  335. {
  336. memset(pPadBuf, 0, sizeof(pPadBuf));
  337. }
  338. else if(strcmp(pPadding, "NONE")==0)
  339. {
  340. if((strcmp(pMode, "CBC")==0) || (strcmp(pMode, "ECB")==0)){
  341. if(nBufLen%SM4_BLOCK_LEN != 0)
  342. {
  343. return luaL_error(L, "buf len should be multiple of 16, len=%d", nBufLen);
  344. }
  345. }
  346. nPadLen = 0;
  347. }
  348. //加密
  349. {
  350. luaL_Buffer b;
  351. uint32_t nRmnLen;
  352. luaL_buffinit( L, &b );
  353. //原始数据和填充数据拼接在一起
  354. if (strcmp((char*)pPadding, "NONE")!=0)
  355. {
  356. pInBuf = luat_heap_malloc(nBufLen+nPadLen);
  357. if(pInBuf == NULL)
  358. {
  359. //LLOGD("aes_encrypt malloc error!!!\n");
  360. luaL_pushresult( &b );
  361. return 1;
  362. }
  363. memcpy(pInBuf, pBuf, nBufLen);
  364. memcpy(pInBuf+nBufLen, pPadBuf, nPadLen);
  365. nBufLen += nPadLen;
  366. nRmnLen = nBufLen;
  367. }
  368. else
  369. {
  370. pInBuf = luat_heap_malloc(nBufLen);
  371. nRmnLen = nBufLen;
  372. if(pInBuf == NULL)
  373. {
  374. //LLOGD("aes_encrypt malloc error!!!\n");
  375. luaL_pushresult( &b );
  376. return 1;
  377. }
  378. memcpy(pInBuf, pBuf, nBufLen);
  379. }
  380. SM4_KEY sm4_key;
  381. memset(&sm4_key,0,sizeof(SM4_KEY));
  382. sm4_set_encrypt_key(&sm4_key, (uint8_t*)pPassword);
  383. if(strcmp(pMode, "ECB") == 0)
  384. {
  385. //开始分组加密,每16字节一组
  386. char out[SM4_BLOCK_LEN];
  387. while(nRmnLen>0)
  388. {
  389. sm4_encrypt(&sm4_key, (uint8_t*)(pInBuf+nBufLen-nRmnLen), (uint8_t*)out);
  390. luaL_addlstring(&b, out, SM4_BLOCK_LEN);
  391. nRmnLen -= SM4_BLOCK_LEN;
  392. }
  393. }
  394. else if((strcmp(pMode, "CBC") == 0))
  395. {
  396. //待加密数据一次性传入
  397. // sm4_cbc_encrypt(pInBuf,pInBuf,nBufLen,&sm4_key,pIV,1);
  398. char *out = luat_heap_malloc(nBufLen);
  399. sm4_cbc_encrypt(&sm4_key, (uint8_t*)pIV, pInBuf, nBufLen / SM4_BLOCK_LEN, (uint8_t*)out);
  400. luaL_addlstring(&b, out, nBufLen);
  401. luat_heap_free(out);
  402. }
  403. if(pInBuf != NULL)
  404. {
  405. luat_heap_free(pInBuf);
  406. pInBuf = NULL;
  407. }
  408. luaL_pushresult( &b );
  409. return 1;
  410. }
  411. }
  412. /*
  413. SM4解密算法
  414. @api gmssl.sm4decrypt(mode,padding,encodeStr,password)
  415. @string 加密模式, CBC或ECB
  416. @string 填充方式, NONE/ZERO/PKCS5/PKCS7
  417. @string 已加密的字符串
  418. @string 密钥
  419. @string 偏移量
  420. @return string 解密的字符串
  421. @usage
  422. -- 参考gmssl.sm4encrypt
  423. */
  424. static int l_sm4_decrypt(lua_State *L)
  425. {
  426. const char *pMode = luaL_checkstring(L, 1);
  427. const char *pPadding = luaL_checkstring(L, 2);
  428. size_t nBufLen = 0;
  429. const char *pBuf = lua_tolstring(L, 3, &nBufLen);
  430. size_t nPswdLen = 0;
  431. const char *pPassword = lua_tolstring(L, 4, &nPswdLen);
  432. size_t nIVLen = 0;
  433. const char *pIV = lua_tolstring(L, 5, &nIVLen);
  434. char out[SM4_BLOCK_LEN];
  435. //检查参数合法性
  436. int isCBC = strcmp((char*)pMode, "CBC") == 0;
  437. int isECB = strcmp((char*)pMode, "ECB") == 0;
  438. if(isCBC || isECB){
  439. if((nBufLen % 16) != 0){
  440. return luaL_error(L, "invalid BufLen length=%d, BufLen must be Integer multiples of 16", nBufLen);
  441. }
  442. }
  443. if((nPswdLen!=16))
  444. {
  445. return luaL_error(L, "invalid password length=%d, only support 128, 192, 256 bits", nPswdLen);
  446. }
  447. if(!isCBC && !isECB)
  448. {
  449. return luaL_error(L, "invalid mode=%s, only support ECB,CBC,CTR", pMode);
  450. }
  451. if((strcmp(pPadding, "NONE")!=0) && (strcmp(pPadding, "PKCS5")!=0) && (strcmp(pPadding, "PKCS7")!=0) && (strcmp((char*)pPadding, "ZERO")!=0))
  452. {
  453. return luaL_error(L, "invalid padding=%s, only support NONE,PKCS5,PKCS7,ZERO", pPadding);
  454. }
  455. if(isCBC && (nIVLen!=16))
  456. {
  457. return luaL_error(L, "invalid iv length=%d, only support 16", nIVLen);
  458. }
  459. //解密
  460. {
  461. luaL_Buffer b;
  462. uint32_t nRmnLen;
  463. luaL_buffinit( L, &b );
  464. nRmnLen = nBufLen;
  465. SM4_KEY sm4_key;
  466. memset(&sm4_key,0,sizeof(SM4_KEY));
  467. sm4_set_decrypt_key(&sm4_key,(uint8_t*)pPassword);
  468. if(isECB)
  469. {
  470. //开始分组解密,每16字节一组
  471. while(nRmnLen>0)
  472. {
  473. sm4_decrypt(&sm4_key,(uint8_t*)(pBuf+nBufLen-nRmnLen), (uint8_t*)out);
  474. //删除填充数据
  475. if(nRmnLen==SM4_BLOCK_LEN)
  476. {
  477. DeletePaddingBuf(&b, pPadding, SM4_BLOCK_LEN, (uint8_t*)out, SM4_BLOCK_LEN);
  478. }
  479. else
  480. {
  481. luaL_addlstring(&b, out, SM4_BLOCK_LEN);
  482. }
  483. nRmnLen -= SM4_BLOCK_LEN;
  484. }
  485. }
  486. else if (isCBC)
  487. {
  488. //待解密数据一次性传入
  489. if (nBufLen <= 1024) {
  490. char out[1024];
  491. sm4_cbc_decrypt(&sm4_key, (uint8_t*)pIV, (uint8_t*)pBuf, nBufLen/SM4_BLOCK_LEN, (uint8_t*)out);
  492. DeletePaddingBuf(&b, pPadding, nBufLen, (uint8_t*)out, SM4_BLOCK_LEN);
  493. }
  494. else {
  495. char *out = luat_heap_malloc(nBufLen);
  496. if (out == NULL) {
  497. LLOGE("out of memory when malloc SM4 decrypt buff");
  498. return 0;
  499. }
  500. sm4_cbc_decrypt(&sm4_key, (uint8_t*)pIV, (uint8_t*)pBuf, nBufLen/SM4_BLOCK_LEN, (uint8_t*)out);
  501. DeletePaddingBuf(&b, pPadding, nBufLen, (uint8_t*)out, SM4_BLOCK_LEN);
  502. luat_heap_free(out);
  503. }
  504. }
  505. luaL_pushresult( &b );
  506. return 1;
  507. }
  508. }
  509. /*
  510. sm2算法签名
  511. @api sm.sm2sign(private,data,id)
  512. @string 私钥,必选,HEX字符串
  513. @string 待计算的数据,必选,原始数据,非HEX字符串
  514. @string id值,非HEX字符串,可选,默认值"1234567812345678"
  515. @return string 前面字符串,未经HEX转换.若签名失败会返回nil
  516. @usage
  517. -- 本API于 2023.10.19 新增
  518. -- 具体用法请查阅demo
  519. */
  520. static int l_sm2_sign(lua_State *L)
  521. {
  522. int ret = 0;
  523. size_t pkLen = 0;
  524. size_t pBufLen = 0;
  525. size_t idLen = 0;
  526. // uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
  527. // size_t siglen = 0;
  528. const char *pk = luaL_checklstring(L, 1, &pkLen);
  529. const char *pBuf = luaL_checklstring(L, 2 ,&pBufLen);
  530. const char *id = luaL_optlstring(L, 3, "1234567812345678", &idLen);
  531. SM2_SIGN_CTX ctx = {0};
  532. uint8_t dgst[SM3_DIGEST_SIZE];
  533. SM2_SIGNATURE sig;
  534. uint8_t pkey[32] = {0};
  535. if (pkLen != 64) {
  536. LLOGW("private key len must be 64 byte HEX string");
  537. return 0;
  538. }
  539. if (pBufLen < 1) {
  540. LLOGW("待签名数据不能为空字符串");
  541. return 0;
  542. }
  543. luat_str_fromhex(pk, 64, (char*)pkey);
  544. ret = sm2_key_set_private_key(&ctx.key, (const uint8_t*)pkey);
  545. if (ret != 1) {
  546. LLOGW("sm2_key_set_private_key %d", ret);
  547. return 0;
  548. }
  549. sm3_init(&ctx.sm3_ctx);
  550. if (id && idLen > 0) {
  551. uint8_t z[SM3_DIGEST_SIZE];
  552. sm2_compute_z(z, &ctx.key.public_key, id, idLen);
  553. sm3_update(&ctx.sm3_ctx, z, sizeof(z));
  554. }
  555. sm3_update(&ctx.sm3_ctx, (const uint8_t*)pBuf, pBufLen);
  556. sm3_finish(&ctx.sm3_ctx, dgst);
  557. ret = sm2_do_sign(&ctx.key, dgst, &sig);
  558. if (ret == 1) {
  559. lua_pushlstring(L, (const char*)sig.r, 64);
  560. return 1;
  561. }
  562. return 0;
  563. }
  564. /*
  565. sm2算法验签
  566. @api sm.sm2verify(pkx, pky, data, id, sig)
  567. @string 公钥X,必选,HEX字符串
  568. @string 公钥Y,必选,HEX字符串
  569. @string 待计算的数据,必选,原始数据,非HEX字符串
  570. @string id值,非HEX字符串,可选,默认值"1234567812345678"
  571. @string 签名数据,必须64字节,非HEX字符串
  572. @return boolean 验证成功返回true,否则返回nil
  573. @usage
  574. -- 本API于 2023.10.19 新增
  575. -- 具体用法请查阅demo
  576. */
  577. static int l_sm2_verify(lua_State *L)
  578. {
  579. int ret = 0;
  580. size_t pkxLen = 0;
  581. size_t pkyLen = 0;
  582. size_t pBufLen = 0;
  583. size_t idLen = 0;
  584. size_t siglen = 0;
  585. const char *pkx = luaL_checklstring(L, 1, &pkxLen);
  586. const char *pky = luaL_checklstring(L, 2, &pkyLen);
  587. const char *pBuf = luaL_checklstring(L, 3, &pBufLen);
  588. const char *id = luaL_optlstring(L, 4, "1234567812345678", &idLen);
  589. const char *sig = luaL_checklstring(L, 5, &siglen);
  590. if (pkxLen != 64 || pkyLen != 64) {
  591. LLOGW("public key x/y len must be 64 byte HEX string");
  592. return 0;
  593. }
  594. if (pBufLen < 1) {
  595. LLOGW("待签名数据不能为空字符串");
  596. return 0;
  597. }
  598. if (siglen != 64) {
  599. LLOGW("sig数据长度应该在64字节");
  600. return 0;
  601. }
  602. SM2_SIGN_CTX ctx = {0};
  603. uint8_t dgst[SM3_DIGEST_SIZE];
  604. SM2_SIGNATURE sigT = {0};
  605. luat_str_fromhex(pkx, 64, (char*)ctx.key.public_key.x);
  606. luat_str_fromhex(pky, 64, (char*)ctx.key.public_key.y);
  607. memcpy(sigT.r, sig, 64);
  608. sm3_init(&ctx.sm3_ctx);
  609. if (id && idLen > 0) {
  610. uint8_t z[SM3_DIGEST_SIZE];
  611. sm2_compute_z(z, &ctx.key.public_key, id, idLen);
  612. sm3_update(&ctx.sm3_ctx, z, sizeof(z));
  613. }
  614. sm3_update(&ctx.sm3_ctx, (const uint8_t*)pBuf, pBufLen);
  615. sm3_finish(&ctx.sm3_ctx, dgst);
  616. ret = sm2_do_verify(&ctx.key, dgst, &sigT);
  617. lua_pushboolean(L, ret == 1 ? 1 : 0);
  618. return 1;
  619. }
  620. #include "rotable2.h"
  621. static const rotable_Reg_t reg_gmssl[] =
  622. {
  623. { "sm2encrypt", ROREG_FUNC(l_sm2_encrypt)},
  624. { "sm2decrypt", ROREG_FUNC(l_sm2_decrypt)},
  625. { "sm3update", ROREG_FUNC(l_sm3_update)},
  626. { "sm3", ROREG_FUNC(l_sm3_update)},
  627. { "sm3hmac", ROREG_FUNC(l_sm3hmac_update)},
  628. { "sm4encrypt", ROREG_FUNC(l_sm4_encrypt)},
  629. { "sm4decrypt", ROREG_FUNC(l_sm4_decrypt)},
  630. { "sm2sign", ROREG_FUNC(l_sm2_sign)},
  631. { "sm2verify", ROREG_FUNC(l_sm2_verify)},
  632. { NULL, ROREG_INT(0) }
  633. };
  634. LUAMOD_API int luaopen_gmssl( lua_State *L ) {
  635. luat_newlib2(L, reg_gmssl);
  636. return 1;
  637. }