luat_lib_crypto.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. /*
  2. @module crypto
  3. @summary 加解密和hash函数
  4. @version 1.0
  5. @date 2020.07.03
  6. @demo crypto
  7. @tag LUAT_USE_CRYPTO
  8. */
  9. #include "luat_base.h"
  10. #include "luat_crypto.h"
  11. #include "luat_mem.h"
  12. #include "luat_str.h"
  13. #include <time.h>
  14. #include "luat_zbuff.h"
  15. #include "luat_str.h"
  16. #define LUAT_LOG_TAG "crypto"
  17. #define LUAT_CRYPTO_TYPE "crypto"
  18. #include "luat_log.h"
  19. /**
  20. 计算md5值
  21. @api crypto.md5(str)
  22. @string 需要计算的字符串
  23. @return string 计算得出的md5值的hex字符串
  24. @usage
  25. -- 计算字符串"abc"的md5
  26. log.info("md5", crypto.md5("abc"))
  27. */
  28. static int l_crypto_md5(lua_State *L) {
  29. size_t size = 0;
  30. const char* str = luaL_checklstring(L, 1, &size);
  31. char tmp[32] = {0};
  32. char dst[32] = {0};
  33. if (luat_crypto_md5_simple(str, size, tmp) == 0) {
  34. luat_str_tohex(tmp, 16, dst);
  35. lua_pushlstring(L, dst, 32);
  36. return 1;
  37. }
  38. return 0;
  39. }
  40. /**
  41. 计算hmac_md5值
  42. @api crypto.hmac_md5(str, key)
  43. @string 需要计算的字符串
  44. @string 密钥
  45. @return string 计算得出的hmac_md5值的hex字符串
  46. @usage
  47. -- 计算字符串"abc"的hmac_md5
  48. log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
  49. */
  50. static int l_crypto_hmac_md5(lua_State *L) {
  51. size_t str_size = 0;
  52. size_t key_size = 0;
  53. const char* str = luaL_checklstring(L, 1, &str_size);
  54. const char* key = luaL_checklstring(L, 2, &key_size);
  55. char tmp[32] = {0};
  56. char dst[32] = {0};
  57. if (luat_crypto_hmac_md5_simple(str, str_size, key, key_size, tmp) == 0) {
  58. luat_str_tohex(tmp, 16, dst);
  59. lua_pushlstring(L, dst, 32);
  60. return 1;
  61. }
  62. return 0;
  63. }
  64. /**
  65. 计算sha1值
  66. @api crypto.sha1(str)
  67. @string 需要计算的字符串
  68. @return string 计算得出的sha1值的hex字符串
  69. @usage
  70. -- 计算字符串"abc"的sha1
  71. log.info("sha1", crypto.sha1("abc"))
  72. */
  73. static int l_crypto_sha1(lua_State *L) {
  74. size_t size = 0;
  75. const char* str = luaL_checklstring(L, 1, &size);
  76. char tmp[40] = {0};
  77. char dst[40] = {0};
  78. if (luat_crypto_sha1_simple(str, size, tmp) == 0) {
  79. luat_str_tohex(tmp, 20, dst);
  80. lua_pushlstring(L, dst, 40);
  81. return 1;
  82. }
  83. return 0;
  84. }
  85. /**
  86. 计算hmac_sha1值
  87. @api crypto.hmac_sha1(str, key)
  88. @string 需要计算的字符串
  89. @string 密钥
  90. @return string 计算得出的hmac_sha1值的hex字符串
  91. @usage
  92. -- 计算字符串"abc"的hmac_sha1
  93. log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
  94. */
  95. static int l_crypto_hmac_sha1(lua_State *L) {
  96. size_t str_size = 0;
  97. size_t key_size = 0;
  98. const char* str = luaL_checklstring(L, 1, &str_size);
  99. const char* key = luaL_checklstring(L, 2, &key_size);
  100. char tmp[40] = {0};
  101. char dst[40] = {0};
  102. if (luat_crypto_hmac_sha1_simple(str, str_size, key, key_size, tmp) == 0) {
  103. luat_str_tohex(tmp, 20, dst);
  104. lua_pushlstring(L, dst, 40);
  105. return 1;
  106. }
  107. return 0;
  108. }
  109. /**
  110. 计算sha256值
  111. @api crypto.sha256(str)
  112. @string 需要计算的字符串
  113. @return string 计算得出的sha256值的hex字符串
  114. @usage
  115. -- 计算字符串"abc"的sha256
  116. log.info("sha256", crypto.sha256("abc"))
  117. */
  118. static int l_crypto_sha256(lua_State *L) {
  119. size_t size = 0;
  120. const char* str = luaL_checklstring(L, 1, &size);
  121. char tmp[64] = {0};
  122. char dst[64] = {0};
  123. if (luat_crypto_sha256_simple(str, size, tmp) == 0) {
  124. luat_str_tohex(tmp, 32, dst);
  125. lua_pushlstring(L, dst, 64);
  126. return 1;
  127. }
  128. return 0;
  129. }
  130. /**
  131. 计算hmac_sha256值
  132. @api crypto.hmac_sha256(str, key)
  133. @string 需要计算的字符串
  134. @string 密钥
  135. @return string 计算得出的hmac_sha256值的hex字符串
  136. @usage
  137. -- 计算字符串"abc"的hmac_sha256
  138. log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
  139. */
  140. static int l_crypto_hmac_sha256(lua_State *L) {
  141. size_t str_size = 0;
  142. size_t key_size = 0;
  143. const char* str = luaL_checklstring(L, 1, &str_size);
  144. const char* key = luaL_checklstring(L, 2, &key_size);
  145. char tmp[64] = {0};
  146. char dst[64] = {0};
  147. if (key_size > 64) {
  148. luat_crypto_sha256_simple(key, key_size, dst);
  149. key = (const char*)dst;
  150. key_size = 64;
  151. }
  152. if (luat_crypto_hmac_sha256_simple(str, str_size, key, key_size, tmp) == 0) {
  153. luat_str_tohex(tmp, 32, dst);
  154. lua_pushlstring(L, dst, 64);
  155. return 1;
  156. }
  157. return 0;
  158. }
  159. //---
  160. /**
  161. 计算sha512值
  162. @api crypto.sha512(str)
  163. @string 需要计算的字符串
  164. @return string 计算得出的sha512值的hex字符串
  165. @usage
  166. -- 计算字符串"abc"的sha512
  167. log.info("sha512", crypto.sha512("abc"))
  168. */
  169. static int l_crypto_sha512(lua_State *L) {
  170. size_t size = 0;
  171. const char* str = luaL_checklstring(L, 1, &size);
  172. char tmp[128] = {0};
  173. char dst[128] = {0};
  174. if (luat_crypto_sha512_simple(str, size, tmp) == 0) {
  175. luat_str_tohex(tmp, 64, dst);
  176. lua_pushlstring(L, dst, 128);
  177. return 1;
  178. }
  179. return 0;
  180. }
  181. /**
  182. 计算hmac_sha512值
  183. @api crypto.hmac_sha512(str, key)
  184. @string 需要计算的字符串
  185. @string 密钥
  186. @return string 计算得出的hmac_sha512值的hex字符串
  187. @usage
  188. -- 计算字符串"abc"的hmac_sha512
  189. log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
  190. */
  191. static int l_crypto_hmac_sha512(lua_State *L) {
  192. size_t str_size = 0;
  193. size_t key_size = 0;
  194. const char* str = luaL_checklstring(L, 1, &str_size);
  195. const char* key = luaL_checklstring(L, 2, &key_size);
  196. char tmp[128] = {0};
  197. char dst[128] = {0};
  198. if (key_size > 128) {
  199. luat_crypto_sha512_simple(key, key_size, dst);
  200. key = (const char*)dst;
  201. key_size = 128;
  202. }
  203. if (luat_crypto_hmac_sha512_simple(str, str_size, key, key_size, tmp) == 0) {
  204. luat_str_tohex(tmp, 64, dst);
  205. lua_pushlstring(L, dst, 128);
  206. return 1;
  207. }
  208. return 0;
  209. }
  210. int l_crypto_cipher_xxx(lua_State *L, uint8_t flags) {
  211. luat_crypto_cipher_ctx_t cctx = {0};
  212. cctx.cipher = luaL_optlstring(L, 1, "AES-128-ECB", &cctx.cipher_size);
  213. cctx.pad = luaL_optlstring(L, 2, "PKCS7", &cctx.pad_size);
  214. cctx.str = luaL_checklstring(L, 3, &cctx.str_size);
  215. cctx.key = luaL_checklstring(L, 4, &cctx.key_size);
  216. cctx.iv = luaL_optlstring(L, 5, "", &cctx.iv_size);
  217. cctx.flags = flags;
  218. luaL_Buffer buff;
  219. luaL_buffinitsize(L, &buff, cctx.str_size + 16);
  220. cctx.outbuff = buff.b;
  221. int ret = luat_crypto_cipher_xxx(&cctx);
  222. if (ret) {
  223. return 0;
  224. }
  225. luaL_pushresultsize(&buff, cctx.outlen);
  226. return 1;
  227. }
  228. /**
  229. 对称加密
  230. @api crypto.cipher_encrypt(type, padding, str, key, iv)
  231. @string 算法名称, 例如 AES-128-ECB/AES-128-CBC, 可查阅crypto.cipher_list()
  232. @string 对齐方式, 支持PKCS7/ZERO/ONE_AND_ZEROS/ZEROS_AND_LEN/NONE
  233. @string 需要加密的数据
  234. @string 密钥,需要对应算法的密钥长度
  235. @string IV值, 非ECB算法需要
  236. @return string 加密后的字符串
  237. @usage
  238. -- 计算AES
  239. local data = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "1234567890123456", "1234567890123456")
  240. local data2 = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "1234567890123456", "1234567890123456", "1234567890666666")
  241. */
  242. int l_crypto_cipher_encrypt(lua_State *L) {
  243. return l_crypto_cipher_xxx(L, 1);
  244. }
  245. /**
  246. 对称解密
  247. @api crypto.cipher_decrypt(type, padding, str, key, iv)
  248. @string 算法名称, 例如 AES-128-ECB/AES-128-CBC, 可查阅crypto.cipher_list()
  249. @string 对齐方式, 支持PKCS7/ZERO/ONE_AND_ZEROS/ZEROS_AND_LEN/NONE
  250. @string 需要解密的数据
  251. @string 密钥,需要对应算法的密钥长度
  252. @string IV值, 非ECB算法需要
  253. @return string 解密后的字符串
  254. @usage
  255. -- 用AES加密,然后用AES解密
  256. local data = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "1234567890123456", "1234567890123456")
  257. local data2 = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data, "1234567890123456")
  258. -- data的hex为 757CCD0CDC5C90EADBEEECF638DD0000
  259. -- data2的值为 1234567890123456
  260. */
  261. int l_crypto_cipher_decrypt(lua_State *L) {
  262. return l_crypto_cipher_xxx(L, 0);
  263. }
  264. typedef struct{
  265. const char *name; //参数模型
  266. uint16_t crc16_polynomial; //多项式
  267. uint16_t initial_value; //初始值
  268. uint16_t finally_data; //结果异或值
  269. uint8_t input_reverse; //输入数据反转
  270. uint8_t output_reverse; //输出数据反转
  271. } crc16method;
  272. static const crc16method crc16method_table[] =
  273. {
  274. {(const char*)"IBM", 0x8005, 0x0000, 0x0000, 1, 1},
  275. {(const char*)"MAXIM", 0x8005, 0x0000, 0xffff, 1, 1},
  276. {(const char*)"USB", 0x8005, 0xffff, 0xffff, 1, 1},
  277. {(const char*)"MODBUS", 0x8005, 0xffff, 0x0000, 1, 1},
  278. {(const char*)"CCITT", 0x1021, 0x0000, 0x0000, 1, 1},
  279. {(const char*)"CCITT-FALSE", 0x1021, 0xffff, 0x0000, 0, 0},
  280. {(const char*)"X25", 0x1021, 0xffff, 0xffff, 1, 1},
  281. {(const char*)"XMODEM", 0x1021, 0x0000,0x0000, 0, 0},
  282. {(const char*)"DNP", 0x3D65, 0x0000, 0xffff, 1, 1},
  283. {(const char*)"USER-DEFINED", 0x0000, 0x0000,0x0000, 0, 0},
  284. };
  285. static inline void InvertUint16(uint16_t *dBuf,uint16_t *srcBuf)
  286. {
  287. int i;
  288. uint16_t tmp[4];
  289. tmp[0] = 0;
  290. for(i=0;i< 16;i++)
  291. {
  292. if(srcBuf[0]& (1 << i))
  293. tmp[0]|=1<<(15 - i);
  294. }
  295. dBuf[0] = tmp[0];
  296. }
  297. /**
  298. 计算CRC16
  299. @api crypto.crc16(method, data, poly, initial, finally, inReversem, outReverse)
  300. @string CRC16模式("IBM","MAXIM","USB","MODBUS","CCITT","CCITT-FALSE","X25","XMODEM","DNP","USER-DEFINED")
  301. @string 字符串或者zbuff对象
  302. @int poly值,默认0x0000,范围0-0xFFFF
  303. @int initial值,默认0x0000,范围0-0xFFFF
  304. @int finally值,默认0x0000,范围0-0xFFFF
  305. @int 输入反转,1反转,默认0不反转
  306. @int 输出反转,1反转,默认0不反转
  307. @return int 对应的CRC16值
  308. @usage
  309. -- 计算字符串的CRC16
  310. local crc = crypto.crc16("dfadfasfdsafdasf")
  311. -- 使用zbuff时,会计算used之后的全部数据,建议使用前seek(0)
  312. local zbuff = zbuff.create("dfadfasfdsafdasf")
  313. zbuff:seek(0)
  314. crc = crypto.crc16(zbuff)
  315. */
  316. static int l_crypto_crc16(lua_State *L)
  317. {
  318. size_t inputlen = 0;
  319. const unsigned char *inputData = NULL;
  320. const char *inputmethod = (const char*)luaL_checkstring(L, 1);
  321. uint16_t poly_default = 0x0000;
  322. uint16_t initial_default = 0x0000;
  323. uint16_t finally_default = 0x0000;
  324. uint16_t in_reverse = 0;
  325. uint16_t out_reverse = 0;
  326. if(lua_isuserdata(L, 2))
  327. {
  328. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  329. inputlen = buff->len - buff->cursor;
  330. inputData = (const unsigned char *)(buff->addr + buff->cursor);
  331. }else{
  332. inputData = (const unsigned char*)lua_tolstring(L,2,&inputlen);
  333. }
  334. for (int i = 0; i < sizeof(crc16method_table)/sizeof(crc16method_table[0]); i++)
  335. {
  336. if (strcmp(crc16method_table[i].name, inputmethod) == 0)
  337. {
  338. poly_default = crc16method_table[i].crc16_polynomial;
  339. initial_default = crc16method_table[i].initial_value;
  340. finally_default = crc16method_table[i].finally_data;
  341. in_reverse = crc16method_table[i].input_reverse;
  342. out_reverse = crc16method_table[i].output_reverse;
  343. }
  344. }
  345. uint16_t poly = (uint16_t)luaL_optnumber(L,3,poly_default);
  346. uint16_t initial = (uint16_t)luaL_optnumber(L,4,initial_default);
  347. uint16_t finally = (uint16_t)luaL_optnumber(L,5,finally_default);
  348. uint8_t inReverse = (uint8_t)luaL_optnumber(L,6,in_reverse);
  349. uint8_t outReverse = (uint8_t)luaL_optnumber(L,7,out_reverse);
  350. uint16_t crc16 = luat_crc16(inputData, inputlen, initial, finally, poly, inReverse);
  351. if (outReverse)
  352. {
  353. uint16_t out = 0;
  354. InvertUint16(&out, &crc16);
  355. crc16 = out;
  356. }
  357. lua_pushinteger(L, crc16);
  358. return 1;
  359. }
  360. /**
  361. 直接计算modbus的crc16值
  362. @api crypto.crc16_modbus(data, start)
  363. @string 数据
  364. @int 初始化值,默认0xFFFF
  365. @return int 对应的CRC16值
  366. @usage
  367. -- 计算CRC16 modbus
  368. local crc = crypto.crc16_modbus(data)
  369. -- 2023.11.06 新增初始值设置
  370. crc = crypto.crc16_modbus(data, 0xFFFF)
  371. */
  372. static int l_crypto_crc16_modbus(lua_State *L)
  373. {
  374. size_t len = 0;
  375. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  376. // uint16_t crc_init = (uint16_t)luaL_optinteger(L, 2, 0xFFFF);
  377. lua_pushinteger(L, luat_crc16_modbus(inputData, len));
  378. return 1;
  379. }
  380. /**
  381. 计算crc32值
  382. @api crypto.crc32(data, start, poly, endv)
  383. @string 数据
  384. @int 初始化值,默认0xFFFFFFFF
  385. @int crc多项式,可选,默认0x04C11DB7
  386. @int 结束值,可选,默认0xFFFFFFFF,计算结果异或结束值才是最终输出值
  387. @return int 对应的CRC32值
  388. @usage
  389. -- 计算CRC32
  390. local crc = crypto.crc32(data)
  391. -- start和poly可选, 是 2025.4.14 新增的参数
  392. local crc = crypto.crc32(data, 0xFFFFFFFF, 0x04C11DB7, 0xFFFFFFFF) --等同于crypto.crc32(data)
  393. */
  394. static int l_crypto_crc32(lua_State *L)
  395. {
  396. size_t len = 0;
  397. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  398. uint32_t start = (uint32_t)luaL_optinteger(L, 2, 0xffffffff);
  399. uint32_t poly = (uint32_t)luaL_optinteger(L, 3, 0x04C11DB7);
  400. uint32_t end = (uint32_t)luaL_optinteger(L, 4, 0xffffffff);
  401. lua_pushinteger(L, luat_crc32(inputData, len, start, poly) ^ end);
  402. return 1;
  403. }
  404. /**
  405. 计算crc8值
  406. @api crypto.crc8(data, poly, start, revert)
  407. @string 数据
  408. @int crc多项式,可选,如果不写,将忽略除了数据外所有参数
  409. @int crc初始值,可选,默认0
  410. @boolean 是否需要逆序处理,默认否
  411. @return int 对应的CRC8值
  412. @usage
  413. -- 计算CRC8
  414. local crc = crypto.crc8(data)
  415. local crc = crypto.crc8(data, 0x31, 0xff, false)
  416. */
  417. static int l_crypto_crc8(lua_State *L)
  418. {
  419. size_t len = 0;
  420. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  421. if (!lua_isinteger(L, 2)) {
  422. lua_pushinteger(L, luat_crc8(inputData, len, 0x00, 0x07, 0));//poly默认值0x0000
  423. } else {
  424. uint8_t poly = (uint8_t)lua_tointeger(L, 2);
  425. uint8_t start = (uint8_t)luaL_optinteger(L, 3, 0);
  426. uint8_t is_rev = 0;
  427. if (lua_isboolean(L, 4)) {
  428. is_rev = (uint8_t)lua_toboolean(L, 4);
  429. }
  430. lua_pushinteger(L, luat_crc8(inputData, len, start, poly, is_rev));
  431. }
  432. return 1;
  433. }
  434. /**
  435. 计算crc7值
  436. @api crypto.crc7(data, poly, start)
  437. @string 数据
  438. @int crc多项式,可选,默认0xE5
  439. @int crc初始值,可选,默认0x00
  440. @return int 对应的CRC7值
  441. @usage
  442. -- 计算CRC7, 本API于2023.10.07新增
  443. local crc = crypto.crc7(data)
  444. local crc = crypto.crc7(data, 0x31, 0xff)
  445. */
  446. static int l_crypto_crc7(lua_State* L) {
  447. size_t len = 0;
  448. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  449. unsigned char poly = (unsigned char)luaL_optinteger(L, 2, 0xe5);
  450. unsigned char start = (unsigned char)luaL_optinteger(L, 3, 0);
  451. unsigned char result = luat_crc7(inputData, len, poly, start);
  452. lua_pushinteger(L, result);
  453. return 1;
  454. }
  455. /**
  456. 生成真随机数
  457. @api crypto.trng(len)
  458. @int 数据长度
  459. @return string 指定随机数字符串
  460. @usage
  461. -- 生成32位随机数ir
  462. local r = crypto.trng(4)
  463. local _, ir = pack.unpack(r, "I")
  464. */
  465. static int l_crypto_trng(lua_State *L) {
  466. int ret = 0;
  467. size_t len = luaL_checkinteger(L, 1);
  468. if (len < 1) {
  469. return 0;
  470. }
  471. if (len > 128)
  472. len = 128;
  473. char buff[128];
  474. ret = luat_crypto_trng(buff, len);
  475. if(ret ==0){
  476. lua_pushlstring(L, buff, len);
  477. return 1;
  478. }
  479. return 0;
  480. }
  481. /**
  482. 计算TOTP动态密码的结果
  483. @api crypto.totp(secret,time)
  484. @string 网站提供的密钥(就是BASE32编码后的结果)
  485. @int 可选,时间戳,默认当前时间
  486. @return int 计算得出的六位数结果 计算失败返回nil
  487. @usage
  488. --使用当前系统时间计算
  489. local otp = crypto.totp("asdfassdfasdfass")
  490. */
  491. static int l_crypto_totp(lua_State *L) {
  492. size_t len = 0;
  493. const char* secret_base32 = luaL_checklstring(L,1,&len);
  494. char * secret = (char *)luat_heap_malloc(len+1);
  495. len = (size_t)luat_str_base32_decode((const uint8_t * )secret_base32,(uint8_t*)secret,len+1);
  496. uint64_t t = 0;
  497. if (lua_isinteger(L, 2)) {
  498. t = (uint64_t)(luaL_checkinteger(L, 2))/30;
  499. }
  500. else {
  501. t = (uint64_t)(time(NULL)/30);
  502. }
  503. uint8_t data[sizeof(uint64_t)] = {0};
  504. for(size_t i=0;i<sizeof(uint64_t);i++)
  505. data[sizeof(uint64_t)-1-i] = *(((uint8_t*)&t)+i);
  506. uint8_t hmac[20] = {0};
  507. int ret = luat_crypto_hmac_sha1_simple((const char *)data, sizeof(data), (const char *)secret, len, hmac);
  508. luat_heap_free(secret);
  509. if(ret == 0)
  510. {
  511. uint8_t offset = hmac[19] & 0x0f;
  512. uint32_t r = (
  513. ((uint32_t)((hmac[offset + 0] & 0x7f)) << 24) |
  514. ((uint32_t)((hmac[offset + 1] & 0xff)) << 16) |
  515. ((uint32_t)((hmac[offset + 2] & 0xff)) << 8) |
  516. ((uint32_t)(hmac[offset + 3] & 0xff))
  517. ) % 1000000;
  518. lua_pushinteger(L,r);
  519. return 1;
  520. }
  521. return 0;
  522. }
  523. /**
  524. 将数据进行base64编码
  525. @api crypto.base64_encode(data)
  526. @string 待编码的数据
  527. @return string 编码后的数据
  528. @usage
  529. -- 本函数与 string.toBase64 是同一个
  530. local data = "123"
  531. local bdata = crypto.base64_encode(data)
  532. log.info("base64", "encode", data, bdata)
  533. data = crypto.base64_decode(data)
  534. log.info("base64", "decode", data, bdata)
  535. */
  536. int l_str_toBase64(lua_State *L);
  537. /**
  538. 将数据进行base64解码
  539. @api crypto.base64_decode(data)
  540. @string 待解码的数据
  541. @return string 解码后的数据
  542. @usage
  543. -- 本函数与 string.fromBase64 是同一个
  544. local data = "123"
  545. local bdata = crypto.base64_encode(data)
  546. log.info("base64", "encode", data, bdata)
  547. data = crypto.base64_decode(data)
  548. log.info("base64", "decode", data, bdata)
  549. */
  550. int l_str_fromBase64(lua_State *L);
  551. /**
  552. 获取当前固件支持的cipher列表
  553. @api crypto.cipher_list()
  554. @return table 本固件支持的cipher列表,字符串数组
  555. @usage
  556. -- 本API于2022.07.27添加
  557. local ciphers = crypto.cipher_list()
  558. if ciphers then
  559. log.info("crypto", "ciphers list", json.encode(ciphers))
  560. end
  561. */
  562. int l_crypto_cipher_list(lua_State *L) {
  563. const char* list[64] = {0};
  564. size_t len = 64;
  565. lua_newtable(L);
  566. int ret = luat_crypto_cipher_list(list, &len);
  567. if (ret == 0) {
  568. for (size_t i = 0; i < len; i++){
  569. lua_pushstring(L, list[i]);
  570. lua_seti(L, -2, i + 1);
  571. }
  572. }
  573. else {
  574. LLOGD("bsp not support cipher_list");
  575. }
  576. return 1;
  577. }
  578. /**
  579. 获取当前固件支持的cipher suites列表
  580. @api crypto.cipher_suites()
  581. @return table 本固件支持的cipher suites列表,字符串数组
  582. @usage
  583. -- 本API于2022.11.16添加
  584. local suites = crypto.cipher_suites()
  585. if suites then
  586. log.info("crypto", "ciphers suites", json.encode(suites))
  587. end
  588. */
  589. int l_crypto_cipher_suites(lua_State *L) {
  590. const char* list[128] = {0};
  591. size_t len = 128;
  592. lua_newtable(L);
  593. int ret = luat_crypto_cipher_suites(list, &len);
  594. if (ret == 0) {
  595. for (size_t i = 0; i < len; i++){
  596. lua_pushstring(L, list[i]);
  597. lua_seti(L, -2, i + 1);
  598. }
  599. }
  600. else {
  601. LLOGD("bsp not support cipher_suites");
  602. }
  603. return 1;
  604. }
  605. /**
  606. 计算文件的hash值(md5/sha1/sha256及hmac形式)
  607. @api crypto.md_file(tp, path, hmac)
  608. @string hash类型, 大小字母, 例如 "MD5" "SHA1" "SHA256"
  609. @string 文件路径, 例如 /luadb/logo.jpg
  610. @string hmac值,可选
  611. @return string HEX过的hash值,若失败会无返回值
  612. @usage
  613. -- 无hmac的hash值
  614. log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
  615. log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
  616. log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
  617. -- 带hmac的hash值
  618. log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
  619. log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
  620. log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
  621. */
  622. static int l_crypto_md_file(lua_State *L) {
  623. size_t key_len = 0;
  624. size_t path_size = 0;
  625. const char* key = NULL;
  626. const char *md = luaL_checkstring(L, 1);
  627. const char* path = luaL_checklstring(L, 2, &path_size);
  628. if (path_size < 2)
  629. return 0;
  630. if (lua_type(L, 3) == LUA_TSTRING) {
  631. key = luaL_checklstring(L, 3, &key_len);
  632. }
  633. char buff[128] = {0};
  634. char output[64];
  635. int ret = luat_crypto_md_file(md, output, key, key_len, path);
  636. if (ret < 1) {
  637. return 0;
  638. }
  639. luat_str_tohex(output, ret, buff);
  640. lua_pushlstring(L, buff, ret *2);
  641. return 1;
  642. }
  643. /**
  644. 计算数据的hash值(md5/sha1/sha256及hmac形式)
  645. @api crypto.md(tp, data, hmac)
  646. @string hash类型, 大小字母, 例如 "MD5" "SHA1" "SHA256"
  647. @string 待处理的数据
  648. @string hmac值,可选
  649. @return string HEX过的hash值,若失败会无返回值
  650. @usage
  651. -- 无hmac的hash值
  652. log.info("md5", crypto.md("MD5", "1234567890"))
  653. log.info("sha1", crypto.md("SHA1", "1234567890"))
  654. log.info("sha256", crypto.md("SHA256", "1234567890"))
  655. -- 带hmac的hash值
  656. log.info("hmac_md5", crypto.md("MD5", "1234567890", "123456"))
  657. log.info("hmac_sha1", crypto.md("SHA1", "1234567890", "123456"))
  658. log.info("hmac_sha256", crypto.md("SHA256", "1234567890", "123456"))
  659. */
  660. static int l_crypto_md(lua_State *L) {
  661. size_t key_len = 0;
  662. size_t data_size = 0;
  663. const char* key = NULL;
  664. const char *md = luaL_checkstring(L, 1);
  665. const char* data = luaL_checklstring(L, 2, &data_size);
  666. if (lua_type(L, 3) == LUA_TSTRING) {
  667. key = luaL_checklstring(L, 3, &key_len);
  668. }
  669. char buff[128] = {0};
  670. char output[64];
  671. int ret = luat_crypto_md_v2(md, data, data_size, output, key, key_len);
  672. if (ret < 1) {
  673. LLOGE("luat_crypto_md return %d", ret);
  674. return 0;
  675. }
  676. luat_str_tohex(output, ret, buff);
  677. lua_pushlstring(L, buff, ret *2);
  678. return 1;
  679. }
  680. /*
  681. 创建流式hash用的stream
  682. @api crypto.hash_init(tp, hmac)
  683. @string hash类型, 大写字母, 例如 "MD5" "SHA1" "SHA256"
  684. @string hmac值,可选
  685. @return userdata 成功返回一个数据结构,否则返回nil
  686. @usage
  687. -- 无hmac的hash stream
  688. local md5_stream = crypto.hash_init("MD5")
  689. local sha1_stream = crypto.hash_init("SHA1")
  690. local sha256_stream = crypto.hash_init("SHA256")
  691. -- 带hmac的hash stream
  692. local md5_stream = crypto.hash_init("MD5", "123456")
  693. local sha1_stream = crypto.hash_init("SHA1", "123456")
  694. local sha256_stream = crypto.hash_init("SHA256", "123456")
  695. */
  696. static int l_crypt_hash_init(lua_State *L) {
  697. luat_crypt_stream_t *stream = (luat_crypt_stream_t *)lua_newuserdata(L, sizeof(luat_crypt_stream_t));
  698. if(stream == NULL) {
  699. return 0;
  700. } else {
  701. memset(stream, 0x00, sizeof(luat_crypt_stream_t));
  702. const char* key = NULL;
  703. const char* md = luaL_checkstring(L, 1);
  704. if(lua_type(L, 2) == LUA_TSTRING) {
  705. key = luaL_checklstring(L, 2, &(stream->key_len));
  706. }
  707. int ret = luat_crypto_md_init(md, key, stream);
  708. if (ret < 0) {
  709. return 0;
  710. } else {
  711. luaL_setmetatable(L, LUAT_CRYPTO_TYPE);
  712. }
  713. }
  714. return 1;
  715. }
  716. /*
  717. 流式hash更新数据
  718. @api crypto.hash_update(stream, data)
  719. @userdata crypto.hash_init()创建的stream, 必选
  720. @string 待计算的数据,必选
  721. @return nil 无返回值
  722. @usage
  723. crypto.hash_update(stream, "OK")
  724. */
  725. static int l_crypt_hash_update(lua_State *L) {
  726. luat_crypt_stream_t *stream = (luat_crypt_stream_t *)luaL_checkudata(L, 1, LUAT_CRYPTO_TYPE);
  727. size_t data_len = 0;
  728. const char *data = luaL_checklstring(L, 2, &data_len);
  729. luat_crypto_md_update(data, data_len ,stream);
  730. return 0;
  731. }
  732. /*
  733. 获取流式hash校验值并释放创建的stream
  734. @api crypto.hash_finish(stream)
  735. @userdata crypto.hash_init()创建的stream,必选
  736. @return string 成功返回计算得出的流式hash值的hex字符串,失败无返回
  737. @usage
  738. local hashResult = crypto.hash_finish(stream)
  739. */
  740. static int l_crypt_hash_finish(lua_State *L) {
  741. luat_crypt_stream_t *stream = (luat_crypt_stream_t *)luaL_checkudata(L, 1, LUAT_CRYPTO_TYPE);
  742. char buff[128] = {0};
  743. char output[64];
  744. int ret = luat_crypto_md_finish(output, stream);
  745. //LLOGD("finish result %d", ret);
  746. if (ret < 1) {
  747. return 0;
  748. }
  749. luat_str_tohex(output, ret, buff);
  750. lua_pushlstring(L, buff, ret * 2);
  751. return 1;
  752. }
  753. /*
  754. 计算checksum校验和
  755. @api crypto.checksum(data, mode)
  756. @string 待计算的数据,必选
  757. @int 模式,累加模式, 0 - 异或, 1 - 累加, 默认为0
  758. @return int checksum值,校验和
  759. @usage
  760. -- 本函数在 2022.12.28 添加
  761. -- 单纯计算checksum值
  762. local ck = crypto.checksum("OK")
  763. log.info("checksum", "ok", string.format("%02X", ck))
  764. -- 第二个参数mode在2023.5.23日添加
  765. */
  766. static int l_crypt_checksum(lua_State *L) {
  767. size_t len = 0;
  768. uint8_t checksum = 0x00;
  769. uint8_t tmp = 0;
  770. const char* sentence = luaL_checklstring(L, 1, &len);
  771. int mode = luaL_optinteger(L, 2, 0);
  772. // LLOGD("mode %d", mode);
  773. for (size_t i = 0; i < len; i++)
  774. {
  775. tmp = *sentence;
  776. if (mode == 1) {
  777. checksum += tmp;
  778. }
  779. else {
  780. checksum ^= tmp;
  781. }
  782. // LLOGD("> %02X > %02X", checksum, tmp);
  783. sentence ++;
  784. }
  785. lua_pushinteger(L, checksum);
  786. return 1;
  787. }
  788. #include "rotable2.h"
  789. static const rotable_Reg_t reg_crypto[] =
  790. {
  791. { "md5" , ROREG_FUNC(l_crypto_md5 )},
  792. { "sha1" , ROREG_FUNC(l_crypto_sha1 )},
  793. { "sha256" , ROREG_FUNC(l_crypto_sha256 )},
  794. { "sha512" , ROREG_FUNC(l_crypto_sha512 )},
  795. { "hmac_md5" , ROREG_FUNC(l_crypto_hmac_md5 )},
  796. { "hmac_sha1" , ROREG_FUNC(l_crypto_hmac_sha1 )},
  797. { "hmac_sha256" , ROREG_FUNC(l_crypto_hmac_sha256 )},
  798. { "hmac_sha512" , ROREG_FUNC(l_crypto_hmac_sha512 )},
  799. { "cipher" , ROREG_FUNC(l_crypto_cipher_encrypt )},
  800. { "cipher_encrypt" ,ROREG_FUNC(l_crypto_cipher_encrypt )},
  801. { "cipher_decrypt" ,ROREG_FUNC(l_crypto_cipher_decrypt )},
  802. { "cipher_list" , ROREG_FUNC(l_crypto_cipher_list )},
  803. { "cipher_suites", ROREG_FUNC(l_crypto_cipher_suites)},
  804. { "crc16", ROREG_FUNC(l_crypto_crc16 )},
  805. { "crc16_modbus", ROREG_FUNC(l_crypto_crc16_modbus )},
  806. { "crc32", ROREG_FUNC(l_crypto_crc32 )},
  807. { "crc8", ROREG_FUNC(l_crypto_crc8 )},
  808. { "crc7", ROREG_FUNC(l_crypto_crc7 )},
  809. { "trng", ROREG_FUNC(l_crypto_trng )},
  810. { "totp", ROREG_FUNC(l_crypto_totp )},
  811. { "base64_encode", ROREG_FUNC(l_str_toBase64)},
  812. { "base64_decode", ROREG_FUNC(l_str_fromBase64)},
  813. { "md_file", ROREG_FUNC(l_crypto_md_file)},
  814. { "md", ROREG_FUNC(l_crypto_md)},
  815. { "checksum", ROREG_FUNC(l_crypt_checksum)},
  816. { "hash_init", ROREG_FUNC(l_crypt_hash_init)},
  817. { "hash_update", ROREG_FUNC(l_crypt_hash_update)},
  818. { "hash_finish", ROREG_FUNC(l_crypt_hash_finish)},
  819. { NULL, ROREG_INT(0) }
  820. };
  821. LUAMOD_API int luaopen_crypto( lua_State *L ) {
  822. luat_newlib2(L, reg_crypto);
  823. luaL_newmetatable(L, LUAT_CRYPTO_TYPE);
  824. lua_pop(L, 1);
  825. return 1;
  826. }
  827. // 添加几个默认实现
  828. #ifndef LUAT_COMPILER_NOWEAK
  829. LUAT_WEAK int luat_crypto_trng(char* buff, size_t len) {
  830. memset(buff, 0, len);
  831. return 0;
  832. }
  833. #endif