filecryption.cpp 13 KB

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