file_access_encrypted.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. #include "file_access_encrypted.h"
  2. #include "aes256.h"
  3. #include "md5.h"
  4. #include "os/copymem.h"
  5. #include "print_string.h"
  6. #define COMP_MAGIC 0x43454447
  7. #include "core/variant.h"
  8. #include <stdio.h>
  9. Error FileAccessEncrypted::open_and_parse(FileAccess *p_base,const Vector<uint8_t>& p_key,Mode p_mode) {
  10. //print_line("open and parse!");
  11. ERR_FAIL_COND_V(file!=NULL,ERR_ALREADY_IN_USE);
  12. ERR_FAIL_COND_V(p_key.size()!=32,ERR_INVALID_PARAMETER);
  13. pos=0;
  14. eofed=false;
  15. if (p_mode==MODE_WRITE_AES256) {
  16. data.clear();
  17. writing=true;
  18. file=p_base;
  19. mode=p_mode;
  20. key=p_key;
  21. } else if (p_mode==MODE_READ) {
  22. writing=false;
  23. key=p_key;
  24. uint32_t magic = p_base->get_32();
  25. print_line("MAGIC: "+itos(magic));
  26. ERR_FAIL_COND_V(magic!=COMP_MAGIC,ERR_FILE_UNRECOGNIZED);
  27. mode=Mode(p_base->get_32());
  28. ERR_FAIL_INDEX_V(mode,MODE_MAX,ERR_FILE_CORRUPT);
  29. ERR_FAIL_COND_V(mode==0,ERR_FILE_CORRUPT);
  30. print_line("MODE: "+itos(mode));
  31. unsigned char md5d[16];
  32. p_base->get_buffer(md5d,16);
  33. length=p_base->get_64();
  34. base=p_base->get_pos();
  35. ERR_FAIL_COND_V(p_base->get_len() < base+length, ERR_FILE_CORRUPT );
  36. int ds = length;
  37. if (ds % 16) {
  38. ds+=16-(ds % 16);
  39. }
  40. data.resize(ds);
  41. int blen = p_base->get_buffer(data.ptr(),ds);
  42. ERR_FAIL_COND_V(blen!=ds,ERR_FILE_CORRUPT);
  43. aes256_context ctx;
  44. aes256_init(&ctx,key.ptr());
  45. for(size_t i=0;i<ds;i+=16) {
  46. aes256_decrypt_ecb(&ctx,&data[i]);
  47. }
  48. aes256_done(&ctx);
  49. data.resize(length);
  50. MD5_CTX md5;
  51. MD5Init(&md5);
  52. MD5Update(&md5,data.ptr(),data.size());
  53. MD5Final(&md5);
  54. ERR_FAIL_COND_V(String::md5(md5.digest)!=String::md5(md5d),ERR_FILE_CORRUPT) ;
  55. file=p_base;
  56. }
  57. return OK;
  58. }
  59. Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base,const String& p_key,Mode p_mode){
  60. String cs = p_key.md5_text();
  61. ERR_FAIL_COND_V(cs.length()!=32,ERR_INVALID_PARAMETER);
  62. Vector<uint8_t> key;
  63. key.resize(32);
  64. for(int i=0;i<32;i++) {
  65. key[i]=cs[i];
  66. }
  67. return open_and_parse(p_base,key,p_mode);
  68. }
  69. Error FileAccessEncrypted::_open(const String& p_path, int p_mode_flags) {
  70. return OK;
  71. }
  72. void FileAccessEncrypted::close() {
  73. if (!file)
  74. return;
  75. if (writing) {
  76. Vector<uint8_t> compressed;
  77. size_t len = data.size();
  78. if (len % 16) {
  79. len+=16-(len % 16);
  80. }
  81. MD5_CTX md5;
  82. MD5Init(&md5);
  83. MD5Update(&md5,data.ptr(),data.size());
  84. MD5Final(&md5);
  85. compressed.resize(len);
  86. zeromem( compressed.ptr(), len );
  87. for(int i=0;i<data.size();i++) {
  88. compressed[i]=data[i];
  89. }
  90. aes256_context ctx;
  91. aes256_init(&ctx,key.ptr());
  92. for(size_t i=0;i<len;i+=16) {
  93. aes256_encrypt_ecb(&ctx,&compressed[i]);
  94. }
  95. aes256_done(&ctx);
  96. file->store_32(COMP_MAGIC);
  97. file->store_32(mode);
  98. file->store_buffer(md5.digest,16);
  99. file->store_64(data.size());
  100. file->store_buffer(compressed.ptr(),compressed.size());
  101. file->close();
  102. memdelete(file);
  103. file=NULL;
  104. data.clear();
  105. } else {
  106. file->close();
  107. memdelete(file);
  108. data.clear();
  109. file=NULL;
  110. }
  111. }
  112. bool FileAccessEncrypted::is_open() const{
  113. return file!=NULL;
  114. }
  115. void FileAccessEncrypted::seek(size_t p_position){
  116. if (p_position > (size_t)data.size())
  117. p_position=data.size();
  118. pos=p_position;
  119. eofed=false;
  120. }
  121. void FileAccessEncrypted::seek_end(int64_t p_position){
  122. seek( data.size() + p_position );
  123. }
  124. size_t FileAccessEncrypted::get_pos() const{
  125. return pos;
  126. }
  127. size_t FileAccessEncrypted::get_len() const{
  128. return data.size();
  129. }
  130. bool FileAccessEncrypted::eof_reached() const{
  131. return eofed;
  132. }
  133. uint8_t FileAccessEncrypted::get_8() const{
  134. ERR_FAIL_COND_V(writing,0);
  135. if (pos>=data.size()) {
  136. eofed=true;
  137. return 0;
  138. }
  139. uint8_t b = data[pos];
  140. pos++;
  141. return b;
  142. }
  143. int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const{
  144. ERR_FAIL_COND_V(writing,0);
  145. int to_copy=MIN(p_length,data.size()-pos);
  146. for(int i=0;i<to_copy;i++) {
  147. p_dst[i]=data[pos++];
  148. }
  149. if (to_copy<p_length) {
  150. eofed=true;
  151. }
  152. return to_copy;
  153. }
  154. Error FileAccessEncrypted::get_error() const{
  155. return eofed?ERR_FILE_EOF:OK;
  156. }
  157. void FileAccessEncrypted::store_buffer(const uint8_t *p_src,int p_length) {
  158. ERR_FAIL_COND(!writing);
  159. if (pos<data.size()) {
  160. for(int i=0;i<p_length;i++) {
  161. store_8(p_src[i]);
  162. }
  163. } else if (pos==data.size()) {
  164. data.resize(pos+p_length);
  165. for(int i=0;i<p_length;i++) {
  166. data[pos+i]=p_src[i];
  167. }
  168. pos+=p_length;
  169. }
  170. }
  171. void FileAccessEncrypted::store_8(uint8_t p_dest){
  172. ERR_FAIL_COND(!writing);
  173. if (pos<data.size()) {
  174. data[pos]=p_dest;
  175. pos++;
  176. } else if (pos==data.size()){
  177. data.push_back(p_dest);
  178. pos++;
  179. }
  180. }
  181. bool FileAccessEncrypted::file_exists(const String& p_name){
  182. FileAccess *fa = FileAccess::open(p_name,FileAccess::READ);
  183. if (!fa)
  184. return false;
  185. memdelete(fa);
  186. return true;
  187. }
  188. uint64_t FileAccessEncrypted::_get_modified_time(const String& p_file){
  189. return 0;
  190. }
  191. FileAccessEncrypted::FileAccessEncrypted() {
  192. file=NULL;
  193. pos=0;
  194. eofed=false;
  195. mode=MODE_MAX;
  196. writing=false;
  197. }
  198. FileAccessEncrypted::~FileAccessEncrypted() {
  199. if (file)
  200. close();
  201. }