file_access_encrypted.cpp 4.9 KB

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