filecryption.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. #include "stdafx.h"
  2. #include "filecryption.h"
  3. #include "fileanalysis.h"
  4. #include "rvcfileheader.h"
  5. #include "asf.h"
  6. #include <iostream>
  7. using namespace std;
  8. #include <stdio.h>
  9. #ifndef RVC_MAX_HEADER_LEN
  10. #define RVC_MAX_HEADER_LEN 512
  11. #endif
  12. #ifndef RVC_FILE_INT_LEN
  13. #define RVC_FILE_INT_LEN 4
  14. #endif
  15. #ifndef RVC_READ_BUFFER_SIZE
  16. #define RVC_READ_BUFFER_SIZE 1024
  17. #endif
  18. #ifndef safe_free
  19. #define safe_free(x) if (x){ free(x); x = NULL;}
  20. #endif
  21. int encryption_file(char* poutfile, size_t uoutlen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion)
  22. {
  23. int iret = -1;
  24. if (NULL == pfilename){
  25. return iret;
  26. }
  27. char pbuffer[RVC_MAX_HEADER_LEN] = {0};
  28. size_t uheaderlen = RVC_MAX_HEADER_LEN;
  29. int ilen = constrcut_rvc_file_header(pbuffer, &uheaderlen, pfilename, pcallback, eversion);
  30. if (0 != ilen){
  31. return iret;
  32. }
  33. unsigned char strkey[SM4ENC_BLOCK_SIZE] = {0};
  34. size_t uindex = (RVC_FILE_HEADER_FLAG_LEN + sizeof(size_t));
  35. if (get_key_from_header_info(strkey, SM4ENC_BLOCK_SIZE, pbuffer + uindex, uheaderlen - uindex, pcallback)){
  36. return iret;
  37. }
  38. if (get_encrytion_filename(poutfile, uoutlen, false, RVC_FILEENC_STR, strlen(RVC_FILEENC_STR), pfilename)){
  39. return iret;
  40. }
  41. FILE* pSrcFile = fopen(pfilename, "rb");
  42. if (NULL == pSrcFile){
  43. return iret;
  44. }
  45. FILE* pDestFile = fopen(poutfile, "wb");
  46. if (NULL == pDestFile){
  47. fclose(pSrcFile);
  48. return iret;
  49. }
  50. //1. 新增自定义文件头
  51. fwrite(pbuffer, 1, uheaderlen, pDestFile);
  52. //获取加密前文件头GUID
  53. char strGuid[HEADER_OBJECT_GUID_LEN] = {0};
  54. fread(strGuid, 1, HEADER_OBJECT_GUID_LEN, pSrcFile);
  55. if (0 != memcmp(strGuid, ASF_Header_GUID, HEADER_OBJECT_GUID_LEN)){
  56. safe_log(pcallback, "%s", "math guid failed, current format is not surpport!");
  57. fclose(pSrcFile);
  58. fclose(pDestFile);
  59. return iret;
  60. }
  61. //2. 拷贝原文件头guid
  62. fwrite(strGuid, 1, HEADER_OBJECT_GUID_LEN, pDestFile);
  63. char strheadsize[ASF_HEADER_SIZE_LEN] = {0};
  64. fread(strheadsize, 1, ASF_HEADER_SIZE_LEN, pSrcFile);
  65. uint64_t uheadlen = get_asf_headsize(strheadsize, ASF_HEADER_SIZE_LEN);
  66. uint64_t uheadobjlen = uheadlen - HEADER_OBJECT_GUID_LEN - ASF_HEADER_SIZE_LEN;
  67. unsigned char* pobjdata = (unsigned char*)malloc(uheadobjlen);
  68. fread(pobjdata, 1, uheadobjlen, pSrcFile);
  69. int iencdatalen = uheadobjlen + SM4ENC_BLOCK_SIZE;
  70. unsigned char* pobjdataenc = (unsigned char*)malloc(iencdatalen);
  71. SM4EncECBMode(strkey, pobjdata, uheadobjlen, pobjdataenc, &iencdatalen);
  72. char strdatalen[ASF_HEADER_SIZE_LEN] = {0};
  73. construct_asf_headsize(strdatalen, ASF_HEADER_SIZE_LEN, iencdatalen + HEADER_OBJECT_GUID_LEN + ASF_HEADER_SIZE_LEN);
  74. //3. 填充加密后文件头长度
  75. fwrite(strdatalen, 1, ASF_HEADER_SIZE_LEN, pDestFile);
  76. //4. 填充加密后文件头内容
  77. fwrite(pobjdataenc, 1, iencdatalen, pDestFile);
  78. char *data_buffer=(char *)malloc(RVC_READ_BUFFER_SIZE);
  79. size_t udatalen = 0;
  80. while(udatalen = fread(data_buffer, 1, RVC_READ_BUFFER_SIZE, pSrcFile)){
  81. fwrite(data_buffer, 1, udatalen, pDestFile);
  82. }
  83. fclose(pSrcFile);
  84. fclose(pDestFile);
  85. safe_free(pobjdata);
  86. safe_free(pobjdataenc);
  87. safe_free(data_buffer);
  88. iret = 0;
  89. return iret;
  90. }
  91. int decryption_file(char* poutfile, size_t uoutlen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion)
  92. {
  93. int iret = -1;
  94. if (NULL == pfilename || eversion >= sizeof(cryption_ver_flag_table)/sizeof(char*) || eversion < 0){
  95. safe_log(pcallback,"%s","invalid encryption version param.");
  96. return iret;
  97. }
  98. FILE* pSrcFile = fopen(pfilename, "rb");
  99. if (NULL == pSrcFile){
  100. safe_log(pcallback,"open file %s failed!",pfilename);
  101. return iret;
  102. }
  103. char strrvcflag[RVC_FILE_HEADER_FLAG_LEN] = {0};
  104. fread(strrvcflag,1, RVC_FILE_HEADER_FLAG_LEN, pSrcFile);
  105. if (0 != memcmp(strrvcflag, rvc_header, RVC_FILE_HEADER_FLAG_LEN)){
  106. safe_log(pcallback,"file %s is not encryption!",pfilename);
  107. fclose(pSrcFile);
  108. iret = 0;
  109. return iret;
  110. }
  111. int irvcheadlen = 0;
  112. fread(&irvcheadlen, 1, sizeof(int), pSrcFile);
  113. char* prvcbuffer = (char*)malloc(irvcheadlen);
  114. memset(prvcbuffer, 0, irvcheadlen);
  115. fread(prvcbuffer, 1, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pSrcFile);
  116. if (0 != memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN)){
  117. if (0 == memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN-1)){
  118. safe_log(pcallback,"file %s encryption and decryption version is not matched!",pfilename);
  119. }
  120. fclose(pSrcFile);
  121. return iret;
  122. }
  123. unsigned char strkey[SM4ENC_BLOCK_SIZE] = {0};
  124. if (get_key_from_header_info(strkey, SM4ENC_BLOCK_SIZE, prvcbuffer, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pcallback)){
  125. return iret;
  126. }
  127. if (get_decrytion_filename(poutfile, uoutlen, RVC_FILEDEC_STR, strlen(RVC_FILEDEC_STR), pfilename)){
  128. return iret;
  129. }
  130. FILE* pDestFile = fopen(poutfile, "wb");
  131. if (NULL == pDestFile){
  132. return iret;
  133. }
  134. char strasfheader[ASF_HEADER_GUID_LEN] = {0};
  135. if (ASF_HEADER_GUID_LEN == fread(strasfheader, 1, ASF_HEADER_GUID_LEN, pSrcFile)){
  136. fwrite(strasfheader, 1, ASF_HEADER_GUID_LEN, pDestFile);
  137. }
  138. char strheadlen[ASF_HEADER_SIZE_LEN] = {0};
  139. fread(strheadlen, 1, ASF_HEADER_SIZE_LEN, pSrcFile);
  140. uint64_t uheadlen = get_asf_headsize(strheadlen, ASF_HEADER_SIZE_LEN);
  141. unsigned char* pheaddata = (unsigned char*)malloc(uheadlen);
  142. unsigned char* pdecheaddata = (unsigned char*)malloc(uheadlen);
  143. int ioutlen = uheadlen;
  144. fread(pheaddata, 1, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pSrcFile);
  145. SM4DecECBMode(strkey, pheaddata, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pdecheaddata, &ioutlen);
  146. construct_asf_headsize(strheadlen,ASF_HEADER_SIZE_LEN,ioutlen + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN);
  147. fwrite(strheadlen, 1, ASF_HEADER_SIZE_LEN, pDestFile);
  148. fwrite(pdecheaddata, 1, ioutlen, pDestFile);
  149. char *data_buffer=(char *)malloc(RVC_READ_BUFFER_SIZE);
  150. size_t udatalen = 0;
  151. while(udatalen = fread(data_buffer, 1, RVC_READ_BUFFER_SIZE, pSrcFile)){
  152. fwrite(data_buffer, 1, udatalen, pDestFile);
  153. }
  154. fclose(pSrcFile);
  155. fclose(pDestFile);
  156. safe_free(data_buffer);
  157. safe_free(pdecheaddata);
  158. safe_free(pheaddata);
  159. return iret;
  160. }
  161. bool is_file_encrypted(const char* pfilename, const filecryption_callback_t* pcallback)
  162. {
  163. bool bret = false;
  164. if (NULL == pfilename){
  165. return bret;
  166. }
  167. FILE* pSrcFile = fopen(pfilename, "rb");
  168. if (NULL == pSrcFile){
  169. safe_log(pcallback,"open file %s failed!",pfilename);
  170. return bret;
  171. }
  172. char strrvcheader[RVC_FILE_HEADER_FLAG_LEN] = {0};
  173. if (RVC_FILE_HEADER_FLAG_LEN == fread(strrvcheader, 1, RVC_FILE_HEADER_FLAG_LEN, pSrcFile)){
  174. if (0 == strnicmp(strrvcheader, rvc_header, RVC_FILE_HEADER_FLAG_LEN)){
  175. bret = true;
  176. }
  177. else{
  178. safe_log(pcallback,"file %s is not encryption!",pfilename);
  179. }
  180. }
  181. fclose(pSrcFile);
  182. return bret;
  183. }
  184. /*
  185. 文件解密功能;
  186. 输入:文件路径
  187. 输出:文件明文头数据,文件明文头长度,加解密前后文件偏移量,自定义头文件头信息
  188. */
  189. int rvc_file_decrypt(unsigned char** pdechead, size_t* udecheadlen, int* ioffset, char** pstrjson, size_t* ujsonlen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion)
  190. {
  191. int iret = -1;
  192. if (NULL == pfilename || eversion >= sizeof(cryption_ver_flag_table)/sizeof(char*) || eversion < 0){
  193. safe_log(pcallback,"%s","invalid cryption version param.");
  194. return iret;
  195. }
  196. FILE* pSrcFile = fopen(pfilename, "rb");
  197. if (NULL == pSrcFile){
  198. safe_log(pcallback,"open file %s failed!",pfilename);
  199. return iret;
  200. }
  201. unsigned char strkey[SM4ENC_BLOCK_SIZE] = {0};
  202. int irvcheadlen = 0;
  203. char strrvcflag[RVC_FILE_HEADER_FLAG_LEN] = {0};
  204. fread(strrvcflag,1, RVC_FILE_HEADER_FLAG_LEN, pSrcFile);
  205. if (0 != memcmp(strrvcflag, rvc_header, RVC_FILE_HEADER_FLAG_LEN)){
  206. //safe_log(pcallback,"file %s is not encrypted!",pfilename);
  207. *pdechead = NULL;
  208. *udecheadlen = 0;
  209. *ioffset = 0;
  210. fclose(pSrcFile);
  211. iret = 0;
  212. return iret;
  213. }
  214. else{
  215. //safe_log(pcallback,"file %s is encrypted!",pfilename);
  216. fread(&irvcheadlen, 1, sizeof(int), pSrcFile);
  217. char* prvcbuffer = (char*)malloc(irvcheadlen);
  218. memset(prvcbuffer, 0, irvcheadlen);
  219. fread(prvcbuffer, 1, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pSrcFile);
  220. if (0 != memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN)){
  221. if (0 == memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN-1)){
  222. safe_log(pcallback,"file %s encryption and decrption version is not matched!",pfilename);
  223. }
  224. safe_free(prvcbuffer);
  225. fclose(pSrcFile);
  226. return iret;
  227. }
  228. if (get_key_from_header_info(strkey, SM4ENC_BLOCK_SIZE, prvcbuffer, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pcallback)){
  229. safe_free(prvcbuffer);
  230. fclose(pSrcFile);
  231. return iret;
  232. }
  233. int ijson = get_file_json_infos_from_rvc_header(pstrjson, ujsonlen, prvcbuffer, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int));
  234. if (0 == ijson){
  235. safe_log(pcallback,"get_file_json_infos_from_rvc_header success!");
  236. }
  237. safe_free(prvcbuffer);
  238. }
  239. char strasfheader[ASF_HEADER_GUID_LEN] = {0};
  240. if (ASF_HEADER_GUID_LEN == fread(strasfheader, 1, ASF_HEADER_GUID_LEN, pSrcFile)){
  241. if (0 != memcmp(strasfheader, ASF_Header_GUID, ASF_HEADER_GUID_LEN)){
  242. safe_log(pcallback,"file %s is current not surrport format!",pfilename);
  243. fclose(pSrcFile);
  244. return iret;
  245. }
  246. }
  247. else{
  248. fclose(pSrcFile);
  249. return iret;
  250. }
  251. char strheadlen[ASF_HEADER_SIZE_LEN] = {0};
  252. fread(strheadlen, 1, ASF_HEADER_SIZE_LEN, pSrcFile);
  253. uint64_t uheadlen = get_asf_headsize(strheadlen, ASF_HEADER_SIZE_LEN);
  254. unsigned char* pheaddata = (unsigned char*)malloc(uheadlen);
  255. fread(pheaddata+ ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN, 1, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pSrcFile);
  256. unsigned char* pdecheaddata = (unsigned char*)malloc(uheadlen);
  257. int ioutlen = uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN ;
  258. SM4DecECBMode(strkey, pheaddata + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pdecheaddata + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN, &ioutlen);
  259. construct_asf_headsize(strheadlen,ASF_HEADER_SIZE_LEN,ioutlen + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN);
  260. memcpy(pdecheaddata, strasfheader, ASF_HEADER_GUID_LEN);
  261. memcpy(pdecheaddata + ASF_HEADER_GUID_LEN, strheadlen, ASF_HEADER_SIZE_LEN);
  262. *pdechead = pdecheaddata;
  263. *udecheadlen = ioutlen + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN;
  264. *ioffset = (irvcheadlen + uheadlen - (*udecheadlen));
  265. safe_free(pheaddata);
  266. fclose(pSrcFile);
  267. iret = 0;
  268. return iret;
  269. }
  270. int rvc_free_data(void** pdechead)
  271. {
  272. int iret = -1;
  273. safe_free(*pdechead);
  274. iret = 0;
  275. return iret;
  276. }