summaryrefslogtreecommitdiffstats
path: root/src/fileio.c
diff options
context:
space:
mode:
authorChristian Brabandt <cb@256bit.org>2021-06-20 14:02:16 +0200
committerBram Moolenaar <Bram@vim.org>2021-06-20 14:02:16 +0200
commitf573c6e1ed58d46d694c802eaf5ae3662a952744 (patch)
tree9d3ccf4402f322b9d1baf130696a6b0e600ae693 /src/fileio.c
parent208f0b48b2c616b29f377a1408290111ed2663f7 (diff)
patch 8.2.3022: available encryption methods are not strong enoughv8.2.3022
Problem: Available encryption methods are not strong enough. Solution: Add initial support for xchaha20. (Christian Brabandt, closes #8394)
Diffstat (limited to 'src/fileio.c')
-rw-r--r--src/fileio.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/fileio.c b/src/fileio.c
index 91c02bfcd0..e05dfa3a5d 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -13,6 +13,10 @@
#include "vim.h"
+#ifdef FEAT_SODIUM
+# include <sodium.h>
+#endif
+
#if defined(__TANDEM)
# include <limits.h> // for SSIZE_MAX
#endif
@@ -148,6 +152,8 @@ readfile(
char_u *p;
off_T filesize = 0;
int skip_read = FALSE;
+ off_T filesize_disk = 0; // file size read from disk
+ off_T filesize_count = 0; // counter
#ifdef FEAT_CRYPT
char_u *cryptkey = NULL;
int did_ask_for_key = FALSE;
@@ -215,6 +221,7 @@ readfile(
int using_b_ffname;
int using_b_fname;
static char *msg_is_a_directory = N_("is a directory");
+ int eof;
au_did_filetype = FALSE; // reset before triggering any autocommands
@@ -405,6 +412,7 @@ readfile(
{
buf_store_time(curbuf, &st, fname);
curbuf->b_mtime_read = curbuf->b_mtime;
+ filesize_disk = st.st_size;
#ifdef UNIX
/*
* Use the protection bits of the original file for the swap file.
@@ -1080,6 +1088,7 @@ retry:
{
linerest = 0;
filesize = 0;
+ filesize_count = 0;
skip_count = lines_to_skip;
read_count = lines_to_read;
conv_restlen = 0;
@@ -1263,7 +1272,23 @@ retry:
/*
* Read bytes from the file.
*/
+# ifdef FEAT_SODIUM
+ // Let the crypt layer work with a buffer size of 8192
+ if (filesize == 0)
+ // set size to 8K + Sodium Crypt Metadata
+ size = WRITEBUFSIZE + 36
+ + crypto_secretstream_xchacha20poly1305_HEADERBYTES
+ + crypto_secretstream_xchacha20poly1305_ABYTES;
+
+ else if (filesize > 0 && (curbuf->b_cryptstate != NULL &&
+ curbuf->b_cryptstate->method_nr == CRYPT_M_SOD))
+ size = WRITEBUFSIZE + crypto_secretstream_xchacha20poly1305_ABYTES;
+# endif
+ eof = size;
size = read_eintr(fd, ptr, size);
+ filesize_count += size;
+ // hit end of file
+ eof = (size < eof || filesize_count == filesize_disk);
}
#ifdef FEAT_CRYPT
@@ -1285,7 +1310,8 @@ retry:
if (crypt_works_inplace(curbuf->b_cryptstate))
{
# endif
- crypt_decode_inplace(curbuf->b_cryptstate, ptr, size);
+ crypt_decode_inplace(curbuf->b_cryptstate, ptr,
+ size, eof);
# ifdef CRYPT_NOT_INPLACE
}
else
@@ -1294,8 +1320,16 @@ retry:
int decrypted_size;
decrypted_size = crypt_decode_alloc(
- curbuf->b_cryptstate, ptr, size, &newptr);
+ curbuf->b_cryptstate, ptr, size,
+ &newptr, eof);
+ if (decrypted_size < 0)
+ {
+ // error message already given
+ error = TRUE;
+ vim_free(newptr);
+ break;
+ }
// If the crypt layer is buffering, not producing
// anything yet, need to read more.
if (decrypted_size == 0)
@@ -1325,6 +1359,7 @@ retry:
if (newptr != NULL)
mch_memmove(new_buffer + linerest, newptr,
decrypted_size);
+ vim_free(newptr);
}
if (new_buffer != NULL)
@@ -1334,6 +1369,7 @@ retry:
new_buffer = NULL;
line_start = buffer;
ptr = buffer + linerest;
+ real_size = size;
}
size = decrypted_size;
}