3636
3737#include < stdio.h>
3838
39- Error FileAccessEncrypted::open_and_parse (Ref<FileAccess> p_base, const Vector<uint8_t > &p_key, Mode p_mode, bool p_with_magic) {
39+ Error FileAccessEncrypted::open_and_parse (Ref<FileAccess> p_base, const Vector<uint8_t > &p_key, Mode p_mode, bool p_with_magic, const Vector< uint8_t > &p_iv ) {
4040 ERR_FAIL_COND_V_MSG (file.is_valid (), ERR_ALREADY_IN_USE, vformat (" Can't open file while another file from path '%s' is open." , file->get_path_absolute ()));
4141 ERR_FAIL_COND_V (p_key.size () != 32 , ERR_INVALID_PARAMETER);
4242
@@ -49,6 +49,16 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
4949 writing = true ;
5050 file = p_base;
5151 key = p_key;
52+ if (p_iv.is_empty ()) {
53+ iv.resize (16 );
54+ CryptoCore::RandomGenerator rng;
55+ ERR_FAIL_COND_V_MSG (rng.init (), FAILED, " Failed to initialize random number generator." );
56+ Error err = rng.get_random_bytes (iv.ptrw (), 16 );
57+ ERR_FAIL_COND_V (err != OK, err);
58+ } else {
59+ ERR_FAIL_COND_V (p_iv.size () != 16 , ERR_INVALID_PARAMETER);
60+ iv = p_iv;
61+ }
5262
5363 } else if (p_mode == MODE_READ) {
5464 writing = false ;
@@ -63,10 +73,8 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
6373 p_base->get_buffer (md5d, 16 );
6474 length = p_base->get_64 ();
6575
66- unsigned char iv[16 ];
67- for (int i = 0 ; i < 16 ; i++) {
68- iv[i] = p_base->get_8 ();
69- }
76+ iv.resize (16 );
77+ p_base->get_buffer (iv.ptrw (), 16 );
7078
7179 base = p_base->get_position ();
7280 ERR_FAIL_COND_V (p_base->get_length () < base + length, ERR_FILE_CORRUPT);
@@ -83,7 +91,7 @@ Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<u
8391 CryptoCore::AESContext ctx;
8492
8593 ctx.set_encode_key (key.ptrw (), 256 ); // Due to the nature of CFB, same key schedule is used for both encryption and decryption!
86- ctx.decrypt_cfb (ds, iv, data.ptrw (), data.ptrw ());
94+ ctx.decrypt_cfb (ds, iv. ptrw () , data.ptrw (), data.ptrw ());
8795 }
8896
8997 data.resize (length);
@@ -145,14 +153,9 @@ void FileAccessEncrypted::_close() {
145153
146154 file->store_buffer (hash, 16 );
147155 file->store_64 (data.size ());
156+ file->store_buffer (iv.ptr (), 16 );
148157
149- unsigned char iv[16 ];
150- for (int i = 0 ; i < 16 ; i++) {
151- iv[i] = Math::rand () % 256 ;
152- file->store_8 (iv[i]);
153- }
154-
155- ctx.encrypt_cfb (len, iv, compressed.ptrw (), compressed.ptrw ());
158+ ctx.encrypt_cfb (len, iv.ptrw (), compressed.ptrw (), compressed.ptrw ());
156159
157160 file->store_buffer (compressed.ptr (), compressed.size ());
158161 data.clear ();
0 commit comments