forked from aniani/vim
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)
This commit is contained in:
committed by
Bram Moolenaar
parent
208f0b48b2
commit
f573c6e1ed
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@@ -71,7 +71,8 @@ jobs:
|
|||||||
cscope \
|
cscope \
|
||||||
libgtk2.0-dev \
|
libgtk2.0-dev \
|
||||||
desktop-file-utils \
|
desktop-file-utils \
|
||||||
libtool-bin
|
libtool-bin \
|
||||||
|
libsodium-dev
|
||||||
|
|
||||||
- name: Install clang-11
|
- name: Install clang-11
|
||||||
if: matrix.compiler == 'clang'
|
if: matrix.compiler == 'clang'
|
||||||
|
@@ -11971,6 +11971,7 @@ scrollbind Compiled with 'scrollbind' support. (always true)
|
|||||||
showcmd Compiled with 'showcmd' support.
|
showcmd Compiled with 'showcmd' support.
|
||||||
signs Compiled with |:sign| support.
|
signs Compiled with |:sign| support.
|
||||||
smartindent Compiled with 'smartindent' support.
|
smartindent Compiled with 'smartindent' support.
|
||||||
|
sodium Compiled with libsodium for better crypt support
|
||||||
sound Compiled with sound support, e.g. `sound_playevent()`
|
sound Compiled with sound support, e.g. `sound_playevent()`
|
||||||
spell Compiled with spell checking support |spell|.
|
spell Compiled with spell checking support |spell|.
|
||||||
startuptime Compiled with |--startuptime| support.
|
startuptime Compiled with |--startuptime| support.
|
||||||
|
@@ -2384,6 +2384,23 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
you write the file the encrypted bytes will be
|
you write the file the encrypted bytes will be
|
||||||
different. The whole undo file is encrypted, not just
|
different. The whole undo file is encrypted, not just
|
||||||
the pieces of text.
|
the pieces of text.
|
||||||
|
*E1193* *E1194* *E1195* *E1196*
|
||||||
|
*E1197* *E1198* *E1199* *E1200* *E1201*
|
||||||
|
xchacha20 XChaCha20 Cipher with Poly1305 Message Authentication
|
||||||
|
Code. Medium strong till strong encryption.
|
||||||
|
Encryption is provided by the libsodium library, it
|
||||||
|
requires Vim to be built with |+sodium|
|
||||||
|
It adds a seed and a message authentication code (MAC)
|
||||||
|
to the file. This needs at least a Vim 8.2.3022 to
|
||||||
|
read the encrypted file.
|
||||||
|
Encryption of swap files is not supported, therefore
|
||||||
|
no swap file will be used when xchacha20 encryption is
|
||||||
|
enabled.
|
||||||
|
Encryption of undo files is not yet supported,
|
||||||
|
therefore no undo file will currently be written.
|
||||||
|
CURRENTLY EXPERIMENTAL: Files written with this method
|
||||||
|
might have to be read back with the same version of
|
||||||
|
Vim if the binary format changes later.
|
||||||
|
|
||||||
You should use "blowfish2", also to re-encrypt older files.
|
You should use "blowfish2", also to re-encrypt older files.
|
||||||
|
|
||||||
|
@@ -444,6 +444,7 @@ m *+ruby/dyn* Ruby interface |ruby-dynamic| |/dyn|
|
|||||||
T *+scrollbind* |'scrollbind'|
|
T *+scrollbind* |'scrollbind'|
|
||||||
B *+signs* |:sign|
|
B *+signs* |:sign|
|
||||||
N *+smartindent* |'smartindent'|
|
N *+smartindent* |'smartindent'|
|
||||||
|
B *+sodium* compiled with libsodium for better encryption support
|
||||||
B *+sound* |sound_playevent()|, |sound_playfile()| functions, etc.
|
B *+sound* |sound_playevent()|, |sound_playfile()| functions, etc.
|
||||||
N *+spell* spell checking support, see |spell|
|
N *+spell* spell checking support, see |spell|
|
||||||
N *+startuptime* |--startuptime| argument
|
N *+startuptime* |--startuptime| argument
|
||||||
|
@@ -322,6 +322,9 @@ MSYS2 has its own git package, and you can also install it via pacman:
|
|||||||
|
|
||||||
$ pacman -S git
|
$ pacman -S git
|
||||||
|
|
||||||
|
For enabling libsodium support, you also need to install the package
|
||||||
|
|
||||||
|
$ pacman -S mingw-w64-x86_64-libsodium
|
||||||
|
|
||||||
2.3. Keep the build environment up-to-date
|
2.3. Keep the build environment up-to-date
|
||||||
|
|
||||||
|
@@ -41,6 +41,9 @@ DEBUG=no
|
|||||||
# set to yes to measure code coverage
|
# set to yes to measure code coverage
|
||||||
COVERAGE=no
|
COVERAGE=no
|
||||||
|
|
||||||
|
# better encryption support using libsodium
|
||||||
|
#SODIUM=yes
|
||||||
|
|
||||||
# set to SIZE for size, SPEED for speed, MAXSPEED for maximum optimization
|
# set to SIZE for size, SPEED for speed, MAXSPEED for maximum optimization
|
||||||
OPTIMIZE=MAXSPEED
|
OPTIMIZE=MAXSPEED
|
||||||
|
|
||||||
@@ -517,6 +520,10 @@ CXXFLAGS = -std=gnu++11
|
|||||||
WINDRES_FLAGS =
|
WINDRES_FLAGS =
|
||||||
EXTRA_LIBS =
|
EXTRA_LIBS =
|
||||||
|
|
||||||
|
ifdef SODIUM
|
||||||
|
DEFINES += -DHAVE_SODIUM
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef GETTEXT
|
ifdef GETTEXT
|
||||||
DEFINES += -DHAVE_GETTEXT -DHAVE_LOCALE_H
|
DEFINES += -DHAVE_GETTEXT -DHAVE_LOCALE_H
|
||||||
GETTEXTINCLUDE = $(GETTEXT)/include
|
GETTEXTINCLUDE = $(GETTEXT)/include
|
||||||
@@ -660,6 +667,10 @@ DEFINES += -DFEAT_DIRECTX_COLOR_EMOJI
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SODIUM),yes)
|
||||||
|
SODIUMLIB = -lsodium
|
||||||
|
endif
|
||||||
|
|
||||||
# Only allow XPM for a GUI build.
|
# Only allow XPM for a GUI build.
|
||||||
ifeq (yes, $(GUI))
|
ifeq (yes, $(GUI))
|
||||||
|
|
||||||
@@ -1064,7 +1075,7 @@ $(EXEOBJC): | $(OUTDIR)
|
|||||||
|
|
||||||
ifeq ($(VIMDLL),yes)
|
ifeq ($(VIMDLL),yes)
|
||||||
$(TARGET): $(OBJ)
|
$(TARGET): $(OBJ)
|
||||||
$(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid -lgdi32 $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB)
|
$(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid -lgdi32 $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB)
|
||||||
|
|
||||||
$(GVIMEXE): $(EXEOBJG) $(VIMDLLBASE).dll
|
$(GVIMEXE): $(EXEOBJG) $(VIMDLLBASE).dll
|
||||||
$(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE)
|
$(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE)
|
||||||
@@ -1073,7 +1084,7 @@ $(VIMEXE): $(EXEOBJC) $(VIMDLLBASE).dll
|
|||||||
$(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE)
|
$(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE)
|
||||||
else
|
else
|
||||||
$(TARGET): $(OBJ)
|
$(TARGET): $(OBJ)
|
||||||
$(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB)
|
$(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
upx: exes
|
upx: exes
|
||||||
|
@@ -41,6 +41,9 @@
|
|||||||
#
|
#
|
||||||
# Sound support: SOUND=yes (default is yes)
|
# Sound support: SOUND=yes (default is yes)
|
||||||
#
|
#
|
||||||
|
# Sodium support: SODIUM=[Path to Sodium directory]
|
||||||
|
# You need to install the msvc package from https://download.libsodium.org/libsodium/releases/
|
||||||
|
#
|
||||||
# DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
|
# DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
|
||||||
# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe.
|
# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe.
|
||||||
# The shared codes between the GUI and the console are built into
|
# The shared codes between the GUI and the console are built into
|
||||||
@@ -372,6 +375,26 @@ SOUND = no
|
|||||||
! endif
|
! endif
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
|
!ifndef SODIUM
|
||||||
|
SODIUM = no
|
||||||
|
!endif
|
||||||
|
|
||||||
|
!if "$(SODIUM)" != "no"
|
||||||
|
! if "$(CPU)" == "AMD64"
|
||||||
|
SOD_LIB = $(SODIUM)\x64\Release\v140\dynamic
|
||||||
|
! elseif "$(CPU)" == "i386"
|
||||||
|
SOD_LIB = $(SODIUM)\x86\Release\v140\dynamic
|
||||||
|
! else
|
||||||
|
SODIUM = no
|
||||||
|
! endif
|
||||||
|
!endif
|
||||||
|
|
||||||
|
!if "$(SODIUM)" != "no"
|
||||||
|
SOD_INC = -I $(SODIUM)\include
|
||||||
|
SOD_DEFS = -DFEAT_SODIUM
|
||||||
|
SOD_LIB = $(SOD_LIB)\libsodium.lib
|
||||||
|
!endif
|
||||||
|
|
||||||
!ifndef NETBEANS
|
!ifndef NETBEANS
|
||||||
NETBEANS = $(GUI)
|
NETBEANS = $(GUI)
|
||||||
!endif
|
!endif
|
||||||
@@ -491,7 +514,7 @@ CON_LIB = $(CON_LIB) /DELAYLOAD:comdlg32.dll /DELAYLOAD:ole32.dll DelayImp.lib
|
|||||||
|
|
||||||
CFLAGS = -c /W3 /GF /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \
|
CFLAGS = -c /W3 /GF /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \
|
||||||
$(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \
|
$(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \
|
||||||
$(NBDEBUG_DEFS) $(XPM_DEFS) \
|
$(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) \
|
||||||
$(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER)
|
$(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER)
|
||||||
|
|
||||||
#>>>>> end of choices
|
#>>>>> end of choices
|
||||||
@@ -703,7 +726,7 @@ CFLAGS = $(CFLAGS) $(CFLAGS_DEPR)
|
|||||||
|
|
||||||
INCL = vim.h alloc.h ascii.h ex_cmds.h feature.h errors.h globals.h \
|
INCL = vim.h alloc.h ascii.h ex_cmds.h feature.h errors.h globals.h \
|
||||||
keymap.h macros.h option.h os_dos.h os_win32.h proto.h regexp.h \
|
keymap.h macros.h option.h os_dos.h os_win32.h proto.h regexp.h \
|
||||||
spell.h structs.h term.h beval.h $(NBDEBUG_INCL)
|
spell.h structs.h term.h beval.h $(NBDEBUG_INCL) $(SOD_INC)
|
||||||
|
|
||||||
OBJ = \
|
OBJ = \
|
||||||
$(OUTDIR)\arabic.obj \
|
$(OUTDIR)\arabic.obj \
|
||||||
@@ -1282,7 +1305,7 @@ conflags = $(conflags) /map /mapinfo:lines
|
|||||||
LINKARGS1 = $(linkdebug) $(conflags)
|
LINKARGS1 = $(linkdebug) $(conflags)
|
||||||
LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(NODEFAULTLIB) $(LIBC) $(OLE_LIB) user32.lib \
|
LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(NODEFAULTLIB) $(LIBC) $(OLE_LIB) user32.lib \
|
||||||
$(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \
|
$(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \
|
||||||
$(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(LINK_PDB)
|
$(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB)
|
||||||
|
|
||||||
# Report link time code generation progress if used.
|
# Report link time code generation progress if used.
|
||||||
!ifdef NODEBUG
|
!ifdef NODEBUG
|
||||||
|
66
src/auto/configure
vendored
66
src/auto/configure
vendored
@@ -839,6 +839,7 @@ with_motif_lib
|
|||||||
with_tlib
|
with_tlib
|
||||||
enable_largefile
|
enable_largefile
|
||||||
enable_canberra
|
enable_canberra
|
||||||
|
enable_libsodium
|
||||||
enable_acl
|
enable_acl
|
||||||
enable_gpm
|
enable_gpm
|
||||||
enable_sysmouse
|
enable_sysmouse
|
||||||
@@ -1513,6 +1514,7 @@ Optional Features:
|
|||||||
--disable-desktop-database-update update disabled
|
--disable-desktop-database-update update disabled
|
||||||
--disable-largefile omit support for large files
|
--disable-largefile omit support for large files
|
||||||
--disable-canberra Do not use libcanberra.
|
--disable-canberra Do not use libcanberra.
|
||||||
|
--disable-libsodium Do not use libsodium.
|
||||||
--disable-acl No check for ACL support.
|
--disable-acl No check for ACL support.
|
||||||
--disable-gpm Don't use gpm (Linux mouse daemon).
|
--disable-gpm Don't use gpm (Linux mouse daemon).
|
||||||
--disable-sysmouse Don't use sysmouse (mouse in *BSD console).
|
--disable-sysmouse Don't use sysmouse (mouse in *BSD console).
|
||||||
@@ -13005,6 +13007,70 @@ rm -f core conftest.err conftest.$ac_objext \
|
|||||||
conftest$ac_exeext conftest.$ac_ext
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking --enable-libsodium argument" >&5
|
||||||
|
$as_echo_n "checking --enable-libsodium argument... " >&6; }
|
||||||
|
# Check whether --enable-libsodium was given.
|
||||||
|
if test "${enable_libsodium+set}" = set; then :
|
||||||
|
enableval=$enable_libsodium;
|
||||||
|
else
|
||||||
|
enable_libsodium="maybe"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test "$enable_libsodium" = "maybe"; then
|
||||||
|
if test "$features" = "big" -o "$features" = "huge"; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Defaulting to yes" >&5
|
||||||
|
$as_echo "Defaulting to yes" >&6; }
|
||||||
|
enable_libsodium="yes"
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Defaulting to no" >&5
|
||||||
|
$as_echo "Defaulting to no" >&6; }
|
||||||
|
enable_libsodium="no"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_libsodium" >&5
|
||||||
|
$as_echo "$enable_libsodium" >&6; }
|
||||||
|
fi
|
||||||
|
if test "$enable_libsodium" = "yes"; then
|
||||||
|
if test "x$PKG_CONFIG" != "xno"; then
|
||||||
|
libsodium_lib=`$PKG_CONFIG --libs libsodium 2>/dev/null`
|
||||||
|
libsodium_cflags=`$PKG_CONFIG --cflags libsodium 2>/dev/null`
|
||||||
|
fi
|
||||||
|
if test "x$libsodium_lib" = "x"; then
|
||||||
|
libsodium_lib=-lsodium
|
||||||
|
libsodium_cflags=
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcanberra" >&5
|
||||||
|
$as_echo_n "checking for libcanberra... " >&6; }
|
||||||
|
ac_save_CFLAGS="$CFLAGS"
|
||||||
|
ac_save_LIBS="$LIBS"
|
||||||
|
CFLAGS="$CFLAGS $libsodium_cflags"
|
||||||
|
LIBS="$LIBS $libsodium_lib"
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
# include <sodium.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("%d", sodium_init());
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
if ac_fn_c_try_link "$LINENO"; then :
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }; $as_echo "#define HAVE_SODIUM 1" >>confdefs.h
|
||||||
|
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no; try installing libsodium-dev" >&5
|
||||||
|
$as_echo "no; try installing libsodium-dev" >&6; }; CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS"
|
||||||
|
fi
|
||||||
|
rm -f core conftest.err conftest.$ac_objext \
|
||||||
|
conftest$ac_exeext conftest.$ac_ext
|
||||||
|
fi
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for st_blksize" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for st_blksize" >&5
|
||||||
$as_echo_n "checking for st_blksize... " >&6; }
|
$as_echo_n "checking for st_blksize... " >&6; }
|
||||||
|
@@ -596,7 +596,8 @@ crypt_blowfish_encode(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *from,
|
char_u *from,
|
||||||
size_t len,
|
size_t len,
|
||||||
char_u *to)
|
char_u *to,
|
||||||
|
int last UNUSED)
|
||||||
{
|
{
|
||||||
bf_state_T *bfs = state->method_state;
|
bf_state_T *bfs = state->method_state;
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -619,7 +620,8 @@ crypt_blowfish_decode(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *from,
|
char_u *from,
|
||||||
size_t len,
|
size_t len,
|
||||||
char_u *to)
|
char_u *to,
|
||||||
|
int last UNUSED)
|
||||||
{
|
{
|
||||||
bf_state_T *bfs = state->method_state;
|
bf_state_T *bfs = state->method_state;
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -680,5 +682,4 @@ blowfish_self_test(void)
|
|||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FEAT_CRYPT
|
#endif // FEAT_CRYPT
|
||||||
|
@@ -30,6 +30,7 @@ struct bw_info
|
|||||||
int bw_flags; // FIO_ flags
|
int bw_flags; // FIO_ flags
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
buf_T *bw_buffer; // buffer being written
|
buf_T *bw_buffer; // buffer being written
|
||||||
|
int bw_finish; // finish encrypting
|
||||||
#endif
|
#endif
|
||||||
char_u bw_rest[CONV_RESTLEN]; // not converted bytes
|
char_u bw_rest[CONV_RESTLEN]; // not converted bytes
|
||||||
int bw_restlen; // nr of bytes in bw_rest[]
|
int bw_restlen; // nr of bytes in bw_rest[]
|
||||||
@@ -493,14 +494,14 @@ buf_write_bytes(struct bw_info *ip)
|
|||||||
if (crypt_works_inplace(ip->bw_buffer->b_cryptstate))
|
if (crypt_works_inplace(ip->bw_buffer->b_cryptstate))
|
||||||
{
|
{
|
||||||
# endif
|
# endif
|
||||||
crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len);
|
crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len, ip->bw_finish);
|
||||||
# ifdef CRYPT_NOT_INPLACE
|
# ifdef CRYPT_NOT_INPLACE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char_u *outbuf;
|
char_u *outbuf;
|
||||||
|
|
||||||
len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf);
|
len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf, ip->bw_finish);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return OK; // Crypt layer is buffering, will flush later.
|
return OK; // Crypt layer is buffering, will flush later.
|
||||||
wlen = write_eintr(ip->bw_fd, outbuf, len);
|
wlen = write_eintr(ip->bw_fd, outbuf, len);
|
||||||
@@ -724,6 +725,7 @@ buf_write(
|
|||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
write_info.bw_buffer = buf;
|
write_info.bw_buffer = buf;
|
||||||
|
write_info.bw_finish = FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// After writing a file changedtick changes but we don't want to display
|
// After writing a file changedtick changes but we don't want to display
|
||||||
@@ -2015,6 +2017,13 @@ restore_backup:
|
|||||||
++s;
|
++s;
|
||||||
if (++len != bufsize)
|
if (++len != bufsize)
|
||||||
continue;
|
continue;
|
||||||
|
#ifdef FEAT_CRYPT
|
||||||
|
if (write_info.bw_fd > 0 && lnum == end
|
||||||
|
&& (write_info.bw_flags & FIO_ENCRYPTED)
|
||||||
|
&& *buf->b_p_key != NUL && !filtering
|
||||||
|
&& *ptr == NUL)
|
||||||
|
write_info.bw_finish = TRUE;
|
||||||
|
#endif
|
||||||
if (buf_write_bytes(&write_info) == FAIL)
|
if (buf_write_bytes(&write_info) == FAIL)
|
||||||
{
|
{
|
||||||
end = 0; // write error: break loop
|
end = 0; // write error: break loop
|
||||||
@@ -2118,6 +2127,12 @@ restore_backup:
|
|||||||
if (len > 0 && end > 0)
|
if (len > 0 && end > 0)
|
||||||
{
|
{
|
||||||
write_info.bw_len = len;
|
write_info.bw_len = len;
|
||||||
|
#ifdef FEAT_CRYPT
|
||||||
|
if (write_info.bw_fd > 0 && lnum >= end
|
||||||
|
&& (write_info.bw_flags & FIO_ENCRYPTED)
|
||||||
|
&& *buf->b_p_key != NUL && !filtering)
|
||||||
|
write_info.bw_finish = TRUE;
|
||||||
|
#endif
|
||||||
if (buf_write_bytes(&write_info) == FAIL)
|
if (buf_write_bytes(&write_info) == FAIL)
|
||||||
end = 0; // write error
|
end = 0; // write error
|
||||||
nchars += len;
|
nchars += len;
|
||||||
|
@@ -208,6 +208,7 @@
|
|||||||
#undef HAVE_STRPTIME
|
#undef HAVE_STRPTIME
|
||||||
#undef HAVE_STRTOL
|
#undef HAVE_STRTOL
|
||||||
#undef HAVE_CANBERRA
|
#undef HAVE_CANBERRA
|
||||||
|
#undef HAVE_SODIUM
|
||||||
#undef HAVE_ST_BLKSIZE
|
#undef HAVE_ST_BLKSIZE
|
||||||
#undef HAVE_SYSCONF
|
#undef HAVE_SYSCONF
|
||||||
#undef HAVE_SYSCTL
|
#undef HAVE_SYSCTL
|
||||||
|
@@ -3767,6 +3767,43 @@ if test "$enable_canberra" = "yes"; then
|
|||||||
AC_MSG_RESULT(no; try installing libcanberra-dev); CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS")
|
AC_MSG_RESULT(no; try installing libcanberra-dev); CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(--enable-libsodium argument)
|
||||||
|
AC_ARG_ENABLE(libsodium,
|
||||||
|
[ --disable-libsodium Do not use libsodium.],
|
||||||
|
, [enable_libsodium="maybe"])
|
||||||
|
|
||||||
|
if test "$enable_libsodium" = "maybe"; then
|
||||||
|
if test "$features" = "big" -o "$features" = "huge"; then
|
||||||
|
AC_MSG_RESULT(Defaulting to yes)
|
||||||
|
enable_libsodium="yes"
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(Defaulting to no)
|
||||||
|
enable_libsodium="no"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT($enable_libsodium)
|
||||||
|
fi
|
||||||
|
if test "$enable_libsodium" = "yes"; then
|
||||||
|
if test "x$PKG_CONFIG" != "xno"; then
|
||||||
|
libsodium_lib=`$PKG_CONFIG --libs libsodium 2>/dev/null`
|
||||||
|
libsodium_cflags=`$PKG_CONFIG --cflags libsodium 2>/dev/null`
|
||||||
|
fi
|
||||||
|
if test "x$libsodium_lib" = "x"; then
|
||||||
|
libsodium_lib=-lsodium
|
||||||
|
libsodium_cflags=
|
||||||
|
fi
|
||||||
|
AC_MSG_CHECKING(for libcanberra)
|
||||||
|
ac_save_CFLAGS="$CFLAGS"
|
||||||
|
ac_save_LIBS="$LIBS"
|
||||||
|
CFLAGS="$CFLAGS $libsodium_cflags"
|
||||||
|
LIBS="$LIBS $libsodium_lib"
|
||||||
|
AC_TRY_LINK([
|
||||||
|
# include <sodium.h>
|
||||||
|
], [
|
||||||
|
printf("%d", sodium_init()); ],
|
||||||
|
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SODIUM),
|
||||||
|
AC_MSG_RESULT(no; try installing libsodium-dev); CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS")
|
||||||
|
fi
|
||||||
|
|
||||||
dnl fstatfs() can take 2 to 4 arguments, try to use st_blksize if possible
|
dnl fstatfs() can take 2 to 4 arguments, try to use st_blksize if possible
|
||||||
AC_MSG_CHECKING(for st_blksize)
|
AC_MSG_CHECKING(for st_blksize)
|
||||||
|
379
src/crypt.c
379
src/crypt.c
@@ -12,6 +12,10 @@
|
|||||||
*/
|
*/
|
||||||
#include "vim.h"
|
#include "vim.h"
|
||||||
|
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
# include <sodium.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(FEAT_CRYPT) || defined(PROTO)
|
#if defined(FEAT_CRYPT) || defined(PROTO)
|
||||||
/*
|
/*
|
||||||
* Optional encryption support.
|
* Optional encryption support.
|
||||||
@@ -33,7 +37,7 @@ typedef struct {
|
|||||||
char *name; // encryption name as used in 'cryptmethod'
|
char *name; // encryption name as used in 'cryptmethod'
|
||||||
char *magic; // magic bytes stored in file header
|
char *magic; // magic bytes stored in file header
|
||||||
int salt_len; // length of salt, or 0 when not using salt
|
int salt_len; // length of salt, or 0 when not using salt
|
||||||
int seed_len; // length of seed, or 0 when not using salt
|
int seed_len; // length of seed, or 0 when not using seed
|
||||||
#ifdef CRYPT_NOT_INPLACE
|
#ifdef CRYPT_NOT_INPLACE
|
||||||
int works_inplace; // encryption/decryption can be done in-place
|
int works_inplace; // encryption/decryption can be done in-place
|
||||||
#endif
|
#endif
|
||||||
@@ -49,16 +53,16 @@ typedef struct {
|
|||||||
// Function pointers for encoding/decoding from one buffer into another.
|
// Function pointers for encoding/decoding from one buffer into another.
|
||||||
// Optional, however, these or the _buffer ones should be configured.
|
// Optional, however, these or the _buffer ones should be configured.
|
||||||
void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len,
|
void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len,
|
||||||
char_u *to);
|
char_u *to, int last);
|
||||||
void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len,
|
void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len,
|
||||||
char_u *to);
|
char_u *to, int last);
|
||||||
|
|
||||||
// Function pointers for encoding and decoding, can buffer data if needed.
|
// Function pointers for encoding and decoding, can buffer data if needed.
|
||||||
// Optional (however, these or the above should be configured).
|
// Optional (however, these or the above should be configured).
|
||||||
long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
|
long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
|
||||||
char_u **newptr);
|
char_u **newptr, int last);
|
||||||
long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
|
long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
|
||||||
char_u **newptr);
|
char_u **newptr, int last);
|
||||||
|
|
||||||
// Function pointers for in-place encoding and decoding, used for
|
// Function pointers for in-place encoding and decoding, used for
|
||||||
// crypt_*_inplace(). "from" and "to" arguments will be equal.
|
// crypt_*_inplace(). "from" and "to" arguments will be equal.
|
||||||
@@ -68,9 +72,9 @@ typedef struct {
|
|||||||
// padding to files).
|
// padding to files).
|
||||||
// This method is used for swap and undo files which have a rigid format.
|
// This method is used for swap and undo files which have a rigid format.
|
||||||
void (*encode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
|
void (*encode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
|
||||||
char_u *p2);
|
char_u *p2, int last);
|
||||||
void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
|
void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
|
||||||
char_u *p2);
|
char_u *p2, int last);
|
||||||
} cryptmethod_T;
|
} cryptmethod_T;
|
||||||
|
|
||||||
// index is method_nr of cryptstate_T, CRYPT_M_*
|
// index is method_nr of cryptstate_T, CRYPT_M_*
|
||||||
@@ -126,10 +130,41 @@ static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
|
|||||||
crypt_blowfish_encode, crypt_blowfish_decode,
|
crypt_blowfish_encode, crypt_blowfish_decode,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// XChaCha20 using libsodium
|
||||||
|
{
|
||||||
|
"xchacha20",
|
||||||
|
"VimCrypt~04!",
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
crypto_pwhash_argon2id_SALTBYTES, // 16
|
||||||
|
#else
|
||||||
|
16,
|
||||||
|
#endif
|
||||||
|
8,
|
||||||
|
#ifdef CRYPT_NOT_INPLACE
|
||||||
|
FALSE,
|
||||||
|
#endif
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
crypt_sodium_init,
|
||||||
|
crypt_sodium_encode, crypt_sodium_decode,
|
||||||
|
crypt_sodium_buffer_encode, crypt_sodium_buffer_decode,
|
||||||
|
crypt_sodium_encode, crypt_sodium_decode,
|
||||||
|
},
|
||||||
|
|
||||||
// NOTE: when adding a new method, use some random bytes for the magic key,
|
// NOTE: when adding a new method, use some random bytes for the magic key,
|
||||||
// to avoid that a text file is recognized as encrypted.
|
// to avoid that a text file is recognized as encrypted.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
typedef struct {
|
||||||
|
size_t count;
|
||||||
|
unsigned char key[crypto_box_SEEDBYTES];
|
||||||
|
// 32, same as crypto_secretstream_xchacha20poly1305_KEYBYTES
|
||||||
|
crypto_secretstream_xchacha20poly1305_state
|
||||||
|
state;
|
||||||
|
} sodium_state_T;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CRYPT_MAGIC_LEN 12 // cannot change
|
#define CRYPT_MAGIC_LEN 12 // cannot change
|
||||||
static char crypt_magic_head[] = "VimCrypt~";
|
static char crypt_magic_head[] = "VimCrypt~";
|
||||||
|
|
||||||
@@ -365,9 +400,16 @@ crypt_create_for_writing(
|
|||||||
// TODO: Should this be crypt method specific? (Probably not worth
|
// TODO: Should this be crypt method specific? (Probably not worth
|
||||||
// it). sha2_seed is pretty bad for large amounts of entropy, so make
|
// it). sha2_seed is pretty bad for large amounts of entropy, so make
|
||||||
// that into something which is suitable for anything.
|
// that into something which is suitable for anything.
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
if (sodium_init() >= 0)
|
||||||
|
{
|
||||||
|
randombytes_buf(salt, salt_len);
|
||||||
|
randombytes_buf(seed, seed_len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
sha2_seed(salt, salt_len, seed, seed_len);
|
sha2_seed(salt, salt_len, seed, seed_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
state = crypt_create(method_nr, key, salt, salt_len, seed, seed_len);
|
state = crypt_create(method_nr, key, salt, salt_len, seed, seed_len);
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
VIM_CLEAR(*header);
|
VIM_CLEAR(*header);
|
||||||
@@ -380,6 +422,14 @@ crypt_create_for_writing(
|
|||||||
void
|
void
|
||||||
crypt_free_state(cryptstate_T *state)
|
crypt_free_state(cryptstate_T *state)
|
||||||
{
|
{
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
if (state->method_nr == CRYPT_M_SOD)
|
||||||
|
{
|
||||||
|
sodium_memzero(state->method_state, sizeof(sodium_state_T));
|
||||||
|
sodium_free(state->method_state);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
vim_free(state->method_state);
|
vim_free(state->method_state);
|
||||||
vim_free(state);
|
vim_free(state);
|
||||||
}
|
}
|
||||||
@@ -395,21 +445,22 @@ crypt_encode_alloc(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *from,
|
char_u *from,
|
||||||
size_t len,
|
size_t len,
|
||||||
char_u **newptr)
|
char_u **newptr,
|
||||||
|
int last)
|
||||||
{
|
{
|
||||||
cryptmethod_T *method = &cryptmethods[state->method_nr];
|
cryptmethod_T *method = &cryptmethods[state->method_nr];
|
||||||
|
|
||||||
if (method->encode_buffer_fn != NULL)
|
if (method->encode_buffer_fn != NULL)
|
||||||
// Has buffer function, pass through.
|
// Has buffer function, pass through.
|
||||||
return method->encode_buffer_fn(state, from, len, newptr);
|
return method->encode_buffer_fn(state, from, len, newptr, last);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
// Not buffering, just return EOF.
|
// Not buffering, just return EOF.
|
||||||
return (long)len;
|
return (long)len;
|
||||||
|
|
||||||
*newptr = alloc(len);
|
*newptr = alloc(len + 50);
|
||||||
if (*newptr == NULL)
|
if (*newptr == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
method->encode_fn(state, from, len, *newptr);
|
method->encode_fn(state, from, len, *newptr, last);
|
||||||
return (long)len;
|
return (long)len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,13 +474,14 @@ crypt_decode_alloc(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *ptr,
|
char_u *ptr,
|
||||||
long len,
|
long len,
|
||||||
char_u **newptr)
|
char_u **newptr,
|
||||||
|
int last)
|
||||||
{
|
{
|
||||||
cryptmethod_T *method = &cryptmethods[state->method_nr];
|
cryptmethod_T *method = &cryptmethods[state->method_nr];
|
||||||
|
|
||||||
if (method->decode_buffer_fn != NULL)
|
if (method->decode_buffer_fn != NULL)
|
||||||
// Has buffer function, pass through.
|
// Has buffer function, pass through.
|
||||||
return method->decode_buffer_fn(state, ptr, len, newptr);
|
return method->decode_buffer_fn(state, ptr, len, newptr, last);
|
||||||
|
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
// Not buffering, just return EOF.
|
// Not buffering, just return EOF.
|
||||||
@@ -438,7 +490,7 @@ crypt_decode_alloc(
|
|||||||
*newptr = alloc(len);
|
*newptr = alloc(len);
|
||||||
if (*newptr == NULL)
|
if (*newptr == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
method->decode_fn(state, ptr, len, *newptr);
|
method->decode_fn(state, ptr, len, *newptr, last);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -451,9 +503,10 @@ crypt_encode(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *from,
|
char_u *from,
|
||||||
size_t len,
|
size_t len,
|
||||||
char_u *to)
|
char_u *to,
|
||||||
|
int last)
|
||||||
{
|
{
|
||||||
cryptmethods[state->method_nr].encode_fn(state, from, len, to);
|
cryptmethods[state->method_nr].encode_fn(state, from, len, to, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // unused
|
#if 0 // unused
|
||||||
@@ -465,9 +518,10 @@ crypt_decode(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *from,
|
char_u *from,
|
||||||
size_t len,
|
size_t len,
|
||||||
char_u *to)
|
char_u *to,
|
||||||
|
int last)
|
||||||
{
|
{
|
||||||
cryptmethods[state->method_nr].decode_fn(state, from, len, to);
|
cryptmethods[state->method_nr].decode_fn(state, from, len, to, last);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -478,9 +532,11 @@ crypt_decode(
|
|||||||
crypt_encode_inplace(
|
crypt_encode_inplace(
|
||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *buf,
|
char_u *buf,
|
||||||
size_t len)
|
size_t len,
|
||||||
|
int last)
|
||||||
{
|
{
|
||||||
cryptmethods[state->method_nr].encode_inplace_fn(state, buf, len, buf);
|
cryptmethods[state->method_nr].encode_inplace_fn(state, buf, len,
|
||||||
|
buf, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -490,9 +546,11 @@ crypt_encode_inplace(
|
|||||||
crypt_decode_inplace(
|
crypt_decode_inplace(
|
||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *buf,
|
char_u *buf,
|
||||||
size_t len)
|
size_t len,
|
||||||
|
int last)
|
||||||
{
|
{
|
||||||
cryptmethods[state->method_nr].decode_inplace_fn(state, buf, len, buf);
|
cryptmethods[state->method_nr].decode_inplace_fn(state, buf, len,
|
||||||
|
buf, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -523,6 +581,19 @@ crypt_check_method(int method)
|
|||||||
msg_scroll = TRUE;
|
msg_scroll = TRUE;
|
||||||
msg(_("Warning: Using a weak encryption method; see :help 'cm'"));
|
msg(_("Warning: Using a weak encryption method; see :help 'cm'"));
|
||||||
}
|
}
|
||||||
|
if (method == CRYPT_M_SOD)
|
||||||
|
{
|
||||||
|
// encryption uses padding and MAC, that does not work very well with
|
||||||
|
// swap and undo files, so disable them
|
||||||
|
mf_close_file(curbuf, TRUE); // remove the swap file
|
||||||
|
set_option_value((char_u *)"swf", 0, NULL, OPT_LOCAL);
|
||||||
|
#ifdef FEAT_PERSISTENT_UNDO
|
||||||
|
set_option_value((char_u *)"udf", 0, NULL, OPT_LOCAL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
msg_scroll = TRUE;
|
||||||
|
msg(_("Note: Encryption of swapfile not supported, disabling swap- and undofile"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -610,4 +681,266 @@ crypt_append_msg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
crypt_sodium_init(
|
||||||
|
cryptstate_T *state UNUSED,
|
||||||
|
char_u *key UNUSED,
|
||||||
|
char_u *salt UNUSED,
|
||||||
|
int salt_len UNUSED,
|
||||||
|
char_u *seed UNUSED,
|
||||||
|
int seed_len UNUSED)
|
||||||
|
{
|
||||||
|
# ifdef FEAT_SODIUM
|
||||||
|
// crypto_box_SEEDBYTES == crypto_secretstream_xchacha20poly1305_KEYBYTES
|
||||||
|
unsigned char dkey[crypto_box_SEEDBYTES]; // 32
|
||||||
|
sodium_state_T *sd_state;
|
||||||
|
|
||||||
|
if (sodium_init() < 0)
|
||||||
|
return FAIL;
|
||||||
|
|
||||||
|
sd_state = (sodium_state_T *)sodium_malloc(sizeof(sodium_state_T));
|
||||||
|
sodium_memzero(sd_state, sizeof(sodium_state_T));
|
||||||
|
|
||||||
|
// derive a key from the password
|
||||||
|
if (crypto_pwhash(dkey, sizeof(dkey), (const char *)key, STRLEN(key), salt,
|
||||||
|
crypto_pwhash_OPSLIMIT_INTERACTIVE, crypto_pwhash_MEMLIMIT_INTERACTIVE,
|
||||||
|
crypto_pwhash_ALG_DEFAULT) != 0)
|
||||||
|
{
|
||||||
|
// out of memory
|
||||||
|
sodium_free(sd_state);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
memcpy(sd_state->key, dkey, crypto_box_SEEDBYTES);
|
||||||
|
sd_state->count = 0;
|
||||||
|
state->method_state = sd_state;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
# else
|
||||||
|
emsg(e_libsodium_not_built_in);
|
||||||
|
return FAIL;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encrypt "from[len]" into "to[len]".
|
||||||
|
* "from" and "to" can be equal to encrypt in place.
|
||||||
|
* Call needs to ensure that there is enough space in to (for the header)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
crypt_sodium_encode(
|
||||||
|
cryptstate_T *state UNUSED,
|
||||||
|
char_u *from UNUSED,
|
||||||
|
size_t len UNUSED,
|
||||||
|
char_u *to UNUSED,
|
||||||
|
int last UNUSED)
|
||||||
|
{
|
||||||
|
# ifdef FEAT_SODIUM
|
||||||
|
// crypto_box_SEEDBYTES == crypto_secretstream_xchacha20poly1305_KEYBYTES
|
||||||
|
sodium_state_T *sod_st = state->method_state;
|
||||||
|
unsigned char tag = last
|
||||||
|
? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0;
|
||||||
|
|
||||||
|
if (sod_st->count == 0)
|
||||||
|
{
|
||||||
|
if (len <= crypto_secretstream_xchacha20poly1305_HEADERBYTES)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_cannot_encrypt_header);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
crypto_secretstream_xchacha20poly1305_init_push(&sod_st->state,
|
||||||
|
to, sod_st->key);
|
||||||
|
to += crypto_secretstream_xchacha20poly1305_HEADERBYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sod_st->count && len <= crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_cannot_encrypt_buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_secretstream_xchacha20poly1305_push(&sod_st->state, to, NULL,
|
||||||
|
from, len, NULL, 0, tag);
|
||||||
|
|
||||||
|
sod_st->count++;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Unused
|
||||||
|
* Decrypt "from[len]" into "to[len]".
|
||||||
|
* "from" and "to" can be equal to encrypt in place.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
crypt_sodium_decode(
|
||||||
|
cryptstate_T *state UNUSED,
|
||||||
|
char_u *from UNUSED,
|
||||||
|
size_t len UNUSED,
|
||||||
|
char_u *to UNUSED,
|
||||||
|
int last UNUSED)
|
||||||
|
{
|
||||||
|
# ifdef FEAT_SODIUM
|
||||||
|
// crypto_box_SEEDBYTES == crypto_secretstream_xchacha20poly1305_KEYBYTES
|
||||||
|
sodium_state_T *sod_st = state->method_state;
|
||||||
|
unsigned char tag;
|
||||||
|
unsigned long long buf_len;
|
||||||
|
char_u *p1 = from;
|
||||||
|
char_u *p2 = to;
|
||||||
|
char_u *buf_out;
|
||||||
|
|
||||||
|
if (sod_st->count == 0
|
||||||
|
&& len <= crypto_secretstream_xchacha20poly1305_HEADERBYTES)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_cannot_decrypt_header);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_out = (char_u *)alloc(len);
|
||||||
|
|
||||||
|
if (buf_out == NULL)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_cannot_allocate_buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sod_st->count == 0)
|
||||||
|
{
|
||||||
|
if (crypto_secretstream_xchacha20poly1305_init_pull(
|
||||||
|
&sod_st->state, from, sod_st->key) != 0)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_decryption_failed_header_incomplete);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
from += crypto_secretstream_xchacha20poly1305_HEADERBYTES;
|
||||||
|
len -= crypto_secretstream_xchacha20poly1305_HEADERBYTES;
|
||||||
|
|
||||||
|
if (p1 == p2)
|
||||||
|
to += crypto_secretstream_xchacha20poly1305_HEADERBYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sod_st->count && len <= crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_cannot_decrypt_buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (crypto_secretstream_xchacha20poly1305_pull(&sod_st->state,
|
||||||
|
buf_out, &buf_len, &tag, from, len, NULL, 0) != 0)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_decription_failed);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
sod_st->count++;
|
||||||
|
|
||||||
|
if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL && !last)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_decyption_failed_premature);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (p1 == p2)
|
||||||
|
mch_memmove(p2, buf_out, buf_len);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
vim_free(buf_out);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encrypt "from[len]" into "to[len]".
|
||||||
|
* "from" and "to" can be equal to encrypt in place.
|
||||||
|
*/
|
||||||
|
long
|
||||||
|
crypt_sodium_buffer_encode(
|
||||||
|
cryptstate_T *state UNUSED,
|
||||||
|
char_u *from UNUSED,
|
||||||
|
size_t len UNUSED,
|
||||||
|
char_u **buf_out UNUSED,
|
||||||
|
int last UNUSED)
|
||||||
|
{
|
||||||
|
# ifdef FEAT_SODIUM
|
||||||
|
// crypto_box_SEEDBYTES == crypto_secretstream_xchacha20poly1305_KEYBYTES
|
||||||
|
unsigned long long out_len;
|
||||||
|
char_u *ptr;
|
||||||
|
unsigned char tag = last
|
||||||
|
? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0;
|
||||||
|
int length;
|
||||||
|
sodium_state_T *sod_st = state->method_state;
|
||||||
|
int first = (sod_st->count == 0);
|
||||||
|
|
||||||
|
length = len + crypto_secretstream_xchacha20poly1305_ABYTES
|
||||||
|
+ (first ? crypto_secretstream_xchacha20poly1305_HEADERBYTES : 0);
|
||||||
|
*buf_out = alloc_clear(length);
|
||||||
|
if (*buf_out == NULL)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_cannot_allocate_buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ptr = *buf_out;
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
crypto_secretstream_xchacha20poly1305_init_push(&sod_st->state,
|
||||||
|
ptr, sod_st->key);
|
||||||
|
ptr += crypto_secretstream_xchacha20poly1305_HEADERBYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
crypto_secretstream_xchacha20poly1305_push(&sod_st->state, ptr,
|
||||||
|
&out_len, from, len, NULL, 0, tag);
|
||||||
|
|
||||||
|
sod_st->count++;
|
||||||
|
return out_len + (first
|
||||||
|
? crypto_secretstream_xchacha20poly1305_HEADERBYTES : 0);
|
||||||
|
# else
|
||||||
|
return -1;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrypt "from[len]" into "to[len]".
|
||||||
|
* "from" and "to" can be equal to encrypt in place.
|
||||||
|
*/
|
||||||
|
long
|
||||||
|
crypt_sodium_buffer_decode(
|
||||||
|
cryptstate_T *state UNUSED,
|
||||||
|
char_u *from UNUSED,
|
||||||
|
size_t len UNUSED,
|
||||||
|
char_u **buf_out UNUSED,
|
||||||
|
int last UNUSED)
|
||||||
|
{
|
||||||
|
# ifdef FEAT_SODIUM
|
||||||
|
// crypto_box_SEEDBYTES == crypto_secretstream_xchacha20poly1305_KEYBYTES
|
||||||
|
sodium_state_T *sod_st = state->method_state;
|
||||||
|
unsigned char tag;
|
||||||
|
unsigned long long out_len;
|
||||||
|
*buf_out = alloc_clear(len);
|
||||||
|
if (*buf_out == NULL)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_cannot_allocate_buffer);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sod_st->count == 0)
|
||||||
|
{
|
||||||
|
if (crypto_secretstream_xchacha20poly1305_init_pull(&sod_st->state,
|
||||||
|
from, sod_st->key) != 0)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_decryption_failed_header_incomplete);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
from += crypto_secretstream_xchacha20poly1305_HEADERBYTES;
|
||||||
|
len -= crypto_secretstream_xchacha20poly1305_HEADERBYTES;
|
||||||
|
sod_st->count++;
|
||||||
|
}
|
||||||
|
if (crypto_secretstream_xchacha20poly1305_pull(&sod_st->state,
|
||||||
|
*buf_out, &out_len, &tag, from, len, NULL, 0) != 0)
|
||||||
|
{
|
||||||
|
emsg(e_libsodium_decription_failed);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL && !last)
|
||||||
|
emsg(e_libsodium_decyption_failed_premature);
|
||||||
|
return (long) out_len;
|
||||||
|
# else
|
||||||
|
return -1;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif // FEAT_CRYPT
|
#endif // FEAT_CRYPT
|
||||||
|
@@ -114,7 +114,8 @@ crypt_zip_encode(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *from,
|
char_u *from,
|
||||||
size_t len,
|
size_t len,
|
||||||
char_u *to)
|
char_u *to,
|
||||||
|
int last UNUSED)
|
||||||
{
|
{
|
||||||
zip_state_T *zs = state->method_state;
|
zip_state_T *zs = state->method_state;
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -137,7 +138,8 @@ crypt_zip_decode(
|
|||||||
cryptstate_T *state,
|
cryptstate_T *state,
|
||||||
char_u *from,
|
char_u *from,
|
||||||
size_t len,
|
size_t len,
|
||||||
char_u *to)
|
char_u *to,
|
||||||
|
int last UNUSED)
|
||||||
{
|
{
|
||||||
zip_state_T *zs = state->method_state;
|
zip_state_T *zs = state->method_state;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
19
src/errors.h
19
src/errors.h
@@ -427,3 +427,22 @@ EXTERN char e_call_to_function_that_failed_to_compile_str[]
|
|||||||
INIT(= N_("E1191: Call to function that failed to compile: %s"));
|
INIT(= N_("E1191: Call to function that failed to compile: %s"));
|
||||||
EXTERN char e_empty_function_name[]
|
EXTERN char e_empty_function_name[]
|
||||||
INIT(= N_("E1192: Empty function name"));
|
INIT(= N_("E1192: Empty function name"));
|
||||||
|
// libsodium
|
||||||
|
EXTERN char e_libsodium_not_built_in[]
|
||||||
|
INIT(= N_("E1193: cryptmethod xchacha20 not built into this Vim"));
|
||||||
|
EXTERN char e_libsodium_cannot_encrypt_header[]
|
||||||
|
INIT(= N_("E1194: Cannot encrypt header, not enough space"));
|
||||||
|
EXTERN char e_libsodium_cannot_encrypt_buffer[]
|
||||||
|
INIT(= N_("E1195: Cannot encrypt buffer, not enough space"));
|
||||||
|
EXTERN char e_libsodium_cannot_decrypt_header[]
|
||||||
|
INIT(= N_("E1196: Cannot decrypt header, not enough space"));
|
||||||
|
EXTERN char e_libsodium_cannot_allocate_buffer[]
|
||||||
|
INIT(= N_("E1197: Cannot allocate_buffer for encryption"));
|
||||||
|
EXTERN char e_libsodium_decryption_failed_header_incomplete[]
|
||||||
|
INIT(= N_("E1198: Decryption failed: Header incomplete!"));
|
||||||
|
EXTERN char e_libsodium_cannot_decrypt_buffer[]
|
||||||
|
INIT(= N_("E1199: Cannot decrypt buffer, not enough space"));
|
||||||
|
EXTERN char e_libsodium_decription_failed[]
|
||||||
|
INIT(= N_("E1200: Decryption failed: corrupted chunk!"));
|
||||||
|
EXTERN char e_libsodium_decyption_failed_premature[]
|
||||||
|
INIT(= N_("E1201: Decryption failed: pre-mature end of file!"));
|
||||||
|
@@ -5070,6 +5070,13 @@ f_has(typval_T *argvars, typval_T *rettv)
|
|||||||
1
|
1
|
||||||
#else
|
#else
|
||||||
0
|
0
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
{"sodium",
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
1
|
||||||
|
#else
|
||||||
|
0
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
{"sound",
|
{"sound",
|
||||||
|
@@ -593,6 +593,13 @@
|
|||||||
# define FEAT_SOUND_CANBERRA
|
# define FEAT_SOUND_CANBERRA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libsodium - add cryptography support
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_SODIUM) && defined(FEAT_BIG)
|
||||||
|
# define FEAT_SODIUM
|
||||||
|
#endif
|
||||||
|
|
||||||
// There are two ways to use XPM.
|
// There are two ways to use XPM.
|
||||||
#if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \
|
#if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \
|
||||||
|| defined(HAVE_X11_XPM_H)
|
|| defined(HAVE_X11_XPM_H)
|
||||||
|
40
src/fileio.c
40
src/fileio.c
@@ -13,6 +13,10 @@
|
|||||||
|
|
||||||
#include "vim.h"
|
#include "vim.h"
|
||||||
|
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
# include <sodium.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__TANDEM)
|
#if defined(__TANDEM)
|
||||||
# include <limits.h> // for SSIZE_MAX
|
# include <limits.h> // for SSIZE_MAX
|
||||||
#endif
|
#endif
|
||||||
@@ -148,6 +152,8 @@ readfile(
|
|||||||
char_u *p;
|
char_u *p;
|
||||||
off_T filesize = 0;
|
off_T filesize = 0;
|
||||||
int skip_read = FALSE;
|
int skip_read = FALSE;
|
||||||
|
off_T filesize_disk = 0; // file size read from disk
|
||||||
|
off_T filesize_count = 0; // counter
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
char_u *cryptkey = NULL;
|
char_u *cryptkey = NULL;
|
||||||
int did_ask_for_key = FALSE;
|
int did_ask_for_key = FALSE;
|
||||||
@@ -215,6 +221,7 @@ readfile(
|
|||||||
int using_b_ffname;
|
int using_b_ffname;
|
||||||
int using_b_fname;
|
int using_b_fname;
|
||||||
static char *msg_is_a_directory = N_("is a directory");
|
static char *msg_is_a_directory = N_("is a directory");
|
||||||
|
int eof;
|
||||||
|
|
||||||
au_did_filetype = FALSE; // reset before triggering any autocommands
|
au_did_filetype = FALSE; // reset before triggering any autocommands
|
||||||
|
|
||||||
@@ -405,6 +412,7 @@ readfile(
|
|||||||
{
|
{
|
||||||
buf_store_time(curbuf, &st, fname);
|
buf_store_time(curbuf, &st, fname);
|
||||||
curbuf->b_mtime_read = curbuf->b_mtime;
|
curbuf->b_mtime_read = curbuf->b_mtime;
|
||||||
|
filesize_disk = st.st_size;
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
/*
|
/*
|
||||||
* Use the protection bits of the original file for the swap file.
|
* Use the protection bits of the original file for the swap file.
|
||||||
@@ -1080,6 +1088,7 @@ retry:
|
|||||||
{
|
{
|
||||||
linerest = 0;
|
linerest = 0;
|
||||||
filesize = 0;
|
filesize = 0;
|
||||||
|
filesize_count = 0;
|
||||||
skip_count = lines_to_skip;
|
skip_count = lines_to_skip;
|
||||||
read_count = lines_to_read;
|
read_count = lines_to_read;
|
||||||
conv_restlen = 0;
|
conv_restlen = 0;
|
||||||
@@ -1263,7 +1272,23 @@ retry:
|
|||||||
/*
|
/*
|
||||||
* Read bytes from the file.
|
* 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);
|
size = read_eintr(fd, ptr, size);
|
||||||
|
filesize_count += size;
|
||||||
|
// hit end of file
|
||||||
|
eof = (size < eof || filesize_count == filesize_disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
@@ -1285,7 +1310,8 @@ retry:
|
|||||||
if (crypt_works_inplace(curbuf->b_cryptstate))
|
if (crypt_works_inplace(curbuf->b_cryptstate))
|
||||||
{
|
{
|
||||||
# endif
|
# endif
|
||||||
crypt_decode_inplace(curbuf->b_cryptstate, ptr, size);
|
crypt_decode_inplace(curbuf->b_cryptstate, ptr,
|
||||||
|
size, eof);
|
||||||
# ifdef CRYPT_NOT_INPLACE
|
# ifdef CRYPT_NOT_INPLACE
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1294,8 +1320,16 @@ retry:
|
|||||||
int decrypted_size;
|
int decrypted_size;
|
||||||
|
|
||||||
decrypted_size = crypt_decode_alloc(
|
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
|
// If the crypt layer is buffering, not producing
|
||||||
// anything yet, need to read more.
|
// anything yet, need to read more.
|
||||||
if (decrypted_size == 0)
|
if (decrypted_size == 0)
|
||||||
@@ -1325,6 +1359,7 @@ retry:
|
|||||||
if (newptr != NULL)
|
if (newptr != NULL)
|
||||||
mch_memmove(new_buffer + linerest, newptr,
|
mch_memmove(new_buffer + linerest, newptr,
|
||||||
decrypted_size);
|
decrypted_size);
|
||||||
|
vim_free(newptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_buffer != NULL)
|
if (new_buffer != NULL)
|
||||||
@@ -1334,6 +1369,7 @@ retry:
|
|||||||
new_buffer = NULL;
|
new_buffer = NULL;
|
||||||
line_start = buffer;
|
line_start = buffer;
|
||||||
ptr = buffer + linerest;
|
ptr = buffer + linerest;
|
||||||
|
real_size = size;
|
||||||
}
|
}
|
||||||
size = decrypted_size;
|
size = decrypted_size;
|
||||||
}
|
}
|
||||||
|
@@ -48,6 +48,11 @@
|
|||||||
# include <time.h>
|
# include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// for randombytes_buf
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
# include <sodium.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SASC) || defined(__amigaos4__)
|
#if defined(SASC) || defined(__amigaos4__)
|
||||||
# include <proto/dos.h> // for Open() and Close()
|
# include <proto/dos.h> // for Open() and Close()
|
||||||
#endif
|
#endif
|
||||||
@@ -64,12 +69,14 @@ typedef struct pointer_entry PTR_EN; // block/line-count pair
|
|||||||
#define BLOCK0_ID1_C0 'c' // block 0 id 1 'cm' 0
|
#define BLOCK0_ID1_C0 'c' // block 0 id 1 'cm' 0
|
||||||
#define BLOCK0_ID1_C1 'C' // block 0 id 1 'cm' 1
|
#define BLOCK0_ID1_C1 'C' // block 0 id 1 'cm' 1
|
||||||
#define BLOCK0_ID1_C2 'd' // block 0 id 1 'cm' 2
|
#define BLOCK0_ID1_C2 'd' // block 0 id 1 'cm' 2
|
||||||
|
#define BLOCK0_ID1_C3 'S' // block 0 id 1 'cm' 3 - but not actually used
|
||||||
|
|
||||||
#if defined(FEAT_CRYPT)
|
#if defined(FEAT_CRYPT)
|
||||||
static int id1_codes[] = {
|
static int id1_codes[] = {
|
||||||
BLOCK0_ID1_C0, // CRYPT_M_ZIP
|
BLOCK0_ID1_C0, // CRYPT_M_ZIP
|
||||||
BLOCK0_ID1_C1, // CRYPT_M_BF
|
BLOCK0_ID1_C1, // CRYPT_M_BF
|
||||||
BLOCK0_ID1_C2, // CRYPT_M_BF2
|
BLOCK0_ID1_C2, // CRYPT_M_BF2
|
||||||
|
BLOCK0_ID1_C3, // CRYPT_M_SOD - Unused!
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -426,11 +433,15 @@ ml_set_mfp_crypt(buf_T *buf)
|
|||||||
{
|
{
|
||||||
int method_nr = crypt_get_method_nr(buf);
|
int method_nr = crypt_get_method_nr(buf);
|
||||||
|
|
||||||
if (method_nr > CRYPT_M_ZIP)
|
if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD)
|
||||||
{
|
{
|
||||||
// Generate a seed and store it in the memfile.
|
// Generate a seed and store it in the memfile.
|
||||||
sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
|
sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
|
||||||
}
|
}
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
else if (method_nr == CRYPT_M_SOD)
|
||||||
|
randombytes_buf(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,7 +458,7 @@ ml_set_b0_crypt(buf_T *buf, ZERO_BL *b0p)
|
|||||||
int method_nr = crypt_get_method_nr(buf);
|
int method_nr = crypt_get_method_nr(buf);
|
||||||
|
|
||||||
b0p->b0_id[1] = id1_codes[method_nr];
|
b0p->b0_id[1] = id1_codes[method_nr];
|
||||||
if (method_nr > CRYPT_M_ZIP)
|
if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD)
|
||||||
{
|
{
|
||||||
// Generate a seed and store it in block 0 and in the memfile.
|
// Generate a seed and store it in block 0 and in the memfile.
|
||||||
sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
|
sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
|
||||||
@@ -482,10 +493,17 @@ ml_set_crypt_key(
|
|||||||
int top;
|
int top;
|
||||||
int old_method;
|
int old_method;
|
||||||
|
|
||||||
if (mfp == NULL)
|
if (mfp == NULL || mfp->mf_fd < 0)
|
||||||
return; // no memfile yet, nothing to do
|
return; // no memfile yet, nothing to do
|
||||||
old_method = crypt_method_nr_from_name(old_cm);
|
old_method = crypt_method_nr_from_name(old_cm);
|
||||||
|
|
||||||
|
if (old_method == CRYPT_M_SOD || crypt_get_method_nr(buf) == CRYPT_M_SOD)
|
||||||
|
{
|
||||||
|
// close the swapfile
|
||||||
|
mf_close_file(buf, TRUE);
|
||||||
|
buf->b_p_swf = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// First make sure the swapfile is in a consistent state, using the old
|
// First make sure the swapfile is in a consistent state, using the old
|
||||||
// key and method.
|
// key and method.
|
||||||
{
|
{
|
||||||
@@ -911,7 +929,8 @@ ml_check_b0_id(ZERO_BL *b0p)
|
|||||||
|| (b0p->b0_id[1] != BLOCK0_ID1
|
|| (b0p->b0_id[1] != BLOCK0_ID1
|
||||||
&& b0p->b0_id[1] != BLOCK0_ID1_C0
|
&& b0p->b0_id[1] != BLOCK0_ID1_C0
|
||||||
&& b0p->b0_id[1] != BLOCK0_ID1_C1
|
&& b0p->b0_id[1] != BLOCK0_ID1_C1
|
||||||
&& b0p->b0_id[1] != BLOCK0_ID1_C2)
|
&& b0p->b0_id[1] != BLOCK0_ID1_C2
|
||||||
|
&& b0p->b0_id[1] != BLOCK0_ID1_C3)
|
||||||
)
|
)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
return OK;
|
return OK;
|
||||||
@@ -2402,7 +2421,9 @@ ml_sync_all(int check_file, int check_char)
|
|||||||
|
|
||||||
FOR_ALL_BUFFERS(buf)
|
FOR_ALL_BUFFERS(buf)
|
||||||
{
|
{
|
||||||
if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL)
|
if (buf->b_ml.ml_mfp == NULL
|
||||||
|
|| buf->b_ml.ml_mfp->mf_fname == NULL
|
||||||
|
|| buf->b_ml.ml_mfp->mf_fd < 0)
|
||||||
continue; // no file
|
continue; // no file
|
||||||
|
|
||||||
ml_flush_line(buf); // flush buffered line
|
ml_flush_line(buf); // flush buffered line
|
||||||
@@ -5320,7 +5341,8 @@ ml_encrypt_data(
|
|||||||
mch_memmove(new_data, dp, head_end - (char_u *)dp);
|
mch_memmove(new_data, dp, head_end - (char_u *)dp);
|
||||||
|
|
||||||
// Encrypt the text.
|
// Encrypt the text.
|
||||||
crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start);
|
crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start,
|
||||||
|
FALSE);
|
||||||
crypt_free_state(state);
|
crypt_free_state(state);
|
||||||
|
|
||||||
// Clear the gap.
|
// Clear the gap.
|
||||||
@@ -5360,7 +5382,7 @@ ml_decrypt_data(
|
|||||||
if (state != NULL)
|
if (state != NULL)
|
||||||
{
|
{
|
||||||
// Decrypt the text in place.
|
// Decrypt the text in place.
|
||||||
crypt_decode_inplace(state, text_start, text_len);
|
crypt_decode_inplace(state, text_start, text_len, FALSE);
|
||||||
crypt_free_state(state);
|
crypt_free_state(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2713,6 +2713,10 @@ set_bool_option(
|
|||||||
|| (opt_flags & OPT_GLOBAL) || opt_flags == 0)
|
|| (opt_flags & OPT_GLOBAL) || opt_flags == 0)
|
||||||
&& !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
|
&& !curbufIsChanged() && curbuf->b_ml.ml_mfp != NULL)
|
||||||
{
|
{
|
||||||
|
#ifdef FEAT_CRYPT
|
||||||
|
if (crypt_get_method_nr(curbuf) == CRYPT_M_SOD)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
u_compute_hash(hash);
|
u_compute_hash(hash);
|
||||||
u_read_undo(NULL, hash, curbuf->b_fname);
|
u_read_undo(NULL, hash, curbuf->b_fname);
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,11 @@ static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete",
|
|||||||
static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL};
|
static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL};
|
||||||
static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
|
static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL};
|
static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2",
|
||||||
|
# ifdef FEAT_SODIUM
|
||||||
|
"xchacha20",
|
||||||
|
# endif
|
||||||
|
NULL};
|
||||||
#endif
|
#endif
|
||||||
static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
|
static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
|
||||||
static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL};
|
static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL};
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* blowfish.c */
|
/* blowfish.c */
|
||||||
void crypt_blowfish_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to);
|
void crypt_blowfish_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
|
||||||
void crypt_blowfish_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to);
|
void crypt_blowfish_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
|
||||||
int crypt_blowfish_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
|
int crypt_blowfish_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
|
||||||
int blowfish_self_test(void);
|
int blowfish_self_test(void);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* crypt.c */
|
/* crypt.c */
|
||||||
int crypt_method_nr_from_name(char_u *name);
|
int crypt_method_nr_from_name(char_u *name);
|
||||||
int crypt_method_nr_from_magic(char *ptr, int len);
|
int crypt_method_nr_from_magic(char *ptr, int len);
|
||||||
|
int crypt_works_inplace(cryptstate_T *state);
|
||||||
int crypt_get_method_nr(buf_T *buf);
|
int crypt_get_method_nr(buf_T *buf);
|
||||||
int crypt_whole_undofile(int method_nr);
|
int crypt_whole_undofile(int method_nr);
|
||||||
int crypt_get_header_len(int method_nr);
|
int crypt_get_header_len(int method_nr);
|
||||||
@@ -11,12 +12,19 @@ cryptstate_T *crypt_create_from_header(int method_nr, char_u *key, char_u *heade
|
|||||||
cryptstate_T *crypt_create_from_file(FILE *fp, char_u *key);
|
cryptstate_T *crypt_create_from_file(FILE *fp, char_u *key);
|
||||||
cryptstate_T *crypt_create_for_writing(int method_nr, char_u *key, char_u **header, int *header_len);
|
cryptstate_T *crypt_create_for_writing(int method_nr, char_u *key, char_u **header, int *header_len);
|
||||||
void crypt_free_state(cryptstate_T *state);
|
void crypt_free_state(cryptstate_T *state);
|
||||||
void crypt_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to);
|
long crypt_encode_alloc(cryptstate_T *state, char_u *from, size_t len, char_u **newptr, int last);
|
||||||
void crypt_encode_inplace(cryptstate_T *state, char_u *buf, size_t len);
|
long crypt_decode_alloc(cryptstate_T *state, char_u *ptr, long len, char_u **newptr, int last);
|
||||||
void crypt_decode_inplace(cryptstate_T *state, char_u *buf, size_t len);
|
void crypt_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
|
||||||
|
void crypt_encode_inplace(cryptstate_T *state, char_u *buf, size_t len, int last);
|
||||||
|
void crypt_decode_inplace(cryptstate_T *state, char_u *buf, size_t len, int last);
|
||||||
void crypt_free_key(char_u *key);
|
void crypt_free_key(char_u *key);
|
||||||
void crypt_check_method(int method);
|
void crypt_check_method(int method);
|
||||||
void crypt_check_current_method(void);
|
void crypt_check_current_method(void);
|
||||||
char_u *crypt_get_key(int store, int twice);
|
char_u *crypt_get_key(int store, int twice);
|
||||||
void crypt_append_msg(buf_T *buf);
|
void crypt_append_msg(buf_T *buf);
|
||||||
|
int crypt_sodium_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
|
||||||
|
void crypt_sodium_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
|
||||||
|
void crypt_sodium_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
|
||||||
|
long crypt_sodium_buffer_encode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
|
||||||
|
long crypt_sodium_buffer_decode(cryptstate_T *state, char_u *from, size_t len, char_u **buf_out, int last);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* crypt_zip.c */
|
/* crypt_zip.c */
|
||||||
int crypt_zip_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
|
int crypt_zip_init(cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len);
|
||||||
void crypt_zip_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to);
|
void crypt_zip_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
|
||||||
void crypt_zip_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to);
|
void crypt_zip_decode(cryptstate_T *state, char_u *from, size_t len, char_u *to, int last);
|
||||||
/* vim: set ft=c : */
|
/* vim: set ft=c : */
|
||||||
|
@@ -2513,11 +2513,12 @@ typedef struct {
|
|||||||
# define CRYPT_M_ZIP 0
|
# define CRYPT_M_ZIP 0
|
||||||
# define CRYPT_M_BF 1
|
# define CRYPT_M_BF 1
|
||||||
# define CRYPT_M_BF2 2
|
# define CRYPT_M_BF2 2
|
||||||
# define CRYPT_M_COUNT 3 // number of crypt methods
|
# define CRYPT_M_SOD 3
|
||||||
|
# define CRYPT_M_COUNT 4 // number of crypt methods
|
||||||
|
|
||||||
// Currently all crypt methods work inplace. If one is added that isn't then
|
// Currently all crypt methods work inplace. If one is added that isn't then
|
||||||
// define this.
|
// define this.
|
||||||
// # define CRYPT_NOT_INPLACE 1
|
# define CRYPT_NOT_INPLACE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_PROP_POPUP
|
#ifdef FEAT_PROP_POPUP
|
||||||
|
BIN
src/testdir/samples/crypt_sodium_invalid.txt
Normal file
BIN
src/testdir/samples/crypt_sodium_invalid.txt
Normal file
Binary file not shown.
@@ -22,6 +22,11 @@ func Test_head_only_3()
|
|||||||
call Common_head_only('VimCrypt~03!abc')
|
call Common_head_only('VimCrypt~03!abc')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_head_only_4()
|
||||||
|
CheckFeature sodium
|
||||||
|
call Common_head_only('VimCrypt~04!abc')
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Crypt_uncrypt(method)
|
func Crypt_uncrypt(method)
|
||||||
exe "set cryptmethod=" . a:method
|
exe "set cryptmethod=" . a:method
|
||||||
" If the blowfish test fails 'cryptmethod' will be 'zip' now.
|
" If the blowfish test fails 'cryptmethod' will be 'zip' now.
|
||||||
@@ -55,6 +60,11 @@ func Test_crypt_blowfish2()
|
|||||||
call Crypt_uncrypt('blowfish2')
|
call Crypt_uncrypt('blowfish2')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_crypt_sodium()
|
||||||
|
CheckFeature sodium
|
||||||
|
call Crypt_uncrypt('xchacha20')
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Uncrypt_stable(method, crypted_text, key, uncrypted_text)
|
func Uncrypt_stable(method, crypted_text, key, uncrypted_text)
|
||||||
split Xtest.txt
|
split Xtest.txt
|
||||||
set bin noeol key= fenc=latin1
|
set bin noeol key= fenc=latin1
|
||||||
@@ -70,6 +80,16 @@ func Uncrypt_stable(method, crypted_text, key, uncrypted_text)
|
|||||||
set key=
|
set key=
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Uncrypt_stable_xxd(method, hex, key, uncrypted_text)
|
||||||
|
" use xxd to write the binary content
|
||||||
|
call system('xxd -r >Xtest.txt', a:hex)
|
||||||
|
call feedkeys(":split Xtest.txt\<CR>" . a:key . "\<CR>", 'xt')
|
||||||
|
call assert_equal(a:uncrypted_text, getline(1, len(a:uncrypted_text)))
|
||||||
|
bwipe!
|
||||||
|
call delete('Xtest.txt')
|
||||||
|
set key=
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_uncrypt_zip()
|
func Test_uncrypt_zip()
|
||||||
call Uncrypt_stable('zip', "VimCrypt~01!\u0006\u001clV'\u00de}Mg\u00a0\u00ea\u00a3V\u00a9\u00e7\u0007E#3\u008e2U\u00e9\u0097", "foofoo", ["1234567890", "aábbccddeëff"])
|
call Uncrypt_stable('zip', "VimCrypt~01!\u0006\u001clV'\u00de}Mg\u00a0\u00ea\u00a3V\u00a9\u00e7\u0007E#3\u008e2U\u00e9\u0097", "foofoo", ["1234567890", "aábbccddeëff"])
|
||||||
endfunc
|
endfunc
|
||||||
@@ -78,10 +98,115 @@ func Test_uncrypt_blowfish()
|
|||||||
call Uncrypt_stable('blowfish', "VimCrypt~02!k)\u00be\u0017\u0097#\u0016\u00ddS\u009c\u00f5=\u00ba\u00e0\u00c8#\u00a5M\u00b4\u0086J\u00c3A\u00cd\u00a5M\u00b4\u0086!\u0080\u0015\u009b\u00f5\u000f\u00e1\u00d2\u0019\u0082\u0016\u0098\u00f7\u000d\u00da", "barbar", ["asdfasdfasdf", "0001112223333"])
|
call Uncrypt_stable('blowfish', "VimCrypt~02!k)\u00be\u0017\u0097#\u0016\u00ddS\u009c\u00f5=\u00ba\u00e0\u00c8#\u00a5M\u00b4\u0086J\u00c3A\u00cd\u00a5M\u00b4\u0086!\u0080\u0015\u009b\u00f5\u000f\u00e1\u00d2\u0019\u0082\u0016\u0098\u00f7\u000d\u00da", "barbar", ["asdfasdfasdf", "0001112223333"])
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_uncrypt_blowfish2()
|
func Test_uncrypt_blowfish2a()
|
||||||
call Uncrypt_stable('blowfish', "VimCrypt~03!\u001e\u00d1N\u00e3;\u00d3\u00c0\u00a0^C)\u0004\u00f7\u007f.\u00b6\u00abF\u000eS\u0019\u00e0\u008b6\u00d2[T\u00cb\u00a7\u0085\u00d8\u00be9\u000b\u00812\u000bQ\u00b3\u00cc@\u0097\u000f\u00df\u009a\u00adIv\u00aa.\u00d8\u00c9\u00ee\u009e`\u00bd$\u00af%\u00d0", "barburp", ["abcdefghijklmnopqrstuvwxyz", "!@#$%^&*()_+=-`~"])
|
call Uncrypt_stable('blowfish', "VimCrypt~03!\u001e\u00d1N\u00e3;\u00d3\u00c0\u00a0^C)\u0004\u00f7\u007f.\u00b6\u00abF\u000eS\u0019\u00e0\u008b6\u00d2[T\u00cb\u00a7\u0085\u00d8\u00be9\u000b\u00812\u000bQ\u00b3\u00cc@\u0097\u000f\u00df\u009a\u00adIv\u00aa.\u00d8\u00c9\u00ee\u009e`\u00bd$\u00af%\u00d0", "barburp", ["abcdefghijklmnopqrstuvwxyz", "!@#$%^&*()_+=-`~"])
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_uncrypt_blowfish2()
|
||||||
|
call Uncrypt_stable('blowfish2', "VimCrypt~03!\u001e\u00d1N\u00e3;\u00d3\u00c0\u00a0^C)\u0004\u00f7\u007f.\u00b6\u00abF\u000eS\u0019\u00e0\u008b6\u00d2[T\u00cb\u00a7\u0085\u00d8\u00be9\u000b\u00812\u000bQ\u00b3\u00cc@\u0097\u000f\u00df\u009a\u00adIv\u00aa.\u00d8\u00c9\u00ee\u009e`\u00bd$\u00af%\u00d0", "barburp", ["abcdefghijklmnopqrstuvwxyz", "!@#$%^&*()_+=-`~"])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_uncrypt_xchacha20()
|
||||||
|
CheckFeature sodium
|
||||||
|
let hex=['00000000: 5669 6d43 7279 7074 7e30 3421 6b7d e607 vimCrypt~04!k}..',
|
||||||
|
\ '00000010: 4ea4 e99f 923e f67f 7b59 a80d 3bca 2f06 N....>..{Y..;./.',
|
||||||
|
\ '00000020: fa11 b951 8d09 0dc9 470f e7cf 8b90 4310 ...Q....G.....C.',
|
||||||
|
\ '00000030: 653b b83b e493 378b 0390 0e38 f912 626b e;.;..7....8..bk',
|
||||||
|
\ '00000040: a02e 4697 0254 2625 2d8e 3a0b 784b e89c ..F..T&%-.:.xK..',
|
||||||
|
\ '00000050: 0c67 a975 3c17 9319 8ffd 1463 7783 a1f3 .g.u<......cw...',
|
||||||
|
\ '00000060: d917 dcb3 8b3e ecd7 c7d4 086b 6059 7ead .....>.....k`Y~.',
|
||||||
|
\ '00000070: 9b07 f96b 5c1b 4d08 cd91 f208 5221 7484 ...k\.M.....R!t.',
|
||||||
|
\ '00000080: 72be 0136 84a1 d3 r..6...']
|
||||||
|
" the file should be in latin1 encoding, this makes sure that readfile()
|
||||||
|
" retries several times converting the multi-byte characters
|
||||||
|
call Uncrypt_stable_xxd('xchacha20', hex, "sodium_crypt", ["abcdefghijklmnopqrstuvwxyzäöü", "ZZZ_äüöÄÜÖ_!@#$%^&*()_+=-`~"])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_uncrypt_xchacha20_invalid()
|
||||||
|
CheckFeature sodium
|
||||||
|
" load an invalid encrypted file and verify it can be decrypted with an
|
||||||
|
" error message
|
||||||
|
try
|
||||||
|
call feedkeys(":split samples/crypt_sodium_invalid.txt\<CR>sodium\<CR>", 'xt')
|
||||||
|
call assert_false(1, 'should not happen')
|
||||||
|
catch
|
||||||
|
call assert_exception('pre-mature')
|
||||||
|
endtry
|
||||||
|
call assert_match("Note: Encryption of swapfile not supported, disabling swap- and undofile", execute(':5messages'))
|
||||||
|
|
||||||
|
call assert_equal(0, &swapfile)
|
||||||
|
call assert_equal("xchacha20", &cryptmethod)
|
||||||
|
call assert_equal('311111111111111111111111', getline('$'))
|
||||||
|
bw!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_uncrypt_xchacha20_2()
|
||||||
|
CheckFeature sodium
|
||||||
|
sp Xcrypt_sodium.txt
|
||||||
|
" Create a larger file, so that Vim will write in several blocks
|
||||||
|
call setline(1, range(1,4000))
|
||||||
|
call assert_equal(1, &swapfile)
|
||||||
|
set cryptmethod=xchacha20
|
||||||
|
call feedkeys(":X\<CR>sodium\<CR>sodium\<CR>", 'xt')
|
||||||
|
" swapfile disabled
|
||||||
|
call assert_equal(0, &swapfile)
|
||||||
|
call assert_match("Note: Encryption of swapfile not supported, disabling swap- and undofile", execute(':messages'))
|
||||||
|
w!
|
||||||
|
" encrypted using xchacha20
|
||||||
|
call assert_match("\[xchacha20\]", execute(':messages'))
|
||||||
|
bw!
|
||||||
|
call feedkeys(":sp Xcrypt_sodium.txt\<CR>sodium\<CR>", 'xt')
|
||||||
|
" successfully decrypted
|
||||||
|
call assert_equal(range(1, 4000)->map( {_, v -> string(v)}), getline(1,'$'))
|
||||||
|
set key=
|
||||||
|
w!
|
||||||
|
" enryption removed
|
||||||
|
call assert_match('"Xcrypt_sodium.txt" 4000L, 18893B written', execute(':message'))
|
||||||
|
bw!
|
||||||
|
call delete('Xcrypt_sodium.txt')
|
||||||
|
set cryptmethod&vim
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_uncrypt_xchacha20_3_persistent_undo()
|
||||||
|
CheckFeature sodium
|
||||||
|
CheckFeature persistent_undo
|
||||||
|
sp Xcrypt_sodium_undo.txt
|
||||||
|
set cryptmethod=xchacha20 undofile
|
||||||
|
call feedkeys(":X\<CR>sodium\<CR>sodium\<CR>", 'xt')
|
||||||
|
call assert_equal(0, &undofile)
|
||||||
|
let ufile=undofile(@%)
|
||||||
|
call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
|
||||||
|
call cursor(1, 1)
|
||||||
|
|
||||||
|
set undolevels=100
|
||||||
|
normal dd
|
||||||
|
set undolevels=100
|
||||||
|
normal dd
|
||||||
|
set undolevels=100
|
||||||
|
normal dd
|
||||||
|
set undolevels=100
|
||||||
|
w!
|
||||||
|
bw!
|
||||||
|
call feedkeys(":sp Xcrypt_sodium_undo.txt\<CR>sodium\<CR>", 'xt')
|
||||||
|
" should fail
|
||||||
|
norm! u
|
||||||
|
call assert_match('Already at oldest change', execute(':1mess'))
|
||||||
|
call assert_fails('verbose rundo' .. fnameescape(ufile), 'E822')
|
||||||
|
bw!
|
||||||
|
set undolevels& cryptmethod& undofile&
|
||||||
|
call delete('Xcrypt_sodium_undo.txt')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_encrypt_xchacha20_missing()
|
||||||
|
if has("sodium")
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
sp Xcrypt_sodium_undo.txt
|
||||||
|
call assert_fails(':set cryptmethod=xchacha20', 'E474')
|
||||||
|
bw!
|
||||||
|
set cm&
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_uncrypt_unknown_method()
|
func Test_uncrypt_unknown_method()
|
||||||
split Xuncrypt_unknown.txt
|
split Xuncrypt_unknown.txt
|
||||||
set bin noeol key= fenc=latin1
|
set bin noeol key= fenc=latin1
|
||||||
|
12
src/undo.c
12
src/undo.c
@@ -963,7 +963,9 @@ undo_flush(bufinfo_T *bi)
|
|||||||
{
|
{
|
||||||
if (bi->bi_buffer != NULL && bi->bi_state != NULL && bi->bi_used > 0)
|
if (bi->bi_buffer != NULL && bi->bi_state != NULL && bi->bi_used > 0)
|
||||||
{
|
{
|
||||||
crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used);
|
// Last parameter is only used for sodium encryption and that
|
||||||
|
// explicitly disables encryption of undofiles.
|
||||||
|
crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used, FALSE);
|
||||||
if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1)
|
if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
bi->bi_used = 0;
|
bi->bi_used = 0;
|
||||||
@@ -995,7 +997,9 @@ fwrite_crypt(bufinfo_T *bi, char_u *ptr, size_t len)
|
|||||||
if (copy == NULL)
|
if (copy == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
crypt_encode(bi->bi_state, ptr, len, copy);
|
// Last parameter is only used for sodium encryption and that
|
||||||
|
// explicitly disables encryption of undofiles.
|
||||||
|
crypt_encode(bi->bi_state, ptr, len, copy, TRUE);
|
||||||
i = fwrite(copy, len, (size_t)1, bi->bi_fp);
|
i = fwrite(copy, len, (size_t)1, bi->bi_fp);
|
||||||
if (copy != small_buf)
|
if (copy != small_buf)
|
||||||
vim_free(copy);
|
vim_free(copy);
|
||||||
@@ -1129,7 +1133,7 @@ undo_read(bufinfo_T *bi, char_u *buffer, size_t size)
|
|||||||
}
|
}
|
||||||
bi->bi_avail = n;
|
bi->bi_avail = n;
|
||||||
bi->bi_used = 0;
|
bi->bi_used = 0;
|
||||||
crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail);
|
crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail, FALSE);
|
||||||
}
|
}
|
||||||
n = size_todo;
|
n = size_todo;
|
||||||
if (n > bi->bi_avail - bi->bi_used)
|
if (n > bi->bi_avail - bi->bi_used)
|
||||||
@@ -1176,7 +1180,7 @@ read_string_decrypt(bufinfo_T *bi, int len)
|
|||||||
ptr[len] = NUL;
|
ptr[len] = NUL;
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
if (bi->bi_state != NULL && bi->bi_buffer == NULL)
|
if (bi->bi_state != NULL && bi->bi_buffer == NULL)
|
||||||
crypt_decode_inplace(bi->bi_state, ptr, len);
|
crypt_decode_inplace(bi->bi_state, ptr, len, FALSE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
|
@@ -553,6 +553,11 @@ static char *(features[]) =
|
|||||||
#else
|
#else
|
||||||
"-smartindent",
|
"-smartindent",
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FEAT_SODIUM
|
||||||
|
"+sodium",
|
||||||
|
#else
|
||||||
|
"-sodium",
|
||||||
|
#endif
|
||||||
#ifdef FEAT_SOUND
|
#ifdef FEAT_SOUND
|
||||||
"+sound",
|
"+sound",
|
||||||
#else
|
#else
|
||||||
@@ -750,6 +755,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
3022,
|
||||||
/**/
|
/**/
|
||||||
3021,
|
3021,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user