luat_crypto_mbedtls.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. // crypto库的软件实现, 基于mbedtls
  2. #ifdef CHIP_EC616
  3. #include "FreeRTOS.h"
  4. #endif
  5. #include "luat_base.h"
  6. #include "luat_crypto.h"
  7. #include "luat_mem.h"
  8. #include "luat_fs.h"
  9. #define LUAT_LOG_TAG "crypto"
  10. #include "luat_log.h"
  11. #include "mbedtls/cipher.h"
  12. #include "mbedtls/md.h"
  13. #include "mbedtls/ssl_ciphersuites.h"
  14. #include "mbedtls/base64.h"
  15. static void add_pkcs_padding( unsigned char *output, size_t output_len,
  16. size_t data_len )
  17. {
  18. size_t padding_len = output_len - data_len;
  19. unsigned char i;
  20. for( i = 0; i < padding_len; i++ )
  21. output[data_len + i] = (unsigned char) padding_len;
  22. }
  23. static int get_pkcs_padding( unsigned char *input, size_t input_len,
  24. size_t *data_len )
  25. {
  26. size_t i, pad_idx;
  27. unsigned char padding_len, bad = 0;
  28. if( NULL == input || NULL == data_len )
  29. return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
  30. padding_len = input[input_len - 1];
  31. *data_len = input_len - padding_len;
  32. /* Avoid logical || since it results in a branch */
  33. bad |= padding_len > input_len;
  34. bad |= padding_len == 0;
  35. /* The number of bytes checked must be independent of padding_len,
  36. * so pick input_len, which is usually 8 or 16 (one block) */
  37. pad_idx = input_len - padding_len;
  38. for( i = 0; i < input_len; i++ )
  39. bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx );
  40. return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) );
  41. }
  42. int luat_crypto_cipher_xxx(luat_crypto_cipher_ctx_t* cctx) {
  43. uint8_t *temp = NULL;
  44. int ret = 0;
  45. int cipher_mode = 0;
  46. unsigned char output[32] = {0};
  47. size_t input_size = 0;
  48. size_t output_size = 0;
  49. size_t block_size = 0;
  50. mbedtls_cipher_context_t ctx;
  51. mbedtls_cipher_init(&ctx);
  52. const mbedtls_cipher_info_t * _cipher = mbedtls_cipher_info_from_string(cctx->cipher);
  53. if (_cipher == NULL) {
  54. LLOGE("mbedtls_cipher_info fail %s not support", cctx->cipher);
  55. goto _error_exit;
  56. }
  57. ret = mbedtls_cipher_setup(&ctx, _cipher);
  58. if (ret) {
  59. LLOGE("mbedtls_cipher_setup fail -0x%04x %s", -ret, cctx->cipher);
  60. goto _error_exit;
  61. }
  62. ret = mbedtls_cipher_setkey(&ctx, (const unsigned char*)cctx->key, cctx->key_size * 8, cctx->flags & 0x1);
  63. if (ret) {
  64. LLOGE("mbedtls_cipher_setkey fail -0x%04x %s", -ret, cctx->cipher);
  65. goto _error_exit;
  66. }
  67. if (cctx->iv_size) {
  68. ret = mbedtls_cipher_set_iv(&ctx, (const unsigned char*)cctx->iv, cctx->iv_size);
  69. if (ret) {
  70. LLOGE("mbedtls_cipher_set_iv fail -0x%04x %s", -ret, cctx->cipher);
  71. goto _error_exit;
  72. }
  73. }
  74. mbedtls_cipher_reset(&ctx);
  75. if (!strcmp("PKCS7", cctx->pad)) {
  76. mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_PKCS7);
  77. }
  78. else if (!strcmp("ZERO", cctx->pad) || !strcmp("ZEROS", cctx->pad)) {
  79. mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_ZEROS);
  80. }
  81. else if (!strcmp("ONE_AND_ZEROS", cctx->pad)) {
  82. mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_ONE_AND_ZEROS);
  83. }
  84. else if (!strcmp("ZEROS_AND_LEN", cctx->pad)) {
  85. mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_ZEROS_AND_LEN);
  86. }
  87. else {
  88. mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_NONE);
  89. }
  90. // 开始注入数据
  91. block_size = mbedtls_cipher_get_block_size(&ctx);
  92. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  93. cipher_mode = mbedtls_cipher_info_get_mode(_cipher);
  94. #else
  95. cipher_mode = _cipher->mode;
  96. #endif
  97. if ((cipher_mode == MBEDTLS_MODE_ECB) && (!strcmp("PKCS7", cctx->pad) || !strcmp("ZERO", cctx->pad)) && (cctx->flags & 0x1)) {
  98. uint32_t new_len = ((cctx->str_size / block_size) + 1) * block_size;
  99. temp = luat_heap_malloc(new_len);
  100. if (temp == NULL) {
  101. LLOGE("out of memory when malloc cipher buffer");
  102. goto _exit;
  103. }
  104. memset(temp, 0, new_len);
  105. memcpy(temp, cctx->str, cctx->str_size);
  106. if (!strcmp("PKCS7", cctx->pad))
  107. {
  108. add_pkcs_padding(temp + cctx->str_size - cctx->str_size % block_size, block_size, cctx->str_size % block_size);
  109. }
  110. else
  111. {
  112. LLOGD("zero padding");
  113. }
  114. cctx->str_size = new_len;
  115. cctx->str = (const char*)temp;
  116. }
  117. for (size_t i = 0; i < cctx->str_size; i+=block_size) {
  118. input_size = cctx->str_size - i;
  119. if (input_size > block_size) {
  120. input_size = block_size;
  121. ret = mbedtls_cipher_update(&ctx, (const unsigned char *)(cctx->str+i), input_size, output, &output_size);
  122. }
  123. else if ((cipher_mode == MBEDTLS_MODE_ECB) && !strcmp("PKCS7", cctx->pad) && !cctx->flags)
  124. {
  125. ret = mbedtls_cipher_update(&ctx, (const unsigned char *)(cctx->str+i), input_size, output, &output_size);
  126. if (ret == 0) {
  127. ret = get_pkcs_padding(output, output_size, &output_size);
  128. if (ret) {
  129. LLOGE("get_pkcs_padding fail 0x%04X %s", -ret, cctx->cipher);
  130. goto _exit;
  131. }
  132. }
  133. }
  134. else {
  135. ret = mbedtls_cipher_update(&ctx, (const unsigned char *)(cctx->str+i), input_size, output, &output_size);
  136. }
  137. if (ret) {
  138. LLOGE("mbedtls_cipher_update fail 0x%04X %s", -ret, cctx->cipher);
  139. goto _exit;
  140. }
  141. //else LLOGD("mbedtls_cipher_update, output size=%ld", output_size);
  142. if (output_size > 0) {
  143. memcpy(cctx->outbuff + cctx->outlen, (const char*)output, output_size);
  144. cctx->outlen += output_size;
  145. }
  146. output_size = 0;
  147. }
  148. output_size = 0;
  149. ret = mbedtls_cipher_finish(&ctx, (unsigned char *)output, &output_size);
  150. if (ret) {
  151. LLOGE("mbedtls_cipher_finish fail 0x%04X %s", -ret, cctx->cipher);
  152. goto _exit;
  153. }
  154. //else LLOGD("mbedtls_cipher_finish, output size=%ld", output_size);
  155. if (output_size > 0) {
  156. memcpy(cctx->outbuff + cctx->outlen, (const char*)output, output_size);
  157. cctx->outlen += output_size;
  158. }
  159. _exit:
  160. if (temp){
  161. luat_heap_free(temp);
  162. }
  163. mbedtls_cipher_free(&ctx);
  164. return 0;
  165. _error_exit:
  166. if (temp){
  167. luat_heap_free(temp);
  168. }
  169. mbedtls_cipher_free(&ctx);
  170. return -1;
  171. }
  172. int luat_crypto_md(const char* md, const char* str, size_t str_size, void* out_ptr, const char* key, size_t key_len) {
  173. const mbedtls_md_info_t * info = mbedtls_md_info_from_string(md);
  174. if (info == NULL) {
  175. LLOGW("no such message digest %s", md);
  176. return -1;
  177. }
  178. if (key_len < 1) {
  179. mbedtls_md(info, (const unsigned char*)str, str_size, (unsigned char*)out_ptr);
  180. }
  181. else {
  182. mbedtls_md_hmac(info, (const unsigned char*)key, key_len, (const unsigned char*)str, str_size, (unsigned char*)out_ptr);
  183. }
  184. return 0;
  185. }
  186. int luat_crypto_md_v2(const char* md, const char* str, size_t str_size, void* out_ptr, const char* key, size_t key_len) {
  187. const mbedtls_md_info_t * info = mbedtls_md_info_from_string(md);
  188. if (info == NULL) {
  189. LLOGW("no such message digest %s", md);
  190. return -1;
  191. }
  192. if (key_len < 1) {
  193. mbedtls_md(info, (const unsigned char*)str, str_size, (unsigned char*)out_ptr);
  194. }
  195. else {
  196. mbedtls_md_hmac(info, (const unsigned char*)key, key_len, (const unsigned char*)str, str_size, (unsigned char*)out_ptr);
  197. }
  198. return mbedtls_md_get_size(info);
  199. }
  200. int luat_crypto_md_file(const char* md, void* out_ptr, const char* key, size_t key_len, const char* path) {
  201. const mbedtls_md_info_t * info = mbedtls_md_info_from_string(md);
  202. if (info == NULL) {
  203. LLOGI("no such message digest %s", md);
  204. return -1;
  205. }
  206. FILE* fd = luat_fs_fopen(path, "rb");
  207. if (fd == NULL) {
  208. LLOGI("no such file %s", path);
  209. return -1;
  210. }
  211. mbedtls_md_context_t ctx;
  212. mbedtls_md_init(&ctx);
  213. mbedtls_md_setup(&ctx, info, key_len > 0 ? 1 : 0);
  214. uint8_t buff[512];
  215. int len = 0;
  216. if (key_len > 0) {
  217. mbedtls_md_hmac_starts(&ctx, (const unsigned char*)key, key_len);
  218. }
  219. else {
  220. mbedtls_md_starts(&ctx);
  221. }
  222. while (1) {
  223. len = luat_fs_fread(buff, 1, 512, fd);
  224. if (len < 1)
  225. break;
  226. if (key_len > 0) {
  227. mbedtls_md_hmac_update(&ctx, buff, len);
  228. }
  229. else {
  230. mbedtls_md_update(&ctx, buff, len);
  231. }
  232. }
  233. luat_fs_fclose(fd);
  234. int ret = 0;
  235. if (key_len > 0) {
  236. ret = mbedtls_md_hmac_finish(&ctx, out_ptr);
  237. }
  238. else {
  239. ret = mbedtls_md_finish(&ctx, out_ptr);
  240. }
  241. mbedtls_md_free(&ctx);
  242. if (ret == 0) {
  243. return mbedtls_md_get_size(info);
  244. }
  245. LLOGI("md finish ret %d", ret);
  246. return ret;
  247. }
  248. int luat_crypto_md_init(const char* md, const char* key, luat_crypt_stream_t *stream) {
  249. const mbedtls_md_info_t * info = mbedtls_md_info_from_string(md);
  250. if (info == NULL) {
  251. return -1;
  252. }
  253. stream->ctx = luat_heap_malloc(sizeof(mbedtls_md_context_t));
  254. mbedtls_md_init((mbedtls_md_context_t *)stream->ctx);
  255. mbedtls_md_setup((mbedtls_md_context_t *)stream->ctx, info, stream->key_len > 0 ? 1 : 0);
  256. stream->result_size = mbedtls_md_get_size(info);
  257. if (stream->key_len > 0){
  258. mbedtls_md_hmac_starts((mbedtls_md_context_t *)stream->ctx, (const unsigned char*)key, stream->key_len);
  259. }
  260. else {
  261. mbedtls_md_starts((mbedtls_md_context_t *)stream->ctx);
  262. }
  263. return 0;
  264. }
  265. int luat_crypto_md_update(const char* str, size_t str_size, luat_crypt_stream_t *stream) {
  266. if (stream->key_len > 0){
  267. mbedtls_md_hmac_update((mbedtls_md_context_t *)stream->ctx, (const unsigned char*)str, str_size);
  268. }
  269. else {
  270. mbedtls_md_update((mbedtls_md_context_t *)stream->ctx, (const unsigned char*)str, str_size);
  271. }
  272. return 0;
  273. }
  274. int luat_crypto_md_finish(void* out_ptr, luat_crypt_stream_t *stream) {
  275. int ret = 0;
  276. if (stream->key_len > 0) {
  277. ret = mbedtls_md_hmac_finish((mbedtls_md_context_t *)stream->ctx, out_ptr);
  278. }
  279. else {
  280. ret = mbedtls_md_finish((mbedtls_md_context_t *)stream->ctx, out_ptr);
  281. }
  282. mbedtls_md_free((mbedtls_md_context_t *)stream->ctx);
  283. luat_heap_free((mbedtls_md_context_t *)stream->ctx);
  284. stream->ctx = NULL;
  285. if (ret == 0) {
  286. return stream->result_size;
  287. }
  288. LLOGI("md finish ret %d", ret);
  289. return ret;
  290. }
  291. int luat_crypto_md5_simple(const char* str, size_t str_size, void* out_ptr) {
  292. return luat_crypto_md("MD5", str, str_size, out_ptr, NULL, 0);
  293. }
  294. int luat_crypto_hmac_md5_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  295. return luat_crypto_md("MD5", str, str_size, out_ptr, mac, mac_size);
  296. }
  297. int luat_crypto_sha1_simple(const char* str, size_t str_size, void* out_ptr) {
  298. return luat_crypto_md("SHA1", str, str_size, out_ptr, NULL, 0);
  299. }
  300. int luat_crypto_hmac_sha1_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  301. return luat_crypto_md("SHA1", str, str_size, out_ptr, mac, mac_size);
  302. }
  303. int luat_crypto_sha256_simple(const char* str, size_t str_size, void* out_ptr) {
  304. return luat_crypto_md("SHA256", str, str_size, out_ptr, NULL, 0);
  305. }
  306. int luat_crypto_hmac_sha256_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  307. return luat_crypto_md("SHA256", str, str_size, out_ptr, mac, mac_size);
  308. }
  309. int luat_crypto_sha512_simple(const char* str, size_t str_size, void* out_ptr) {
  310. return luat_crypto_md("SHA512", str, str_size, out_ptr, NULL, 0);
  311. }
  312. int luat_crypto_hmac_sha512_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  313. return luat_crypto_md("SHA512", str, str_size, out_ptr, mac, mac_size);
  314. }
  315. const int *mbedtls_cipher_list( void );
  316. int luat_crypto_cipher_list(const char** list, size_t* len) {
  317. size_t count = 0;
  318. size_t limit = *len;
  319. const int *cipher = mbedtls_cipher_list();
  320. for (size_t i = 0; i < limit; i++)
  321. {
  322. if (cipher[i] == 0)
  323. break;
  324. count ++;
  325. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  326. list[i] = mbedtls_cipher_info_get_name(mbedtls_cipher_info_from_type(cipher[i]));
  327. #else
  328. list[i] = mbedtls_cipher_info_from_type(cipher[i])->name;
  329. #endif
  330. }
  331. *len = count;
  332. return 0;
  333. }
  334. int luat_crypto_cipher_suites(const char** list, size_t* len) {
  335. #if defined(MBEDTLS_SSL_TLS_C) && defined(LUAT_USE_NETWORK)
  336. size_t count = 0;
  337. size_t limit = *len;
  338. const int *suites = mbedtls_ssl_list_ciphersuites();
  339. const mbedtls_ssl_ciphersuite_t * suite = NULL;
  340. for (size_t i = 0; i < limit; i++)
  341. {
  342. if (suites[i] == 0)
  343. break;
  344. suite = mbedtls_ssl_ciphersuite_from_id(suites[i]);
  345. if (suite == NULL)
  346. continue;
  347. count ++;
  348. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  349. list[i] = mbedtls_ssl_ciphersuite_get_name(suite);
  350. #else
  351. list[i] = suite->name;
  352. #endif
  353. }
  354. *len = count;
  355. #else
  356. (void)list;
  357. *len = 0;
  358. #endif
  359. return 0;
  360. }
  361. /**
  362. * @brief BASE64加密
  363. * @param dst buffer
  364. * @param dlen buffer长度
  365. * @param olen 写入的字节数
  366. * @param src 加密密钥
  367. * @param slen 加密密钥长度
  368. * @return 0成功
  369. */
  370. int luat_crypto_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen )
  371. {
  372. mbedtls_base64_encode(dst, dlen, olen, src, slen);
  373. return 0;
  374. }
  375. /**
  376. * @brief BASE64解密
  377. * @param dst buffer
  378. * @param dlen buffer长度
  379. * @param olen 写入的字节数
  380. * @param src 密钥
  381. * @param slen 密钥长度
  382. * @return 0成功
  383. */
  384. int luat_crypto_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen )
  385. {
  386. mbedtls_base64_decode(dst, dlen, olen, src, slen);
  387. return 0;
  388. }