file_access_encrypted.cpp 4.8 KB

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