comparison src/fileio.c @ 24970:7e9e53a0368f v8.2.3022

patch 8.2.3022: available encryption methods are not strong enough Commit: https://github.com/vim/vim/commit/f573c6e1ed58d46d694c802eaf5ae3662a952744 Author: Christian Brabandt <cb@256bit.org> Date: Sun Jun 20 14:02:16 2021 +0200 patch 8.2.3022: available encryption methods are not strong enough Problem: Available encryption methods are not strong enough. Solution: Add initial support for xchaha20. (Christian Brabandt, closes #8394)
author Bram Moolenaar <Bram@vim.org>
date Sun, 20 Jun 2021 14:15:07 +0200
parents 7334bf933510
children 85d1e82ed134
comparison
equal deleted inserted replaced
24969:445ed84ae76a 24970:7e9e53a0368f
10 /* 10 /*
11 * fileio.c: read from and write to a file 11 * fileio.c: read from and write to a file
12 */ 12 */
13 13
14 #include "vim.h" 14 #include "vim.h"
15
16 #ifdef FEAT_SODIUM
17 # include <sodium.h>
18 #endif
15 19
16 #if defined(__TANDEM) 20 #if defined(__TANDEM)
17 # include <limits.h> // for SSIZE_MAX 21 # include <limits.h> // for SSIZE_MAX
18 #endif 22 #endif
19 #if (defined(UNIX) || defined(VMS)) && defined(FEAT_EVAL) 23 #if (defined(UNIX) || defined(VMS)) && defined(FEAT_EVAL)
146 colnr_T len; 150 colnr_T len;
147 long size = 0; 151 long size = 0;
148 char_u *p; 152 char_u *p;
149 off_T filesize = 0; 153 off_T filesize = 0;
150 int skip_read = FALSE; 154 int skip_read = FALSE;
155 off_T filesize_disk = 0; // file size read from disk
156 off_T filesize_count = 0; // counter
151 #ifdef FEAT_CRYPT 157 #ifdef FEAT_CRYPT
152 char_u *cryptkey = NULL; 158 char_u *cryptkey = NULL;
153 int did_ask_for_key = FALSE; 159 int did_ask_for_key = FALSE;
154 #endif 160 #endif
155 #ifdef FEAT_PERSISTENT_UNDO 161 #ifdef FEAT_PERSISTENT_UNDO
213 char_u *old_b_ffname; 219 char_u *old_b_ffname;
214 char_u *old_b_fname; 220 char_u *old_b_fname;
215 int using_b_ffname; 221 int using_b_ffname;
216 int using_b_fname; 222 int using_b_fname;
217 static char *msg_is_a_directory = N_("is a directory"); 223 static char *msg_is_a_directory = N_("is a directory");
224 int eof;
218 225
219 au_did_filetype = FALSE; // reset before triggering any autocommands 226 au_did_filetype = FALSE; // reset before triggering any autocommands
220 227
221 curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read 228 curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read
222 229
403 // Remember time of file. 410 // Remember time of file.
404 if (mch_stat((char *)fname, &st) >= 0) 411 if (mch_stat((char *)fname, &st) >= 0)
405 { 412 {
406 buf_store_time(curbuf, &st, fname); 413 buf_store_time(curbuf, &st, fname);
407 curbuf->b_mtime_read = curbuf->b_mtime; 414 curbuf->b_mtime_read = curbuf->b_mtime;
415 filesize_disk = st.st_size;
408 #ifdef UNIX 416 #ifdef UNIX
409 /* 417 /*
410 * Use the protection bits of the original file for the swap file. 418 * Use the protection bits of the original file for the swap file.
411 * This makes it possible for others to read the name of the 419 * This makes it possible for others to read the name of the
412 * edited file from the swapfile, but only if they can read the 420 * edited file from the swapfile, but only if they can read the
1078 1086
1079 if (!skip_read) 1087 if (!skip_read)
1080 { 1088 {
1081 linerest = 0; 1089 linerest = 0;
1082 filesize = 0; 1090 filesize = 0;
1091 filesize_count = 0;
1083 skip_count = lines_to_skip; 1092 skip_count = lines_to_skip;
1084 read_count = lines_to_read; 1093 read_count = lines_to_read;
1085 conv_restlen = 0; 1094 conv_restlen = 0;
1086 #ifdef FEAT_PERSISTENT_UNDO 1095 #ifdef FEAT_PERSISTENT_UNDO
1087 read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0 1096 read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0
1261 else 1270 else
1262 { 1271 {
1263 /* 1272 /*
1264 * Read bytes from the file. 1273 * Read bytes from the file.
1265 */ 1274 */
1275 # ifdef FEAT_SODIUM
1276 // Let the crypt layer work with a buffer size of 8192
1277 if (filesize == 0)
1278 // set size to 8K + Sodium Crypt Metadata
1279 size = WRITEBUFSIZE + 36
1280 + crypto_secretstream_xchacha20poly1305_HEADERBYTES
1281 + crypto_secretstream_xchacha20poly1305_ABYTES;
1282
1283 else if (filesize > 0 && (curbuf->b_cryptstate != NULL &&
1284 curbuf->b_cryptstate->method_nr == CRYPT_M_SOD))
1285 size = WRITEBUFSIZE + crypto_secretstream_xchacha20poly1305_ABYTES;
1286 # endif
1287 eof = size;
1266 size = read_eintr(fd, ptr, size); 1288 size = read_eintr(fd, ptr, size);
1289 filesize_count += size;
1290 // hit end of file
1291 eof = (size < eof || filesize_count == filesize_disk);
1267 } 1292 }
1268 1293
1269 #ifdef FEAT_CRYPT 1294 #ifdef FEAT_CRYPT
1270 /* 1295 /*
1271 * At start of file: Check for magic number of encryption. 1296 * At start of file: Check for magic number of encryption.
1283 { 1308 {
1284 # ifdef CRYPT_NOT_INPLACE 1309 # ifdef CRYPT_NOT_INPLACE
1285 if (crypt_works_inplace(curbuf->b_cryptstate)) 1310 if (crypt_works_inplace(curbuf->b_cryptstate))
1286 { 1311 {
1287 # endif 1312 # endif
1288 crypt_decode_inplace(curbuf->b_cryptstate, ptr, size); 1313 crypt_decode_inplace(curbuf->b_cryptstate, ptr,
1314 size, eof);
1289 # ifdef CRYPT_NOT_INPLACE 1315 # ifdef CRYPT_NOT_INPLACE
1290 } 1316 }
1291 else 1317 else
1292 { 1318 {
1293 char_u *newptr = NULL; 1319 char_u *newptr = NULL;
1294 int decrypted_size; 1320 int decrypted_size;
1295 1321
1296 decrypted_size = crypt_decode_alloc( 1322 decrypted_size = crypt_decode_alloc(
1297 curbuf->b_cryptstate, ptr, size, &newptr); 1323 curbuf->b_cryptstate, ptr, size,
1298 1324 &newptr, eof);
1325
1326 if (decrypted_size < 0)
1327 {
1328 // error message already given
1329 error = TRUE;
1330 vim_free(newptr);
1331 break;
1332 }
1299 // If the crypt layer is buffering, not producing 1333 // If the crypt layer is buffering, not producing
1300 // anything yet, need to read more. 1334 // anything yet, need to read more.
1301 if (decrypted_size == 0) 1335 if (decrypted_size == 0)
1302 continue; 1336 continue;
1303 1337
1323 1357
1324 mch_memmove(new_buffer, buffer, linerest); 1358 mch_memmove(new_buffer, buffer, linerest);
1325 if (newptr != NULL) 1359 if (newptr != NULL)
1326 mch_memmove(new_buffer + linerest, newptr, 1360 mch_memmove(new_buffer + linerest, newptr,
1327 decrypted_size); 1361 decrypted_size);
1362 vim_free(newptr);
1328 } 1363 }
1329 1364
1330 if (new_buffer != NULL) 1365 if (new_buffer != NULL)
1331 { 1366 {
1332 vim_free(buffer); 1367 vim_free(buffer);
1333 buffer = new_buffer; 1368 buffer = new_buffer;
1334 new_buffer = NULL; 1369 new_buffer = NULL;
1335 line_start = buffer; 1370 line_start = buffer;
1336 ptr = buffer + linerest; 1371 ptr = buffer + linerest;
1372 real_size = size;
1337 } 1373 }
1338 size = decrypted_size; 1374 size = decrypted_size;
1339 } 1375 }
1340 # endif 1376 # endif
1341 } 1377 }