luat_lib_crypto.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  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. #include "crc.h"
  265. /**
  266. 计算CRC16
  267. @api crypto.crc16(method, data, poly, initial, finally, inReversem outReverse)
  268. @string CRC16模式("IBM","MAXIM","USB","MODBUS","CCITT","CCITT-FALSE","X25","XMODEM","DNP","USER-DEFINED")
  269. @string 字符串
  270. @int poly值
  271. @int initial值
  272. @int finally值
  273. @int 输入反转,1反转,默认0不反转
  274. @int 输入反转,1反转,默认0不反转
  275. @return int 对应的CRC16值
  276. @usage
  277. -- 计算CRC16
  278. local crc = crypto.crc16("")
  279. */
  280. static int l_crypto_crc16(lua_State *L)
  281. {
  282. size_t inputlen;
  283. const unsigned char *inputData;
  284. const char *inputmethod = (const char*)luaL_checkstring(L, 1);
  285. if(lua_isuserdata(L, 2))
  286. {
  287. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  288. inputlen = buff->len - buff->cursor;
  289. inputData = (const unsigned char *)(buff->addr + buff->cursor);
  290. }else{
  291. inputData = (const unsigned char*)lua_tolstring(L,2,&inputlen);
  292. }
  293. uint16_t poly = (uint16_t)luaL_optnumber(L,3,0x0000);
  294. uint16_t initial = (uint16_t)luaL_optnumber(L,4,0x0000);
  295. uint16_t finally = (uint16_t)luaL_optnumber(L,5,0x0000);
  296. uint8_t inReverse = (uint8_t)luaL_optnumber(L,6,0);
  297. uint8_t outReverse = (uint8_t)luaL_optnumber(L,7,0);
  298. lua_pushinteger(L, calcCRC16(inputData, inputmethod,inputlen,poly,initial,finally,inReverse,outReverse));
  299. return 1;
  300. }
  301. /**
  302. 直接计算modbus的crc16值
  303. @api crypto.crc16_modbus(data, start)
  304. @string 数据
  305. @int 初始化值,默认0xFFFF
  306. @return int 对应的CRC16值
  307. @usage
  308. -- 计算CRC16 modbus
  309. local crc = crypto.crc16_modbus(data)
  310. -- 2023.11.06 新增初始值设置
  311. crc = crypto.crc16_modbus(data, 0xFFFF)
  312. */
  313. static int l_crypto_crc16_modbus(lua_State *L)
  314. {
  315. size_t len = 0;
  316. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  317. uint16_t crc_init = (uint16_t)luaL_optinteger(L, 2, 0xFFFF);
  318. lua_pushinteger(L, calcCRC16_modbus(inputData, len, crc_init));
  319. return 1;
  320. }
  321. /**
  322. 计算crc32值
  323. @api crypto.crc32(data, start, poly, endv)
  324. @string 数据
  325. @int 初始化值,默认0xFFFFFFFF
  326. @int crc多项式,可选,默认0x04C11DB7
  327. @int 结束值,可选,默认0xFFFFFFFF,计算结果异或结束值才是最终输出值
  328. @return int 对应的CRC32值
  329. @usage
  330. -- 计算CRC32
  331. local crc = crypto.crc32(data)
  332. -- start和poly可选, 是 2025.4.14 新增的参数
  333. local crc = crypto.crc32(data, 0xFFFFFFFF, 0x04C11DB7, 0xFFFFFFFF) --等同于crypto.crc32(data)
  334. */
  335. static int l_crypto_crc32(lua_State *L)
  336. {
  337. size_t len = 0;
  338. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  339. uint32_t start = (uint32_t)luaL_optinteger(L, 2, 0xffffffff);
  340. uint32_t poly = (uint32_t)luaL_optinteger(L, 3, 0x04C11DB7);
  341. uint32_t end = (uint32_t)luaL_optinteger(L, 4, 0xffffffff);
  342. lua_pushinteger(L, luat_crc32(inputData, len, start, poly) ^ end);
  343. return 1;
  344. }
  345. /**
  346. 计算crc8值
  347. @api crypto.crc8(data, poly, start, revert)
  348. @string 数据
  349. @int crc多项式,可选,如果不写,将忽略除了数据外所有参数
  350. @int crc初始值,可选,默认0
  351. @boolean 是否需要逆序处理,默认否
  352. @return int 对应的CRC8值
  353. @usage
  354. -- 计算CRC8
  355. local crc = crypto.crc8(data)
  356. local crc = crypto.crc8(data, 0x31, 0xff, false)
  357. */
  358. static int l_crypto_crc8(lua_State *L)
  359. {
  360. size_t len = 0;
  361. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  362. if (!lua_isinteger(L, 2)) {
  363. lua_pushinteger(L, calcCRC8(inputData, len));
  364. } else {
  365. uint8_t poly = (uint8_t)lua_tointeger(L, 2);
  366. uint8_t start = (uint8_t)luaL_optinteger(L, 3, 0);
  367. uint8_t is_rev = 0;
  368. if (lua_isboolean(L, 4)) {
  369. is_rev = (uint8_t)lua_toboolean(L, 4);
  370. }
  371. lua_pushinteger(L, luat_crc8(inputData, len, start, poly, is_rev));
  372. }
  373. return 1;
  374. }
  375. /**
  376. 计算crc7值
  377. @api crypto.crc7(data, poly, start)
  378. @string 数据
  379. @int crc多项式,可选,默认0xE5
  380. @int crc初始值,可选,默认0x00
  381. @return int 对应的CRC7值
  382. @usage
  383. -- 计算CRC7, 本API于2023.10.07新增
  384. local crc = crypto.crc7(data)
  385. local crc = crypto.crc7(data, 0x31, 0xff)
  386. */
  387. static int l_crypto_crc7(lua_State* L) {
  388. size_t len = 0;
  389. const unsigned char *inputData = (const unsigned char*)luaL_checklstring(L, 1, &len);
  390. unsigned char poly = (unsigned char)luaL_optinteger(L, 2, 0xe5);
  391. unsigned char start = (unsigned char)luaL_optinteger(L, 3, 0);
  392. unsigned char result = luat_crc7(inputData, len, poly, start);
  393. lua_pushinteger(L, result);
  394. return 1;
  395. }
  396. /**
  397. 生成真随机数
  398. @api crypto.trng(len)
  399. @int 数据长度
  400. @return string 指定随机数字符串
  401. @usage
  402. -- 生成32位随机数ir
  403. local r = crypto.trng(4)
  404. local _, ir = pack.unpack(r, "I")
  405. */
  406. static int l_crypto_trng(lua_State *L) {
  407. int ret = 0;
  408. size_t len = luaL_checkinteger(L, 1);
  409. if (len < 1) {
  410. return 0;
  411. }
  412. if (len > 128)
  413. len = 128;
  414. char buff[128];
  415. ret = luat_crypto_trng(buff, len);
  416. if(ret ==0){
  417. lua_pushlstring(L, buff, len);
  418. return 1;
  419. }
  420. return 0;
  421. }
  422. /**
  423. 计算TOTP动态密码的结果
  424. @api crypto.totp(secret,time)
  425. @string 网站提供的密钥(就是BASE32编码后的结果)
  426. @int 可选,时间戳,默认当前时间
  427. @return int 计算得出的六位数结果 计算失败返回nil
  428. @usage
  429. --使用当前系统时间计算
  430. local otp = crypto.totp("asdfassdfasdfass")
  431. */
  432. static int l_crypto_totp(lua_State *L) {
  433. size_t len = 0;
  434. const char* secret_base32 = luaL_checklstring(L,1,&len);
  435. char * secret = (char *)luat_heap_malloc(len+1);
  436. len = (size_t)luat_str_base32_decode((const uint8_t * )secret_base32,(uint8_t*)secret,len+1);
  437. uint64_t t = 0;
  438. if (lua_isinteger(L, 2)) {
  439. t = (uint64_t)(luaL_checkinteger(L, 2))/30;
  440. }
  441. else {
  442. t = (uint64_t)(time(NULL)/30);
  443. }
  444. uint8_t data[sizeof(uint64_t)] = {0};
  445. for(size_t i=0;i<sizeof(uint64_t);i++)
  446. data[sizeof(uint64_t)-1-i] = *(((uint8_t*)&t)+i);
  447. uint8_t hmac[20] = {0};
  448. int ret = luat_crypto_hmac_sha1_simple((const char *)data, sizeof(data), (const char *)secret, len, hmac);
  449. luat_heap_free(secret);
  450. if(ret == 0)
  451. {
  452. uint8_t offset = hmac[19] & 0x0f;
  453. uint32_t r = (
  454. ((uint32_t)((hmac[offset + 0] & 0x7f)) << 24) |
  455. ((uint32_t)((hmac[offset + 1] & 0xff)) << 16) |
  456. ((uint32_t)((hmac[offset + 2] & 0xff)) << 8) |
  457. ((uint32_t)(hmac[offset + 3] & 0xff))
  458. ) % 1000000;
  459. lua_pushinteger(L,r);
  460. return 1;
  461. }
  462. return 0;
  463. }
  464. /**
  465. 将数据进行base64编码
  466. @api crypto.base64_encode(data)
  467. @string 待编码的数据
  468. @return string 编码后的数据
  469. @usage
  470. -- 本函数与 string.toBase64 是同一个
  471. local data = "123"
  472. local bdata = crypto.base64_encode(data)
  473. log.info("base64", "encode", data, bdata)
  474. data = crypto.base64_decode(data)
  475. log.info("base64", "decode", data, bdata)
  476. */
  477. int l_str_toBase64(lua_State *L);
  478. /**
  479. 将数据进行base64解码
  480. @api crypto.base64_decode(data)
  481. @string 待解码的数据
  482. @return string 解码后的数据
  483. @usage
  484. -- 本函数与 string.fromBase64 是同一个
  485. local data = "123"
  486. local bdata = crypto.base64_encode(data)
  487. log.info("base64", "encode", data, bdata)
  488. data = crypto.base64_decode(data)
  489. log.info("base64", "decode", data, bdata)
  490. */
  491. int l_str_fromBase64(lua_State *L);
  492. /**
  493. 获取当前固件支持的cipher列表
  494. @api crypto.cipher_list()
  495. @return table 本固件支持的cipher列表,字符串数组
  496. @usage
  497. -- 本API于2022.07.27添加
  498. local ciphers = crypto.cipher_list()
  499. if ciphers then
  500. log.info("crypto", "ciphers list", json.encode(ciphers))
  501. end
  502. */
  503. int l_crypto_cipher_list(lua_State *L) {
  504. const char* list[64] = {0};
  505. size_t len = 64;
  506. lua_newtable(L);
  507. int ret = luat_crypto_cipher_list(list, &len);
  508. if (ret == 0) {
  509. for (size_t i = 0; i < len; i++){
  510. lua_pushstring(L, list[i]);
  511. lua_seti(L, -2, i + 1);
  512. }
  513. }
  514. else {
  515. LLOGD("bsp not support cipher_list");
  516. }
  517. return 1;
  518. }
  519. /**
  520. 获取当前固件支持的cipher suites列表
  521. @api crypto.cipher_suites()
  522. @return table 本固件支持的cipher suites列表,字符串数组
  523. @usage
  524. -- 本API于2022.11.16添加
  525. local suites = crypto.cipher_suites()
  526. if suites then
  527. log.info("crypto", "ciphers suites", json.encode(suites))
  528. end
  529. */
  530. int l_crypto_cipher_suites(lua_State *L) {
  531. const char* list[128] = {0};
  532. size_t len = 128;
  533. lua_newtable(L);
  534. int ret = luat_crypto_cipher_suites(list, &len);
  535. if (ret == 0) {
  536. for (size_t i = 0; i < len; i++){
  537. lua_pushstring(L, list[i]);
  538. lua_seti(L, -2, i + 1);
  539. }
  540. }
  541. else {
  542. LLOGD("bsp not support cipher_suites");
  543. }
  544. return 1;
  545. }
  546. /**
  547. 计算文件的hash值(md5/sha1/sha256及hmac形式)
  548. @api crypto.md_file(tp, path, hmac)
  549. @string hash类型, 大小字母, 例如 "MD5" "SHA1" "SHA256"
  550. @string 文件路径, 例如 /luadb/logo.jpg
  551. @string hmac值,可选
  552. @return string HEX过的hash值,若失败会无返回值
  553. @usage
  554. -- 无hmac的hash值
  555. log.info("md5", crypto.md_file("MD5", "/luadb/logo.jpg"))
  556. log.info("sha1", crypto.md_file("SHA1", "/luadb/logo.jpg"))
  557. log.info("sha256", crypto.md_file("SHA256", "/luadb/logo.jpg"))
  558. -- 带hmac的hash值
  559. log.info("hmac_md5", crypto.md_file("MD5", "/luadb/logo.jpg", "123456"))
  560. log.info("hmac_sha1", crypto.md_file("SHA1", "/luadb/logo.jpg", "123456"))
  561. log.info("hmac_sha256", crypto.md_file("SHA256", "/luadb/logo.jpg", "123456"))
  562. */
  563. static int l_crypto_md_file(lua_State *L) {
  564. size_t key_len = 0;
  565. size_t path_size = 0;
  566. const char* key = NULL;
  567. const char *md = luaL_checkstring(L, 1);
  568. const char* path = luaL_checklstring(L, 2, &path_size);
  569. if (path_size < 2)
  570. return 0;
  571. if (lua_type(L, 3) == LUA_TSTRING) {
  572. key = luaL_checklstring(L, 3, &key_len);
  573. }
  574. char buff[128] = {0};
  575. char output[64];
  576. int ret = luat_crypto_md_file(md, output, key, key_len, path);
  577. if (ret < 1) {
  578. return 0;
  579. }
  580. luat_str_tohex(output, ret, buff);
  581. lua_pushlstring(L, buff, ret *2);
  582. return 1;
  583. }
  584. /**
  585. 计算数据的hash值(md5/sha1/sha256及hmac形式)
  586. @api crypto.md(tp, data, hmac)
  587. @string hash类型, 大小字母, 例如 "MD5" "SHA1" "SHA256"
  588. @string 待处理的数据
  589. @string hmac值,可选
  590. @return string HEX过的hash值,若失败会无返回值
  591. @usage
  592. -- 无hmac的hash值
  593. log.info("md5", crypto.md("MD5", "1234567890"))
  594. log.info("sha1", crypto.md("SHA1", "1234567890"))
  595. log.info("sha256", crypto.md("SHA256", "1234567890"))
  596. -- 带hmac的hash值
  597. log.info("hmac_md5", crypto.md("MD5", "1234567890", "123456"))
  598. log.info("hmac_sha1", crypto.md("SHA1", "1234567890", "123456"))
  599. log.info("hmac_sha256", crypto.md("SHA256", "1234567890", "123456"))
  600. */
  601. static int l_crypto_md(lua_State *L) {
  602. size_t key_len = 0;
  603. size_t data_size = 0;
  604. const char* key = NULL;
  605. const char *md = luaL_checkstring(L, 1);
  606. const char* data = luaL_checklstring(L, 2, &data_size);
  607. if (lua_type(L, 3) == LUA_TSTRING) {
  608. key = luaL_checklstring(L, 3, &key_len);
  609. }
  610. char buff[128] = {0};
  611. char output[64];
  612. int ret = luat_crypto_md_v2(md, data, data_size, output, key, key_len);
  613. if (ret < 1) {
  614. LLOGE("luat_crypto_md return %d", ret);
  615. return 0;
  616. }
  617. luat_str_tohex(output, ret, buff);
  618. lua_pushlstring(L, buff, ret *2);
  619. return 1;
  620. }
  621. /*
  622. 创建流式hash用的stream
  623. @api crypto.hash_init(tp)
  624. @string hash类型, 大写字母, 例如 "MD5" "SHA1" "SHA256"
  625. @string hmac值,可选
  626. @return userdata 成功返回一个数据结构,否则返回nil
  627. @usage
  628. -- 无hmac的hash stream
  629. local md5_stream = crypto.hash_init("MD5")
  630. local sha1_stream = crypto.hash_init("SHA1")
  631. local sha256_stream = crypto.hash_init("SHA256")
  632. -- 带hmac的hash stream
  633. local md5_stream = crypto.hash_init("MD5", "123456")
  634. local sha1_stream = crypto.hash_init("SHA1", "123456")
  635. local sha256_stream = crypto.hash_init("SHA256", "123456")
  636. */
  637. static int l_crypt_hash_init(lua_State *L) {
  638. luat_crypt_stream_t *stream = (luat_crypt_stream_t *)lua_newuserdata(L, sizeof(luat_crypt_stream_t));
  639. if(stream == NULL) {
  640. return 0;
  641. } else {
  642. memset(stream, 0x00, sizeof(luat_crypt_stream_t));
  643. const char* key = NULL;
  644. const char* md = luaL_checkstring(L, 1);
  645. if(lua_type(L, 2) == LUA_TSTRING) {
  646. key = luaL_checklstring(L, 2, &(stream->key_len));
  647. }
  648. int ret = luat_crypto_md_init(md, key, stream);
  649. if (ret < 0) {
  650. return 0;
  651. } else {
  652. luaL_setmetatable(L, LUAT_CRYPTO_TYPE);
  653. }
  654. }
  655. return 1;
  656. }
  657. /*
  658. 流式hash更新数据
  659. @api crypto.hash_update(stream, data)
  660. @userdata crypto.hash_init()创建的stream, 必选
  661. @string 待计算的数据,必选
  662. @return nil 无返回值
  663. @usage
  664. crypto.hash_update(stream, "OK")
  665. */
  666. static int l_crypt_hash_update(lua_State *L) {
  667. luat_crypt_stream_t *stream = (luat_crypt_stream_t *)luaL_checkudata(L, 1, LUAT_CRYPTO_TYPE);
  668. size_t data_len = 0;
  669. const char *data = luaL_checklstring(L, 2, &data_len);
  670. luat_crypto_md_update(data, data_len ,stream);
  671. return 0;
  672. }
  673. /*
  674. 获取流式hash校验值并释放创建的stream
  675. @api crypto.hash_finish(stream)
  676. @userdata crypto.hash_init()创建的stream,必选
  677. @return string 成功返回计算得出的流式hash值的hex字符串,失败无返回
  678. @usage
  679. local hashResult = crypto.hash_finish(stream)
  680. */
  681. static int l_crypt_hash_finish(lua_State *L) {
  682. luat_crypt_stream_t *stream = (luat_crypt_stream_t *)luaL_checkudata(L, 1, LUAT_CRYPTO_TYPE);
  683. char buff[128] = {0};
  684. char output[64];
  685. int ret = luat_crypto_md_finish(output, stream);
  686. //LLOGD("finish result %d", ret);
  687. if (ret < 1) {
  688. return 0;
  689. }
  690. luat_str_tohex(output, ret, buff);
  691. lua_pushlstring(L, buff, ret * 2);
  692. return 1;
  693. }
  694. /*
  695. 计算checksum校验和
  696. @api crypto.checksum(data, mode)
  697. @string 待计算的数据,必选
  698. @int 模式,累加模式, 0 - 异或, 1 - 累加, 默认为0
  699. @return int checksum值,校验和
  700. @usage
  701. -- 本函数在 2022.12.28 添加
  702. -- 单纯计算checksum值
  703. local ck = crypto.checksum("OK")
  704. log.info("checksum", "ok", string.format("%02X", ck))
  705. -- 第二个参数mode在2023.5.23日添加
  706. */
  707. static int l_crypt_checksum(lua_State *L) {
  708. size_t len = 0;
  709. uint8_t checksum = 0x00;
  710. uint8_t tmp = 0;
  711. const char* sentence = luaL_checklstring(L, 1, &len);
  712. int mode = luaL_optinteger(L, 2, 0);
  713. // LLOGD("mode %d", mode);
  714. for (size_t i = 0; i < len; i++)
  715. {
  716. tmp = *sentence;
  717. if (mode == 1) {
  718. checksum += tmp;
  719. }
  720. else {
  721. checksum ^= tmp;
  722. }
  723. // LLOGD("> %02X > %02X", checksum, tmp);
  724. sentence ++;
  725. }
  726. lua_pushinteger(L, checksum);
  727. return 1;
  728. }
  729. #include "rotable2.h"
  730. static const rotable_Reg_t reg_crypto[] =
  731. {
  732. { "md5" , ROREG_FUNC(l_crypto_md5 )},
  733. { "sha1" , ROREG_FUNC(l_crypto_sha1 )},
  734. { "sha256" , ROREG_FUNC(l_crypto_sha256 )},
  735. { "sha512" , ROREG_FUNC(l_crypto_sha512 )},
  736. { "hmac_md5" , ROREG_FUNC(l_crypto_hmac_md5 )},
  737. { "hmac_sha1" , ROREG_FUNC(l_crypto_hmac_sha1 )},
  738. { "hmac_sha256" , ROREG_FUNC(l_crypto_hmac_sha256 )},
  739. { "hmac_sha512" , ROREG_FUNC(l_crypto_hmac_sha512 )},
  740. { "cipher" , ROREG_FUNC(l_crypto_cipher_encrypt )},
  741. { "cipher_encrypt" ,ROREG_FUNC(l_crypto_cipher_encrypt )},
  742. { "cipher_decrypt" ,ROREG_FUNC(l_crypto_cipher_decrypt )},
  743. { "cipher_list" , ROREG_FUNC(l_crypto_cipher_list )},
  744. { "cipher_suites", ROREG_FUNC(l_crypto_cipher_suites)},
  745. { "crc16", ROREG_FUNC(l_crypto_crc16 )},
  746. { "crc16_modbus", ROREG_FUNC(l_crypto_crc16_modbus )},
  747. { "crc32", ROREG_FUNC(l_crypto_crc32 )},
  748. { "crc8", ROREG_FUNC(l_crypto_crc8 )},
  749. { "crc7", ROREG_FUNC(l_crypto_crc7 )},
  750. { "trng", ROREG_FUNC(l_crypto_trng )},
  751. { "totp", ROREG_FUNC(l_crypto_totp )},
  752. { "base64_encode", ROREG_FUNC(l_str_toBase64)},
  753. { "base64_decode", ROREG_FUNC(l_str_fromBase64)},
  754. { "md_file", ROREG_FUNC(l_crypto_md_file)},
  755. { "md", ROREG_FUNC(l_crypto_md)},
  756. { "checksum", ROREG_FUNC(l_crypt_checksum)},
  757. { "hash_init", ROREG_FUNC(l_crypt_hash_init)},
  758. { "hash_update", ROREG_FUNC(l_crypt_hash_update)},
  759. { "hash_finish", ROREG_FUNC(l_crypt_hash_finish)},
  760. { NULL, ROREG_INT(0) }
  761. };
  762. LUAMOD_API int luaopen_crypto( lua_State *L ) {
  763. luat_newlib2(L, reg_crypto);
  764. luaL_newmetatable(L, LUAT_CRYPTO_TYPE);
  765. lua_pop(L, 1);
  766. return 1;
  767. }
  768. // 添加几个默认实现
  769. #ifndef LUAT_COMPILER_NOWEAK
  770. LUAT_WEAK int luat_crypto_trng(char* buff, size_t len) {
  771. memset(buff, 0, len);
  772. return 0;
  773. }
  774. #endif