luat_lib_crypto.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  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_malloc.h"
  12. #include "luat_str.h"
  13. #include <time.h>
  14. #include "luat_zbuff.h"
  15. #define LUAT_LOG_TAG "crypto"
  16. #include "luat_log.h"
  17. static const unsigned char hexchars[] = "0123456789ABCDEF";
  18. static void fixhex(const char* source, char* dst, size_t len) {
  19. for (size_t i = 0; i < len; i++)
  20. {
  21. char ch = *(source+i);
  22. dst[i*2] = hexchars[(unsigned char)ch >> 4];
  23. dst[i*2+1] = hexchars[(unsigned char)ch & 0xF];
  24. }
  25. }
  26. /**
  27. 计算md5值
  28. @api crypto.md5(str)
  29. @string 需要计算的字符串
  30. @return string 计算得出的md5值的hex字符串
  31. @usage
  32. -- 计算字符串"abc"的md5
  33. log.info("md5", crypto.md5("abc"))
  34. */
  35. static int l_crypto_md5(lua_State *L) {
  36. size_t size = 0;
  37. const char* str = luaL_checklstring(L, 1, &size);
  38. char tmp[32] = {0};
  39. char dst[32] = {0};
  40. if (luat_crypto_md5_simple(str, size, tmp) == 0) {
  41. fixhex(tmp, dst, 16);
  42. lua_pushlstring(L, dst, 32);
  43. return 1;
  44. }
  45. return 0;
  46. }
  47. /**
  48. 计算hmac_md5值
  49. @api crypto.hmac_md5(str, key)
  50. @string 需要计算的字符串
  51. @string 密钥
  52. @return string 计算得出的hmac_md5值的hex字符串
  53. @usage
  54. -- 计算字符串"abc"的hmac_md5
  55. log.info("hmac_md5", crypto.hmac_md5("abc", "1234567890"))
  56. */
  57. static int l_crypto_hmac_md5(lua_State *L) {
  58. size_t str_size = 0;
  59. size_t key_size = 0;
  60. const char* str = luaL_checklstring(L, 1, &str_size);
  61. const char* key = luaL_checklstring(L, 2, &key_size);
  62. char tmp[32] = {0};
  63. char dst[32] = {0};
  64. if (luat_crypto_hmac_md5_simple(str, str_size, key, key_size, tmp) == 0) {
  65. fixhex(tmp, dst, 16);
  66. lua_pushlstring(L, dst, 32);
  67. return 1;
  68. }
  69. return 0;
  70. }
  71. /**
  72. 计算sha1值
  73. @api crypto.sha1(str)
  74. @string 需要计算的字符串
  75. @return string 计算得出的sha1值的hex字符串
  76. @usage
  77. -- 计算字符串"abc"的sha1
  78. log.info("sha1", crypto.sha1("abc"))
  79. */
  80. static int l_crypto_sha1(lua_State *L) {
  81. size_t size = 0;
  82. const char* str = luaL_checklstring(L, 1, &size);
  83. char tmp[40] = {0};
  84. char dst[40] = {0};
  85. if (luat_crypto_sha1_simple(str, size, tmp) == 0) {
  86. fixhex(tmp, dst, 20);
  87. lua_pushlstring(L, dst, 40);
  88. return 1;
  89. }
  90. return 0;
  91. }
  92. /**
  93. 计算hmac_sha1值
  94. @api crypto.hmac_sha1(str, key)
  95. @string 需要计算的字符串
  96. @string 密钥
  97. @return string 计算得出的hmac_sha1值的hex字符串
  98. @usage
  99. -- 计算字符串"abc"的hmac_sha1
  100. log.info("hmac_sha1", crypto.hmac_sha1("abc", "1234567890"))
  101. */
  102. static int l_crypto_hmac_sha1(lua_State *L) {
  103. size_t str_size = 0;
  104. size_t key_size = 0;
  105. const char* str = luaL_checklstring(L, 1, &str_size);
  106. const char* key = luaL_checklstring(L, 2, &key_size);
  107. char tmp[40] = {0};
  108. char dst[40] = {0};
  109. if (luat_crypto_hmac_sha1_simple(str, str_size, key, key_size, tmp) == 0) {
  110. fixhex(tmp, dst, 20);
  111. lua_pushlstring(L, dst, 40);
  112. return 1;
  113. }
  114. return 0;
  115. }
  116. /**
  117. 计算sha256值
  118. @api crypto.sha256(str)
  119. @string 需要计算的字符串
  120. @return string 计算得出的sha256值的hex字符串
  121. @usage
  122. -- 计算字符串"abc"的sha256
  123. log.info("sha256", crypto.sha256("abc"))
  124. */
  125. static int l_crypto_sha256(lua_State *L) {
  126. size_t size = 0;
  127. const char* str = luaL_checklstring(L, 1, &size);
  128. char tmp[64] = {0};
  129. char dst[64] = {0};
  130. if (luat_crypto_sha256_simple(str, size, tmp) == 0) {
  131. fixhex(tmp, dst, 32);
  132. lua_pushlstring(L, dst, 64);
  133. return 1;
  134. }
  135. return 0;
  136. }
  137. /**
  138. 计算hmac_sha256值
  139. @api crypto.hmac_sha256(str, key)
  140. @string 需要计算的字符串
  141. @string 密钥
  142. @return string 计算得出的hmac_sha256值的hex字符串
  143. @usage
  144. -- 计算字符串"abc"的hmac_sha256
  145. log.info("hmac_sha256", crypto.hmac_sha256("abc", "1234567890"))
  146. */
  147. static int l_crypto_hmac_sha256(lua_State *L) {
  148. size_t str_size = 0;
  149. size_t key_size = 0;
  150. const char* str = luaL_checklstring(L, 1, &str_size);
  151. const char* key = luaL_checklstring(L, 2, &key_size);
  152. char tmp[64] = {0};
  153. char dst[64] = {0};
  154. if (key_size > 64) {
  155. luat_crypto_sha256_simple(key, key_size, dst);
  156. key = (const char*)dst;
  157. key_size = 64;
  158. }
  159. if (luat_crypto_hmac_sha256_simple(str, str_size, key, key_size, tmp) == 0) {
  160. fixhex(tmp, dst, 32);
  161. lua_pushlstring(L, dst, 64);
  162. return 1;
  163. }
  164. return 0;
  165. }
  166. //---
  167. /**
  168. 计算sha512值
  169. @api crypto.sha512(str)
  170. @string 需要计算的字符串
  171. @return string 计算得出的sha512值的hex字符串
  172. @usage
  173. -- 计算字符串"abc"的sha512
  174. log.info("sha512", crypto.sha512("abc"))
  175. */
  176. static int l_crypto_sha512(lua_State *L) {
  177. size_t size = 0;
  178. const char* str = luaL_checklstring(L, 1, &size);
  179. char tmp[128] = {0};
  180. char dst[128] = {0};
  181. if (luat_crypto_sha512_simple(str, size, tmp) == 0) {
  182. fixhex(tmp, dst, 64);
  183. lua_pushlstring(L, dst, 128);
  184. return 1;
  185. }
  186. return 0;
  187. }
  188. /**
  189. 计算hmac_sha512值
  190. @api crypto.hmac_sha512(str, key)
  191. @string 需要计算的字符串
  192. @string 密钥
  193. @return string 计算得出的hmac_sha512值的hex字符串
  194. @usage
  195. -- 计算字符串"abc"的hmac_sha512
  196. log.info("hmac_sha512", crypto.hmac_sha512("abc", "1234567890"))
  197. */
  198. static int l_crypto_hmac_sha512(lua_State *L) {
  199. size_t str_size = 0;
  200. size_t key_size = 0;
  201. const char* str = luaL_checklstring(L, 1, &str_size);
  202. const char* key = luaL_checklstring(L, 2, &key_size);
  203. char tmp[128] = {0};
  204. char dst[128] = {0};
  205. if (key_size > 128) {
  206. luat_crypto_sha512_simple(key, key_size, dst);
  207. key = (const char*)dst;
  208. key_size = 128;
  209. }
  210. if (luat_crypto_hmac_sha512_simple(str, str_size, key, key_size, tmp) == 0) {
  211. fixhex(tmp, dst, 64);
  212. lua_pushlstring(L, dst, 128);
  213. return 1;
  214. }
  215. return 0;
  216. }
  217. int l_crypto_cipher_xxx(lua_State *L, uint8_t flags);
  218. /**
  219. 对称加密
  220. @api crypto.cipher_encrypt(type, padding, str, key, iv)
  221. @string 算法名称, 例如 AES-128-ECB/AES-128-CBC, 可查阅crypto.cipher_list()
  222. @string 对齐方式, 支持PKCS7/ZERO/ONE_AND_ZEROS/ZEROS_AND_LEN/NONE
  223. @string 需要加密的数据
  224. @string 密钥,需要对应算法的密钥长度
  225. @string IV值, 非ECB算法需要
  226. @return string 加密后的字符串
  227. @usage
  228. -- 计算AES
  229. local data = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "1234567890123456", "1234567890123456")
  230. local data2 = crypto.cipher_encrypt("AES-128-CBC", "PKCS7", "1234567890123456", "1234567890123456", "1234567890666666")
  231. */
  232. int l_crypto_cipher_encrypt(lua_State *L) {
  233. return l_crypto_cipher_xxx(L, 1);
  234. }
  235. /**
  236. 对称解密
  237. @api crypto.cipher_decrypt(type, padding, str, key, iv)
  238. @string 算法名称, 例如 AES-128-ECB/AES-128-CBC, 可查阅crypto.cipher_list()
  239. @string 对齐方式, 支持PKCS7/ZERO/ONE_AND_ZEROS/ZEROS_AND_LEN/NONE
  240. @string 需要解密的数据
  241. @string 密钥,需要对应算法的密钥长度
  242. @string IV值, 非ECB算法需要
  243. @return string 解密后的字符串
  244. @usage
  245. -- 用AES加密,然后用AES解密
  246. local data = crypto.cipher_encrypt("AES-128-ECB", "PKCS7", "1234567890123456", "1234567890123456")
  247. local data2 = crypto.cipher_decrypt("AES-128-ECB", "PKCS7", data, "1234567890123456")
  248. -- data的hex为 757CCD0CDC5C90EADBEEECF638DD0000
  249. -- data2的值为 1234567890123456
  250. */
  251. int l_crypto_cipher_decrypt(lua_State *L) {
  252. return l_crypto_cipher_xxx(L, 0);
  253. }
  254. #include "crc.h"
  255. /**
  256. 计算CRC16
  257. @api crypto.crc16(method, data, poly, initial, finally, inReversem outReverse)
  258. @string CRC16模式("IBM","MAXIM","USB","MODBUS","CCITT","CCITT-FALSE","X25","XMODEM","DNP","USER-DEFINED")
  259. @string 字符串
  260. @int poly值
  261. @int initial值
  262. @int finally值
  263. @int 输入反转,1反转,默认0不反转
  264. @int 输入反转,1反转,默认0不反转
  265. @return int 对应的CRC16值
  266. @usage
  267. -- 计算CRC16
  268. local crc = crypto.crc16("")
  269. */
  270. static int l_crypto_crc16(lua_State *L)
  271. {
  272. size_t inputlen;
  273. const unsigned char *inputData;
  274. const char *inputmethod = (const char*)luaL_checkstring(L, 1);
  275. if(lua_isuserdata(L, 2))
  276. {
  277. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  278. inputlen = buff->len - buff->cursor;
  279. inputData = (const unsigned char *)(buff->addr + buff->cursor);
  280. }else{
  281. inputData = (const unsigned char*)lua_tolstring(L,2,&inputlen);
  282. }
  283. uint16_t poly = luaL_optnumber(L,3,0x0000);
  284. uint16_t initial = luaL_optnumber(L,4,0x0000);
  285. uint16_t finally = luaL_optnumber(L,5,0x0000);
  286. uint8_t inReverse = luaL_optnumber(L,6,0);
  287. uint8_t outReverse = luaL_optnumber(L,7,0);
  288. lua_pushinteger(L, calcCRC16(inputData, inputmethod,inputlen,poly,initial,finally,inReverse,outReverse));
  289. return 1;
  290. }
  291. /**
  292. 直接计算modbus的crc16值
  293. @api crypto.crc16_modbus(data)
  294. @string 数据
  295. @return int 对应的CRC16值
  296. @usage
  297. -- 计算CRC16 modbus
  298. local crc = crypto.crc16_modbus(data)
  299. */
  300. static int l_crypto_crc16_modbus(lua_State *L)
  301. {
  302. size_t len = 0;
  303. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  304. lua_pushinteger(L, calcCRC16_modbus(inputData, len));
  305. return 1;
  306. }
  307. /**
  308. 计算crc32值
  309. @api crypto.crc32(data)
  310. @string 数据
  311. @return int 对应的CRC32值
  312. @usage
  313. -- 计算CRC32
  314. local crc = crypto.crc32(data)
  315. */
  316. static int l_crypto_crc32(lua_State *L)
  317. {
  318. size_t len = 0;
  319. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  320. lua_pushinteger(L, calcCRC32(inputData, len));
  321. return 1;
  322. }
  323. /**
  324. 计算crc8值
  325. @api crypto.crc8(data)
  326. @string 数据
  327. @int crc多项式,可选,如果不写,将忽略除了数据外所有参数
  328. @int crc初始值,可选,默认0
  329. @boolean 是否需要逆序处理,默认否
  330. @return int 对应的CRC8值
  331. @usage
  332. -- 计算CRC8
  333. local crc = crypto.crc8(data)
  334. local crc = crypto.crc8(data, 0x31, 0xff, false)
  335. */
  336. static int l_crypto_crc8(lua_State *L)
  337. {
  338. size_t len = 0;
  339. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  340. if (!lua_isinteger(L, 2)) {
  341. lua_pushinteger(L, calcCRC8(inputData, len));
  342. } else {
  343. uint8_t poly = lua_tointeger(L, 2);
  344. uint8_t start = luaL_optinteger(L, 3, 0);
  345. uint8_t is_rev = 0;
  346. if (lua_isboolean(L, 4)) {
  347. is_rev = lua_toboolean(L, 4);
  348. }
  349. uint8_t i;
  350. uint8_t CRC8 = start;
  351. uint8_t *Src = (uint8_t *)inputData;
  352. if (is_rev)
  353. {
  354. poly = 0;
  355. for (i = 0; i < 8; i++)
  356. {
  357. if (start & (1 << (7 - i)))
  358. {
  359. poly |= 1 << i;
  360. }
  361. }
  362. while (len--)
  363. {
  364. CRC8 ^= *Src++;
  365. for (i = 0; i < 8; i++)
  366. {
  367. if ((CRC8 & 0x01))
  368. {
  369. CRC8 >>= 1;
  370. CRC8 ^= poly;
  371. }
  372. else
  373. {
  374. CRC8 >>= 1;
  375. }
  376. }
  377. }
  378. }
  379. else
  380. {
  381. while (len--)
  382. {
  383. CRC8 ^= *Src++;
  384. for (i = 8; i > 0; --i)
  385. {
  386. if ((CRC8 & 0x80))
  387. {
  388. CRC8 <<= 1;
  389. CRC8 ^= poly;
  390. }
  391. else
  392. {
  393. CRC8 <<= 1;
  394. }
  395. }
  396. }
  397. }
  398. lua_pushinteger(L, CRC8);
  399. }
  400. return 1;
  401. }
  402. /**
  403. 生成真随机数
  404. @api crypto.trng(len)
  405. @int 数据长度
  406. @return string 指定随机数字符串
  407. @usage
  408. -- 生成32位随机数ir
  409. local r = crypto.trng(4)
  410. local _, ir = pack.unpack(r, "I")
  411. */
  412. static int l_crypto_trng(lua_State *L) {
  413. int ret = 0;
  414. size_t len = luaL_checkinteger(L, 1);
  415. if (len < 1) {
  416. return 0;
  417. }
  418. if (len > 128)
  419. len = 128;
  420. char buff[128];
  421. ret = luat_crypto_trng(buff, len);
  422. if(ret ==0){
  423. lua_pushlstring(L, buff, len);
  424. return 1;
  425. }
  426. return 0;
  427. }
  428. /**
  429. 计算TOTP动态密码的结果
  430. @api crypto.totp(secret,time)
  431. @string 网站提供的密钥(就是BASE32编码后的结果)
  432. @int 可选,时间戳,默认当前时间
  433. @return int 计算得出的六位数结果 计算失败返回nil
  434. @usage
  435. --使用当前系统时间计算
  436. local otp = crypto.totp("asdfassdfasdfass")
  437. */
  438. static int l_crypto_totp(lua_State *L) {
  439. size_t len = 0;
  440. const char* secret_base32 = luaL_checklstring(L,1,&len);
  441. char * secret = (char *)luat_heap_malloc(len+1);
  442. len = (size_t)luat_str_base32_decode((const uint8_t * )secret_base32,(uint8_t*)secret,len+1);
  443. uint64_t t = (uint64_t)(luaL_optinteger(L,2,(lua_Integer)time(NULL))/30);
  444. uint8_t data[sizeof(t)] = {0};
  445. for(int i=0;i<sizeof(t);i++)
  446. data[sizeof(t)-1-i] = *(((uint8_t*)&t)+i);
  447. uint8_t hmac[20] = {0};
  448. if(luat_crypto_hmac_sha1_simple((const char *)data, sizeof(data), (const char *)secret, len, hmac) == 0)
  449. {
  450. uint8_t offset = hmac[19] & 0x0f;
  451. uint32_t r = (
  452. ((uint32_t)((hmac[offset + 0] & 0x7f)) << 24) |
  453. ((uint32_t)((hmac[offset + 1] & 0xff)) << 16) |
  454. ((uint32_t)((hmac[offset + 2] & 0xff)) << 8) |
  455. ((uint32_t)(hmac[offset + 3] & 0xff))
  456. ) % 1000000;
  457. lua_pushinteger(L,r);
  458. return 1;
  459. }
  460. return 0;
  461. }
  462. /**
  463. 将数据进行base64编码
  464. @api crypto.base64_encode(data)
  465. @string 待编码的数据
  466. @return string 编码后的数据
  467. @usage
  468. -- 本函数与 string.toBase64 是同一个
  469. local data = "123"
  470. local bdata = crypto.base64_encode(data)
  471. log.info("base64", "encode", data, bdata)
  472. data = crypto.base64_decode(data)
  473. log.info("base64", "decode", data, bdata)
  474. */
  475. int l_str_toBase64(lua_State *L);
  476. /**
  477. 将数据进行base64解码
  478. @api crypto.base64_decode(data)
  479. @string 待解码的数据
  480. @return string 解码后的数据
  481. @usage
  482. -- 本函数与 string.fromBase64 是同一个
  483. local data = "123"
  484. local bdata = crypto.base64_encode(data)
  485. log.info("base64", "encode", data, bdata)
  486. data = crypto.base64_decode(data)
  487. log.info("base64", "decode", data, bdata)
  488. */
  489. int l_str_fromBase64(lua_State *L);
  490. /**
  491. 获取当前固件支持的cipher列表
  492. @api crypto.cipher_list()
  493. @return table 本固件支持的cipher列表,字符串数组
  494. @usage
  495. -- 本API于2022.07.27添加
  496. local ciphers = crypto.cipher_list()
  497. if ciphers then
  498. log.info("crypto", "ciphers list", json.encode(ciphers))
  499. end
  500. */
  501. int l_crypto_cipher_list(lua_State *L) {
  502. const char* list[64] = {0};
  503. size_t len = 64;
  504. lua_newtable(L);
  505. if (list == NULL) {
  506. LLOGD("out of memory when cipher_list");
  507. return 1;
  508. }
  509. int ret = luat_crypto_cipher_list(list, &len);
  510. if (ret == 0) {
  511. for (size_t i = 0; i < len; i++){
  512. lua_pushstring(L, list[i]);
  513. lua_seti(L, -2, i + 1);
  514. }
  515. }
  516. else {
  517. LLOGD("bsp not support cipher_list");
  518. }
  519. return 1;
  520. }
  521. /**
  522. 获取当前固件支持的cipher suites列表
  523. @api crypto.cipher_suites()
  524. @return table 本固件支持的cipher suites列表,字符串数组
  525. @usage
  526. -- 本API于2022.11.16添加
  527. local suites = crypto.cipher_suites()
  528. if suites then
  529. log.info("crypto", "ciphers suites", json.encode(suites))
  530. end
  531. */
  532. int l_crypto_cipher_suites(lua_State *L) {
  533. const char* list[128] = {0};
  534. size_t len = 128;
  535. lua_newtable(L);
  536. if (list == NULL) {
  537. LLOGD("out of memory when cipher_list");
  538. return 1;
  539. }
  540. int ret = luat_crypto_cipher_suites(list, &len);
  541. if (ret == 0) {
  542. for (size_t i = 0; i < len; i++){
  543. lua_pushstring(L, list[i]);
  544. lua_seti(L, -2, i + 1);
  545. }
  546. }
  547. else {
  548. LLOGD("bsp not support cipher_suites");
  549. }
  550. return 1;
  551. }
  552. /**
  553. 计算文件的hash值(md5/sha1/sha256及hmac形式)
  554. @api crypto.md_file(tp, path, hmac)
  555. @string hash类型, 大小字母, 例如 "MD5" "SHA1" "SHA256"
  556. @string 文件路径, 例如 /luadb/logo.jpg
  557. @string hmac值,可选
  558. @return string HEX过的hash值,若失败会无返回值
  559. @usage
  560. -- 无hmac的hash值
  561. log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
  562. log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
  563. log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
  564. -- 带hmac的hash值
  565. log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
  566. log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
  567. log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
  568. */
  569. static int l_crypto_md_file(lua_State *L) {
  570. size_t key_len = 0;
  571. size_t path_size = 0;
  572. const char* key = NULL;
  573. const char *md = luaL_checkstring(L, 1);
  574. const char* path = luaL_checklstring(L, 2, &path_size);
  575. if (path_size < 2)
  576. return 0;
  577. if (lua_type(L, 3) == LUA_TSTRING) {
  578. key = luaL_checklstring(L, 3, &key_len);
  579. }
  580. char buff[128] = {0};
  581. char output[64];
  582. int ret = luat_crypto_md_file(md, output, key, key_len, path);
  583. if (ret < 1) {
  584. return 0;
  585. }
  586. fixhex(output, buff, ret);
  587. lua_pushlstring(L, buff, ret *2);
  588. return 1;
  589. }
  590. /**
  591. 计算数据的hash值(md5/sha1/sha256及hmac形式)
  592. @api crypto.md(tp, data, hmac)
  593. @string hash类型, 大小字母, 例如 "MD5" "SHA1" "SHA256"
  594. @string 待处理的数据
  595. @string hmac值,可选
  596. @return string HEX过的hash值,若失败会无返回值
  597. @usage
  598. -- 无hmac的hash值
  599. log.info("md5", crypto.md("MD5", "1234567890"))
  600. log.info("sha1", crypto.md("SHA1", "1234567890"))
  601. log.info("sha256", crypto.md("SHA256", "1234567890"))
  602. -- 带hmac的hash值
  603. log.info("hmac_md5", crypto.md("MD5", "1234567890", "123456"))
  604. log.info("hmac_sha1", crypto.md("SHA1", "1234567890", "123456"))
  605. log.info("hmac_sha256", crypto.md("SHA256", "1234567890", "123456"))
  606. */
  607. static int l_crypto_md(lua_State *L) {
  608. size_t key_len = 0;
  609. size_t data_size = 0;
  610. const char* key = NULL;
  611. const char *md = luaL_checkstring(L, 1);
  612. const char* data = luaL_checklstring(L, 2, &data_size);
  613. if (lua_type(L, 3) == LUA_TSTRING) {
  614. key = luaL_checklstring(L, 3, &key_len);
  615. }
  616. char buff[128] = {0};
  617. char output[64];
  618. int ret = luat_crypto_md(md, data, data_size, output, key, key_len);
  619. if (ret < 1) {
  620. return 0;
  621. }
  622. fixhex(output, buff, ret);
  623. lua_pushlstring(L, buff, ret *2);
  624. return 1;
  625. }
  626. /*
  627. 计算checksum校验和
  628. @api crypto.checksum(data)
  629. @string 待计算的数据,必选
  630. @return int checksum值,校验和
  631. @usage
  632. -- 本函数在 2022.12.28 添加
  633. -- 单纯计算checksum值
  634. local ck = crypto.checksum("OK")
  635. log.info("checksum", "ok", string.format("%02X", ck))
  636. */
  637. static int l_crypt_checksum(lua_State *L) {
  638. size_t len = 0;
  639. uint8_t checksum = 0x00;
  640. const char* sentence = luaL_checklstring(L, 1, &len);
  641. for (size_t i = 0; i < len; i++)
  642. {
  643. checksum ^= *sentence++;
  644. }
  645. // if (lua_isboolean(L, 2) && lua_toboolean(L, 2) == 1) {
  646. // luaL_Buffer buff;
  647. // luaL_buffinitsize(L, &buff, len + 1);
  648. // luaL_addlstring(&buff, sentence, len);
  649. // luaL_addchar(&buff, checksum);
  650. // luaL_pushresult(&buff);
  651. // }
  652. // else {
  653. lua_pushinteger(L, checksum);
  654. // }
  655. return 1;
  656. }
  657. #include "rotable2.h"
  658. static const rotable_Reg_t reg_crypto[] =
  659. {
  660. { "md5" , ROREG_FUNC(l_crypto_md5 )},
  661. { "sha1" , ROREG_FUNC(l_crypto_sha1 )},
  662. { "sha256" , ROREG_FUNC(l_crypto_sha256 )},
  663. { "sha512" , ROREG_FUNC(l_crypto_sha512 )},
  664. { "hmac_md5" , ROREG_FUNC(l_crypto_hmac_md5 )},
  665. { "hmac_sha1" , ROREG_FUNC(l_crypto_hmac_sha1 )},
  666. { "hmac_sha256" , ROREG_FUNC(l_crypto_hmac_sha256 )},
  667. { "hmac_sha512" , ROREG_FUNC(l_crypto_hmac_sha512 )},
  668. { "cipher" , ROREG_FUNC(l_crypto_cipher_encrypt )},
  669. { "cipher_encrypt" ,ROREG_FUNC(l_crypto_cipher_encrypt )},
  670. { "cipher_decrypt" ,ROREG_FUNC(l_crypto_cipher_decrypt )},
  671. { "cipher_list" , ROREG_FUNC(l_crypto_cipher_list )},
  672. { "cipher_suites", ROREG_FUNC(l_crypto_cipher_suites)},
  673. { "crc16", ROREG_FUNC(l_crypto_crc16 )},
  674. { "crc16_modbus", ROREG_FUNC(l_crypto_crc16_modbus )},
  675. { "crc32", ROREG_FUNC(l_crypto_crc32 )},
  676. { "crc8", ROREG_FUNC(l_crypto_crc8 )},
  677. { "trng", ROREG_FUNC(l_crypto_trng )},
  678. { "totp", ROREG_FUNC(l_crypto_totp )},
  679. { "base64_encode", ROREG_FUNC(l_str_toBase64)},
  680. { "base64_decode", ROREG_FUNC(l_str_fromBase64)},
  681. { "md_file", ROREG_FUNC(l_crypto_md_file)},
  682. { "md", ROREG_FUNC(l_crypto_md)},
  683. { "checksum", ROREG_FUNC(l_crypt_checksum)},
  684. { NULL, ROREG_INT(0) }
  685. };
  686. LUAMOD_API int luaopen_crypto( lua_State *L ) {
  687. luat_newlib2(L, reg_crypto);
  688. return 1;
  689. }
  690. // 添加几个默认实现
  691. #ifndef LUAT_COMPILER_NOWEAK
  692. LUAT_WEAK int luat_crypto_md5_simple(const char* str, size_t str_size, void* out_ptr) {return -1;}
  693. LUAT_WEAK int luat_crypto_hmac_md5_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {return -1;}
  694. LUAT_WEAK int luat_crypto_sha1_simple(const char* str, size_t str_size, void* out_ptr) {return -1;}
  695. LUAT_WEAK int luat_crypto_hmac_sha1_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {return -1;}
  696. LUAT_WEAK int luat_crypto_sha256_simple(const char* str, size_t str_size, void* out_ptr) {return -1;}
  697. LUAT_WEAK int luat_crypto_hmac_sha256_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {return -1;}
  698. LUAT_WEAK int luat_crypto_sha512_simple(const char* str, size_t str_size, void* out_ptr) {return -1;}
  699. LUAT_WEAK int luat_crypto_hmac_sha512_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {return -1;}
  700. LUAT_WEAK int l_crypto_cipher_xxx(lua_State *L, uint8_t flags) {return 0;}
  701. LUAT_WEAK int luat_crypto_trng(char* buff, size_t len) {
  702. memset(buff, 0, len);
  703. return 0;
  704. }
  705. #endif