luat_crypto_mbedtls.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  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. return -1;
  176. }
  177. if (key_len < 1) {
  178. mbedtls_md(info, (const unsigned char*)str, str_size, (unsigned char*)out_ptr);
  179. }
  180. else {
  181. mbedtls_md_hmac(info, (const unsigned char*)key, key_len, (const unsigned char*)str, str_size, (unsigned char*)out_ptr);
  182. }
  183. return 0;
  184. }
  185. int luat_crypto_md_file(const char* md, void* out_ptr, const char* key, size_t key_len, const char* path) {
  186. const mbedtls_md_info_t * info = mbedtls_md_info_from_string(md);
  187. if (info == NULL) {
  188. LLOGI("no such message digest %s", md);
  189. return -1;
  190. }
  191. FILE* fd = luat_fs_fopen(path, "rb");
  192. if (fd == NULL) {
  193. LLOGI("no such file %s", path);
  194. return -1;
  195. }
  196. mbedtls_md_context_t ctx;
  197. mbedtls_md_init(&ctx);
  198. mbedtls_md_setup(&ctx, info, key_len > 0 ? 1 : 0);
  199. uint8_t buff[512];
  200. int len = 0;
  201. if (key_len > 0) {
  202. mbedtls_md_hmac_starts(&ctx, (const unsigned char*)key, key_len);
  203. }
  204. else {
  205. mbedtls_md_starts(&ctx);
  206. }
  207. while (1) {
  208. len = luat_fs_fread(buff, 1, 512, fd);
  209. if (len < 1)
  210. break;
  211. if (key_len > 0) {
  212. mbedtls_md_hmac_update(&ctx, buff, len);
  213. }
  214. else {
  215. mbedtls_md_update(&ctx, buff, len);
  216. }
  217. }
  218. luat_fs_fclose(fd);
  219. int ret = 0;
  220. if (key_len > 0) {
  221. ret = mbedtls_md_hmac_finish(&ctx, out_ptr);
  222. }
  223. else {
  224. ret = mbedtls_md_finish(&ctx, out_ptr);
  225. }
  226. mbedtls_md_free(&ctx);
  227. if (ret == 0) {
  228. return mbedtls_md_get_size(info);
  229. }
  230. LLOGI("md finish ret %d", ret);
  231. return ret;
  232. }
  233. int luat_crypto_md_init(const char* md, const char* key, luat_crypt_stream_t *stream) {
  234. const mbedtls_md_info_t * info = mbedtls_md_info_from_string(md);
  235. if (info == NULL) {
  236. return -1;
  237. }
  238. stream->ctx = luat_heap_malloc(sizeof(mbedtls_md_context_t));
  239. mbedtls_md_init((mbedtls_md_context_t *)stream->ctx);
  240. mbedtls_md_setup((mbedtls_md_context_t *)stream->ctx, info, stream->key_len > 0 ? 1 : 0);
  241. stream->result_size = mbedtls_md_get_size(info);
  242. if (stream->key_len > 0){
  243. mbedtls_md_hmac_starts((mbedtls_md_context_t *)stream->ctx, (const unsigned char*)key, stream->key_len);
  244. }
  245. else {
  246. mbedtls_md_starts((mbedtls_md_context_t *)stream->ctx);
  247. }
  248. return 0;
  249. }
  250. int luat_crypto_md_update(const char* str, size_t str_size, luat_crypt_stream_t *stream) {
  251. if (stream->key_len > 0){
  252. mbedtls_md_hmac_update((mbedtls_md_context_t *)stream->ctx, (const unsigned char*)str, str_size);
  253. }
  254. else {
  255. mbedtls_md_update((mbedtls_md_context_t *)stream->ctx, (const unsigned char*)str, str_size);
  256. }
  257. return 0;
  258. }
  259. int luat_crypto_md_finish(void* out_ptr, luat_crypt_stream_t *stream) {
  260. int ret = 0;
  261. if (stream->key_len > 0) {
  262. ret = mbedtls_md_hmac_finish((mbedtls_md_context_t *)stream->ctx, out_ptr);
  263. }
  264. else {
  265. ret = mbedtls_md_finish((mbedtls_md_context_t *)stream->ctx, out_ptr);
  266. }
  267. mbedtls_md_free((mbedtls_md_context_t *)stream->ctx);
  268. luat_heap_free((mbedtls_md_context_t *)stream->ctx);
  269. stream->ctx = NULL;
  270. if (ret == 0) {
  271. return stream->result_size;
  272. }
  273. LLOGI("md finish ret %d", ret);
  274. return ret;
  275. }
  276. int luat_crypto_md5_simple(const char* str, size_t str_size, void* out_ptr) {
  277. return luat_crypto_md("MD5", str, str_size, out_ptr, NULL, 0);
  278. }
  279. int luat_crypto_hmac_md5_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  280. return luat_crypto_md("MD5", str, str_size, out_ptr, mac, mac_size);
  281. }
  282. int luat_crypto_sha1_simple(const char* str, size_t str_size, void* out_ptr) {
  283. return luat_crypto_md("SHA1", str, str_size, out_ptr, NULL, 0);
  284. }
  285. int luat_crypto_hmac_sha1_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  286. return luat_crypto_md("SHA1", str, str_size, out_ptr, mac, mac_size);
  287. }
  288. int luat_crypto_sha256_simple(const char* str, size_t str_size, void* out_ptr) {
  289. return luat_crypto_md("SHA256", str, str_size, out_ptr, NULL, 0);
  290. }
  291. int luat_crypto_hmac_sha256_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  292. return luat_crypto_md("SHA256", str, str_size, out_ptr, mac, mac_size);
  293. }
  294. int luat_crypto_sha512_simple(const char* str, size_t str_size, void* out_ptr) {
  295. return luat_crypto_md("SHA512", str, str_size, out_ptr, NULL, 0);
  296. }
  297. int luat_crypto_hmac_sha512_simple(const char* str, size_t str_size, const char* mac, size_t mac_size, void* out_ptr) {
  298. return luat_crypto_md("SHA512", str, str_size, out_ptr, mac, mac_size);
  299. }
  300. const int *mbedtls_cipher_list( void );
  301. int luat_crypto_cipher_list(const char** list, size_t* len) {
  302. size_t count = 0;
  303. size_t limit = *len;
  304. const int *cipher = mbedtls_cipher_list();
  305. for (size_t i = 0; i < limit; i++)
  306. {
  307. if (cipher[i] == 0)
  308. break;
  309. count ++;
  310. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  311. list[i] = mbedtls_cipher_info_get_name(mbedtls_cipher_info_from_type(cipher[i]));
  312. #else
  313. list[i] = mbedtls_cipher_info_from_type(cipher[i])->name;
  314. #endif
  315. }
  316. *len = count;
  317. return 0;
  318. }
  319. int luat_crypto_cipher_suites(const char** list, size_t* len) {
  320. #if defined(MBEDTLS_SSL_TLS_C) && defined(LUAT_USE_NETWORK)
  321. size_t count = 0;
  322. size_t limit = *len;
  323. const int *suites = mbedtls_ssl_list_ciphersuites();
  324. const mbedtls_ssl_ciphersuite_t * suite = NULL;
  325. for (size_t i = 0; i < limit; i++)
  326. {
  327. if (suites[i] == 0)
  328. break;
  329. suite = mbedtls_ssl_ciphersuite_from_id(suites[i]);
  330. if (suite == NULL)
  331. continue;
  332. count ++;
  333. #if MBEDTLS_VERSION_NUMBER >= 0x03000000
  334. list[i] = mbedtls_ssl_ciphersuite_get_name(suite);
  335. #else
  336. list[i] = suite->name;
  337. #endif
  338. }
  339. *len = count;
  340. #else
  341. (void)list;
  342. *len = 0;
  343. #endif
  344. return 0;
  345. }
  346. /**
  347. * @brief BASE64加密
  348. * @param dst buffer
  349. * @param dlen buffer长度
  350. * @param olen 写入的字节数
  351. * @param src 加密密钥
  352. * @param slen 加密密钥长度
  353. * @return 0成功
  354. */
  355. int luat_crypto_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen )
  356. {
  357. mbedtls_base64_encode(dst, dlen, olen, src, slen);
  358. return 0;
  359. }
  360. /**
  361. * @brief BASE64解密
  362. * @param dst buffer
  363. * @param dlen buffer长度
  364. * @param olen 写入的字节数
  365. * @param src 密钥
  366. * @param slen 密钥长度
  367. * @return 0成功
  368. */
  369. int luat_crypto_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen )
  370. {
  371. mbedtls_base64_decode(dst, dlen, olen, src, slen);
  372. return 0;
  373. }