To: vim_dev@googlegroups.com Subject: Patch 8.2.3022 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3022 Problem: Available encryption methods are not strong enough. Solution: Add initial support for xchaha20. (Christian Brabandt, closes #8394) Files: .github/workflows/ci.yml, runtime/doc/eval.txt, runtime/doc/options.txt, runtime/doc/various.txt, src/INSTALLpc.txt, src/Make_cyg_ming.mak, src/Make_mvc.mak, src/auto/configure, src/blowfish.c, src/bufwrite.c, src/config.h.in, src/configure.ac, src/crypt.c, src/crypt_zip.c, src/errors.h, src/evalfunc.c, src/feature.h, src/fileio.c, src/memline.c, src/option.c, src/optionstr.c, src/proto/blowfish.pro, src/proto/crypt.pro, src/proto/crypt_zip.pro, src/structs.h, src/testdir/samples/crypt_sodium_invalid.txt, src/testdir/test_crypt.vim, src/undo.c, src/version.c *** ../vim-8.2.3021/.github/workflows/ci.yml 2021-02-13 17:08:29.903796267 +0100 --- .github/workflows/ci.yml 2021-06-20 12:51:47.132478459 +0200 *************** *** 71,77 **** cscope \ libgtk2.0-dev \ desktop-file-utils \ ! libtool-bin - name: Install clang-11 if: matrix.compiler == 'clang' --- 71,78 ---- cscope \ libgtk2.0-dev \ desktop-file-utils \ ! libtool-bin \ ! libsodium-dev - name: Install clang-11 if: matrix.compiler == 'clang' *** ../vim-8.2.3021/runtime/doc/eval.txt 2021-06-19 20:45:07.349511367 +0200 --- runtime/doc/eval.txt 2021-06-20 12:51:47.136478444 +0200 *************** *** 11951,11956 **** --- 11971,11977 ---- showcmd Compiled with 'showcmd' support. signs Compiled with |:sign| support. smartindent Compiled with 'smartindent' support. + sodium Compiled with libsodium for better crypt support sound Compiled with sound support, e.g. `sound_playevent()` spell Compiled with spell checking support |spell|. startuptime Compiled with |--startuptime| support. *** ../vim-8.2.3021/runtime/doc/options.txt 2021-05-31 18:40:45.996805282 +0200 --- runtime/doc/options.txt 2021-06-20 13:02:04.578532122 +0200 *************** *** 2380,2385 **** --- 2384,2406 ---- you write the file the encrypted bytes will be different. The whole undo file is encrypted, not just 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. *** ../vim-8.2.3021/runtime/doc/various.txt 2021-01-31 17:02:06.266490126 +0100 --- runtime/doc/various.txt 2021-06-20 12:51:47.136478444 +0200 *************** *** 444,449 **** --- 444,450 ---- T *+scrollbind* |'scrollbind'| B *+signs* |:sign| N *+smartindent* |'smartindent'| + B *+sodium* compiled with libsodium for better encryption support B *+sound* |sound_playevent()|, |sound_playfile()| functions, etc. N *+spell* spell checking support, see |spell| N *+startuptime* |--startuptime| argument *** ../vim-8.2.3021/src/INSTALLpc.txt 2020-11-14 21:04:29.213262892 +0100 --- src/INSTALLpc.txt 2021-06-20 12:51:47.136478444 +0200 *************** *** 322,327 **** --- 322,330 ---- $ 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 *** ../vim-8.2.3021/src/Make_cyg_ming.mak 2021-06-02 17:07:02.276398163 +0200 --- src/Make_cyg_ming.mak 2021-06-20 12:51:47.140478432 +0200 *************** *** 41,46 **** --- 41,49 ---- # set to yes to measure code coverage COVERAGE=no + # better encryption support using libsodium + #SODIUM=yes + # set to SIZE for size, SPEED for speed, MAXSPEED for maximum optimization OPTIMIZE=MAXSPEED *************** *** 517,522 **** --- 520,529 ---- WINDRES_FLAGS = EXTRA_LIBS = + ifdef SODIUM + DEFINES += -DHAVE_SODIUM + endif + ifdef GETTEXT DEFINES += -DHAVE_GETTEXT -DHAVE_LOCALE_H GETTEXTINCLUDE = $(GETTEXT)/include *************** *** 660,665 **** --- 667,676 ---- endif endif + ifeq ($(SODIUM),yes) + SODIUMLIB = -lsodium + endif + # Only allow XPM for a GUI build. ifeq (yes, $(GUI)) *************** *** 1064,1070 **** ifeq ($(VIMDLL),yes) $(TARGET): $(OBJ) ! $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid -lgdi32 $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(GVIMEXE): $(EXEOBJG) $(VIMDLLBASE).dll $(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE) --- 1075,1081 ---- ifeq ($(VIMDLL),yes) $(TARGET): $(OBJ) ! $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid -lgdi32 $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB) $(GVIMEXE): $(EXEOBJG) $(VIMDLLBASE).dll $(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE) *************** *** 1073,1079 **** $(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE) else $(TARGET): $(OBJ) ! $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) endif upx: exes --- 1084,1090 ---- $(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE) else $(TARGET): $(OBJ) ! $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) $(SODIUMLIB) endif upx: exes *** ../vim-8.2.3021/src/Make_mvc.mak 2021-06-02 17:07:02.276398163 +0200 --- src/Make_mvc.mak 2021-06-20 13:02:42.326416497 +0200 *************** *** 41,46 **** --- 41,49 ---- # # 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) # Creates vim{32,64}.dll, and stub gvim.exe and vim.exe. # The shared codes between the GUI and the console are built into *************** *** 372,377 **** --- 375,400 ---- ! 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 NETBEANS = $(GUI) !endif *************** *** 491,497 **** CFLAGS = -c /W3 /GF /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \ $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \ ! $(NBDEBUG_DEFS) $(XPM_DEFS) \ $(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) #>>>>> end of choices --- 514,520 ---- CFLAGS = -c /W3 /GF /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \ $(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \ ! $(NBDEBUG_DEFS) $(XPM_DEFS) $(SOD_DEFS) \ $(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER) #>>>>> end of choices *************** *** 703,709 **** 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 \ ! spell.h structs.h term.h beval.h $(NBDEBUG_INCL) OBJ = \ $(OUTDIR)\arabic.obj \ --- 726,732 ---- 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 \ ! spell.h structs.h term.h beval.h $(NBDEBUG_INCL) $(SOD_INC) OBJ = \ $(OUTDIR)\arabic.obj \ *************** *** 1282,1288 **** LINKARGS1 = $(linkdebug) $(conflags) LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(NODEFAULTLIB) $(LIBC) $(OLE_LIB) user32.lib \ $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \ ! $(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(LINK_PDB) # Report link time code generation progress if used. !ifdef NODEBUG --- 1305,1311 ---- LINKARGS1 = $(linkdebug) $(conflags) LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(NODEFAULTLIB) $(LIBC) $(OLE_LIB) user32.lib \ $(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \ ! $(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(SOD_LIB) $(LINK_PDB) # Report link time code generation progress if used. !ifdef NODEBUG *** ../vim-8.2.3021/src/auto/configure 2021-06-10 18:50:51.806711124 +0200 --- src/auto/configure 2021-06-20 13:36:53.996548337 +0200 *************** *** 839,844 **** --- 839,845 ---- with_tlib enable_largefile enable_canberra + enable_libsodium enable_acl enable_gpm enable_sysmouse *************** *** 1513,1518 **** --- 1514,1520 ---- --disable-desktop-database-update update disabled --disable-largefile omit support for large files --disable-canberra Do not use libcanberra. + --disable-libsodium Do not use libsodium. --disable-acl No check for ACL support. --disable-gpm Don't use gpm (Linux mouse daemon). --disable-sysmouse Don't use sysmouse (mouse in *BSD console). *************** *** 13005,13010 **** --- 13007,13076 ---- conftest$ac_exeext conftest.$ac_ext 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 + + 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_n "checking for st_blksize... " >&6; } *** ../vim-8.2.3021/src/blowfish.c 2021-06-02 13:28:11.423120478 +0200 --- src/blowfish.c 2021-06-20 12:51:47.144478420 +0200 *************** *** 596,602 **** cryptstate_T *state, char_u *from, size_t len, ! char_u *to) { bf_state_T *bfs = state->method_state; size_t i; --- 596,603 ---- cryptstate_T *state, char_u *from, size_t len, ! char_u *to, ! int last UNUSED) { bf_state_T *bfs = state->method_state; size_t i; *************** *** 619,625 **** cryptstate_T *state, char_u *from, size_t len, ! char_u *to) { bf_state_T *bfs = state->method_state; size_t i; --- 620,627 ---- cryptstate_T *state, char_u *from, size_t len, ! char_u *to, ! int last UNUSED) { bf_state_T *bfs = state->method_state; size_t i; *************** *** 680,684 **** } return OK; } - #endif // FEAT_CRYPT --- 682,685 ---- *** ../vim-8.2.3021/src/bufwrite.c 2021-02-01 20:34:57.249893201 +0100 --- src/bufwrite.c 2021-06-20 12:51:47.152478393 +0200 *************** *** 30,35 **** --- 30,36 ---- int bw_flags; // FIO_ flags #ifdef FEAT_CRYPT buf_T *bw_buffer; // buffer being written + int bw_finish; // finish encrypting #endif char_u bw_rest[CONV_RESTLEN]; // not converted bytes int bw_restlen; // nr of bytes in bw_rest[] *************** *** 493,506 **** if (crypt_works_inplace(ip->bw_buffer->b_cryptstate)) { # endif ! crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len); # ifdef CRYPT_NOT_INPLACE } else { char_u *outbuf; ! len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf); if (len == 0) return OK; // Crypt layer is buffering, will flush later. wlen = write_eintr(ip->bw_fd, outbuf, len); --- 494,507 ---- if (crypt_works_inplace(ip->bw_buffer->b_cryptstate)) { # endif ! crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len, ip->bw_finish); # ifdef CRYPT_NOT_INPLACE } else { char_u *outbuf; ! len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf, ip->bw_finish); if (len == 0) return OK; // Crypt layer is buffering, will flush later. wlen = write_eintr(ip->bw_fd, outbuf, len); *************** *** 724,729 **** --- 725,731 ---- #endif #ifdef FEAT_CRYPT write_info.bw_buffer = buf; + write_info.bw_finish = FALSE; #endif // After writing a file changedtick changes but we don't want to display *************** *** 2015,2020 **** --- 2017,2029 ---- ++s; if (++len != bufsize) 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) { end = 0; // write error: break loop *************** *** 2118,2123 **** --- 2127,2138 ---- if (len > 0 && end > 0) { 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) end = 0; // write error nchars += len; *** ../vim-8.2.3021/src/config.h.in 2021-03-10 21:26:34.148867591 +0100 --- src/config.h.in 2021-06-20 12:51:47.152478393 +0200 *************** *** 208,213 **** --- 208,214 ---- #undef HAVE_STRPTIME #undef HAVE_STRTOL #undef HAVE_CANBERRA + #undef HAVE_SODIUM #undef HAVE_ST_BLKSIZE #undef HAVE_SYSCONF #undef HAVE_SYSCTL *** ../vim-8.2.3021/src/configure.ac 2021-06-10 18:50:51.806711124 +0200 --- src/configure.ac 2021-06-20 13:36:51.308552622 +0200 *************** *** 3767,3772 **** --- 3767,3809 ---- AC_MSG_RESULT(no; try installing libcanberra-dev); CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS") 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 + ], [ + 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 AC_MSG_CHECKING(for st_blksize) *** ../vim-8.2.3021/src/crypt.c 2019-11-30 20:50:07.000000000 +0100 --- src/crypt.c 2021-06-20 13:13:43.020361247 +0200 *************** *** 12,17 **** --- 12,21 ---- */ #include "vim.h" + #ifdef FEAT_SODIUM + # include + #endif + #if defined(FEAT_CRYPT) || defined(PROTO) /* * Optional encryption support. *************** *** 33,39 **** char *name; // encryption name as used in 'cryptmethod' char *magic; // magic bytes stored in file header int salt_len; // length of salt, or 0 when not using salt ! int seed_len; // length of seed, or 0 when not using salt #ifdef CRYPT_NOT_INPLACE int works_inplace; // encryption/decryption can be done in-place #endif --- 37,43 ---- char *name; // encryption name as used in 'cryptmethod' char *magic; // magic bytes stored in file header int salt_len; // length of salt, or 0 when not using salt ! int seed_len; // length of seed, or 0 when not using seed #ifdef CRYPT_NOT_INPLACE int works_inplace; // encryption/decryption can be done in-place #endif *************** *** 49,64 **** // Function pointers for encoding/decoding from one buffer into another. // Optional, however, these or the _buffer ones should be configured. void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u *to); void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u *to); // Function pointers for encoding and decoding, can buffer data if needed. // Optional (however, these or the above should be configured). long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u **newptr); long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u **newptr); // Function pointers for in-place encoding and decoding, used for // crypt_*_inplace(). "from" and "to" arguments will be equal. --- 53,68 ---- // Function pointers for encoding/decoding from one buffer into another. // Optional, however, these or the _buffer ones should be configured. void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u *to, int last); void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u *to, int last); // Function pointers for encoding and decoding, can buffer data if needed. // Optional (however, these or the above should be configured). long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u **newptr, int last); long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len, ! char_u **newptr, int last); // Function pointers for in-place encoding and decoding, used for // crypt_*_inplace(). "from" and "to" arguments will be equal. *************** *** 68,76 **** // padding to files). // 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, ! char_u *p2); void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len, ! char_u *p2); } cryptmethod_T; // index is method_nr of cryptstate_T, CRYPT_M_* --- 72,80 ---- // padding to files). // 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, ! char_u *p2, int last); void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len, ! char_u *p2, int last); } cryptmethod_T; // index is method_nr of cryptstate_T, CRYPT_M_* *************** *** 126,135 **** --- 130,170 ---- 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, // 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 static char crypt_magic_head[] = "VimCrypt~"; *************** *** 260,266 **** state->method_nr = method_nr; if (cryptmethods[method_nr].init_fn( ! state, key, salt, salt_len, seed, seed_len) == FAIL) { vim_free(state); return NULL; --- 295,301 ---- state->method_nr = method_nr; if (cryptmethods[method_nr].init_fn( ! state, key, salt, salt_len, seed, seed_len) == FAIL) { vim_free(state); return NULL; *************** *** 365,373 **** // TODO: Should this be crypt method specific? (Probably not worth // it). sha2_seed is pretty bad for large amounts of entropy, so make // that into something which is suitable for anything. ! sha2_seed(salt, salt_len, seed, seed_len); } - state = crypt_create(method_nr, key, salt, salt_len, seed, seed_len); if (state == NULL) VIM_CLEAR(*header); --- 400,415 ---- // TODO: Should this be crypt method specific? (Probably not worth // it). sha2_seed is pretty bad for large amounts of entropy, so make // 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); } state = crypt_create(method_nr, key, salt, salt_len, seed, seed_len); if (state == NULL) VIM_CLEAR(*header); *************** *** 380,386 **** void crypt_free_state(cryptstate_T *state) { ! vim_free(state->method_state); vim_free(state); } --- 422,436 ---- void 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); } *************** *** 395,415 **** cryptstate_T *state, char_u *from, size_t len, ! char_u **newptr) { cryptmethod_T *method = &cryptmethods[state->method_nr]; if (method->encode_buffer_fn != NULL) // Has buffer function, pass through. ! return method->encode_buffer_fn(state, from, len, newptr); if (len == 0) // Not buffering, just return EOF. return (long)len; ! *newptr = alloc(len); if (*newptr == NULL) return -1; ! method->encode_fn(state, from, len, *newptr); return (long)len; } --- 445,466 ---- cryptstate_T *state, char_u *from, size_t len, ! char_u **newptr, ! int last) { cryptmethod_T *method = &cryptmethods[state->method_nr]; if (method->encode_buffer_fn != NULL) // Has buffer function, pass through. ! return method->encode_buffer_fn(state, from, len, newptr, last); if (len == 0) // Not buffering, just return EOF. return (long)len; ! *newptr = alloc(len + 50); if (*newptr == NULL) return -1; ! method->encode_fn(state, from, len, *newptr, last); return (long)len; } *************** *** 423,435 **** cryptstate_T *state, char_u *ptr, long len, ! char_u **newptr) { cryptmethod_T *method = &cryptmethods[state->method_nr]; if (method->decode_buffer_fn != NULL) // Has buffer function, pass through. ! return method->decode_buffer_fn(state, ptr, len, newptr); if (len == 0) // Not buffering, just return EOF. --- 474,487 ---- cryptstate_T *state, char_u *ptr, long len, ! char_u **newptr, ! int last) { cryptmethod_T *method = &cryptmethods[state->method_nr]; if (method->decode_buffer_fn != NULL) // Has buffer function, pass through. ! return method->decode_buffer_fn(state, ptr, len, newptr, last); if (len == 0) // Not buffering, just return EOF. *************** *** 438,444 **** *newptr = alloc(len); if (*newptr == NULL) return -1; ! method->decode_fn(state, ptr, len, *newptr); return len; } #endif --- 490,496 ---- *newptr = alloc(len); if (*newptr == NULL) return -1; ! method->decode_fn(state, ptr, len, *newptr, last); return len; } #endif *************** *** 451,459 **** cryptstate_T *state, char_u *from, size_t len, ! char_u *to) { ! cryptmethods[state->method_nr].encode_fn(state, from, len, to); } #if 0 // unused --- 503,512 ---- cryptstate_T *state, char_u *from, size_t len, ! char_u *to, ! int last) { ! cryptmethods[state->method_nr].encode_fn(state, from, len, to, last); } #if 0 // unused *************** *** 465,473 **** cryptstate_T *state, char_u *from, size_t len, ! char_u *to) { ! cryptmethods[state->method_nr].decode_fn(state, from, len, to); } #endif --- 518,527 ---- cryptstate_T *state, char_u *from, size_t len, ! char_u *to, ! int last) { ! cryptmethods[state->method_nr].decode_fn(state, from, len, to, last); } #endif *************** *** 478,486 **** crypt_encode_inplace( cryptstate_T *state, char_u *buf, ! size_t len) { ! cryptmethods[state->method_nr].encode_inplace_fn(state, buf, len, buf); } /* --- 532,542 ---- crypt_encode_inplace( cryptstate_T *state, char_u *buf, ! size_t len, ! int last) { ! cryptmethods[state->method_nr].encode_inplace_fn(state, buf, len, ! buf, last); } /* *************** *** 490,498 **** crypt_decode_inplace( cryptstate_T *state, char_u *buf, ! size_t len) { ! cryptmethods[state->method_nr].decode_inplace_fn(state, buf, len, buf); } /* --- 546,556 ---- crypt_decode_inplace( cryptstate_T *state, char_u *buf, ! size_t len, ! int last) { ! cryptmethods[state->method_nr].decode_inplace_fn(state, buf, len, ! buf, last); } /* *************** *** 523,528 **** --- 581,599 ---- msg_scroll = TRUE; 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 *************** *** 610,613 **** --- 681,946 ---- } } + 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 *** ../vim-8.2.3021/src/crypt_zip.c 2019-11-30 20:50:30.000000000 +0100 --- src/crypt_zip.c 2021-06-20 12:51:47.152478393 +0200 *************** *** 114,120 **** cryptstate_T *state, char_u *from, size_t len, ! char_u *to) { zip_state_T *zs = state->method_state; size_t i; --- 114,121 ---- cryptstate_T *state, char_u *from, size_t len, ! char_u *to, ! int last UNUSED) { zip_state_T *zs = state->method_state; size_t i; *************** *** 137,143 **** cryptstate_T *state, char_u *from, size_t len, ! char_u *to) { zip_state_T *zs = state->method_state; size_t i; --- 138,145 ---- cryptstate_T *state, char_u *from, size_t len, ! char_u *to, ! int last UNUSED) { zip_state_T *zs = state->method_state; size_t i; *** ../vim-8.2.3021/src/errors.h 2021-06-12 12:16:51.478922236 +0200 --- src/errors.h 2021-06-20 12:51:47.152478393 +0200 *************** *** 427,429 **** --- 427,448 ---- INIT(= N_("E1191: Call to function that failed to compile: %s")); EXTERN char e_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!")); *** ../vim-8.2.3021/src/evalfunc.c 2021-06-07 22:04:48.406620074 +0200 --- src/evalfunc.c 2021-06-20 12:51:47.156478381 +0200 *************** *** 5072,5077 **** --- 5072,5084 ---- 0 #endif }, + {"sodium", + #ifdef FEAT_SODIUM + 1 + #else + 0 + #endif + }, {"sound", #ifdef FEAT_SOUND 1 *** ../vim-8.2.3021/src/feature.h 2021-03-29 20:49:01.486055361 +0200 --- src/feature.h 2021-06-20 12:51:47.156478381 +0200 *************** *** 593,598 **** --- 593,605 ---- # define FEAT_SOUND_CANBERRA #endif + /* + * libsodium - add cryptography support + */ + #if defined(HAVE_SODIUM) && defined(FEAT_BIG) + # define FEAT_SODIUM + #endif + // There are two ways to use XPM. #if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \ || defined(HAVE_X11_XPM_H) *** ../vim-8.2.3021/src/fileio.c 2021-06-02 13:28:11.427120469 +0200 --- src/fileio.c 2021-06-20 13:25:03.582216661 +0200 *************** *** 13,18 **** --- 13,22 ---- #include "vim.h" + #ifdef FEAT_SODIUM + # include + #endif + #if defined(__TANDEM) # include // for SSIZE_MAX #endif *************** *** 148,153 **** --- 152,159 ---- 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,220 **** --- 221,227 ---- 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,410 **** --- 412,418 ---- { 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,1085 **** --- 1088,1094 ---- { linerest = 0; filesize = 0; + filesize_count = 0; skip_count = lines_to_skip; read_count = lines_to_read; conv_restlen = 0; *************** *** 1263,1269 **** --- 1272,1294 ---- /* * 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,1291 **** if (crypt_works_inplace(curbuf->b_cryptstate)) { # endif ! crypt_decode_inplace(curbuf->b_cryptstate, ptr, size); # ifdef CRYPT_NOT_INPLACE } else --- 1310,1317 ---- if (crypt_works_inplace(curbuf->b_cryptstate)) { # endif ! crypt_decode_inplace(curbuf->b_cryptstate, ptr, ! size, eof); # ifdef CRYPT_NOT_INPLACE } else *************** *** 1294,1301 **** int decrypted_size; decrypted_size = crypt_decode_alloc( ! curbuf->b_cryptstate, ptr, size, &newptr); // If the crypt layer is buffering, not producing // anything yet, need to read more. if (decrypted_size == 0) --- 1320,1335 ---- int decrypted_size; decrypted_size = crypt_decode_alloc( ! 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,1330 **** --- 1359,1365 ---- if (newptr != NULL) mch_memmove(new_buffer + linerest, newptr, decrypted_size); + vim_free(newptr); } if (new_buffer != NULL) *************** *** 1334,1339 **** --- 1369,1375 ---- new_buffer = NULL; line_start = buffer; ptr = buffer + linerest; + real_size = size; } size = decrypted_size; } *** ../vim-8.2.3021/src/memline.c 2021-06-09 12:33:36.908213351 +0200 --- src/memline.c 2021-06-20 13:18:45.303410360 +0200 *************** *** 48,53 **** --- 48,58 ---- # include #endif + // for randombytes_buf + #ifdef FEAT_SODIUM + # include + #endif + #if defined(SASC) || defined(__amigaos4__) # include // for Open() and Close() #endif *************** *** 64,75 **** --- 69,82 ---- #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_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) static int id1_codes[] = { BLOCK0_ID1_C0, // CRYPT_M_ZIP BLOCK0_ID1_C1, // CRYPT_M_BF BLOCK0_ID1_C2, // CRYPT_M_BF2 + BLOCK0_ID1_C3, // CRYPT_M_SOD - Unused! }; #endif *************** *** 426,436 **** { int method_nr = crypt_get_method_nr(buf); ! if (method_nr > CRYPT_M_ZIP) { // Generate a seed and store it in the memfile. sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0); } } } --- 433,447 ---- { int method_nr = crypt_get_method_nr(buf); ! if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD) { // Generate a seed and store it in the memfile. 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,453 **** int method_nr = crypt_get_method_nr(buf); b0p->b0_id[1] = id1_codes[method_nr]; ! if (method_nr > CRYPT_M_ZIP) { // Generate a seed and store it in block 0 and in the memfile. sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0); --- 458,464 ---- int method_nr = crypt_get_method_nr(buf); b0p->b0_id[1] = id1_codes[method_nr]; ! if (method_nr > CRYPT_M_ZIP && method_nr < CRYPT_M_SOD) { // Generate a seed and store it in block 0 and in the memfile. sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0); *************** *** 482,491 **** int top; int old_method; ! if (mfp == NULL) return; // no memfile yet, nothing to do old_method = crypt_method_nr_from_name(old_cm); // First make sure the swapfile is in a consistent state, using the old // key and method. { --- 493,509 ---- int top; int old_method; ! if (mfp == NULL || mfp->mf_fd < 0) return; // no memfile yet, nothing to do 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 // key and method. { *************** *** 911,917 **** || (b0p->b0_id[1] != BLOCK0_ID1 && b0p->b0_id[1] != BLOCK0_ID1_C0 && b0p->b0_id[1] != BLOCK0_ID1_C1 ! && b0p->b0_id[1] != BLOCK0_ID1_C2) ) return FAIL; return OK; --- 929,936 ---- || (b0p->b0_id[1] != BLOCK0_ID1 && b0p->b0_id[1] != BLOCK0_ID1_C0 && b0p->b0_id[1] != BLOCK0_ID1_C1 ! && b0p->b0_id[1] != BLOCK0_ID1_C2 ! && b0p->b0_id[1] != BLOCK0_ID1_C3) ) return FAIL; return OK; *************** *** 2402,2408 **** FOR_ALL_BUFFERS(buf) { ! if (buf->b_ml.ml_mfp == NULL || buf->b_ml.ml_mfp->mf_fname == NULL) continue; // no file ml_flush_line(buf); // flush buffered line --- 2421,2429 ---- FOR_ALL_BUFFERS(buf) { ! 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 ml_flush_line(buf); // flush buffered line *************** *** 5320,5326 **** mch_memmove(new_data, dp, head_end - (char_u *)dp); // Encrypt the text. ! crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start); crypt_free_state(state); // Clear the gap. --- 5341,5348 ---- mch_memmove(new_data, dp, head_end - (char_u *)dp); // Encrypt the text. ! crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start, ! FALSE); crypt_free_state(state); // Clear the gap. *************** *** 5360,5366 **** if (state != NULL) { // Decrypt the text in place. ! crypt_decode_inplace(state, text_start, text_len); crypt_free_state(state); } } --- 5382,5388 ---- if (state != NULL) { // Decrypt the text in place. ! crypt_decode_inplace(state, text_start, text_len, FALSE); crypt_free_state(state); } } *************** *** 5407,5413 **** // of the block for the salt. vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); return crypt_create(method_nr, key, salt, (int)STRLEN(salt), ! seed, MF_SEED_LEN); } #endif --- 5429,5435 ---- // of the block for the salt. vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset); return crypt_create(method_nr, key, salt, (int)STRLEN(salt), ! seed, MF_SEED_LEN); } #endif *** ../vim-8.2.3021/src/option.c 2021-06-20 12:40:05.342813034 +0200 --- src/option.c 2021-06-20 12:51:47.156478381 +0200 *************** *** 2713,2718 **** --- 2713,2722 ---- || (opt_flags & OPT_GLOBAL) || opt_flags == 0) && !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_read_undo(NULL, hash, curbuf->b_fname); } *** ../vim-8.2.3021/src/optionstr.c 2021-05-15 17:23:22.882858583 +0200 --- src/optionstr.c 2021-06-20 12:51:47.156478381 +0200 *************** *** 24,30 **** static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL}; static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL}; #ifdef FEAT_CRYPT ! static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL}; #endif static char *(p_cmp_values[]) = {"internal", "keepascii", NULL}; static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL}; --- 24,34 ---- static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL}; static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL}; #ifdef FEAT_CRYPT ! static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", ! # ifdef FEAT_SODIUM ! "xchacha20", ! # endif ! NULL}; #endif static char *(p_cmp_values[]) = {"internal", "keepascii", NULL}; static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL}; *** ../vim-8.2.3021/src/proto/blowfish.pro 2019-12-12 12:55:14.000000000 +0100 --- src/proto/blowfish.pro 2021-06-20 13:19:20.803298483 +0200 *************** *** 1,6 **** /* blowfish.c */ ! void crypt_blowfish_encode(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 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); /* vim: set ft=c : */ --- 1,6 ---- /* blowfish.c */ ! 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, 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 blowfish_self_test(void); /* vim: set ft=c : */ *** ../vim-8.2.3021/src/proto/crypt.pro 2019-12-12 12:55:16.000000000 +0100 --- src/proto/crypt.pro 2021-06-20 13:23:39.386482590 +0200 *************** *** 1,6 **** --- 1,7 ---- /* crypt.c */ int crypt_method_nr_from_name(char_u *name); 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_whole_undofile(int method_nr); int crypt_get_header_len(int method_nr); *************** *** 11,22 **** 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); void crypt_free_state(cryptstate_T *state); ! void crypt_encode(cryptstate_T *state, char_u *from, size_t len, char_u *to); ! void crypt_encode_inplace(cryptstate_T *state, char_u *buf, size_t len); ! void crypt_decode_inplace(cryptstate_T *state, char_u *buf, size_t len); void crypt_free_key(char_u *key); void crypt_check_method(int method); void crypt_check_current_method(void); char_u *crypt_get_key(int store, int twice); void crypt_append_msg(buf_T *buf); /* vim: set ft=c : */ --- 12,30 ---- 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); void crypt_free_state(cryptstate_T *state); ! long crypt_encode_alloc(cryptstate_T *state, char_u *from, size_t len, char_u **newptr, int last); ! long crypt_decode_alloc(cryptstate_T *state, char_u *ptr, long len, char_u **newptr, int last); ! 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_check_method(int method); void crypt_check_current_method(void); char_u *crypt_get_key(int store, int twice); 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-8.2.3021/src/proto/crypt_zip.pro 2019-12-12 12:55:16.000000000 +0100 --- src/proto/crypt_zip.pro 2021-06-20 13:23:49.774449777 +0200 *************** *** 1,5 **** /* 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); ! void crypt_zip_encode(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); /* vim: set ft=c : */ --- 1,5 ---- /* 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); ! 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, int last); /* vim: set ft=c : */ *** ../vim-8.2.3021/src/structs.h 2021-06-10 19:39:07.277697688 +0200 --- src/structs.h 2021-06-20 12:51:47.160478366 +0200 *************** *** 2513,2523 **** # define CRYPT_M_ZIP 0 # define CRYPT_M_BF 1 # define CRYPT_M_BF2 2 ! # define CRYPT_M_COUNT 3 // number of crypt methods // Currently all crypt methods work inplace. If one is added that isn't then // define this. ! // # define CRYPT_NOT_INPLACE 1 #endif #ifdef FEAT_PROP_POPUP --- 2513,2524 ---- # define CRYPT_M_ZIP 0 # define CRYPT_M_BF 1 # define CRYPT_M_BF2 2 ! # 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 // define this. ! # define CRYPT_NOT_INPLACE 1 #endif #ifdef FEAT_PROP_POPUP *** ../vim-8.2.3021/src/testdir/samples/crypt_sodium_invalid.txt 2021-06-20 13:58:39.677389885 +0200 --- src/testdir/samples/crypt_sodium_invalid.txt 2021-06-20 13:55:48.649862857 +0200 *************** *** 0 **** --- 1,65 ---- + VimCrypt~04!;ë&mÞÀyŽ}¡)Bb¸ã¹7Z«â€ÏĄեbRʑq¡Z*Qªc}#Qxµ àWÕÇF"rô#A˜p΁&Ÿ©{íàØvAF•FôXïþW– 5›Ñì÷ß4G¶2ݹ@èõÅÆQÏ)¾”¬FÑsÕõ–xùÅk9ü˜âΙ®HÚ‰2BŸàþ)³Öã5"HÕr»Ô¶æ"÷‘),ÞÒ$‰º„KÈÙrÒHƒ‹U{nþ !(Aê[¶â ˜ Ÿñ­º—ÏzU¿¹š,êÑÔy§F + õgÆÿÇæ'Be¾x‹>µcàºæÌ6ùTBÁÿadœ!'†˜„÷}^¡7Ýü‘˜Ù“1›®Öæ"EŽåöÜw÷C]Ä¥13V“èVŽÎƒ =՗;õÛq _x¼ž˜kՒð8’;fdÔºÚþ&¨3P + ü©¤Ï®=‘åHˆ2§¸ª­Gþ ›àÌua ~…Åm-e ¢ð—­C³Qj.º¢À¢EKáôþC˜å8²Ê—º¶¹1X©×²ÅàºÆ«Ñ¯ ÅW_ + smBÝþ׿„IϐħC¤¿Ø½Æê"šßý–ÝCb"‚ÑW/5ÇQÄ 2:²…EvÕ'e¨ˆëgƒË¤˜:rTÙ¤˜ Œ…æPE¥e•q¢^^`0be/\t)˜3EÜÂZ‡CWV* C¿s&‘[‹"=µˆ_£{ìÔuÆm4€èkEO}ÿì&lãdv¨ ©×ÐB#´ÏáÊÞ9EÏûÜ&õÎÔÀTž¢f.~v>·ÓÎ1‘ä »nf›“.mªÈ áv 8aÌ»—z7ìEºO¥Ž³âç5F=v­/þÆUmg|Ì=ÀÓ–-Ž9¨?¢ÂG½úOódmþgý€8ÜÎìÿÜ-E;ªEzú F¾@8œáÚ ‹Ø•qôR(##–oI*1æ탡+¼ØPoôJ-ó­Uꦱhs¢¾JO¯M' + ³ÄuuMÓs–9+4­-®%í†ð³ê̒]@Ðg4( ¾Gsù¼P—–„.#Š´žYî„nIµi»ÌZÓ/’/à“_›.ºöH"‘úÝWîŽöóþÃãOäoáÌ}{'3ZÚ(kÆño>”à@¶VDC1ש+ÿa• ç­¥q:|óÖoËg,Lžîæ¥&W,Ž)ãµ·?f×ËJü'Î8÷â ´'UO´‡ž$½‹¹õ˜à)öýïà/JJ„Y×gúÆÛÐqj©®Pxá\Yqî›ØÞÖ>ÆÓÞÖ?‹œqß¹âjÌQHäo‡Dtm8“-Ìa‘e­ !œ»°ùøjÉf çI5~O§ÕXhݼË$1Y\*4\Öo/hxãLÐ)ñˆ7€9>­ñOC‰ã08/À»ßÊ¿»ŸÝèDp£{6ŸÁ¿hCsHdØæáé·4°»òݶ¥­ÌóZ>æÖÅîa4Ñ¥€&F^.ÏÞ¡B{ˆçÓòKÝbÞÙhBÂω,˜Fç4 ø· ÿŠŸ¬Ç#æH + Æu÷9°k 4يQû8Ù®sUi@a—U172+Uwu`ü«€âÑ)?A½#Ä4M·îëÇ_’§¿»aQ(–uPËîÀY–\9)ÍT À¥;qª´–8-œÍ0L›“ŽbgÞbðXåÞk6t¤õMke[hEk[ŒDÒv¡éɺ¶÷T¼ÌÍÜÆniäƒÖµFU1ƒ1?<#mœÊ S™-  ¢>ƒ<óxÖ¿:í( KOÒ¤uÏÖëXI0é(jµû‘ V(E:þvǼ|¿W™˜Å¨â¥_üŠ¯H˜ÆV3z,wŠÏ;z~aÈBÀÄeSÓüÖçI}yǒŠPïô‡(# ÏG˜8L|_TŒdò–³)x˜Œ2·ªh”‚ ǧšÞ·GÈD}̑G¥Bë¥É o„Bñ¸0V~—E£ÙïÆGÿªóêÒ?Ú:¨9]@,vÕ6Ñk-8½¬´ÐÒêjæ‹DÒâufS/ÉPVO›'òMiýl½Ÿ¡u˜qòÃèKÞ¤öUŸpÎ`‚Fƒ vÖÌB1ÂÅ™¤@: ªË™Å‰c»Ë5µÌÏ÷|jŸOcžFí{þ"Š]|»„…¤É|ì¦ׅ÷… ÄùhßS536›˜¢Z k¶wðÝÓ;”ðéàßSŒv€6ÚOðwú—wß®‚Ôѓ=(ÌmÜ·¾»òQŽ0|y_1s° ÀÈs@jË\+ªðFõŠ ?§ž­`‹÷ÁþA7B¤`QDHG;½^[1㞳Z Êó°·—tû×µWh*_´¹e¼þ˜²@MÑm?û.Ÿ€™Æ„÷¡JF—&çhÓ}ïðw[ùÉ ÍêZ‘»0BÍ!åûÞÆGgŒeœ2Æ[ï¿:ÛÆ1jð%ñ¸9@r(CËÒE¨ŸëÂ[oTõ^k]“[Eµ½c$DäG؃•/®hˆ @tÞ¨«ôä «x$«Á¢®é֟ÍØÉåœ] Ð + gjU®ÙÁhíðþÂ%X“QŠí"qXxÄUÐ †A{0{GR‡yNÝuv3í6Èþ²1Ô< ;¥t/&Ì$ÒŸdÓøÊ*N-BäZÇæ`øáQo‚׆5­¤6ïŒØ  ]Ÿ7r3¶¾éc‹ë%ý mŔtƒhﲕ4|ÎØÐÜ°bzëRnÓµGRh“×8 šIP‹˜m?;*O»š´(¤°aW›¶úuBhSk|Xªyt«S„™(úž×™ò–ÔÝXÄxÑnú‘0}+ 7Ó¬»¥Œm1$¸KT…78ë+þ·¥S»!@J’33¨â}õĐÆæ×I[¶pÿ·†/5F¿à þê"MN¥\b«$**(6ÇОr^¥ÒJÚ8Iõ,ÉX|üªóô|j¦_²äÔ´ ¨B¼tÒ'™n–¨£ÉyQñ7iÊ«”¿UíÌcÝ̧?Ñîñu³ýœ®8…%Îø¿‘²ÉXVâ&M&~— + ÿ‹¤Vm‰=÷Wä®ê’ vcsBø©ßè˜Û…Ü^ KÚT"bNÛÁjªº@Jä/5©*ž9’zŽ-X›‹uŒÅPþà|Ó!9»6êvš’J@)ý˜„·ó3æOl«ÿ ȓÇÍ»p0¦™‡òžÒŸÀ)µ9<’}@fÈ“Eܙ+šó÷I¿¢îQmŒó)ßuÒ³/lÆ_ãû•¿w¾Û4Šù7³ñô‰TÈìÕóϛÐÌæ;ΐ^ž~ÁÊÝÉ#Cúý\äü‡‚?ü8-6+¦F»&üâ¥ëʚõq,¼Ñ¥øoÒD+Õ>éF ºS‡‚“šÝ´êU@”­kj …?­·ñÆ<ÿ—Ùè~R¾zß²ì0ò§›ÌÝö¡ 6FÃGû"}C;€6ÞE 9ÖÔî<àϜz§a&{âf4+ØxzY^ˆ´Ï-MqŸ®B­—ÿv:IáL¦ún^¤E¢±¬¹Àæ9®/¼Í‡iƜ“Ö jwùj + Õ¢…S§±Üþ~„‰®YР]GQº¶±Ë±W¯Ë8Ÿ„܅^¼Xô£Ãe_„OÎË ‚æ=¶l\ÖÈ + š‚¬»¢3š¨4XIlmHj{SKƒ'ñòŸ±.fÐ RÄ yYð„Xÿ࢖‹û\mä¬bš¦¤dúJ#¨tïþjÙq&ÒKÞ4/DªúКíTx^!Ÿõ(j%Æà*…³M1ô°Kpªƒ%Ùþ¤h[˜e2Ù$3,p@øýA#ÛHÇ×þ­ò)r[aqM͞¤H쇓ŸpêÂÚƒò£„=4Ö$ùd!Û¸—eV¡Îê©o€)bxÔÅÊ9ç݂7`‘an—ûàQrrš8^ë…Ö©r»Õ܅CXÆ:)ø8ðÖ(YˆAßf¿ßªz¥Œ„’L`{ryRlªÊjB§ vʘ¼e3t1gÿá¥ã¼øû¤‹w¡Ñh+EFåÊpœÀcd6ÛO„ô«ëðcA猇ŒÊ­ÕT£_ÄtnÍ1½`íHn‡”€õçŒh + dRÝ3k¹yø³‹ª‚:§•í~cù…Ü VÖ9§5`r(ß»š×P<£ßtHåõ¹+ÿ-½D-h¾ÐSøé3w*¿ì2ûâ‘n&D£€IyÖïTIüf1{Á¸÷šW¥–#“˦·™¬ïKc'‰!ÏúæÇd|˜ÙÖf±x(ÁàæU'БULåî5EY»Ý)X2½+M‹ŸæS˜µ;ݵ©í.…œ¼RdÀ¬iŠ'ÖÜúÎUãõ Ø + MhÙ9ŸkÞ4nO'Þ±‘f$³²¾]c CÚ¹úgôµK(ßÝZDv³4$†×ž`f⊳®¦(y0¨nŽÏ6$@…'4è¤Ñ¿` ¬À’Ý.—E4êí¸šò¿ #YÎ&ùâigb¿–G“êçK•pBí”Æþ”‹þ©e¨5G;æyž-ž„ÅÀ­ N4Ÿ`[B#nW”@tHÿû»õG'ŠJʛï)kÂ&pUfø.dK<õpø¹WøÝðú‹¦ + ßµÁiՐ12ÿq÷AÇûÂ3|F@o‚ˆNYˆ%"Ñ㓔´Tx"ðch ÷P;8K6Ä}AA$> ÀÄqXaöÓ_ØXϵZ½£ÞÊ + ° “ý$1Âz¹õ ÅépQ^³KH>˜Ï}]Ã3;h¼B×¢Þ¦áó÷zOšÆ:ƒ¢#RÏù+,jõ|" Reó'”‡ÿ)YzsŠ ô|jRÍJDfç ¤Á[ð¸z~a~d,p?N=LBYÓH”ðÛ¸ùÐKU°wB6øSp~<Ճ+©e¥…Ë µ>/°[ëm†”Õn|{ûÞK«^“×Á-çÁ¦¯LTÑÿ%Eم­^eAò„(}:ûPîè/e½Ên¹µ/ö°Ëna¦;ĝ›½°¤ÿJ~ñªœ,xÏõuy{î¼¢6ð%\„¸.Œj-¯õ![SL#»m¡vo3ÏWo’ÈÄN€!*×TJ±‰²-‹3ÛkªäyÄÐB 3 ŠJRâ}}·[²RxÄ?ú›´½jz{:¡)ý§:‚å‹“íÛ>ñ²uÝínȜÛáóªûG< rs­=X˜Á |¤hqv.ä!´í7†ÀТê÷U[Õ8UG•.l´›OZ„Õd9ã%9—!8HfÄ9lîO-©èær…u[.ùŒ_Ö½^2íÚïÈQˆ áç Z\?KNr¹AuSÚk[4“„ЕD2?V¦IÃgöúŸ5æÓgü<œêñ€´•>¶SQò¼ésf}†¤~ Ó×ö¿—µšmO$Öôvéð!a¬ ÕìÐ14û¬R/¯2=d¿dS\™Îf‰f¶oÀ`èŽèf}ð£‹,X 6òH¾ª«•w WËèøQÉùۈŽmÌÎcÙÚÄHª˜Ñ/2?>ҘQiÉJDˆ.¢æ{t€g´Ù…ÄoŽM`ŸGv½Â‰0%¡uŸÕ Êæ8Û)"ÝÎmúAävÙ='b­¯Yª¹²1ßøã­*LÌB¶)—à µé‘Q-õ) –™©œU;ú³¡öÃä#ïg(è@´'ºöpb¹ád$ZM1á²Øg ëØÍÛDЬ·ÞDqxÀ. ùü2çëÃí=ÈpŒ|>ݾï>^%™-oÏæÜ`Ý°(ÎG°\G„ZoG+§ ®ORMí7>PËçÆÚO¤|xVEªÝäø>6p¢…6bd§å7ëª + úHÄÒôÛnzÓFë«ÏküÖåÿ0­Ôf¼ˆËÚoÛ*»¶<"F¡–$`[ŽœDLП 5p£òk-Ó±âø£g`¢¯`§}o gf‘N I®¸fBu;Ïò¦§ C2QI‘ú…Ê¿ ¶¦ÇHö Ó\šx¸j¼ + rÜ*ö‹ ú¦<öȍÉ]ðÙo‡JŽç2ê˜,Ëx—ÚÉǜB{€Ë×ô‹²i°EÅÎå)Ç3õg¹¿=Ó¥²0éPGøb + .V’’p`º@PfiHùíÔPž|¤ô¼þ `,ú˜!%Hžð œ;ïSZ¶˜dýÆEáéÿ­ûxyz|üÂÊ<,Ó´ÕB0Š˜à¨TG:•ÁÀOÄï 0O)AŽ<‰]ü^W—¸¡Ÿ—cÜ£>zñþK—T#Y¢%ÙxWjo,¥Ì/`Z*ÙäÉtMâèbF‚é(¼¨ä´üK3=BP2C¯ýÐø5ÅXLÛj—ˆ®û×VŸjŸé>½Œ6ïè¾ë僚_¹ìI{9bþ ¾˜Rº~+ó.2ç¿÷ÿÊWx¼´·íÀ_&I„Ë5Ã7Ú,Ç×Ië@6¾îǎøNìE\ïÿ§¥«åœg»Z + l£C\èK + ŒAW„Îl‚'è/ýX‡ÙÉÊȽIéŽÑ†v0á ¸ØȳçV†õ¾f ¦7u€«‘>gBø}IÉêlT’Ç‘ZܯéÂÓ + Œ\·Dr.p´}¢°Ø“³ÂǓөÁj|ù =ˆû™ð[é!¥Ù—/:\û‹¨¾ šB2%ã¢xÛé „…|Õ¶J½xÙLq^pÉ{<©$ù1epÁ(ÌRV Ëʵ¥Õê½'¬_nf"HcX¥=k :„]‡ñoÊ~;+£Õ9À®„±W¬l dÙ§æ ‰é7:I™Ùt>n»€fÝD^ô±Z«LéRÊÑ·–Ñ@jUdpäœÄ6ŒpFcÁ°NáÅß荕»óв’¦B%Ö6—P$ÆiÁ„¦kNW~ß>ü_*3a*[Áÿ^d6œSYéÏüZ…ÜŽw|û›Ÿ°ŒŠŽaýëP×SȪ)ËÇ»îÁ9ÝS¥®÷ßȁí1½1t{ÐpC™Æ4ÄËP;§ê5*ÿ‡²RZ=öêRgI~‹q7ìäNiÍ;æ%íÒ¥ê ‡85¾Ä¼ü_S³üDÌ·&Ó ñó:nÔM¤ Œ:› Ö´ö}¾cփ·Ó‰aw¨‰a + é¬ÿíçNå‹ry ‰€y…±\ZK‘ + ©:‰uŸxÅ/)eÂ`³ÃÁ†™¾¬º`ÇÑñVE£27!ÍZSÔË P9Söª-ÌT€²¬;_:b©Röc÷˜o2’·d¾¥ŠÄ\ÞKÌpB:.~Œ)bjÔ.ž„!L¿ÈïEgÃt©ÌÀ XòÍ5öå¼pëž-Yœ°â:¸ºÞ{<“NFJÝòÿîhOt}!‹ + !ÓÍÉi’Þ²£¯ º@ÿÐ76¶Á‚HoEC•¹:9¶‚@üer:w÷ªY|«Y ­¸gXߏRÍðGEDðøxQ²d¥ý”ÂJ›—dٍt@.㋄÷.f:tn6Ö¸âõ'!âeßVÎ÷GŠ“ƒ¶²ØÛJ£áen=?ã'f Hʸ1ác-žN\V¢QT &˜¾¾NæۛÀ"Hn~åõb‰^H0/èz߈¬¢/‹ùª;ÛRõV<·ú*±§fyzEÌܺ³v}.^¤á&ÂÒoÛ$•Zl>ûÁž¶Ò»Ý¶ 5O¬Š°iæ—WÆhM0!Ù!6HÝhaΘé%â(ÖOd·ÍJ Z ÀX# …BøŒ:Qæ¥@ý¼XÄðÕ¯¶xžPÄ ,H­H]1­rbù™ŒÑÚ «©lÄkͯ°ä[\„Ê)5Z­J?Ä ýtؙ@é¡·¹Åɨ¹ˆbšÓ_Áâèýz™Ñ%³/«†Ÿ{c"¸‡Gw ˆô´C‡¼ŽÏ1¾^ݦšÅyúS)± ø¸D­6\Vs`X¼Ã[՗7tû0…(@T.;²<¯#JµnÚ?Ü^ ¥RCá&õ[K´2˜ê&ùU¬vu•skOäöøá0é|ûÖÓL*© ˆù1epx¸Â× + KÙɸEw™~Ș׎Íê¶ü_è¶Iõ5E5”ë;æcâ¬íøJÇù†™‘ù¯nv$Ê®Ueèø`;Ʌ’=+@AûŽÌ$¦0ò+ + Œ¢1+)¨á¢°9g€þI9ƵO7`éÀ_0ά>‰7”'º»]àP£r«ed lúòŠ\«©FÖ-ùXQÕñø×Ó¢5Ú÷ê&ðua^–Û•[ÖÿC܆V¸¦[!FÃáù`qk÷OΚàҋiÔv£Pf¥Þdt£¼yΦ#½¬’ø»BwøNÛÁ}G Sƒ|(-›ï¸Úh¤ï×è䰂Ín–FCΰ ûâX,»‘…hS3¹î{¥U˜ vµjÄDcýHwï½$¸¸ï;AðùÝá´y(\äþ‰±šrÞe}u  =t0–¸Y :®¬Ý¾%Ú#¶µ ?7ÑFfÓ3ø›œ ¸ûm¢à¨$¤ØÎ_Ã\,ã“W¾´i\Ã)§±ÚÒQðsÑÓóæ„ÛÁ…-È¥¼;a£ïÍÀÇH*Á€e&5)ˆëót­Z½[#òÅï’4…¦ ¦Ø^¬(7+Êɳ‘ÓãG[ião¬ ùÜiz~ƒ>ɃqèvÄ-)êU + -ÆO“N\,Á:ž¿ìŶ†Q_KĒ”1 + ±´T* n»E˜]–‚ßjýpsHÁ¥±Q,ÓmQ1šv¯¨%¡ËÛ õ"¿ÓêqÏzkÂ5Û^±üߏ&ñ–Y׫)+©ù­w2e@¸ IKŒÔ¤#ÿÎÀ¼}ó¨ !‡ÒƒOŒõ¯eçè2•kÍ*’wÊÇÇé…èü¿˜h]¯ýçžÄ7ƒEÔöC]HOe—ÚÌ]xŒñY •l?›À¹ÞKuáù‰ûØš—k6ƒ8-ÉÀü~¬f·oÁ#Câê=!)Õ !қiÖT}aÂ0é^tÚ8TŸ·úL˜SÑ ±Ùöœ¹F?*cÌÜHLúáþ¨Ï´ÛÕ³pY¶TÄ~•3P7ÔÇÏòhñʆej¼¤@—µþë]aÆØۡ݊‡mˆùðÿf´‚VvÏÓs½£ù/K½¨Å#°@  + 8¦ìÜQï8\¢ˆƒ)¦Xö´#³ä*¤nÆÒñîß{åœßl¤" + jFm%‚K’O¯©Ç xò :CÈ ?e,©âå÷chùÅôD½ú¼sB È£KoZlº²±ºC#£’ŽH{ÕÚäfØ¡·#DÞm¢-“(žyÊG…æàhx¡à¸[:NYÓ¡4¢€üÞ$7ªx{¾ÅJPç¥ý­OôMÜ& + §Tæâ’V’'¤Š.,†kvv35hùU>aƒ0Äï\+?‡¦ë³±* ‡e÷ˆÒAÞ ãSÙ¦Zã¶Ê ؤ…c&ÈÜÿZêN®¼ ½)ç̶z*—ZI§|‘L6‹g«C„rzW8Û-SLåŒTo–³eŸiƒÖM¡ ÊKdÜR€ØlYÎ)¹Iÿn•sÈÍc£ôÏm¨µ\­C=#ÎýVäUII’…üWÁsÿ q¾JRPÉÚ=-EþƲ + ï¬5Ð8ãç•Ê8O48øö¸Ý + Ïú>©n²Í÷˜>Îú3ŒM57/zRïïB¦jAâ3DÈÖxlœóÓÄÙt3_ÍñjÒüîêÓ9$4£ÌªÍmRj+Èjà,~4¼+ªjÆÎtN÷Ë-ÉT&Ÿõ‹éå:¸mŸ ûí34›ED6áî2ÿü[-ïcÖùQÅL²&_óN—L+uNJDŸýɼòåúµ«6_‚aY±=ÖØé÷zrš§ý÷yN­庛¦µûÃ_žHUnÌ÷LïpÝ߄±ãÌãX‡•Ç·™MaBˆçК…dûˆÄmõÙ|p¹ÜjÄ*#I€~¿›Ô?«çZá¶á¢i1™©¼»!l&¨Oø)âp“©((ϺG*¸ ԞV‡”.\7†¸£§„_—šô–FG³í5áUgèQG!ïåï»Ó¥²lœª«MÞߪ>ÉßÝÞ@RU|E’pJÚ¸\º'Š…’^à ËèÀ§Q•5Ó i^«.ŸЕ.—9dï!Jl@Ö¡œ…Å ØîÕKœ­ÉÔÙÁ.¦»[ãk˜-Å!”nâ + |%÷Èb@gû Æþ1°xìÒ2èÓG8Hãª:]ëIمªâšø1¼pó”6ù÷XÇUo“-ՈZú{&Õ®ñWÄð/Zw?RÆÏ>m…’ԍžwgÅÏJ€Góª⒁ &Ӆ#¤ZCgVô•k¦ã4ZéSK¡šNE-¼q…^pL¢Ù\_6X~cà¨ì^ ßàH eNPLŒ‚}éTœÃ9’I瓜W7n§€Ñ¨³’W@$mJLy§§qpºÊøßLšžaoK• + _œÙ¯ÎD…™àÏl‹]u±`>¯2ú4~­ ×?p=Ü7 !¿ÿé¡;jAÌ­K›]vWuLÍKèŸ@€Á$,óÓ6è¹_Ëzv¾–ãìµh¢B’¼ã“ä@èóåœ)$7üKß󮪖A*ðòo|ÉSH¸£>Ÿä*Á¶ßÙg+ðé_»+)NÇÃãw÷à »=ufCpD(® + B0ÕÁÚ\~TĦ9FUù%b->ôò¨‹\gð[©Å«œo'Î]ðw3 Tt?÷ÄøÈ ö /‚PºˆÝñw÷IAõ!Èw°,mŸ2úÝíÕý¢Îu ¡*ç9ëöQþv[‚1øöãà¸#|ªØ³2ãæî¯Póœk4œA§Õ{“5%÷p,˜ãO}Gͦ @{VEÝ%h(†£yƒ + Èb?Ôs¾à ¸¤ó.:Ðê'|Û Ì$¹Y3W£=×Þ6Õªl’Øҕ”Ûs4*W¡`ËÒGÛ%Ä ÐÙ¢4Ž¥-ùè€Ð¶ˆlÁœ¦rªV:©ñáaæѺ⪔›áPÑ0À¹˜“&Íþ±;ăF×KE†œ’íÞ%òž½ƒ°Mrx£»0ð~¬Å89­Dûv§²ËÊ-Ç0(TÕáz†©…R~)‘Cíâ›[ê)¡„Êg|ÒȸC¯ðŸ²•©ï6QÃEö˜z EŸÝœ2˼\P’»ÊÈoP>þ‚8_ËHîõþ›Š6LŠ²h7*gx ïùæ2Èu=ãœ) UO¨âÜ;kċ氝òß%®¶³ J©8dxšaÕf“]íîAÇvŸß{|p"¡$©øð™Öo7^P)["õÏaù Çe/Àž-œ¿ä±/ƒéK;A©<¡'$}¦LhŒ†z½–†Rêü5^ŸÊ—èô=¢S!å?WsÞåÔs‡ÛÀ4®¿ö½zòˆaõOÉŽE¡Ÿ¸·†ßXø<еäo†Äbé6 HöÅ"ž¥NðiÊ{#öî¥1;å:h_µÕO\ÆӀ¯”R! VOôsL7vÿMLŒ1۝Xº + e"ˆ"¡ÀÒ¸ñ‡nN=³0œ &اÞI²Q†²Ý5¶ðHߌ±¯ÌrG‡:ù‹kƒÈð·¶UròãA{rò¸ˆžH Šü@ nƒÞ÷9ÐåV»pþ›ËŠ¸®Á‚LGªK>Õµ‚ž‡‡öA²0”¼òN¯–y=,ó`O]]"8¦œ{°±þ¹h$²Mó­tÆ¢@"ÚÅcüu¬û8ãÖø­22œ¹1$y]&1à¿gWw{âù2pÝ؛ޏÂð•!Äauü6±yÍð‹X¼¤ {ß.8ºÑžñçd,ë6ÙQبŽú…;Ÿ !¹4øgäM ì-ϼdH2yw!ÕοT˜‹\±úvÆ#™“£·¾£Œ¬ 7Øt½?~Gí}®+z¢£P£*?z>õ´¾¥ö¢Q:@ÕÇzohªãïëlX‚5!?–“©áȗ•G`¤óZsh°œœ&Ë¥êãí&`]GòùÞ3“Ð’~».§AÂKSæ ­”c98]²± + b&Ý"ÉeèsדH¯#šÆϒ}1 Z„˜Õ’›š¯g0<礰Ëyã5ت‘Oð5+3îq¯rcq4½!š‘È,ÕÐÅ'nÄOsî×ÉđŽf'‚Æ=B•†zA~WëLcòÛÝ÷ª×éG°¾0/X‚Š†^˜cBؑ‚´ÑÁ´B”ð[Û%?…½GȓÁ¾8+Нx¨ÈæjÛDH,Þ¥Ån™>ç…øOÉ´Y¸åeÆEkfÉoÜ.“áàøÞ§±Õ«çTÒá"Åöð6 ) oô¦Ê—YGðgÛ%ÄåyU-ªZõ &³k %óÃf¼øã!å/"VŽcG6/yU­®SYMϼTq#hËoò”ÀÀ!Iç8¶üɁi½؍†øóø¹»;]:¤m×imzŠto’6Ùý-çMT¹+¡r ¬î“úÀA㊠r`÷,¢Ì:[Qv¥]i÷ü¢á°9‡ï0Å­ÕN>—8m…T´µ®H2˱‰OKn ¥WRÆñÜðD ^'Á±é?³Ét.½±ò<}6*g¡•±Xû4NFAuÕ>?‰úèâG ¯„Xxƕ?f“c£3q¹×© æïס¸±ðKØ¢ &™#ˆÂÖ­ÄoË„GÆáóXç¬G4óx0ôðQõ'™HïÄlZÕÕmgÉ|Š›½·˜q³¾™ãùyÆ­ZvÂH(ñžV ˆ™OÒPæ 7|¬L”Ù&¤hŒÚVîêò;P‡Îñ‰<õd©} RŠ^–zubŒê!dÊf¢<¬#dSJoüÝ:czçé åJOvà + µ­èÚk7›Ã†9ÑÕ¯A…¬ö¿PÈIP! ٛÅwߊJiC¡×Æb†ýXÚÅcíl‡vï/d¤¯˜ý…„ 𚡇:ùr4ñÿìØóf®ªÄe`äÃ<µ×Fg<žˆ–u•™ÉŒ›iX ¤Ïž¢š›§Ò|¦ ¤ç”`Ss,;µËÖ®®ËÆ}Vc³BÜ©Á¬©„¤ k±âýœD‹/ߛH?á®ãˆKǺR¿å>:@'¤#^Hœ6_Á üi*mßÃ+úÖNñ•T„bÁzayŽ6ÄZê*Ž›îÉ´YÜxN#‹@âÀ®¯Çºcx°ÔËTmÏ?¡×XX||Û%Œ[’€9L ²ÓŽôȪ£²óy2JodåXk„þ$YŽ¸ €[´mç‡kÕzÝyb?‰7:l¼%´ù-n³"N•´ÀäŸ=Ý ˆŽtçñT ’lšBz(£ <L»i<Æ·j†oÿ^iy‚F®ºÊ×è_MháÚm7á!ËRcçT(f̏ý?ŸŸv$aåüa§gz‘jx£9ôss¹ mo=֓RŸ,ò²Ðˆ€[ÜÖ´Ãü‹ + hÃuÊ^g©BMòµtlƒ†N!ðîŒà”¯”ÿä?!iÙÑfOR%.—â’Àûã$¶ÛÁ@ñ’û•–²E¾pÝƬr…§Ý}ð+„°¢–3 + θ$‰Y?7D1¡MÃÙ>æÝÔí¨…õ\º9\V ¢R\’]ì®Òuè?u‡_Zxü‡ÑÒfoÂåˆç¦O’ÚÑòD˜E«iBÕß2\ø¢$k/ø‰¡Vû¶èê¦æÛ#r¡ ä²ÜæmÙa]6·^oí0ǐž˜Vf s;C‰XföUÁ8Eþ" ãè$©nŽ€º.åZBʔq„'y3:{×é`+úÁx‰qMӇKEGÁÆt6›(å¥àsÜ;0˜úv!%Çô‰DYJ4DsHi¹Ú‡XØMÔ¼Ým¼~ëqùD`3¶bÂ"û³s³u©"s1ü{¦o`—õóºX¨Nõ£òÅÁöŽp#Ò³Z4q‡Ê‘Ê + 5äg+8'É9lßJµÚã­RÃÿ LíM¶8\Ýs€ÔVV2ÿ±zêj&vžŸMzv®¬Œ ¬w%õÀäkœp)(¼Kè¦÷BAo0 "==ïvIÜ^ˆ¬:¥K;ýÝ*Õ#·b¶æzyú½QÄMÏ®yy‚]¨f½JÔ7Ç2JXàlš¬ÓOÝÞa² Ïl0›'¦ ÐÁ' è=Iž«æ~Ðr’%ã²ÖOh*‡W’=[>l§^Ÿ!*¦ Nh$Hñú  + ¤äw8õ"໊‚Z1 iÿ=ç-»ÆÀ¶P¯Œ¡ÈLÐ$#6|øoLaÚ«é1éÍŒö-fŒ4|>™’2=ƒ”ÓX“%€²aq¼`?˜—T3Ô\+·ß¶Úµ<7jINqlÁzÌtb˜¸ǵ9÷}cf˜+®ÏÙÁD¡z å+ç¾ÅOt)«1tu(tÓa܊ÇI]UL\BXIJõ{‡Ë:Õ²¼K0†úljKô†Ê°~vt›sQ‹ÏouëÑKµž$æۖܡɺ8B ü(7PúF`æsÍ$Q! ƒGE¾oÜÝòyŽ˜í܏ÿÞƒÈ öO;š›Uì’BJZe}l”áӐ!Oz@¬RùɅ)«C÷º¹+£Ñ0˃´ šæ!.–“ï̱\Ä JECNÃ-ª.^‰Ž$ÄZ¦yr#X•µ>½_8EšNBëï¾WpãÆ(Ҕj0$h3`ÄÞ¸€à˾V!Rjå=mÞÕ/ñ\¾h*øPɂòg§è‚óp¤TÒ𠴊<þ¨%Cl×TFí[7Ñ%²IwoÒø·P°=úcE£r™¤›\7½g³ÑõÿEݸbœ… ;ß?¼¢ê%WºQ`‹“fsJ[Β°°üxØÁ3µÓêÅ›/^cŽYûH ñ_ZØw-!uB³Þ3í—&÷IjÝ%¯^n¡º ³ÔÙ£dñfî%²Ùl*ÖZÀWÔã5K¸9@ÒøóA© + šÕhzÿ2DkşáÇ1h5jÊMÁÜg­{m²ã¿.Ü sŠâǏ¸"Oä›Å§l>Ý':cr cÕª>Ò;µ]£'}<Â<]܎¿#óÉiÿKà4YýÅWí’{5œôÇÚMÓ²ïfx «{©ÓƒqP4zm57çrȝߋ›™‡Êýís@°g*JRrô—Ž–$Ú ÓŒ‚E1&NìdÌ + #‹%&âW)£BÀà©Õz®GQC÷3&CИí!{³‘8V‰ƒŸY?ßt¯G™>–3ƒ…v5ý¼; ’‚ÃIX}mM¦tnh8{M<B†ã#èZ–ˆ@qÁpÉI±cìä“ ¬æ‰™Óö `ڒ×)Iu#K7`ÁýÅI[C£Z¾Èl7qp?Ù£Ï R4¯FíՒŠ„6&ýÕ \ No newline at end of file *** ../vim-8.2.3021/src/testdir/test_crypt.vim 2020-08-12 18:50:31.875655822 +0200 --- src/testdir/test_crypt.vim 2021-06-20 13:58:02.237493920 +0200 *************** *** 22,27 **** --- 22,32 ---- call Common_head_only('VimCrypt~03!abc') endfunc + func Test_head_only_4() + CheckFeature sodium + call Common_head_only('VimCrypt~04!abc') + endfunc + func Crypt_uncrypt(method) exe "set cryptmethod=" . a:method " If the blowfish test fails 'cryptmethod' will be 'zip' now. *************** *** 55,60 **** --- 60,70 ---- call Crypt_uncrypt('blowfish2') endfunc + func Test_crypt_sodium() + CheckFeature sodium + call Crypt_uncrypt('xchacha20') + endfunc + func Uncrypt_stable(method, crypted_text, key, uncrypted_text) split Xtest.txt set bin noeol key= fenc=latin1 *************** *** 70,75 **** --- 80,95 ---- set key= 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\" . a:key . "\", '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() 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 *************** *** 78,87 **** 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 ! func Test_uncrypt_blowfish2() 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 func Test_uncrypt_unknown_method() split Xuncrypt_unknown.txt set bin noeol key= fenc=latin1 --- 98,212 ---- 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 ! 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", "!@#$%^&*()_+=-`~"]) 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\sodium\", '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\sodium\sodium\", '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\sodium\", '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\sodium\sodium\", '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\sodium\", '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() split Xuncrypt_unknown.txt set bin noeol key= fenc=latin1 *** ../vim-8.2.3021/src/undo.c 2020-08-30 19:26:40.736556825 +0200 --- src/undo.c 2021-06-20 12:55:37.791731158 +0200 *************** *** 963,969 **** { 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); if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1) return FAIL; bi->bi_used = 0; --- 963,971 ---- { if (bi->bi_buffer != NULL && bi->bi_state != NULL && bi->bi_used > 0) { ! // 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) return FAIL; bi->bi_used = 0; *************** *** 995,1001 **** if (copy == NULL) return 0; } ! crypt_encode(bi->bi_state, ptr, len, copy); i = fwrite(copy, len, (size_t)1, bi->bi_fp); if (copy != small_buf) vim_free(copy); --- 997,1005 ---- if (copy == NULL) return 0; } ! // 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); if (copy != small_buf) vim_free(copy); *************** *** 1129,1135 **** } bi->bi_avail = n; bi->bi_used = 0; ! crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail); } n = size_todo; if (n > bi->bi_avail - bi->bi_used) --- 1133,1139 ---- } bi->bi_avail = n; bi->bi_used = 0; ! crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail, FALSE); } n = size_todo; if (n > bi->bi_avail - bi->bi_used) *************** *** 1176,1182 **** ptr[len] = NUL; #ifdef FEAT_CRYPT if (bi->bi_state != NULL && bi->bi_buffer == NULL) ! crypt_decode_inplace(bi->bi_state, ptr, len); #endif } return ptr; --- 1180,1186 ---- ptr[len] = NUL; #ifdef FEAT_CRYPT if (bi->bi_state != NULL && bi->bi_buffer == NULL) ! crypt_decode_inplace(bi->bi_state, ptr, len, FALSE); #endif } return ptr; *** ../vim-8.2.3021/src/version.c 2021-06-20 12:40:05.342813034 +0200 --- src/version.c 2021-06-20 12:54:03.556035811 +0200 *************** *** 553,558 **** --- 553,563 ---- #else "-smartindent", #endif + #ifdef FEAT_SODIUM + "+sodium", + #else + "-sodium", + #endif #ifdef FEAT_SOUND "+sound", #else *** ../vim-8.2.3021/src/version.c 2021-06-20 12:40:05.342813034 +0200 --- src/version.c 2021-06-20 12:54:03.556035811 +0200 *************** *** 752,753 **** --- 757,760 ---- { /* Add new patch number below this line */ + /**/ + 3022, /**/ -- Computers are useless. They can only give you answers. -- Pablo Picasso /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///