Karsten Hopp 5f67cf
To: vim_dev@googlegroups.com
Karsten Hopp 5f67cf
Subject: Patch 7.4.399
Karsten Hopp 5f67cf
Fcc: outbox
Karsten Hopp 5f67cf
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 5f67cf
Mime-Version: 1.0
Karsten Hopp 5f67cf
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 5f67cf
Content-Transfer-Encoding: 8bit
Karsten Hopp 5f67cf
------------
Karsten Hopp 5f67cf
Karsten Hopp 5f67cf
Patch 7.4.399
Karsten Hopp 5f67cf
Problem:    Encryption implementation is messy.  Blowfish encryption has a
Karsten Hopp 5f67cf
	    weakness.
Karsten Hopp 5f67cf
Solution:   Refactor the encryption, store the state in an allocated struct
Karsten Hopp 5f67cf
	    instead of using a save/restore mechanism.  Introduce the
Karsten Hopp 5f67cf
	    "blowfish2" method, which does not have the weakness and encrypts
Karsten Hopp 5f67cf
	    the whole undo file. (largely by David Leadbeater)
Karsten Hopp 5f67cf
Files:	    runtime/doc/editing.txt, runtime/doc/options.txt, src/Makefile,
Karsten Hopp 5f67cf
	    src/blowfish.c, src/crypt.c, src/crypt_zip.c, src/ex_docmd.c,
Karsten Hopp 5f67cf
	    src/fileio.c, src/globals.h, src/main.c, src/memline.c,
Karsten Hopp 5f67cf
	    src/misc2.c, src/option.c, src/proto.h, src/proto/blowfish.pro,
Karsten Hopp 5f67cf
	    src/proto/crypt.pro, src/proto/crypt_zip.pro,
Karsten Hopp 5f67cf
	    src/proto/fileio.pro, src/proto/misc2.pro, src/structs.h,
Karsten Hopp 5f67cf
	    src/undo.c, src/testdir/test71.in, src/testdir/test71.ok,
Karsten Hopp 5f67cf
	    src/testdir/test71a.in, src/testdir/test72.in,
Karsten Hopp 5f67cf
	    src/testdir/test72.ok
Karsten Hopp 5f67cf
Karsten Hopp 5f67cf
Karsten Hopp 5f67cf
*** ../vim-7.4.398/runtime/doc/editing.txt	2013-08-10 13:24:53.000000000 +0200
Karsten Hopp 5f67cf
--- runtime/doc/editing.txt	2014-08-09 15:35:40.101354406 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1361,1371 ****
Karsten Hopp 5f67cf
  {only available when compiled with the |+cryptv| feature}  *E833*
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  The text in the swap file and the undo file is also encrypted.  *E843*
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  Note: The text in memory is not encrypted.  A system administrator may be able
Karsten Hopp 5f67cf
  to see your text while you are editing it.  When filtering text with
Karsten Hopp 5f67cf
! ":!filter" or using ":w !command" the text is not encrypted, this may reveal
Karsten Hopp 5f67cf
! it to others.  The 'viminfo' file is not encrypted.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  WARNING: If you make a typo when entering the key and then write the file and
Karsten Hopp 5f67cf
  exit, the text will be lost!
Karsten Hopp 5f67cf
--- 1362,1382 ----
Karsten Hopp 5f67cf
  {only available when compiled with the |+cryptv| feature}  *E833*
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  The text in the swap file and the undo file is also encrypted.  *E843*
Karsten Hopp 5f67cf
+ However, this is done block-by-block and may reduce the time needed to crack a
Karsten Hopp 5f67cf
+ password.  You can disable the swap file, but then a crash will cause you to
Karsten Hopp 5f67cf
+ lose your work.  The undo file can be disabled without much disadvantage. >
Karsten Hopp 5f67cf
+ 	:set noundofile
Karsten Hopp 5f67cf
+ 	:noswapfile edit secrets
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  Note: The text in memory is not encrypted.  A system administrator may be able
Karsten Hopp 5f67cf
  to see your text while you are editing it.  When filtering text with
Karsten Hopp 5f67cf
! ":!filter" or using ":w !command" the text is also not encrypted, this may
Karsten Hopp 5f67cf
! reveal it to others.  The 'viminfo' file is not encrypted.
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! You could do this to edit very secret text: >
Karsten Hopp 5f67cf
! 	:set noundofile viminfo=
Karsten Hopp 5f67cf
! 	:noswapfile edit secrets.txt
Karsten Hopp 5f67cf
! Keep in mind that without a swap file you risk loosing your work in a crash.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  WARNING: If you make a typo when entering the key and then write the file and
Karsten Hopp 5f67cf
  exit, the text will be lost!
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1392,1409 ****
Karsten Hopp 5f67cf
  	:set key=
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  You can use the 'cryptmethod' option to select the type of encryption, use one
Karsten Hopp 5f67cf
! of these two: >
Karsten Hopp 5f67cf
! 	:setlocal cm=zip       " weak method, backwards compatible
Karsten Hopp 5f67cf
! 	:setlocal cm=blowfish  " strong method
Karsten Hopp 5f67cf
  Do this before writing the file.  When reading an encrypted file it will be
Karsten Hopp 5f67cf
  set automatically to the method used when that file was written.  You can
Karsten Hopp 5f67cf
  change 'cryptmethod' before writing that file to change the method.
Karsten Hopp 5f67cf
  To set the default method, used for new files, use one of these in your
Karsten Hopp 5f67cf
  |vimrc| file: >
Karsten Hopp 5f67cf
  	set cm=zip
Karsten Hopp 5f67cf
! 	set cm=blowfish
Karsten Hopp 5f67cf
  The message given for reading and writing a file will show "[crypted]" when
Karsten Hopp 5f67cf
! using zip, "[blowfish]" when using blowfish.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  When writing an undo file, the same key and method will be used for the text
Karsten Hopp 5f67cf
  in the undo file. |persistent-undo|.
Karsten Hopp 5f67cf
--- 1403,1427 ----
Karsten Hopp 5f67cf
  	:set key=
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  You can use the 'cryptmethod' option to select the type of encryption, use one
Karsten Hopp 5f67cf
! of these: >
Karsten Hopp 5f67cf
! 	:setlocal cm=zip        " weak method, backwards compatible
Karsten Hopp 5f67cf
! 	:setlocal cm=blowfish   " method with flaws
Karsten Hopp 5f67cf
! 	:setlocal cm=blowfish2  " medium strong method
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
  Do this before writing the file.  When reading an encrypted file it will be
Karsten Hopp 5f67cf
  set automatically to the method used when that file was written.  You can
Karsten Hopp 5f67cf
  change 'cryptmethod' before writing that file to change the method.
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  To set the default method, used for new files, use one of these in your
Karsten Hopp 5f67cf
  |vimrc| file: >
Karsten Hopp 5f67cf
  	set cm=zip
Karsten Hopp 5f67cf
! 	set cm=blowfish2
Karsten Hopp 5f67cf
! Use the first one if you need to be compatible with Vim 7.2 and older.  Using
Karsten Hopp 5f67cf
! "blowfish2" is highly recommended if you can use a Vim version that supports
Karsten Hopp 5f67cf
! it.
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
  The message given for reading and writing a file will show "[crypted]" when
Karsten Hopp 5f67cf
! using zip, "[blowfish]" when using blowfish, etc.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  When writing an undo file, the same key and method will be used for the text
Karsten Hopp 5f67cf
  in the undo file. |persistent-undo|.
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1438,1444 ****
Karsten Hopp 5f67cf
       0	string	VimCrypt~	Vim encrypted file
Karsten Hopp 5f67cf
       >9	string	01	- "zip" cryptmethod
Karsten Hopp 5f67cf
       >9	string	02	- "blowfish" cryptmethod
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  Notes:
Karsten Hopp 5f67cf
  - Encryption is not possible when doing conversion with 'charconvert'.
Karsten Hopp 5f67cf
--- 1456,1462 ----
Karsten Hopp 5f67cf
       0	string	VimCrypt~	Vim encrypted file
Karsten Hopp 5f67cf
       >9	string	01	- "zip" cryptmethod
Karsten Hopp 5f67cf
       >9	string	02	- "blowfish" cryptmethod
Karsten Hopp 5f67cf
!      >9	string	03	- "blowfish2" cryptmethod
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  Notes:
Karsten Hopp 5f67cf
  - Encryption is not possible when doing conversion with 'charconvert'.
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1462,1481 ****
Karsten Hopp 5f67cf
  - Pkzip uses the same encryption as 'cryptmethod' "zip", and US Govt has no
Karsten Hopp 5f67cf
    objection to its export.  Pkzip's public file APPNOTE.TXT describes this
Karsten Hopp 5f67cf
    algorithm in detail.
Karsten Hopp 5f67cf
  - Vim originates from the Netherlands.  That is where the sources come from.
Karsten Hopp 5f67cf
    Thus the encryption code is not exported from the USA.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  ==============================================================================
Karsten Hopp 5f67cf
  10. Timestamps					*timestamp* *timestamps*
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! Vim remembers the modification timestamp of a file when you begin editing it.
Karsten Hopp 5f67cf
! This is used to avoid that you have two different versions of the same file
Karsten Hopp 5f67cf
! (without you knowing this).
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! After a shell command is run (|:!cmd| |suspend| |:read!| |K|) timestamps are
Karsten Hopp 5f67cf
! compared for all buffers in a window.   Vim will run any associated
Karsten Hopp 5f67cf
! |FileChangedShell| autocommands or display a warning for any files that have
Karsten Hopp 5f67cf
! changed.  In the GUI this happens when Vim regains input focus.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  							*E321* *E462*
Karsten Hopp 5f67cf
  If you want to automatically reload a file when it has been changed outside of
Karsten Hopp 5f67cf
--- 1480,1504 ----
Karsten Hopp 5f67cf
  - Pkzip uses the same encryption as 'cryptmethod' "zip", and US Govt has no
Karsten Hopp 5f67cf
    objection to its export.  Pkzip's public file APPNOTE.TXT describes this
Karsten Hopp 5f67cf
    algorithm in detail.
Karsten Hopp 5f67cf
+ - The implmentation of 'cryptmethod' "blowfish" has a flaw.  It is possible to
Karsten Hopp 5f67cf
+   crack the first 64 bytes of a file and in some circumstances more of the
Karsten Hopp 5f67cf
+   file. Use of it is not recommended, but it's still the strongest method
Karsten Hopp 5f67cf
+   supported by Vim 7.3 and 7.4.  The "zip" method is even weaker.
Karsten Hopp 5f67cf
  - Vim originates from the Netherlands.  That is where the sources come from.
Karsten Hopp 5f67cf
    Thus the encryption code is not exported from the USA.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  ==============================================================================
Karsten Hopp 5f67cf
  10. Timestamps					*timestamp* *timestamps*
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! Vim remembers the modification timestamp, mode and size of a file when you
Karsten Hopp 5f67cf
! begin editing it.  This is used to avoid that you have two different versions
Karsten Hopp 5f67cf
! of the same file (without you knowing this).
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! After a shell command is run (|:!cmd| |suspend| |:read!| |K|) timestamps,
Karsten Hopp 5f67cf
! file modes and file sizes are compared for all buffers in a window.   Vim will
Karsten Hopp 5f67cf
! run any associated |FileChangedShell| autocommands or display a warning for
Karsten Hopp 5f67cf
! any files that have changed.  In the GUI this happens when Vim regains input
Karsten Hopp 5f67cf
! focus.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  							*E321* *E462*
Karsten Hopp 5f67cf
  If you want to automatically reload a file when it has been changed outside of
Karsten Hopp 5f67cf
*** ../vim-7.4.398/runtime/doc/options.txt	2014-08-06 14:52:05.039236174 +0200
Karsten Hopp 5f67cf
--- runtime/doc/options.txt	2014-08-09 15:36:48.165353916 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2229,2238 ****
Karsten Hopp 5f67cf
  	   zip		PkZip compatible method.  A weak kind of encryption.
Karsten Hopp 5f67cf
  			Backwards compatible with Vim 7.2 and older.
Karsten Hopp 5f67cf
  							*blowfish*
Karsten Hopp 5f67cf
! 	   blowfish	Blowfish method.  Strong encryption.  Requires Vim 7.3
Karsten Hopp 5f67cf
! 			or later, files can NOT be read by Vim 7.2 and older.
Karsten Hopp 5f67cf
! 			This adds a "seed" to the file, every time you write
Karsten Hopp 5f67cf
! 			the file the encrypted bytes will be different.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	When reading an encrypted file 'cryptmethod' will be set automatically
Karsten Hopp 5f67cf
  	to the detected method of the file being read.  Thus if you write it
Karsten Hopp 5f67cf
--- 2229,2246 ----
Karsten Hopp 5f67cf
  	   zip		PkZip compatible method.  A weak kind of encryption.
Karsten Hopp 5f67cf
  			Backwards compatible with Vim 7.2 and older.
Karsten Hopp 5f67cf
  							*blowfish*
Karsten Hopp 5f67cf
! 	   blowfish	Blowfish method.  Medium strong encryption but it has
Karsten Hopp 5f67cf
! 			an implementation flaw.  Requires Vim 7.3 or later,
Karsten Hopp 5f67cf
! 			files can NOT be read by Vim 7.2 and older.  This adds
Karsten Hopp 5f67cf
! 			a "seed" to the file, every time you write the file
Karsten Hopp 5f67cf
! 			the encrypted bytes will be different.
Karsten Hopp 5f67cf
! 							*blowfish2*
Karsten Hopp 5f67cf
! 	   blowfish2	Blowfish method.  Medium strong encryption.  Requires
Karsten Hopp 5f67cf
! 			Vim 7.4.399 or later, files can NOT be read by Vim 7.3
Karsten Hopp 5f67cf
! 			and older.  This adds a "seed" to the file, every time
Karsten Hopp 5f67cf
! 			you write the file the encrypted bytes will be
Karsten Hopp 5f67cf
! 			different.  The whole undo file is encrypted, not just
Karsten Hopp 5f67cf
! 			the pieces of text.
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	When reading an encrypted file 'cryptmethod' will be set automatically
Karsten Hopp 5f67cf
  	to the detected method of the file being read.  Thus if you write it
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/Makefile	2014-05-22 14:54:22.850468654 +0200
Karsten Hopp 5f67cf
--- src/Makefile	2014-08-09 15:37:19.689353690 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1431,1436 ****
Karsten Hopp 5f67cf
--- 1431,1438 ----
Karsten Hopp 5f67cf
  	blowfish.c \
Karsten Hopp 5f67cf
  	buffer.c \
Karsten Hopp 5f67cf
  	charset.c \
Karsten Hopp 5f67cf
+ 	crypt.c \
Karsten Hopp 5f67cf
+ 	crypt_zip.c \
Karsten Hopp 5f67cf
  	diff.c \
Karsten Hopp 5f67cf
  	digraph.c \
Karsten Hopp 5f67cf
  	edit.c \
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1520,1525 ****
Karsten Hopp 5f67cf
--- 1522,1529 ----
Karsten Hopp 5f67cf
  	objects/buffer.o \
Karsten Hopp 5f67cf
  	objects/blowfish.o \
Karsten Hopp 5f67cf
  	objects/charset.o \
Karsten Hopp 5f67cf
+ 	objects/crypt.o \
Karsten Hopp 5f67cf
+ 	objects/crypt_zip.o \
Karsten Hopp 5f67cf
  	objects/diff.o \
Karsten Hopp 5f67cf
  	objects/digraph.o \
Karsten Hopp 5f67cf
  	objects/edit.o \
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1589,1594 ****
Karsten Hopp 5f67cf
--- 1593,1600 ----
Karsten Hopp 5f67cf
  	blowfish.pro \
Karsten Hopp 5f67cf
  	buffer.pro \
Karsten Hopp 5f67cf
  	charset.pro \
Karsten Hopp 5f67cf
+ 	crypt.pro \
Karsten Hopp 5f67cf
+ 	crypt_zip.pro \
Karsten Hopp 5f67cf
  	diff.pro \
Karsten Hopp 5f67cf
  	digraph.pro \
Karsten Hopp 5f67cf
  	edit.pro \
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1753,1762 ****
Karsten Hopp 5f67cf
  languages:
Karsten Hopp 5f67cf
  	@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
Karsten Hopp 5f67cf
  		cd $(PODIR); \
Karsten Hopp 5f67cf
! 		CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix); \
Karsten Hopp 5f67cf
  	fi
Karsten Hopp 5f67cf
  	-@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
Karsten Hopp 5f67cf
! 		cd $(PODIR); CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix) converted; \
Karsten Hopp 5f67cf
  	fi
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  # Update the *.po files for changes in the sources.  Only run manually.
Karsten Hopp 5f67cf
--- 1759,1769 ----
Karsten Hopp 5f67cf
  languages:
Karsten Hopp 5f67cf
  	@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
Karsten Hopp 5f67cf
  		cd $(PODIR); \
Karsten Hopp 5f67cf
! 		  CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix); \
Karsten Hopp 5f67cf
  	fi
Karsten Hopp 5f67cf
  	-@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
Karsten Hopp 5f67cf
! 		cd $(PODIR); \
Karsten Hopp 5f67cf
! 		  CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix) converted; \
Karsten Hopp 5f67cf
  	fi
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  # Update the *.po files for changes in the sources.  Only run manually.
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1883,1890 ****
Karsten Hopp 5f67cf
--- 1890,1903 ----
Karsten Hopp 5f67cf
  # Run individual test, assuming that Vim was already compiled.
Karsten Hopp 5f67cf
  test1 test2 test3 test4 test5 test6 test7 test8 test9 \
Karsten Hopp 5f67cf
  	test_autoformat_join \
Karsten Hopp 5f67cf
+ 	test_breakindent \
Karsten Hopp 5f67cf
+ 	test_changelist \
Karsten Hopp 5f67cf
  	test_eval \
Karsten Hopp 5f67cf
+ 	test_insertcount \
Karsten Hopp 5f67cf
+ 	test_listlbr \
Karsten Hopp 5f67cf
+ 	test_listlbr_utf8 \
Karsten Hopp 5f67cf
  	test_options \
Karsten Hopp 5f67cf
+ 	test_qf_title \
Karsten Hopp 5f67cf
  	test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \
Karsten Hopp 5f67cf
  	test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \
Karsten Hopp 5f67cf
  	test30 test31 test32 test33 test34 test35 test36 test37 test38 test39 \
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2506,2511 ****
Karsten Hopp 5f67cf
--- 2519,2530 ----
Karsten Hopp 5f67cf
  objects/charset.o: charset.c
Karsten Hopp 5f67cf
  	$(CCC) -o $@ charset.c
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
+ objects/crypt.o: crypt.c
Karsten Hopp 5f67cf
+ 	$(CCC) -o $@ crypt.c
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ objects/crypt_zip.o: crypt_zip.c
Karsten Hopp 5f67cf
+ 	$(CCC) -o $@ crypt_zip.c
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  objects/diff.o: diff.c
Karsten Hopp 5f67cf
  	$(CCC) -o $@ diff.c
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2855,2860 ****
Karsten Hopp 5f67cf
--- 2874,2887 ----
Karsten Hopp 5f67cf
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
Karsten Hopp 5f67cf
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
Karsten Hopp 5f67cf
   arabic.h
Karsten Hopp 5f67cf
+ objects/crypt.o: crypt.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \
Karsten Hopp 5f67cf
+  ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
Karsten Hopp 5f67cf
+  gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
Karsten Hopp 5f67cf
+  arabic.h
Karsten Hopp 5f67cf
+ objects/crypt_zip.o: crypt_zip.c vim.h auto/config.h feature.h os_unix.h \
Karsten Hopp 5f67cf
+  auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
Karsten Hopp 5f67cf
+  regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
Karsten Hopp 5f67cf
+  globals.h farsi.h arabic.h
Karsten Hopp 5f67cf
  objects/diff.o: diff.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \
Karsten Hopp 5f67cf
   ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
Karsten Hopp 5f67cf
   gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/blowfish.c	2014-02-11 15:23:27.930123631 +0100
Karsten Hopp 5f67cf
--- src/blowfish.c	2014-08-09 15:31:32.493356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 9,25 ****
Karsten Hopp 5f67cf
   * Blowfish encryption for Vim; in Blowfish cipher feedback mode.
Karsten Hopp 5f67cf
   * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh
Karsten Hopp 5f67cf
   * Based on http://www.schneier.com/blowfish.html by Bruce Schneier.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #include "vim.h"
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! #if defined(FEAT_CRYPT)
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define ARRAY_LENGTH(A)      (sizeof(A)/sizeof(A[0]))
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define BF_BLOCK    8
Karsten Hopp 5f67cf
  #define BF_BLOCK_MASK 7
Karsten Hopp 5f67cf
! #define BF_CFB_LEN  (8*(BF_BLOCK))
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  typedef union {
Karsten Hopp 5f67cf
      UINT32_T ul[2];
Karsten Hopp 5f67cf
--- 9,33 ----
Karsten Hopp 5f67cf
   * Blowfish encryption for Vim; in Blowfish cipher feedback mode.
Karsten Hopp 5f67cf
   * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh
Karsten Hopp 5f67cf
   * Based on http://www.schneier.com/blowfish.html by Bruce Schneier.
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * There are two variants:
Karsten Hopp 5f67cf
+  * - The old one "blowfish" has a flaw which makes it much easier to crack the
Karsten Hopp 5f67cf
+  *   key.  To see this, make a text file with one line of 1000 "x" characters
Karsten Hopp 5f67cf
+  *   and write it encrypted.  Use "xxd" to inspect the bytes in the file.  You
Karsten Hopp 5f67cf
+  *   will see that a block of 8 bytes repeats 8 times.
Karsten Hopp 5f67cf
+  * - The new one "blowfish2" is better.  It uses an 8 byte CFB to avoid the
Karsten Hopp 5f67cf
+  *   repeats.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #include "vim.h"
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! #if defined(FEAT_CRYPT) || defined(PROTO)
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define ARRAY_LENGTH(A)      (sizeof(A)/sizeof(A[0]))
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define BF_BLOCK    8
Karsten Hopp 5f67cf
  #define BF_BLOCK_MASK 7
Karsten Hopp 5f67cf
! #define BF_MAX_CFB_LEN  (8 * BF_BLOCK)
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  typedef union {
Karsten Hopp 5f67cf
      UINT32_T ul[2];
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 37,50 ****
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! static void bf_e_block __ARGS((UINT32_T *p_xl, UINT32_T *p_xr));
Karsten Hopp 5f67cf
! static void bf_e_cblock __ARGS((char_u *block));
Karsten Hopp 5f67cf
! static int bf_check_tables __ARGS((UINT32_T a_ipa[18], UINT32_T a_sbi[4][256], UINT32_T val));
Karsten Hopp 5f67cf
  static int bf_self_test __ARGS((void));
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /* Blowfish code */
Karsten Hopp 5f67cf
! static UINT32_T pax[18];
Karsten Hopp 5f67cf
! static UINT32_T ipa[18] = {
Karsten Hopp 5f67cf
      0x243f6a88u, 0x85a308d3u, 0x13198a2eu,
Karsten Hopp 5f67cf
      0x03707344u, 0xa4093822u, 0x299f31d0u,
Karsten Hopp 5f67cf
      0x082efa98u, 0xec4e6c89u, 0x452821e6u,
Karsten Hopp 5f67cf
--- 45,70 ----
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! /* The state of encryption, referenced by cryptstate_T. */
Karsten Hopp 5f67cf
! typedef struct {
Karsten Hopp 5f67cf
!     UINT32_T	pax[18];	    /* P-array */
Karsten Hopp 5f67cf
!     UINT32_T	sbx[4][256];	    /* S-boxes */
Karsten Hopp 5f67cf
!     int		randbyte_offset;
Karsten Hopp 5f67cf
!     int		update_offset;
Karsten Hopp 5f67cf
!     char_u	cfb_buffer[BF_MAX_CFB_LEN]; /* up to 64 bytes used */
Karsten Hopp 5f67cf
!     int		cfb_len;	    /* size of cfb_buffer actually used */
Karsten Hopp 5f67cf
! } bf_state_T;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! static void bf_e_block __ARGS((bf_state_T *state, UINT32_T *p_xl, UINT32_T *p_xr));
Karsten Hopp 5f67cf
! static void bf_e_cblock __ARGS((bf_state_T *state, char_u *block));
Karsten Hopp 5f67cf
! static int bf_check_tables __ARGS((UINT32_T pax[18], UINT32_T sbx[4][256], UINT32_T val));
Karsten Hopp 5f67cf
  static int bf_self_test __ARGS((void));
Karsten Hopp 5f67cf
+ static void bf_key_init __ARGS((bf_state_T *state, char_u *password, char_u *salt, int salt_len));
Karsten Hopp 5f67cf
+ static void bf_cfb_init __ARGS((bf_state_T *state, char_u *seed, int seed_len));
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /* Blowfish code */
Karsten Hopp 5f67cf
! static UINT32_T pax_init[18] = {
Karsten Hopp 5f67cf
      0x243f6a88u, 0x85a308d3u, 0x13198a2eu,
Karsten Hopp 5f67cf
      0x03707344u, 0xa4093822u, 0x299f31d0u,
Karsten Hopp 5f67cf
      0x082efa98u, 0xec4e6c89u, 0x452821e6u,
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 53,60 ****
Karsten Hopp 5f67cf
      0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
Karsten Hopp 5f67cf
  };
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! static UINT32_T sbx[4][256];
Karsten Hopp 5f67cf
! static UINT32_T sbi[4][256] = {
Karsten Hopp 5f67cf
     {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u,
Karsten Hopp 5f67cf
      0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u,
Karsten Hopp 5f67cf
      0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u,
Karsten Hopp 5f67cf
--- 73,79 ----
Karsten Hopp 5f67cf
      0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
Karsten Hopp 5f67cf
  };
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! static UINT32_T sbx_init[4][256] = {
Karsten Hopp 5f67cf
     {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u,
Karsten Hopp 5f67cf
      0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u,
Karsten Hopp 5f67cf
      0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u,
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 314,346 ****
Karsten Hopp 5f67cf
   }
Karsten Hopp 5f67cf
  };
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  #define F1(i) \
Karsten Hopp 5f67cf
!     xl ^= pax[i]; \
Karsten Hopp 5f67cf
!     xr ^= ((sbx[0][xl >> 24] + \
Karsten Hopp 5f67cf
!     sbx[1][(xl & 0xFF0000) >> 16]) ^ \
Karsten Hopp 5f67cf
!     sbx[2][(xl & 0xFF00) >> 8]) + \
Karsten Hopp 5f67cf
!     sbx[3][xl & 0xFF];
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define F2(i) \
Karsten Hopp 5f67cf
!     xr ^= pax[i]; \
Karsten Hopp 5f67cf
!     xl ^= ((sbx[0][xr >> 24] + \
Karsten Hopp 5f67cf
!     sbx[1][(xr & 0xFF0000) >> 16]) ^ \
Karsten Hopp 5f67cf
!     sbx[2][(xr & 0xFF00) >> 8]) + \
Karsten Hopp 5f67cf
!     sbx[3][xr & 0xFF];
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! bf_e_block(p_xl, p_xr)
Karsten Hopp 5f67cf
      UINT32_T *p_xl;
Karsten Hopp 5f67cf
      UINT32_T *p_xr;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     UINT32_T temp, xl = *p_xl, xr = *p_xr;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     F1(0) F2(1) F1(2) F2(3) F1(4) F2(5) F1(6) F2(7)
Karsten Hopp 5f67cf
!     F1(8) F2(9) F1(10) F2(11) F1(12) F2(13) F1(14) F2(15)
Karsten Hopp 5f67cf
!     xl ^= pax[16];
Karsten Hopp 5f67cf
!     xr ^= pax[17];
Karsten Hopp 5f67cf
      temp = xl;
Karsten Hopp 5f67cf
      xl = xr;
Karsten Hopp 5f67cf
      xr = temp;
Karsten Hopp 5f67cf
--- 333,372 ----
Karsten Hopp 5f67cf
   }
Karsten Hopp 5f67cf
  };
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define F1(i) \
Karsten Hopp 5f67cf
!     xl ^= bfs->pax[i]; \
Karsten Hopp 5f67cf
!     xr ^= ((bfs->sbx[0][xl >> 24] + \
Karsten Hopp 5f67cf
!     bfs->sbx[1][(xl & 0xFF0000) >> 16]) ^ \
Karsten Hopp 5f67cf
!     bfs->sbx[2][(xl & 0xFF00) >> 8]) + \
Karsten Hopp 5f67cf
!     bfs->sbx[3][xl & 0xFF];
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define F2(i) \
Karsten Hopp 5f67cf
!     xr ^= bfs->pax[i]; \
Karsten Hopp 5f67cf
!     xl ^= ((bfs->sbx[0][xr >> 24] + \
Karsten Hopp 5f67cf
!     bfs->sbx[1][(xr & 0xFF0000) >> 16]) ^ \
Karsten Hopp 5f67cf
!     bfs->sbx[2][(xr & 0xFF00) >> 8]) + \
Karsten Hopp 5f67cf
!     bfs->sbx[3][xr & 0xFF];
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! bf_e_block(bfs, p_xl, p_xr)
Karsten Hopp 5f67cf
!     bf_state_T *bfs;
Karsten Hopp 5f67cf
      UINT32_T *p_xl;
Karsten Hopp 5f67cf
      UINT32_T *p_xr;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     UINT32_T temp;
Karsten Hopp 5f67cf
!     UINT32_T xl = *p_xl;
Karsten Hopp 5f67cf
!     UINT32_T xr = *p_xr;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     F1(0) F2(1)
Karsten Hopp 5f67cf
!     F1(2) F2(3)
Karsten Hopp 5f67cf
!     F1(4) F2(5)
Karsten Hopp 5f67cf
!     F1(6) F2(7)
Karsten Hopp 5f67cf
!     F1(8) F2(9)
Karsten Hopp 5f67cf
!     F1(10) F2(11)
Karsten Hopp 5f67cf
!     F1(12) F2(13)
Karsten Hopp 5f67cf
!     F1(14) F2(15)
Karsten Hopp 5f67cf
!     xl ^= bfs->pax[16];
Karsten Hopp 5f67cf
!     xr ^= bfs->pax[17];
Karsten Hopp 5f67cf
      temp = xl;
Karsten Hopp 5f67cf
      xl = xr;
Karsten Hopp 5f67cf
      xr = temp;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 348,369 ****
Karsten Hopp 5f67cf
      *p_xr = xr;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- #if 0  /* not used */
Karsten Hopp 5f67cf
-     static void
Karsten Hopp 5f67cf
- bf_d_block(p_xl, p_xr)
Karsten Hopp 5f67cf
-     UINT32_T *p_xl;
Karsten Hopp 5f67cf
-     UINT32_T *p_xr;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     UINT32_T temp, xl = *p_xl, xr = *p_xr;
Karsten Hopp 5f67cf
-     F1(17) F2(16) F1(15) F2(14) F1(13) F2(12) F1(11) F2(10)
Karsten Hopp 5f67cf
-     F1(9) F2(8) F1(7) F2(6) F1(5) F2(4) F1(3) F2(2)
Karsten Hopp 5f67cf
-     xl ^= pax[1];
Karsten Hopp 5f67cf
-     xr ^= pax[0];
Karsten Hopp 5f67cf
-     temp = xl; xl = xr; xr = temp;
Karsten Hopp 5f67cf
-     *p_xl = xl; *p_xr = xr;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef WORDS_BIGENDIAN
Karsten Hopp 5f67cf
  # define htonl2(x) \
Karsten Hopp 5f67cf
--- 374,379 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 374,380 ****
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! bf_e_cblock(block)
Karsten Hopp 5f67cf
      char_u *block;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      block8	bk;
Karsten Hopp 5f67cf
--- 384,391 ----
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! bf_e_cblock(bfs, block)
Karsten Hopp 5f67cf
!     bf_state_T *bfs;
Karsten Hopp 5f67cf
      char_u *block;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      block8	bk;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 382,416 ****
Karsten Hopp 5f67cf
      memcpy(bk.uc, block, 8);
Karsten Hopp 5f67cf
      htonl2(bk.ul[0]);
Karsten Hopp 5f67cf
      htonl2(bk.ul[1]);
Karsten Hopp 5f67cf
!     bf_e_block(&bk.ul[0], &bk.ul[1]);
Karsten Hopp 5f67cf
      htonl2(bk.ul[0]);
Karsten Hopp 5f67cf
      htonl2(bk.ul[1]);
Karsten Hopp 5f67cf
      memcpy(block, bk.uc, 8);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- #if 0  /* not used */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- bf_d_cblock(block)
Karsten Hopp 5f67cf
-     char_u *block;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     block8 bk;
Karsten Hopp 5f67cf
-     memcpy(bk.uc, block, 8);
Karsten Hopp 5f67cf
-     htonl2(bk.ul[0]); htonl2(bk.ul[1]);
Karsten Hopp 5f67cf
-     bf_d_block(&bk.ul[0], &bk.ul[1]);
Karsten Hopp 5f67cf
-     htonl2(bk.ul[0]); htonl2(bk.ul[1]);
Karsten Hopp 5f67cf
-     memcpy(block, bk.uc, 8);
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
   * Initialize the crypt method using "password" as the encryption key and
Karsten Hopp 5f67cf
   * "salt[salt_len]" as the salt.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     void
Karsten Hopp 5f67cf
! bf_key_init(password, salt, salt_len)
Karsten Hopp 5f67cf
!     char_u *password;
Karsten Hopp 5f67cf
!     char_u *salt;
Karsten Hopp 5f67cf
!     int    salt_len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int      i, j, keypos = 0;
Karsten Hopp 5f67cf
      unsigned u;
Karsten Hopp 5f67cf
--- 393,414 ----
Karsten Hopp 5f67cf
      memcpy(bk.uc, block, 8);
Karsten Hopp 5f67cf
      htonl2(bk.ul[0]);
Karsten Hopp 5f67cf
      htonl2(bk.ul[1]);
Karsten Hopp 5f67cf
!     bf_e_block(bfs, &bk.ul[0], &bk.ul[1]);
Karsten Hopp 5f67cf
      htonl2(bk.ul[0]);
Karsten Hopp 5f67cf
      htonl2(bk.ul[1]);
Karsten Hopp 5f67cf
      memcpy(block, bk.uc, 8);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
   * Initialize the crypt method using "password" as the encryption key and
Karsten Hopp 5f67cf
   * "salt[salt_len]" as the salt.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static void
Karsten Hopp 5f67cf
! bf_key_init(bfs, password, salt, salt_len)
Karsten Hopp 5f67cf
!     bf_state_T	*bfs;
Karsten Hopp 5f67cf
!     char_u	*password;
Karsten Hopp 5f67cf
!     char_u	*salt;
Karsten Hopp 5f67cf
!     int		salt_len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int      i, j, keypos = 0;
Karsten Hopp 5f67cf
      unsigned u;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 418,424 ****
Karsten Hopp 5f67cf
      char_u   *key;
Karsten Hopp 5f67cf
      int      keylen;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     /* Process the key 1000 times.
Karsten Hopp 5f67cf
       * See http://en.wikipedia.org/wiki/Key_strengthening. */
Karsten Hopp 5f67cf
      key = sha256_key(password, salt, salt_len);
Karsten Hopp 5f67cf
      for (i = 0; i < 1000; i++)
Karsten Hopp 5f67cf
--- 416,422 ----
Karsten Hopp 5f67cf
      char_u   *key;
Karsten Hopp 5f67cf
      int      keylen;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     /* Process the key 1001 times.
Karsten Hopp 5f67cf
       * See http://en.wikipedia.org/wiki/Key_strengthening. */
Karsten Hopp 5f67cf
      key = sha256_key(password, salt, salt_len);
Karsten Hopp 5f67cf
      for (i = 0; i < 1000; i++)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 437,488 ****
Karsten Hopp 5f67cf
  	key[i] = u;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     mch_memmove(sbx, sbi, 4 * 4 * 256);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < 18; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	val = 0;
Karsten Hopp 5f67cf
  	for (j = 0; j < 4; ++j)
Karsten Hopp 5f67cf
  	    val = (val << 8) | key[keypos++ % keylen];
Karsten Hopp 5f67cf
! 	pax[i] = ipa[i] ^ val;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      data_l = data_r = 0;
Karsten Hopp 5f67cf
      for (i = 0; i < 18; i += 2)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	bf_e_block(&data_l, &data_r);
Karsten Hopp 5f67cf
! 	pax[i + 0] = data_l;
Karsten Hopp 5f67cf
! 	pax[i + 1] = data_r;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < 4; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	for (j = 0; j < 256; j += 2)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    bf_e_block(&data_l, &data_r);
Karsten Hopp 5f67cf
! 	    sbx[i][j + 0] = data_l;
Karsten Hopp 5f67cf
! 	    sbx[i][j + 1] = data_r;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * BF Self test for corrupted tables or instructions
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! bf_check_tables(a_ipa, a_sbi, val)
Karsten Hopp 5f67cf
!     UINT32_T a_ipa[18];
Karsten Hopp 5f67cf
!     UINT32_T a_sbi[4][256];
Karsten Hopp 5f67cf
      UINT32_T val;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int i, j;
Karsten Hopp 5f67cf
      UINT32_T c = 0;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < 18; i++)
Karsten Hopp 5f67cf
! 	c ^= a_ipa[i];
Karsten Hopp 5f67cf
      for (i = 0; i < 4; i++)
Karsten Hopp 5f67cf
  	for (j = 0; j < 256; j++)
Karsten Hopp 5f67cf
! 	    c ^= a_sbi[i][j];
Karsten Hopp 5f67cf
      return c == val;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
--- 435,488 ----
Karsten Hopp 5f67cf
  	key[i] = u;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     /* Use "key" to initialize the P-array ("pax") and S-boxes ("sbx") of
Karsten Hopp 5f67cf
!      * Blowfish. */
Karsten Hopp 5f67cf
!     mch_memmove(bfs->sbx, sbx_init, 4 * 4 * 256);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < 18; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	val = 0;
Karsten Hopp 5f67cf
  	for (j = 0; j < 4; ++j)
Karsten Hopp 5f67cf
  	    val = (val << 8) | key[keypos++ % keylen];
Karsten Hopp 5f67cf
! 	bfs->pax[i] = pax_init[i] ^ val;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      data_l = data_r = 0;
Karsten Hopp 5f67cf
      for (i = 0; i < 18; i += 2)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	bf_e_block(bfs, &data_l, &data_r);
Karsten Hopp 5f67cf
! 	bfs->pax[i + 0] = data_l;
Karsten Hopp 5f67cf
! 	bfs->pax[i + 1] = data_r;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < 4; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	for (j = 0; j < 256; j += 2)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    bf_e_block(bfs, &data_l, &data_r);
Karsten Hopp 5f67cf
! 	    bfs->sbx[i][j + 0] = data_l;
Karsten Hopp 5f67cf
! 	    bfs->sbx[i][j + 1] = data_r;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Blowfish self-test for corrupted tables or instructions.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! bf_check_tables(pax, sbx, val)
Karsten Hopp 5f67cf
!     UINT32_T pax[18];
Karsten Hopp 5f67cf
!     UINT32_T sbx[4][256];
Karsten Hopp 5f67cf
      UINT32_T val;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int i, j;
Karsten Hopp 5f67cf
      UINT32_T c = 0;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < 18; i++)
Karsten Hopp 5f67cf
! 	c ^= pax[i];
Karsten Hopp 5f67cf
      for (i = 0; i < 4; i++)
Karsten Hopp 5f67cf
  	for (j = 0; j < 256; j++)
Karsten Hopp 5f67cf
! 	    c ^= sbx[i][j];
Karsten Hopp 5f67cf
      return c == val;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 520,525 ****
Karsten Hopp 5f67cf
--- 520,529 ----
Karsten Hopp 5f67cf
      int    err = 0;
Karsten Hopp 5f67cf
      block8 bk;
Karsten Hopp 5f67cf
      UINT32_T ui = 0xffffffffUL;
Karsten Hopp 5f67cf
+     bf_state_T state;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     vim_memset(&state, 0, sizeof(bf_state_T));
Karsten Hopp 5f67cf
+     state.cfb_len = BF_MAX_CFB_LEN;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* We can't simply use sizeof(UINT32_T), it would generate a compiler
Karsten Hopp 5f67cf
       * warning. */
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 528,548 ****
Karsten Hopp 5f67cf
  	EMSG(_("E820: sizeof(uint32_t) != 4"));
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (!bf_check_tables(ipa, sbi, 0x6ffa520a))
Karsten Hopp 5f67cf
  	err++;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      bn = ARRAY_LENGTH(bf_test_data);
Karsten Hopp 5f67cf
      for (i = 0; i < bn; i++)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	bf_key_init((char_u *)(bf_test_data[i].password),
Karsten Hopp 5f67cf
  		    bf_test_data[i].salt,
Karsten Hopp 5f67cf
  		    (int)STRLEN(bf_test_data[i].salt));
Karsten Hopp 5f67cf
! 	if (!bf_check_tables(pax, sbx, bf_test_data[i].keysum))
Karsten Hopp 5f67cf
  	    err++;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	/* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */
Karsten Hopp 5f67cf
  	memcpy(bk.uc, bf_test_data[i].plaintxt, 8);
Karsten Hopp 5f67cf
! 	bf_e_cblock(bk.uc);
Karsten Hopp 5f67cf
  	if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0)
Karsten Hopp 5f67cf
--- 532,552 ----
Karsten Hopp 5f67cf
  	EMSG(_("E820: sizeof(uint32_t) != 4"));
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (!bf_check_tables(pax_init, sbx_init, 0x6ffa520a))
Karsten Hopp 5f67cf
  	err++;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      bn = ARRAY_LENGTH(bf_test_data);
Karsten Hopp 5f67cf
      for (i = 0; i < bn; i++)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	bf_key_init(&state, (char_u *)(bf_test_data[i].password),
Karsten Hopp 5f67cf
  		    bf_test_data[i].salt,
Karsten Hopp 5f67cf
  		    (int)STRLEN(bf_test_data[i].salt));
Karsten Hopp 5f67cf
! 	if (!bf_check_tables(state.pax, state.sbx, bf_test_data[i].keysum))
Karsten Hopp 5f67cf
  	    err++;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	/* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */
Karsten Hopp 5f67cf
  	memcpy(bk.uc, bf_test_data[i].plaintxt, 8);
Karsten Hopp 5f67cf
! 	bf_e_cblock(&state, bk.uc);
Karsten Hopp 5f67cf
  	if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 554,596 ****
Karsten Hopp 5f67cf
      return err > 0 ? FAIL : OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! /* Cipher feedback mode. */
Karsten Hopp 5f67cf
! static int randbyte_offset = 0;
Karsten Hopp 5f67cf
! static int update_offset = 0;
Karsten Hopp 5f67cf
! static char_u cfb_buffer[BF_CFB_LEN]; /* 64 bytes */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Initialize with seed "iv[iv_len]".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     void
Karsten Hopp 5f67cf
! bf_cfb_init(iv, iv_len)
Karsten Hopp 5f67cf
!     char_u *iv;
Karsten Hopp 5f67cf
!     int    iv_len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int i, mi;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     randbyte_offset = update_offset = 0;
Karsten Hopp 5f67cf
!     vim_memset(cfb_buffer, 0, BF_CFB_LEN);
Karsten Hopp 5f67cf
!     if (iv_len > 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	mi = iv_len > BF_CFB_LEN ? iv_len : BF_CFB_LEN;
Karsten Hopp 5f67cf
  	for (i = 0; i < mi; i++)
Karsten Hopp 5f67cf
! 	    cfb_buffer[i % BF_CFB_LEN] ^= iv[i % iv_len];
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! #define BF_CFB_UPDATE(c) { \
Karsten Hopp 5f67cf
!     cfb_buffer[update_offset] ^= (char_u)c; \
Karsten Hopp 5f67cf
!     if (++update_offset == BF_CFB_LEN) \
Karsten Hopp 5f67cf
! 	update_offset = 0; \
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! #define BF_RANBYTE(t) { \
Karsten Hopp 5f67cf
!     if ((randbyte_offset & BF_BLOCK_MASK) == 0) \
Karsten Hopp 5f67cf
! 	bf_e_cblock(&cfb_buffer[randbyte_offset]); \
Karsten Hopp 5f67cf
!     t = cfb_buffer[randbyte_offset]; \
Karsten Hopp 5f67cf
!     if (++randbyte_offset == BF_CFB_LEN) \
Karsten Hopp 5f67cf
! 	randbyte_offset = 0; \
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
--- 558,600 ----
Karsten Hopp 5f67cf
      return err > 0 ? FAIL : OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! /*
Karsten Hopp 5f67cf
!  * CFB: Cipher Feedback Mode.
Karsten Hopp 5f67cf
!  */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Initialize with seed "seed[seed_len]".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static void
Karsten Hopp 5f67cf
! bf_cfb_init(bfs, seed, seed_len)
Karsten Hopp 5f67cf
!     bf_state_T	*bfs;
Karsten Hopp 5f67cf
!     char_u	*seed;
Karsten Hopp 5f67cf
!     int		seed_len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int i, mi;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     bfs->randbyte_offset = bfs->update_offset = 0;
Karsten Hopp 5f67cf
!     vim_memset(bfs->cfb_buffer, 0, bfs->cfb_len);
Karsten Hopp 5f67cf
!     if (seed_len > 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	mi = seed_len > bfs->cfb_len ? seed_len : bfs->cfb_len;
Karsten Hopp 5f67cf
  	for (i = 0; i < mi; i++)
Karsten Hopp 5f67cf
! 	    bfs->cfb_buffer[i % bfs->cfb_len] ^= seed[i % seed_len];
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! #define BF_CFB_UPDATE(bfs, c) { \
Karsten Hopp 5f67cf
!     bfs->cfb_buffer[bfs->update_offset] ^= (char_u)c; \
Karsten Hopp 5f67cf
!     if (++bfs->update_offset == bfs->cfb_len) \
Karsten Hopp 5f67cf
! 	bfs->update_offset = 0; \
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! #define BF_RANBYTE(bfs, t) { \
Karsten Hopp 5f67cf
!     if ((bfs->randbyte_offset & BF_BLOCK_MASK) == 0) \
Karsten Hopp 5f67cf
! 	bf_e_cblock(bfs, &(bfs->cfb_buffer[bfs->randbyte_offset])); \
Karsten Hopp 5f67cf
!     t = bfs->cfb_buffer[bfs->randbyte_offset]; \
Karsten Hopp 5f67cf
!     if (++bfs->randbyte_offset == bfs->cfb_len) \
Karsten Hopp 5f67cf
! 	bfs->randbyte_offset = 0; \
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 598,687 ****
Karsten Hopp 5f67cf
   * "from" and "to" can be equal to encrypt in place.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      void
Karsten Hopp 5f67cf
! bf_crypt_encode(from, len, to)
Karsten Hopp 5f67cf
      char_u	*from;
Karsten Hopp 5f67cf
      size_t	len;
Karsten Hopp 5f67cf
      char_u	*to;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      size_t	i;
Karsten Hopp 5f67cf
      int		ztemp, t;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < len; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	ztemp = from[i];
Karsten Hopp 5f67cf
! 	BF_RANBYTE(t);
Karsten Hopp 5f67cf
! 	BF_CFB_UPDATE(ztemp);
Karsten Hopp 5f67cf
  	to[i] = t ^ ztemp;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Decrypt "ptr[len]" in place.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      void
Karsten Hopp 5f67cf
! bf_crypt_decode(ptr, len)
Karsten Hopp 5f67cf
!     char_u	*ptr;
Karsten Hopp 5f67cf
!     long	len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     char_u	*p;
Karsten Hopp 5f67cf
      int		t;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     for (p = ptr; p < ptr + len; ++p)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	BF_RANBYTE(t);
Karsten Hopp 5f67cf
! 	*p ^= t;
Karsten Hopp 5f67cf
! 	BF_CFB_UPDATE(*p);
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Initialize the encryption keys and the random header according to
Karsten Hopp 5f67cf
-  * the given password.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
      void
Karsten Hopp 5f67cf
! bf_crypt_init_keys(passwd)
Karsten Hopp 5f67cf
!     char_u *passwd;		/* password string with which to modify keys */
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
!     char_u *p;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     for (p = passwd; *p != NUL; ++p)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	BF_CFB_UPDATE(*p);
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! static int save_randbyte_offset;
Karsten Hopp 5f67cf
! static int save_update_offset;
Karsten Hopp 5f67cf
! static char_u save_cfb_buffer[BF_CFB_LEN];
Karsten Hopp 5f67cf
! static UINT32_T save_pax[18];
Karsten Hopp 5f67cf
! static UINT32_T save_sbx[4][256];
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! /*
Karsten Hopp 5f67cf
!  * Save the current crypt state.  Can only be used once before
Karsten Hopp 5f67cf
!  * bf_crypt_restore().
Karsten Hopp 5f67cf
!  */
Karsten Hopp 5f67cf
!     void
Karsten Hopp 5f67cf
! bf_crypt_save()
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
!     save_randbyte_offset = randbyte_offset;
Karsten Hopp 5f67cf
!     save_update_offset = update_offset;
Karsten Hopp 5f67cf
!     mch_memmove(save_cfb_buffer, cfb_buffer, BF_CFB_LEN);
Karsten Hopp 5f67cf
!     mch_memmove(save_pax, pax, 4 * 18);
Karsten Hopp 5f67cf
!     mch_memmove(save_sbx, sbx, 4 * 4 * 256);
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! /*
Karsten Hopp 5f67cf
!  * Restore the current crypt state.  Can only be used after
Karsten Hopp 5f67cf
!  * bf_crypt_save().
Karsten Hopp 5f67cf
!  */
Karsten Hopp 5f67cf
!     void
Karsten Hopp 5f67cf
! bf_crypt_restore()
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
!     randbyte_offset = save_randbyte_offset;
Karsten Hopp 5f67cf
!     update_offset = save_update_offset;
Karsten Hopp 5f67cf
!     mch_memmove(cfb_buffer, save_cfb_buffer, BF_CFB_LEN);
Karsten Hopp 5f67cf
!     mch_memmove(pax, save_pax, 4 * 18);
Karsten Hopp 5f67cf
!     mch_memmove(sbx, save_sbx, 4 * 4 * 256);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
--- 602,670 ----
Karsten Hopp 5f67cf
   * "from" and "to" can be equal to encrypt in place.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      void
Karsten Hopp 5f67cf
! crypt_blowfish_encode(state, from, len, to)
Karsten Hopp 5f67cf
!     cryptstate_T *state;
Karsten Hopp 5f67cf
      char_u	*from;
Karsten Hopp 5f67cf
      size_t	len;
Karsten Hopp 5f67cf
      char_u	*to;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
+     bf_state_T *bfs = state->method_state;
Karsten Hopp 5f67cf
      size_t	i;
Karsten Hopp 5f67cf
      int		ztemp, t;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < len; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	ztemp = from[i];
Karsten Hopp 5f67cf
! 	BF_RANBYTE(bfs, t);
Karsten Hopp 5f67cf
! 	BF_CFB_UPDATE(bfs, ztemp);
Karsten Hopp 5f67cf
  	to[i] = t ^ ztemp;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Decrypt "from[len]" into "to[len]".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      void
Karsten Hopp 5f67cf
! crypt_blowfish_decode(state, from, len, to)
Karsten Hopp 5f67cf
!     cryptstate_T *state;
Karsten Hopp 5f67cf
!     char_u	*from;
Karsten Hopp 5f67cf
!     size_t	len;
Karsten Hopp 5f67cf
!     char_u	*to;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     bf_state_T *bfs = state->method_state;
Karsten Hopp 5f67cf
!     size_t	i;
Karsten Hopp 5f67cf
      int		t;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     for (i = 0; i < len; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	BF_RANBYTE(bfs, t);
Karsten Hopp 5f67cf
! 	to[i] = from[i] ^ t;
Karsten Hopp 5f67cf
! 	BF_CFB_UPDATE(bfs, to[i]);
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      void
Karsten Hopp 5f67cf
! crypt_blowfish_init(state, key, salt, salt_len, seed, seed_len)
Karsten Hopp 5f67cf
!     cryptstate_T	*state;
Karsten Hopp 5f67cf
!     char_u*		key;
Karsten Hopp 5f67cf
!     char_u*		salt;
Karsten Hopp 5f67cf
!     int			salt_len;
Karsten Hopp 5f67cf
!     char_u*		seed;
Karsten Hopp 5f67cf
!     int			seed_len;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
!     bf_state_T	*bfs = (bf_state_T *)alloc_clear(sizeof(bf_state_T));
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     state->method_state = bfs;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     /* "blowfish" uses a 64 byte buffer, causing it to repeat 8 byte groups 8
Karsten Hopp 5f67cf
!      * times.  "blowfish2" uses a 8 byte buffer to avoid repeating. */
Karsten Hopp 5f67cf
!     bfs->cfb_len = state->method_nr == CRYPT_M_BF ? BF_MAX_CFB_LEN : BF_BLOCK;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (blowfish_self_test() == FAIL)
Karsten Hopp 5f67cf
! 	return;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     bf_key_init(bfs, key, salt, salt_len);
Karsten Hopp 5f67cf
!     bf_cfb_init(bfs, seed, seed_len);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/crypt.c	2014-08-10 13:30:43.816787293 +0200
Karsten Hopp 5f67cf
--- src/crypt.c	2014-08-09 15:37:46.189353499 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 0 ****
Karsten Hopp 5f67cf
--- 1,585 ----
Karsten Hopp 5f67cf
+ /* vi:set ts=8 sts=4 sw=4:
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * VIM - Vi IMproved	by Bram Moolenaar
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * Do ":help uganda"  in Vim to read copying and usage conditions.
Karsten Hopp 5f67cf
+  * Do ":help credits" in Vim to see a list of people who contributed.
Karsten Hopp 5f67cf
+  * See README.txt for an overview of the Vim source code.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * crypt.c: Generic encryption support.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ #include "vim.h"
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ #if defined(FEAT_CRYPT) || defined(PROTO)
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Optional encryption support.
Karsten Hopp 5f67cf
+  * Mohsin Ahmed, mosh@sasi.com, 1998-09-24
Karsten Hopp 5f67cf
+  * Based on zip/crypt sources.
Karsten Hopp 5f67cf
+  * Refactored by David Leadbeater, 2014.
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
Karsten Hopp 5f67cf
+  * most countries.  There are a few exceptions, but that still should not be a
Karsten Hopp 5f67cf
+  * problem since this code was originally created in Europe and India.
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * Blowfish addition originally made by Mohsin Ahmed,
Karsten Hopp 5f67cf
+  * http://www.cs.albany.edu/~mosh 2010-03-14
Karsten Hopp 5f67cf
+  * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
Karsten Hopp 5f67cf
+  * and sha256 by Christophe Devine.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ typedef struct {
Karsten Hopp 5f67cf
+     char    *name;	/* encryption name as used in 'cryptmethod' */
Karsten Hopp 5f67cf
+     char    *magic;	/* magic bytes stored in file header */
Karsten Hopp 5f67cf
+     int	    salt_len;	/* length of salt, or 0 when not using salt */
Karsten Hopp 5f67cf
+     int	    seed_len;	/* length of seed, or 0 when not using salt */
Karsten Hopp 5f67cf
+     int	    works_inplace; /* encryption/decryption can be done in-place */
Karsten Hopp 5f67cf
+     int	    whole_undofile; /* whole undo file is encrypted */
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Optional function pointer for a self-test. */
Karsten Hopp 5f67cf
+     int (* self_test_fn)();
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Function pointer for initializing encryption/decription. */
Karsten Hopp 5f67cf
+     void (* init_fn)(cryptstate_T *state, char_u *key,
Karsten Hopp 5f67cf
+ 		      char_u *salt, int salt_len, char_u *seed, int seed_len);
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Function pointers for encoding/decoding from one buffer into another.
Karsten Hopp 5f67cf
+      * Optional, however, these or the _buffer ones should be configured. */
Karsten Hopp 5f67cf
+     void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len,
Karsten Hopp 5f67cf
+ 								  char_u *to);
Karsten Hopp 5f67cf
+     void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len,
Karsten Hopp 5f67cf
+ 								  char_u *to);
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Function pointers for encoding and decoding, can buffer data if needed.
Karsten Hopp 5f67cf
+      * Optional (however, these or the above should be configured). */
Karsten Hopp 5f67cf
+     long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
Karsten Hopp 5f67cf
+ 							     char_u **newptr);
Karsten Hopp 5f67cf
+     long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
Karsten Hopp 5f67cf
+ 							     char_u **newptr);
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Function pointers for in-place encoding and decoding, used for
Karsten Hopp 5f67cf
+      * crypt_*_inplace(). "from" and "to" arguments will be equal.
Karsten Hopp 5f67cf
+      * These may be the same as decode_fn and encode_fn above, however an
Karsten Hopp 5f67cf
+      * algorithm may implement them in a way that is not interchangeable with
Karsten Hopp 5f67cf
+      * the crypt_(en|de)code() interface (for example because it wishes to add
Karsten Hopp 5f67cf
+      * padding to files).
Karsten Hopp 5f67cf
+      * This method is used for swap and undo files which have a rigid format.
Karsten Hopp 5f67cf
+      */
Karsten Hopp 5f67cf
+     void (*encode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
Karsten Hopp 5f67cf
+ 								  char_u *p2);
Karsten Hopp 5f67cf
+     void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
Karsten Hopp 5f67cf
+ 								  char_u *p2);
Karsten Hopp 5f67cf
+ } cryptmethod_T;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /* index is method_nr of cryptstate_T, CRYPT_M_* */
Karsten Hopp 5f67cf
+ static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
Karsten Hopp 5f67cf
+     /* PK_Zip; very weak */
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	"zip",
Karsten Hopp 5f67cf
+ 	"VimCrypt~01!",
Karsten Hopp 5f67cf
+ 	0,
Karsten Hopp 5f67cf
+ 	0,
Karsten Hopp 5f67cf
+ 	TRUE,
Karsten Hopp 5f67cf
+ 	FALSE,
Karsten Hopp 5f67cf
+ 	NULL,
Karsten Hopp 5f67cf
+ 	crypt_zip_init,
Karsten Hopp 5f67cf
+ 	crypt_zip_encode, crypt_zip_decode,
Karsten Hopp 5f67cf
+ 	NULL, NULL,
Karsten Hopp 5f67cf
+ 	crypt_zip_encode, crypt_zip_decode,
Karsten Hopp 5f67cf
+     },
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Blowfish/CFB + SHA-256 custom key derivation; implementation issues. */
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	"blowfish",
Karsten Hopp 5f67cf
+ 	"VimCrypt~02!",
Karsten Hopp 5f67cf
+ 	8,
Karsten Hopp 5f67cf
+ 	8,
Karsten Hopp 5f67cf
+ 	TRUE,
Karsten Hopp 5f67cf
+ 	FALSE,
Karsten Hopp 5f67cf
+ 	blowfish_self_test,
Karsten Hopp 5f67cf
+ 	crypt_blowfish_init,
Karsten Hopp 5f67cf
+ 	crypt_blowfish_encode, crypt_blowfish_decode,
Karsten Hopp 5f67cf
+ 	NULL, NULL,
Karsten Hopp 5f67cf
+ 	crypt_blowfish_encode, crypt_blowfish_decode,
Karsten Hopp 5f67cf
+     },
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Blowfish/CFB + SHA-256 custom key derivation; fixed. */
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	"blowfish2",
Karsten Hopp 5f67cf
+ 	"VimCrypt~03!",
Karsten Hopp 5f67cf
+ 	8,
Karsten Hopp 5f67cf
+ 	8,
Karsten Hopp 5f67cf
+ 	TRUE,
Karsten Hopp 5f67cf
+ 	TRUE,
Karsten Hopp 5f67cf
+ 	blowfish_self_test,
Karsten Hopp 5f67cf
+ 	crypt_blowfish_init,
Karsten Hopp 5f67cf
+ 	crypt_blowfish_encode, crypt_blowfish_decode,
Karsten Hopp 5f67cf
+ 	NULL, NULL,
Karsten Hopp 5f67cf
+ 	crypt_blowfish_encode, crypt_blowfish_decode,
Karsten Hopp 5f67cf
+     },
Karsten Hopp 5f67cf
+ };
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ #define CRYPT_MAGIC_LEN	12	/* cannot change */
Karsten Hopp 5f67cf
+ static char	crypt_magic_head[] = "VimCrypt~";
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Return int value for crypt method name.
Karsten Hopp 5f67cf
+  * 0 for "zip", the old method.  Also for any non-valid value.
Karsten Hopp 5f67cf
+  * 1 for "blowfish".
Karsten Hopp 5f67cf
+  * 2 for "blowfish2".
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     int
Karsten Hopp 5f67cf
+ crypt_method_nr_from_name(name)
Karsten Hopp 5f67cf
+     char_u  *name;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     int i;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     for (i = 0; i < CRYPT_M_COUNT; ++i)
Karsten Hopp 5f67cf
+ 	if (STRCMP(name, cryptmethods[i].name) == 0)
Karsten Hopp 5f67cf
+ 	    return i;
Karsten Hopp 5f67cf
+     return 0;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Get the crypt method used for a file from "ptr[len]", the magic text at the
Karsten Hopp 5f67cf
+  * start of the file.
Karsten Hopp 5f67cf
+  * Returns -1 when no encryption used.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     int
Karsten Hopp 5f67cf
+ crypt_method_nr_from_magic(ptr, len)
Karsten Hopp 5f67cf
+     char  *ptr;
Karsten Hopp 5f67cf
+     int   len;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     int i;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (len < CRYPT_MAGIC_LEN)
Karsten Hopp 5f67cf
+ 	return -1;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     for (i = 0; i < CRYPT_M_COUNT; i++)
Karsten Hopp 5f67cf
+ 	if (memcmp(ptr, cryptmethods[i].magic, CRYPT_MAGIC_LEN) == 0)
Karsten Hopp 5f67cf
+ 	    return i;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     i = (int)STRLEN(crypt_magic_head);
Karsten Hopp 5f67cf
+     if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0)
Karsten Hopp 5f67cf
+ 	EMSG(_("E821: File is encrypted with unknown method"));
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     return -1;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Return TRUE if the crypt method for "method_nr" can be done in-place.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     int
Karsten Hopp 5f67cf
+ crypt_works_inplace(state)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     return cryptmethods[state->method_nr].works_inplace;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Get the crypt method for buffer "buf" as a number.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     int
Karsten Hopp 5f67cf
+ crypt_get_method_nr(buf)
Karsten Hopp 5f67cf
+     buf_T *buf;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     return crypt_method_nr_from_name(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Return TRUE when the buffer uses an encryption method that encrypts the
Karsten Hopp 5f67cf
+  * whole undo file, not only the text.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     int
Karsten Hopp 5f67cf
+ crypt_whole_undofile(method_nr)
Karsten Hopp 5f67cf
+     int method_nr;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     return cryptmethods[method_nr].whole_undofile;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Get crypt method specifc length of the file header in bytes.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     int
Karsten Hopp 5f67cf
+ crypt_get_header_len(method_nr)
Karsten Hopp 5f67cf
+     int method_nr;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     return CRYPT_MAGIC_LEN
Karsten Hopp 5f67cf
+ 	+ cryptmethods[method_nr].salt_len
Karsten Hopp 5f67cf
+ 	+ cryptmethods[method_nr].seed_len;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Set the crypt method for buffer "buf" to "method_nr" using the int value as
Karsten Hopp 5f67cf
+  * returned by crypt_method_nr_from_name().
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_set_cm_option(buf, method_nr)
Karsten Hopp 5f67cf
+     buf_T   *buf;
Karsten Hopp 5f67cf
+     int	    method_nr;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     free_string_option(buf->b_p_cm);
Karsten Hopp 5f67cf
+     buf->b_p_cm = vim_strsave((char_u *)cryptmethods[method_nr].name);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * If the crypt method for the current buffer has a self-test, run it and
Karsten Hopp 5f67cf
+  * return OK/FAIL.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     int
Karsten Hopp 5f67cf
+ crypt_self_test()
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     int method_nr = crypt_get_method_nr(curbuf);
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (cryptmethods[method_nr].self_test_fn == NULL)
Karsten Hopp 5f67cf
+ 	return OK;
Karsten Hopp 5f67cf
+     return cryptmethods[method_nr].self_test_fn();
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Allocate a crypt state and initialize it.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     cryptstate_T *
Karsten Hopp 5f67cf
+ crypt_create(method_nr, key, salt, salt_len, seed, seed_len)
Karsten Hopp 5f67cf
+     int		method_nr;
Karsten Hopp 5f67cf
+     char_u	*key;
Karsten Hopp 5f67cf
+     char_u	*salt;
Karsten Hopp 5f67cf
+     int		salt_len;
Karsten Hopp 5f67cf
+     char_u	*seed;
Karsten Hopp 5f67cf
+     int		seed_len;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     cryptstate_T *state = (cryptstate_T *)alloc((int)sizeof(cryptstate_T));
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     state->method_nr = method_nr;
Karsten Hopp 5f67cf
+     cryptmethods[method_nr].init_fn(state, key, salt, salt_len, seed, seed_len);
Karsten Hopp 5f67cf
+     return state;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Allocate a crypt state from a file header and initialize it.
Karsten Hopp 5f67cf
+  * Assumes that header contains at least the number of bytes that
Karsten Hopp 5f67cf
+  * crypt_get_header_len() returns for "method_nr".
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     cryptstate_T *
Karsten Hopp 5f67cf
+ crypt_create_from_header(method_nr, key, header)
Karsten Hopp 5f67cf
+     int		method_nr;
Karsten Hopp 5f67cf
+     char_u	*key;
Karsten Hopp 5f67cf
+     char_u	*header;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     char_u	*salt = NULL;
Karsten Hopp 5f67cf
+     char_u	*seed = NULL;
Karsten Hopp 5f67cf
+     int		salt_len = cryptmethods[method_nr].salt_len;
Karsten Hopp 5f67cf
+     int		seed_len = cryptmethods[method_nr].seed_len;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (salt_len > 0)
Karsten Hopp 5f67cf
+ 	salt = header + CRYPT_MAGIC_LEN;
Karsten Hopp 5f67cf
+     if (seed_len > 0)
Karsten Hopp 5f67cf
+ 	seed = header + CRYPT_MAGIC_LEN + salt_len;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     return crypt_create(method_nr, key, salt, salt_len, seed, seed_len);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Read the crypt method specific header data from "fp".
Karsten Hopp 5f67cf
+  * Return an allocated cryptstate_T or NULL on error.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     cryptstate_T *
Karsten Hopp 5f67cf
+ crypt_create_from_file(fp, key)
Karsten Hopp 5f67cf
+     FILE    *fp;
Karsten Hopp 5f67cf
+     char_u  *key;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     int		method_nr;
Karsten Hopp 5f67cf
+     int		header_len;
Karsten Hopp 5f67cf
+     char	magic_buffer[CRYPT_MAGIC_LEN];
Karsten Hopp 5f67cf
+     char_u	*buffer;
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (fread(magic_buffer, CRYPT_MAGIC_LEN, 1, fp) != 1)
Karsten Hopp 5f67cf
+ 	return NULL;
Karsten Hopp 5f67cf
+     method_nr = crypt_method_nr_from_magic(magic_buffer, CRYPT_MAGIC_LEN);
Karsten Hopp 5f67cf
+     if (method_nr < 0)
Karsten Hopp 5f67cf
+ 	return NULL;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     header_len = crypt_get_header_len(method_nr);
Karsten Hopp 5f67cf
+     if ((buffer = alloc(header_len)) == NULL)
Karsten Hopp 5f67cf
+ 	return NULL;
Karsten Hopp 5f67cf
+     mch_memmove(buffer, magic_buffer, CRYPT_MAGIC_LEN);
Karsten Hopp 5f67cf
+     if (header_len > CRYPT_MAGIC_LEN
Karsten Hopp 5f67cf
+ 	    && fread(buffer + CRYPT_MAGIC_LEN,
Karsten Hopp 5f67cf
+ 				    header_len - CRYPT_MAGIC_LEN, 1, fp) != 1)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	vim_free(buffer);
Karsten Hopp 5f67cf
+ 	return NULL;
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     state = crypt_create_from_header(method_nr, key, buffer);
Karsten Hopp 5f67cf
+     vim_free(buffer);
Karsten Hopp 5f67cf
+     return state;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Allocate a cryptstate_T for writing and initialize it with "key".
Karsten Hopp 5f67cf
+  * Allocates and fills in the header and stores it in "header", setting
Karsten Hopp 5f67cf
+  * "header_len".  The header may include salt and seed, depending on
Karsten Hopp 5f67cf
+  * cryptmethod.  Caller must free header.
Karsten Hopp 5f67cf
+  * Returns the state or NULL on failure.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     cryptstate_T *
Karsten Hopp 5f67cf
+ crypt_create_for_writing(method_nr, key, header, header_len)
Karsten Hopp 5f67cf
+     int	    method_nr;
Karsten Hopp 5f67cf
+     char_u  *key;
Karsten Hopp 5f67cf
+     char_u  **header;
Karsten Hopp 5f67cf
+     int	    *header_len;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     int	    len = crypt_get_header_len(method_nr);
Karsten Hopp 5f67cf
+     char_u  *salt = NULL;
Karsten Hopp 5f67cf
+     char_u  *seed = NULL;
Karsten Hopp 5f67cf
+     int	    salt_len = cryptmethods[method_nr].salt_len;
Karsten Hopp 5f67cf
+     int	    seed_len = cryptmethods[method_nr].seed_len;
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     *header_len = len;
Karsten Hopp 5f67cf
+     *header = alloc(len);
Karsten Hopp 5f67cf
+     if (*header == NULL)
Karsten Hopp 5f67cf
+ 	return NULL;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     mch_memmove(*header, cryptmethods[method_nr].magic, CRYPT_MAGIC_LEN);
Karsten Hopp 5f67cf
+     if (salt_len > 0 || seed_len > 0)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	if (salt_len > 0)
Karsten Hopp 5f67cf
+ 	    salt = *header + CRYPT_MAGIC_LEN;
Karsten Hopp 5f67cf
+ 	if (seed_len > 0)
Karsten Hopp 5f67cf
+ 	    seed = *header + CRYPT_MAGIC_LEN + salt_len;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 	/* TODO: Should this be crypt method specific? (Probably not worth
Karsten Hopp 5f67cf
+ 	 * it).  sha2_seed is pretty bad for large amounts of entropy, so make
Karsten Hopp 5f67cf
+ 	 * that into something which is suitable for anything. */
Karsten Hopp 5f67cf
+ 	sha2_seed(salt, salt_len, seed, seed_len);
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     state = crypt_create(method_nr, key, salt, salt_len, seed, seed_len);
Karsten Hopp 5f67cf
+     if (state == NULL)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	vim_free(*header);
Karsten Hopp 5f67cf
+ 	*header = NULL;
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+     return state;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Free the crypt state.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_free_state(state)
Karsten Hopp 5f67cf
+     cryptstate_T	*state;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     vim_free(state->method_state);
Karsten Hopp 5f67cf
+     vim_free(state);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Encode "from[len]" and store the result in a newly allocated buffer, which
Karsten Hopp 5f67cf
+  * is stored in "newptr".
Karsten Hopp 5f67cf
+  * Return number of bytes in "newptr", 0 for need more or -1 on error.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     long
Karsten Hopp 5f67cf
+ crypt_encode_alloc(state, from, len, newptr)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*from;
Karsten Hopp 5f67cf
+     size_t	len;
Karsten Hopp 5f67cf
+     char_u	**newptr;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     cryptmethod_T *method = &cryptmethods[state->method_nr];
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (method->encode_buffer_fn != NULL)
Karsten Hopp 5f67cf
+ 	/* Has buffer function, pass through. */
Karsten Hopp 5f67cf
+ 	return method->encode_buffer_fn(state, from, len, newptr);
Karsten Hopp 5f67cf
+     if (len == 0)
Karsten Hopp 5f67cf
+ 	/* Not buffering, just return EOF. */
Karsten Hopp 5f67cf
+ 	return len;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     *newptr = alloc(len);
Karsten Hopp 5f67cf
+     if (*newptr == NULL)
Karsten Hopp 5f67cf
+ 	return -1;
Karsten Hopp 5f67cf
+     method->encode_fn(state, from, len, *newptr);
Karsten Hopp 5f67cf
+     return len;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Decrypt "ptr[len]" and store the result in a newly allocated buffer, which
Karsten Hopp 5f67cf
+  * is stored in "newptr".
Karsten Hopp 5f67cf
+  * Return number of bytes in "newptr", 0 for need more or -1 on error.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     long
Karsten Hopp 5f67cf
+ crypt_decode_alloc(state, ptr, len, newptr)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*ptr;
Karsten Hopp 5f67cf
+     long	len;
Karsten Hopp 5f67cf
+     char_u      **newptr;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     cryptmethod_T *method = &cryptmethods[state->method_nr];
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (method->decode_buffer_fn != NULL)
Karsten Hopp 5f67cf
+ 	/* Has buffer function, pass through. */
Karsten Hopp 5f67cf
+ 	return method->decode_buffer_fn(state, ptr, len, newptr);
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (len == 0)
Karsten Hopp 5f67cf
+ 	/* Not buffering, just return EOF. */
Karsten Hopp 5f67cf
+ 	return len;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     *newptr = alloc(len);
Karsten Hopp 5f67cf
+     if (*newptr == NULL)
Karsten Hopp 5f67cf
+ 	return -1;
Karsten Hopp 5f67cf
+     method->decode_fn(state, ptr, len, *newptr);
Karsten Hopp 5f67cf
+     return len;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Encrypting "from[len]" into "to[len]".
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_encode(state, from, len, to)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*from;
Karsten Hopp 5f67cf
+     size_t	len;
Karsten Hopp 5f67cf
+     char_u	*to;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     cryptmethods[state->method_nr].encode_fn(state, from, len, to);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * decrypting "from[len]" into "to[len]".
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_decode(state, from, len, to)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*from;
Karsten Hopp 5f67cf
+     size_t	len;
Karsten Hopp 5f67cf
+     char_u	*to;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     cryptmethods[state->method_nr].decode_fn(state, from, len, to);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Simple inplace encryption, modifies "buf[len]" in place.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_encode_inplace(state, buf, len)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*buf;
Karsten Hopp 5f67cf
+     size_t	len;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     cryptmethods[state->method_nr].encode_inplace_fn(state, buf, len, buf);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Simple inplace decryption, modifies "buf[len]" in place.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_decode_inplace(state, buf, len)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*buf;
Karsten Hopp 5f67cf
+     size_t	len;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     cryptmethods[state->method_nr].decode_inplace_fn(state, buf, len, buf);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Free an allocated crypt key.  Clear the text to make sure it doesn't stay
Karsten Hopp 5f67cf
+  * in memory anywhere.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_free_key(key)
Karsten Hopp 5f67cf
+     char_u *key;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     char_u *p;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (key != NULL)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	for (p = key; *p != NUL; ++p)
Karsten Hopp 5f67cf
+ 	    *p = 0;
Karsten Hopp 5f67cf
+ 	vim_free(key);
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Ask the user for a crypt key.
Karsten Hopp 5f67cf
+  * When "store" is TRUE, the new key is stored in the 'key' option, and the
Karsten Hopp 5f67cf
+  * 'key' option value is returned: Don't free it.
Karsten Hopp 5f67cf
+  * When "store" is FALSE, the typed key is returned in allocated memory.
Karsten Hopp 5f67cf
+  * Returns NULL on failure.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     char_u *
Karsten Hopp 5f67cf
+ crypt_get_key(store, twice)
Karsten Hopp 5f67cf
+     int		store;
Karsten Hopp 5f67cf
+     int		twice;	    /* Ask for the key twice. */
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     char_u	*p1, *p2 = NULL;
Karsten Hopp 5f67cf
+     int		round;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     for (round = 0; ; ++round)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	cmdline_star = TRUE;
Karsten Hopp 5f67cf
+ 	cmdline_row = msg_row;
Karsten Hopp 5f67cf
+ 	p1 = getcmdline_prompt(NUL, round == 0
Karsten Hopp 5f67cf
+ 		? (char_u *)_("Enter encryption key: ")
Karsten Hopp 5f67cf
+ 		: (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
Karsten Hopp 5f67cf
+ 		NULL);
Karsten Hopp 5f67cf
+ 	cmdline_star = FALSE;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 	if (p1 == NULL)
Karsten Hopp 5f67cf
+ 	    break;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 	if (round == twice)
Karsten Hopp 5f67cf
+ 	{
Karsten Hopp 5f67cf
+ 	    if (p2 != NULL && STRCMP(p1, p2) != 0)
Karsten Hopp 5f67cf
+ 	    {
Karsten Hopp 5f67cf
+ 		MSG(_("Keys don't match!"));
Karsten Hopp 5f67cf
+ 		crypt_free_key(p1);
Karsten Hopp 5f67cf
+ 		crypt_free_key(p2);
Karsten Hopp 5f67cf
+ 		p2 = NULL;
Karsten Hopp 5f67cf
+ 		round = -1;		/* do it again */
Karsten Hopp 5f67cf
+ 		continue;
Karsten Hopp 5f67cf
+ 	    }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 	    if (store)
Karsten Hopp 5f67cf
+ 	    {
Karsten Hopp 5f67cf
+ 		set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
Karsten Hopp 5f67cf
+ 		crypt_free_key(p1);
Karsten Hopp 5f67cf
+ 		p1 = curbuf->b_p_key;
Karsten Hopp 5f67cf
+ 	    }
Karsten Hopp 5f67cf
+ 	    break;
Karsten Hopp 5f67cf
+ 	}
Karsten Hopp 5f67cf
+ 	p2 = p1;
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* since the user typed this, no need to wait for return */
Karsten Hopp 5f67cf
+     if (msg_didout)
Karsten Hopp 5f67cf
+ 	msg_putchar('\n');
Karsten Hopp 5f67cf
+     need_wait_return = FALSE;
Karsten Hopp 5f67cf
+     msg_didout = FALSE;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     crypt_free_key(p2);
Karsten Hopp 5f67cf
+     return p1;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Append a message to IObuff for the encryption/decryption method being used.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_append_msg(buf)
Karsten Hopp 5f67cf
+     buf_T *buf;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     if (crypt_get_method_nr(buf) == 0)
Karsten Hopp 5f67cf
+ 	STRCAT(IObuff, _("[crypted]"));
Karsten Hopp 5f67cf
+     else
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	STRCAT(IObuff, "[");
Karsten Hopp 5f67cf
+ 	STRCAT(IObuff, *buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
Karsten Hopp 5f67cf
+ 	STRCAT(IObuff, "]");
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ #endif /* FEAT_CRYPT */
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/crypt_zip.c	2014-08-10 13:30:43.824787293 +0200
Karsten Hopp 5f67cf
--- src/crypt_zip.c	2014-08-09 15:31:32.493356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 0 ****
Karsten Hopp 5f67cf
--- 1,158 ----
Karsten Hopp 5f67cf
+ /* vi:set ts=8 sts=4 sw=4:
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * VIM - Vi IMproved	by Bram Moolenaar
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * Do ":help uganda"  in Vim to read copying and usage conditions.
Karsten Hopp 5f67cf
+  * Do ":help credits" in Vim to see a list of people who contributed.
Karsten Hopp 5f67cf
+  * See README.txt for an overview of the Vim source code.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * crypt_zip.c: Zip encryption support.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ #include "vim.h"
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ #if defined(FEAT_CRYPT) || defined(PROTO)
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Optional encryption support.
Karsten Hopp 5f67cf
+  * Mohsin Ahmed, mosh@sasi.com, 98-09-24
Karsten Hopp 5f67cf
+  * Based on zip/crypt sources.
Karsten Hopp 5f67cf
+  *
Karsten Hopp 5f67cf
+  * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
Karsten Hopp 5f67cf
+  * most countries.  There are a few exceptions, but that still should not be a
Karsten Hopp 5f67cf
+  * problem since this code was originally created in Europe and India.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /* Need a type that should be 32 bits. 64 also works but wastes space. */
Karsten Hopp 5f67cf
+ # if VIM_SIZEOF_INT >= 4
Karsten Hopp 5f67cf
+ typedef unsigned int u32_T;	/* int is at least 32 bits */
Karsten Hopp 5f67cf
+ # else
Karsten Hopp 5f67cf
+ typedef unsigned long u32_T;	/* long should be 32 bits or more */
Karsten Hopp 5f67cf
+ # endif
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /* The state of encryption, referenced by cryptstate_T. */
Karsten Hopp 5f67cf
+ typedef struct {
Karsten Hopp 5f67cf
+     u32_T keys[3];
Karsten Hopp 5f67cf
+ } zip_state_T;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ static void make_crc_tab __ARGS((void));
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ static u32_T crc_32_table[256];
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Fill the CRC table, if not done already.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     static void
Karsten Hopp 5f67cf
+ make_crc_tab()
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     u32_T	s, t, v;
Karsten Hopp 5f67cf
+     static int	done = FALSE;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     if (done)
Karsten Hopp 5f67cf
+ 	return;
Karsten Hopp 5f67cf
+     for (t = 0; t < 256; t++)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	v = t;
Karsten Hopp 5f67cf
+ 	for (s = 0; s < 8; s++)
Karsten Hopp 5f67cf
+ 	    v = (v >> 1) ^ ((v & 1) * (u32_T)0xedb88320L);
Karsten Hopp 5f67cf
+ 	crc_32_table[t] = v;
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+     done = TRUE;
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ #define CRC32(c, b) (crc_32_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Return the next byte in the pseudo-random sequence.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ #define DECRYPT_BYTE_ZIP(keys, t) { \
Karsten Hopp 5f67cf
+     short_u temp = (short_u)keys[2] | 2; \
Karsten Hopp 5f67cf
+     t = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff); \
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Update the encryption keys with the next byte of plain text.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ #define UPDATE_KEYS_ZIP(keys, c) { \
Karsten Hopp 5f67cf
+     keys[0] = CRC32(keys[0], (c)); \
Karsten Hopp 5f67cf
+     keys[1] += keys[0] & 0xff; \
Karsten Hopp 5f67cf
+     keys[1] = keys[1] * 134775813L + 1; \
Karsten Hopp 5f67cf
+     keys[2] = CRC32(keys[2], (int)(keys[1] >> 24)); \
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Initialize for encryption/decryption.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_zip_init(state, key, salt, salt_len, seed, seed_len)
Karsten Hopp 5f67cf
+     cryptstate_T    *state;
Karsten Hopp 5f67cf
+     char_u	    *key;
Karsten Hopp 5f67cf
+     char_u	    *salt UNUSED;
Karsten Hopp 5f67cf
+     int		    salt_len UNUSED;
Karsten Hopp 5f67cf
+     char_u	    *seed UNUSED;
Karsten Hopp 5f67cf
+     int		    seed_len UNUSED;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     char_u	*p;
Karsten Hopp 5f67cf
+     zip_state_T	*zs;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     zs = (zip_state_T *)alloc(sizeof(zip_state_T));
Karsten Hopp 5f67cf
+     state->method_state = zs;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     make_crc_tab();
Karsten Hopp 5f67cf
+     zs->keys[0] = 305419896L;
Karsten Hopp 5f67cf
+     zs->keys[1] = 591751049L;
Karsten Hopp 5f67cf
+     zs->keys[2] = 878082192L;
Karsten Hopp 5f67cf
+     for (p = key; *p != NUL; ++p)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	UPDATE_KEYS_ZIP(zs->keys, (int)*p);
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Encrypt "from[len]" into "to[len]".
Karsten Hopp 5f67cf
+  * "from" and "to" can be equal to encrypt in place.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_zip_encode(state, from, len, to)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*from;
Karsten Hopp 5f67cf
+     size_t	len;
Karsten Hopp 5f67cf
+     char_u	*to;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     zip_state_T *zs = state->method_state;
Karsten Hopp 5f67cf
+     size_t	i;
Karsten Hopp 5f67cf
+     int		ztemp, t;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     for (i = 0; i < len; ++i)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	ztemp = from[i];
Karsten Hopp 5f67cf
+ 	DECRYPT_BYTE_ZIP(zs->keys, t);
Karsten Hopp 5f67cf
+ 	UPDATE_KEYS_ZIP(zs->keys, ztemp);
Karsten Hopp 5f67cf
+ 	to[i] = t ^ ztemp;
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Decrypt "from[len]" into "to[len]".
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ crypt_zip_decode(state, from, len, to)
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
+     char_u	*from;
Karsten Hopp 5f67cf
+     size_t	len;
Karsten Hopp 5f67cf
+     char_u	*to;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
+     zip_state_T *zs = state->method_state;
Karsten Hopp 5f67cf
+     size_t	i;
Karsten Hopp 5f67cf
+     short_u	temp;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     for (i = 0; i < len; ++i)
Karsten Hopp 5f67cf
+     {
Karsten Hopp 5f67cf
+ 	temp = (short_u)zs->keys[2] | 2;
Karsten Hopp 5f67cf
+ 	temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
Karsten Hopp 5f67cf
+ 	UPDATE_KEYS_ZIP(zs->keys, to[i] = from[i] ^ temp);
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ #endif /* FEAT_CRYPT */
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/ex_docmd.c	2014-08-06 18:17:03.475147780 +0200
Karsten Hopp 5f67cf
--- src/ex_docmd.c	2014-08-09 15:31:32.493356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 11506,11513 ****
Karsten Hopp 5f67cf
  ex_X(eap)
Karsten Hopp 5f67cf
      exarg_T	*eap UNUSED;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     if (get_crypt_method(curbuf) == 0 || blowfish_self_test() == OK)
Karsten Hopp 5f67cf
! 	(void)get_crypt_key(TRUE, TRUE);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
--- 11506,11512 ----
Karsten Hopp 5f67cf
  ex_X(eap)
Karsten Hopp 5f67cf
      exarg_T	*eap UNUSED;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     (void)crypt_get_key(TRUE, TRUE);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/fileio.c	2014-06-12 14:01:27.575769788 +0200
Karsten Hopp 5f67cf
--- src/fileio.c	2014-08-09 15:31:32.497356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 24,43 ****
Karsten Hopp 5f67cf
  #define BUFSIZE		8192	/* size of normal write buffer */
Karsten Hopp 5f67cf
  #define SMBUFSIZE	256	/* size of emergency write buffer */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
- /* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
Karsten Hopp 5f67cf
- static char	*crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"};
Karsten Hopp 5f67cf
- static char	crypt_magic_head[] = "VimCrypt~";
Karsten Hopp 5f67cf
- # define CRYPT_MAGIC_LEN	12		/* must be multiple of 4! */
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /* For blowfish, after the magic header, we store 8 bytes of salt and then 8
Karsten Hopp 5f67cf
-  * bytes of seed (initialisation vector). */
Karsten Hopp 5f67cf
- static int	crypt_salt_len[] = {0, 8};
Karsten Hopp 5f67cf
- static int	crypt_seed_len[] = {0, 8};
Karsten Hopp 5f67cf
- #define CRYPT_SALT_LEN_MAX 8
Karsten Hopp 5f67cf
- #define CRYPT_SEED_LEN_MAX 8
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  /* Is there any system that doesn't have access()? */
Karsten Hopp 5f67cf
  #define USE_MCH_ACCESS
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
--- 24,29 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 55,61 ****
Karsten Hopp 5f67cf
  static void check_marks_read __ARGS((void));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
- static int crypt_method_from_magic __ARGS((char *ptr, int len));
Karsten Hopp 5f67cf
  static char_u *check_for_cryptkey __ARGS((char_u *cryptkey, char_u *ptr, long *sizep, off_t *filesizep, int newfile, char_u *fname, int *did_ask));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef UNIX
Karsten Hopp 5f67cf
--- 41,46 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 116,121 ****
Karsten Hopp 5f67cf
--- 101,109 ----
Karsten Hopp 5f67cf
  #ifdef HAS_BW_FLAGS
Karsten Hopp 5f67cf
      int		bw_flags;	/* FIO_ flags */
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+     buf_T	*bw_buffer;	/* buffer being written */
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_MBYTE
Karsten Hopp 5f67cf
      char_u	bw_rest[CONV_RESTLEN]; /* not converted bytes */
Karsten Hopp 5f67cf
      int		bw_restlen;	/* nr of bytes in bw_rest[] */
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 250,256 ****
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
      char_u	*cryptkey = NULL;
Karsten Hopp 5f67cf
      int		did_ask_for_key = FALSE;
Karsten Hopp 5f67cf
-     int		crypt_method_used;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_PERSISTENT_UNDO
Karsten Hopp 5f67cf
      context_sha256_T sha_ctx;
Karsten Hopp 5f67cf
--- 238,243 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 966,978 ****
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
-     if (cryptkey != NULL)
Karsten Hopp 5f67cf
- 	/* Need to reset the state, but keep the key, don't want to ask for it
Karsten Hopp 5f67cf
- 	 * again. */
Karsten Hopp 5f67cf
- 	crypt_pop_state();
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
      /*
Karsten Hopp 5f67cf
       * When retrying with another "fenc" and the first time "fileformat"
Karsten Hopp 5f67cf
       * will be reset.
Karsten Hopp 5f67cf
--- 953,958 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1175,1180 ****
Karsten Hopp 5f67cf
--- 1155,1169 ----
Karsten Hopp 5f67cf
  	if (read_undo_file)
Karsten Hopp 5f67cf
  	    sha256_start(&sha_ctx);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+ 	if (curbuf->b_cryptstate != NULL)
Karsten Hopp 5f67cf
+ 	{
Karsten Hopp 5f67cf
+ 	    /* Need to free the state, but keep the key, don't want to ask for
Karsten Hopp 5f67cf
+ 	     * it again. */
Karsten Hopp 5f67cf
+ 	    crypt_free_state(curbuf->b_cryptstate);
Karsten Hopp 5f67cf
+ 	    curbuf->b_cryptstate = NULL;
Karsten Hopp 5f67cf
+ 	}
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      while (!error && !got_int)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1339,1344 ****
Karsten Hopp 5f67cf
--- 1328,1403 ----
Karsten Hopp 5f67cf
  		    size = read_eintr(fd, ptr, size);
Karsten Hopp 5f67cf
  		}
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+ 		/*
Karsten Hopp 5f67cf
+ 		 * At start of file: Check for magic number of encryption.
Karsten Hopp 5f67cf
+ 		 */
Karsten Hopp 5f67cf
+ 		if (filesize == 0 && size > 0)
Karsten Hopp 5f67cf
+ 		    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
Karsten Hopp 5f67cf
+ 						  &filesize, newfile, sfname,
Karsten Hopp 5f67cf
+ 						  &did_ask_for_key);
Karsten Hopp 5f67cf
+ 		/*
Karsten Hopp 5f67cf
+ 		 * Decrypt the read bytes.  This is done before checking for
Karsten Hopp 5f67cf
+ 		 * EOF because the crypt layer may be buffering.
Karsten Hopp 5f67cf
+ 		 */
Karsten Hopp 5f67cf
+ 		if (cryptkey != NULL && size > 0)
Karsten Hopp 5f67cf
+ 		{
Karsten Hopp 5f67cf
+ 		    if (crypt_works_inplace(curbuf->b_cryptstate))
Karsten Hopp 5f67cf
+ 		    {
Karsten Hopp 5f67cf
+ 			crypt_decode_inplace(curbuf->b_cryptstate, ptr, size);
Karsten Hopp 5f67cf
+ 		    }
Karsten Hopp 5f67cf
+ 		    else
Karsten Hopp 5f67cf
+ 		    {
Karsten Hopp 5f67cf
+ 			char_u	*newptr = NULL;
Karsten Hopp 5f67cf
+ 			int	decrypted_size;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 			decrypted_size = crypt_decode_alloc(
Karsten Hopp 5f67cf
+ 				    curbuf->b_cryptstate, ptr, size, &newptr);
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 			/* If the crypt layer is buffering, not producing
Karsten Hopp 5f67cf
+ 			 * anything yet, need to read more. */
Karsten Hopp 5f67cf
+ 			if (size > 0 && decrypted_size == 0)
Karsten Hopp 5f67cf
+ 			    continue;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 			if (linerest == 0)
Karsten Hopp 5f67cf
+ 			{
Karsten Hopp 5f67cf
+ 			    /* Simple case: reuse returned buffer (may be
Karsten Hopp 5f67cf
+ 			     * NULL, checked later). */
Karsten Hopp 5f67cf
+ 			    new_buffer = newptr;
Karsten Hopp 5f67cf
+ 			}
Karsten Hopp 5f67cf
+ 			else
Karsten Hopp 5f67cf
+ 			{
Karsten Hopp 5f67cf
+ 			    long_u	new_size;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 			    /* Need new buffer to add bytes carried over. */
Karsten Hopp 5f67cf
+ 			    new_size = (long_u)(decrypted_size + linerest + 1);
Karsten Hopp 5f67cf
+ 			    new_buffer = lalloc(new_size, FALSE);
Karsten Hopp 5f67cf
+ 			    if (new_buffer == NULL)
Karsten Hopp 5f67cf
+ 			    {
Karsten Hopp 5f67cf
+ 				do_outofmem_msg(new_size);
Karsten Hopp 5f67cf
+ 				error = TRUE;
Karsten Hopp 5f67cf
+ 				break;
Karsten Hopp 5f67cf
+ 			    }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 			    mch_memmove(new_buffer, buffer, linerest);
Karsten Hopp 5f67cf
+ 			    if (newptr != NULL)
Karsten Hopp 5f67cf
+ 				mch_memmove(new_buffer + linerest, newptr,
Karsten Hopp 5f67cf
+ 							      decrypted_size);
Karsten Hopp 5f67cf
+ 			}
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 			if (new_buffer != NULL)
Karsten Hopp 5f67cf
+ 			{
Karsten Hopp 5f67cf
+ 			    vim_free(buffer);
Karsten Hopp 5f67cf
+ 			    buffer = new_buffer;
Karsten Hopp 5f67cf
+ 			    new_buffer = NULL;
Karsten Hopp 5f67cf
+ 			    line_start = buffer;
Karsten Hopp 5f67cf
+ 			    ptr = buffer + linerest;
Karsten Hopp 5f67cf
+ 			}
Karsten Hopp 5f67cf
+ 			size = decrypted_size;
Karsten Hopp 5f67cf
+ 		    }
Karsten Hopp 5f67cf
+ 		}
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  		if (size <= 0)
Karsten Hopp 5f67cf
  		{
Karsten Hopp 5f67cf
  		    if (size < 0)		    /* read error */
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1403,1423 ****
Karsten Hopp 5f67cf
  		    }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  		}
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
- 		/*
Karsten Hopp 5f67cf
- 		 * At start of file: Check for magic number of encryption.
Karsten Hopp 5f67cf
- 		 */
Karsten Hopp 5f67cf
- 		if (filesize == 0)
Karsten Hopp 5f67cf
- 		    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
Karsten Hopp 5f67cf
- 					&filesize, newfile, sfname,
Karsten Hopp 5f67cf
- 					&did_ask_for_key);
Karsten Hopp 5f67cf
- 		/*
Karsten Hopp 5f67cf
- 		 * Decrypt the read bytes.
Karsten Hopp 5f67cf
- 		 */
Karsten Hopp 5f67cf
- 		if (cryptkey != NULL && size > 0)
Karsten Hopp 5f67cf
- 		    crypt_decode(ptr, size);
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
  	    }
Karsten Hopp 5f67cf
  	    skip_read = FALSE;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
--- 1462,1467 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1430,1439 ****
Karsten Hopp 5f67cf
  	     */
Karsten Hopp 5f67cf
  	    if ((filesize == 0
Karsten Hopp 5f67cf
  # ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! 		   || (filesize == (CRYPT_MAGIC_LEN
Karsten Hopp 5f67cf
! 					   + crypt_salt_len[use_crypt_method]
Karsten Hopp 5f67cf
! 					   + crypt_seed_len[use_crypt_method])
Karsten Hopp 5f67cf
! 							  && cryptkey != NULL)
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  		       )
Karsten Hopp 5f67cf
  		    && (fio_flags == FIO_UCSBOM
Karsten Hopp 5f67cf
--- 1474,1482 ----
Karsten Hopp 5f67cf
  	     */
Karsten Hopp 5f67cf
  	    if ((filesize == 0
Karsten Hopp 5f67cf
  # ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! 		   || (cryptkey != NULL
Karsten Hopp 5f67cf
! 			&& filesize == crypt_get_header_len(
Karsten Hopp 5f67cf
! 						 crypt_get_method_nr(curbuf)))
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  		       )
Karsten Hopp 5f67cf
  		    && (fio_flags == FIO_UCSBOM
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2262,2276 ****
Karsten Hopp 5f67cf
  	save_file_ff(curbuf);		/* remember the current file format */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     crypt_method_used = use_crypt_method;
Karsten Hopp 5f67cf
!     if (cryptkey != NULL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	crypt_pop_state();
Karsten Hopp 5f67cf
! 	if (cryptkey != curbuf->b_p_key)
Karsten Hopp 5f67cf
! 	    free_crypt_key(cryptkey);
Karsten Hopp 5f67cf
! 	/* don't set cryptkey to NULL, it's used below as a flag that
Karsten Hopp 5f67cf
! 	 * encryption was used */
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_MBYTE
Karsten Hopp 5f67cf
--- 2305,2319 ----
Karsten Hopp 5f67cf
  	save_file_ff(curbuf);		/* remember the current file format */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (curbuf->b_cryptstate != NULL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	crypt_free_state(curbuf->b_cryptstate);
Karsten Hopp 5f67cf
! 	curbuf->b_cryptstate = NULL;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
+     if (cryptkey != NULL && cryptkey != curbuf->b_p_key)
Karsten Hopp 5f67cf
+ 	crypt_free_key(cryptkey);
Karsten Hopp 5f67cf
+     /* Don't set cryptkey to NULL, it's used below as a flag that
Karsten Hopp 5f67cf
+      * encryption was used. */
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_MBYTE
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2457,2466 ****
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
  	    if (cryptkey != NULL)
Karsten Hopp 5f67cf
  	    {
Karsten Hopp 5f67cf
! 		if (crypt_method_used == 1)
Karsten Hopp 5f67cf
! 		    STRCAT(IObuff, _("[blowfish]"));
Karsten Hopp 5f67cf
! 		else
Karsten Hopp 5f67cf
! 		    STRCAT(IObuff, _("[crypted]"));
Karsten Hopp 5f67cf
  		c = TRUE;
Karsten Hopp 5f67cf
  	    }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
--- 2500,2506 ----
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
  	    if (cryptkey != NULL)
Karsten Hopp 5f67cf
  	    {
Karsten Hopp 5f67cf
! 		crypt_append_msg(curbuf);
Karsten Hopp 5f67cf
  		c = TRUE;
Karsten Hopp 5f67cf
  	    }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2489,2497 ****
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
  	    if (cryptkey != NULL)
Karsten Hopp 5f67cf
  		msg_add_lines(c, (long)linecnt, filesize
Karsten Hopp 5f67cf
! 			- CRYPT_MAGIC_LEN
Karsten Hopp 5f67cf
! 			- crypt_salt_len[use_crypt_method]
Karsten Hopp 5f67cf
! 			- crypt_seed_len[use_crypt_method]);
Karsten Hopp 5f67cf
  	    else
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  		msg_add_lines(c, (long)linecnt, filesize);
Karsten Hopp 5f67cf
--- 2529,2535 ----
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
  	    if (cryptkey != NULL)
Karsten Hopp 5f67cf
  		msg_add_lines(c, (long)linecnt, filesize
Karsten Hopp 5f67cf
! 			 - crypt_get_header_len(crypt_get_method_nr(curbuf)));
Karsten Hopp 5f67cf
  	    else
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  		msg_add_lines(c, (long)linecnt, filesize);
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2882,2914 ****
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #if defined(FEAT_CRYPT) || defined(PROTO)
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
-  * Get the crypt method used for a file from "ptr[len]", the magic text at the
Karsten Hopp 5f67cf
-  * start of the file.
Karsten Hopp 5f67cf
-  * Returns -1 when no encryption used.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     static int
Karsten Hopp 5f67cf
- crypt_method_from_magic(ptr, len)
Karsten Hopp 5f67cf
-     char  *ptr;
Karsten Hopp 5f67cf
-     int   len;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     int i;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     for (i = 0; i < (int)(sizeof(crypt_magic) / sizeof(crypt_magic[0])); i++)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	if (len < (CRYPT_MAGIC_LEN + crypt_salt_len[i] + crypt_seed_len[i]))
Karsten Hopp 5f67cf
- 	    continue;
Karsten Hopp 5f67cf
- 	if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0)
Karsten Hopp 5f67cf
- 	    return i;
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     i = (int)STRLEN(crypt_magic_head);
Karsten Hopp 5f67cf
-     if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0)
Karsten Hopp 5f67cf
- 	EMSG(_("E821: File is encrypted with unknown method"));
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     return -1;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
   * Check for magic number used for encryption.  Applies to the current buffer.
Karsten Hopp 5f67cf
   * If found, the magic number is removed from ptr[*sizep] and *sizep and
Karsten Hopp 5f67cf
   * *filesizep are updated.
Karsten Hopp 5f67cf
--- 2920,2925 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2924,2930 ****
Karsten Hopp 5f67cf
      char_u	*fname;		/* file name to display */
Karsten Hopp 5f67cf
      int		*did_ask;	/* flag: whether already asked for key */
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     int method = crypt_method_from_magic((char *)ptr, *sizep);
Karsten Hopp 5f67cf
      int b_p_ro = curbuf->b_p_ro;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (method >= 0)
Karsten Hopp 5f67cf
--- 2935,2941 ----
Karsten Hopp 5f67cf
      char_u	*fname;		/* file name to display */
Karsten Hopp 5f67cf
      int		*did_ask;	/* flag: whether already asked for key */
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     int method = crypt_method_nr_from_magic((char *)ptr, *sizep);
Karsten Hopp 5f67cf
      int b_p_ro = curbuf->b_p_ro;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (method >= 0)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2933,2941 ****
Karsten Hopp 5f67cf
  	 * Avoids accidentally overwriting the file with garbage. */
Karsten Hopp 5f67cf
  	curbuf->b_p_ro = TRUE;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	set_crypt_method(curbuf, method);
Karsten Hopp 5f67cf
! 	if (method > 0)
Karsten Hopp 5f67cf
! 	    (void)blowfish_self_test();
Karsten Hopp 5f67cf
  	if (cryptkey == NULL && !*did_ask)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    if (*curbuf->b_p_key)
Karsten Hopp 5f67cf
--- 2944,2950 ----
Karsten Hopp 5f67cf
  	 * Avoids accidentally overwriting the file with garbage. */
Karsten Hopp 5f67cf
  	curbuf->b_p_ro = TRUE;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	crypt_set_cm_option(curbuf, method);
Karsten Hopp 5f67cf
  	if (cryptkey == NULL && !*did_ask)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    if (*curbuf->b_p_key)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2948,2954 ****
Karsten Hopp 5f67cf
  		 * Happens when retrying to detect encoding. */
Karsten Hopp 5f67cf
  		smsg((char_u *)_(need_key_msg), fname);
Karsten Hopp 5f67cf
  		msg_scroll = TRUE;
Karsten Hopp 5f67cf
! 		cryptkey = get_crypt_key(newfile, FALSE);
Karsten Hopp 5f67cf
  		*did_ask = TRUE;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  		/* check if empty key entered */
Karsten Hopp 5f67cf
--- 2957,2963 ----
Karsten Hopp 5f67cf
  		 * Happens when retrying to detect encoding. */
Karsten Hopp 5f67cf
  		smsg((char_u *)_(need_key_msg), fname);
Karsten Hopp 5f67cf
  		msg_scroll = TRUE;
Karsten Hopp 5f67cf
! 		cryptkey = crypt_get_key(newfile, FALSE);
Karsten Hopp 5f67cf
  		*did_ask = TRUE;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  		/* check if empty key entered */
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2963,2986 ****
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	if (cryptkey != NULL)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    int seed_len = crypt_seed_len[method];
Karsten Hopp 5f67cf
! 	    int salt_len = crypt_salt_len[method];
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	    crypt_push_state();
Karsten Hopp 5f67cf
! 	    use_crypt_method = method;
Karsten Hopp 5f67cf
! 	    if (method == 0)
Karsten Hopp 5f67cf
! 		crypt_init_keys(cryptkey);
Karsten Hopp 5f67cf
! 	    else
Karsten Hopp 5f67cf
! 	    {
Karsten Hopp 5f67cf
! 		bf_key_init(cryptkey, ptr + CRYPT_MAGIC_LEN, salt_len);
Karsten Hopp 5f67cf
! 		bf_cfb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len);
Karsten Hopp 5f67cf
! 	    }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- 	    /* Remove magic number from the text */
Karsten Hopp 5f67cf
- 	    *filesizep += CRYPT_MAGIC_LEN + salt_len + seed_len;
Karsten Hopp 5f67cf
- 	    *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len;
Karsten Hopp 5f67cf
- 	    mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len,
Karsten Hopp 5f67cf
- 							      (size_t)*sizep);
Karsten Hopp 5f67cf
  	    /* Restore the read-only flag. */
Karsten Hopp 5f67cf
  	    curbuf->b_p_ro = b_p_ro;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
--- 2972,2989 ----
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	if (cryptkey != NULL)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    int header_len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	    curbuf->b_cryptstate = crypt_create_from_header(
Karsten Hopp 5f67cf
! 						       method, cryptkey, ptr);
Karsten Hopp 5f67cf
! 	    crypt_set_cm_option(curbuf, method);
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	    /* Remove cryptmethod specific header from the text. */
Karsten Hopp 5f67cf
! 	    header_len = crypt_get_header_len(method);
Karsten Hopp 5f67cf
! 	    *filesizep += header_len;
Karsten Hopp 5f67cf
! 	    *sizep -= header_len;
Karsten Hopp 5f67cf
! 	    mch_memmove(ptr, ptr + header_len, (size_t)*sizep);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	    /* Restore the read-only flag. */
Karsten Hopp 5f67cf
  	    curbuf->b_p_ro = b_p_ro;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2992,3076 ****
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      return cryptkey;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Check for magic number used for encryption.  Applies to the current buffer.
Karsten Hopp 5f67cf
-  * If found and decryption is possible returns OK;
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     int
Karsten Hopp 5f67cf
- prepare_crypt_read(fp)
Karsten Hopp 5f67cf
-     FILE	*fp;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     int		method;
Karsten Hopp 5f67cf
-     char_u	buffer[CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
Karsten Hopp 5f67cf
- 						    + CRYPT_SEED_LEN_MAX + 2];
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     if (fread(buffer, CRYPT_MAGIC_LEN, 1, fp) != 1)
Karsten Hopp 5f67cf
- 	return FAIL;
Karsten Hopp 5f67cf
-     method = crypt_method_from_magic((char *)buffer,
Karsten Hopp 5f67cf
- 					CRYPT_MAGIC_LEN +
Karsten Hopp 5f67cf
- 					CRYPT_SEED_LEN_MAX +
Karsten Hopp 5f67cf
- 					CRYPT_SALT_LEN_MAX);
Karsten Hopp 5f67cf
-     if (method < 0 || method != get_crypt_method(curbuf))
Karsten Hopp 5f67cf
- 	return FAIL;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     crypt_push_state();
Karsten Hopp 5f67cf
-     if (method == 0)
Karsten Hopp 5f67cf
- 	crypt_init_keys(curbuf->b_p_key);
Karsten Hopp 5f67cf
-     else
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	int salt_len = crypt_salt_len[method];
Karsten Hopp 5f67cf
- 	int seed_len = crypt_seed_len[method];
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- 	if (fread(buffer, salt_len + seed_len, 1, fp) != 1)
Karsten Hopp 5f67cf
- 	    return FAIL;
Karsten Hopp 5f67cf
- 	bf_key_init(curbuf->b_p_key, buffer, salt_len);
Karsten Hopp 5f67cf
- 	bf_cfb_init(buffer + salt_len, seed_len);
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
-     return OK;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Prepare for writing encrypted bytes for buffer "buf".
Karsten Hopp 5f67cf
-  * Returns a pointer to an allocated header of length "*lenp".
Karsten Hopp 5f67cf
-  * When out of memory returns NULL.
Karsten Hopp 5f67cf
-  * Otherwise calls crypt_push_state(), call crypt_pop_state() later.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     char_u *
Karsten Hopp 5f67cf
- prepare_crypt_write(buf, lenp)
Karsten Hopp 5f67cf
-     buf_T *buf;
Karsten Hopp 5f67cf
-     int   *lenp;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     char_u  *header;
Karsten Hopp 5f67cf
-     int	    seed_len = crypt_seed_len[get_crypt_method(buf)];
Karsten Hopp 5f67cf
-     int     salt_len = crypt_salt_len[get_crypt_method(buf)];
Karsten Hopp 5f67cf
-     char_u  *salt;
Karsten Hopp 5f67cf
-     char_u  *seed;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     header = alloc_clear(CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
Karsten Hopp 5f67cf
- 						    + CRYPT_SEED_LEN_MAX + 2);
Karsten Hopp 5f67cf
-     if (header != NULL)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	crypt_push_state();
Karsten Hopp 5f67cf
- 	use_crypt_method = get_crypt_method(buf);  /* select zip or blowfish */
Karsten Hopp 5f67cf
- 	vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method],
Karsten Hopp 5f67cf
- 							     CRYPT_MAGIC_LEN);
Karsten Hopp 5f67cf
- 	if (use_crypt_method == 0)
Karsten Hopp 5f67cf
- 	    crypt_init_keys(buf->b_p_key);
Karsten Hopp 5f67cf
- 	else
Karsten Hopp 5f67cf
- 	{
Karsten Hopp 5f67cf
- 	    /* Using blowfish, add salt and seed. */
Karsten Hopp 5f67cf
- 	    salt = header + CRYPT_MAGIC_LEN;
Karsten Hopp 5f67cf
- 	    seed = salt + salt_len;
Karsten Hopp 5f67cf
- 	    sha2_seed(salt, salt_len, seed, seed_len);
Karsten Hopp 5f67cf
- 	    bf_key_init(buf->b_p_key, salt, salt_len);
Karsten Hopp 5f67cf
- 	    bf_cfb_init(seed, seed_len);
Karsten Hopp 5f67cf
- 	}
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
-     *lenp = CRYPT_MAGIC_LEN + salt_len + seed_len;
Karsten Hopp 5f67cf
-     return header;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  #endif  /* FEAT_CRYPT */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef UNIX
Karsten Hopp 5f67cf
--- 2995,3000 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 3224,3232 ****
Karsten Hopp 5f67cf
      int		    write_undo_file = FALSE;
Karsten Hopp 5f67cf
      context_sha256_T sha_ctx;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
- #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
-     int		    crypt_method_used;
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (fname == NULL || *fname == NUL)	/* safety check */
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
--- 3148,3153 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 3262,3267 ****
Karsten Hopp 5f67cf
--- 3183,3191 ----
Karsten Hopp 5f67cf
      write_info.bw_iconv_fd = (iconv_t)-1;
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+     write_info.bw_buffer = buf;
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* After writing a file changedtick changes but we don't want to display
Karsten Hopp 5f67cf
       * the line. */
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4505,4521 ****
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
      if (*buf->b_p_key != NUL && !filtering)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	char_u *header;
Karsten Hopp 5f67cf
! 	int    header_len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	header = prepare_crypt_write(buf, &header_len);
Karsten Hopp 5f67cf
! 	if (header == NULL)
Karsten Hopp 5f67cf
  	    end = 0;
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    /* Write magic number, so that Vim knows that this file is
Karsten Hopp 5f67cf
! 	     * encrypted when reading it again.  This also undergoes utf-8 to
Karsten Hopp 5f67cf
! 	     * ucs-2/4 conversion when needed. */
Karsten Hopp 5f67cf
  	    write_info.bw_buf = header;
Karsten Hopp 5f67cf
  	    write_info.bw_len = header_len;
Karsten Hopp 5f67cf
  	    write_info.bw_flags = FIO_NOCONVERT;
Karsten Hopp 5f67cf
--- 4429,4445 ----
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
      if (*buf->b_p_key != NUL && !filtering)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	char_u		*header;
Karsten Hopp 5f67cf
! 	int		header_len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	buf->b_cryptstate = crypt_create_for_writing(crypt_get_method_nr(buf),
Karsten Hopp 5f67cf
! 					  buf->b_p_key, &header, &header_len);
Karsten Hopp 5f67cf
! 	if (buf->b_cryptstate == NULL || header == NULL)
Karsten Hopp 5f67cf
  	    end = 0;
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    /* Write magic number, so that Vim knows how this file is
Karsten Hopp 5f67cf
! 	     * encrypted when reading it back. */
Karsten Hopp 5f67cf
  	    write_info.bw_buf = header;
Karsten Hopp 5f67cf
  	    write_info.bw_len = header_len;
Karsten Hopp 5f67cf
  	    write_info.bw_flags = FIO_NOCONVERT;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4769,4780 ****
Karsten Hopp 5f67cf
  	mch_set_acl(wfname, acl);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     crypt_method_used = use_crypt_method;
Karsten Hopp 5f67cf
!     if (wb_flags & FIO_ENCRYPTED)
Karsten Hopp 5f67cf
! 	crypt_pop_state();
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  #if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
Karsten Hopp 5f67cf
      if (wfname != fname)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
--- 4693,4705 ----
Karsten Hopp 5f67cf
  	mch_set_acl(wfname, acl);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (buf->b_cryptstate != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	crypt_free_state(buf->b_cryptstate);
Karsten Hopp 5f67cf
! 	buf->b_cryptstate = NULL;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #if defined(FEAT_MBYTE) && defined(FEAT_EVAL)
Karsten Hopp 5f67cf
      if (wfname != fname)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4924,4933 ****
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
  	if (wb_flags & FIO_ENCRYPTED)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    if (crypt_method_used == 1)
Karsten Hopp 5f67cf
! 		STRCAT(IObuff, _("[blowfish]"));
Karsten Hopp 5f67cf
! 	    else
Karsten Hopp 5f67cf
! 		STRCAT(IObuff, _("[crypted]"));
Karsten Hopp 5f67cf
  	    c = TRUE;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
--- 4849,4855 ----
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
  	if (wb_flags & FIO_ENCRYPTED)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    crypt_append_msg(buf);
Karsten Hopp 5f67cf
  	    c = TRUE;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 5740,5747 ****
Karsten Hopp 5f67cf
  #endif /* FEAT_MBYTE */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (flags & FIO_ENCRYPTED)		/* encrypt the data */
Karsten Hopp 5f67cf
! 	crypt_encode(buf, len, buf);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      wlen = write_eintr(ip->bw_fd, buf, len);
Karsten Hopp 5f67cf
--- 5662,5687 ----
Karsten Hopp 5f67cf
  #endif /* FEAT_MBYTE */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (flags & FIO_ENCRYPTED)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	/* Encrypt the data. Do it in-place if possible, otherwise use an
Karsten Hopp 5f67cf
! 	 * allocated buffer. */
Karsten Hopp 5f67cf
! 	if (crypt_works_inplace(ip->bw_buffer->b_cryptstate))
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len);
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
! 	else
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    char_u *outbuf;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	    len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf);
Karsten Hopp 5f67cf
! 	    if (len == 0)
Karsten Hopp 5f67cf
! 		return OK;  /* Crypt layer is buffering, will flush later. */
Karsten Hopp 5f67cf
! 	    wlen = write_eintr(ip->bw_fd, outbuf, len);
Karsten Hopp 5f67cf
! 	    vim_free(outbuf);
Karsten Hopp 5f67cf
! 	    return (wlen < len) ? FAIL : OK;
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      wlen = write_eintr(ip->bw_fd, buf, len);
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/globals.h	2014-08-06 18:17:03.475147780 +0200
Karsten Hopp 5f67cf
--- src/globals.h	2014-08-09 15:31:32.497356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 105,114 ****
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  EXTERN int	screen_cleared INIT(= FALSE);	/* screen has been cleared */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
- EXTERN int      use_crypt_method INIT(= 0);
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
   * When '$' is included in 'cpoptions' option set:
Karsten Hopp 5f67cf
   * When a change command is given that deletes only part of a line, a dollar
Karsten Hopp 5f67cf
--- 105,110 ----
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/main.c	2014-05-28 18:22:37.876225054 +0200
Karsten Hopp 5f67cf
--- src/main.c	2014-08-09 15:31:32.497356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 846,853 ****
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
      if (params.ask_for_key)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	(void)blowfish_self_test();
Karsten Hopp 5f67cf
! 	(void)get_crypt_key(TRUE, TRUE);
Karsten Hopp 5f67cf
  	TIME_MSG("getting crypt key");
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
--- 846,852 ----
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
      if (params.ask_for_key)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	(void)crypt_get_key(TRUE, TRUE);
Karsten Hopp 5f67cf
  	TIME_MSG("getting crypt key");
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/memline.c	2014-03-23 16:03:56.171311627 +0100
Karsten Hopp 5f67cf
--- src/memline.c	2014-08-09 15:39:22.629352806 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 63,68 ****
Karsten Hopp 5f67cf
--- 63,77 ----
Karsten Hopp 5f67cf
  #define BLOCK0_ID1     '0'		    /* block 0 id 1 */
Karsten Hopp 5f67cf
  #define BLOCK0_ID1_C0  'c'		    /* block 0 id 1 'cm' 0 */
Karsten Hopp 5f67cf
  #define BLOCK0_ID1_C1  'C'		    /* block 0 id 1 'cm' 1 */
Karsten Hopp 5f67cf
+ #define BLOCK0_ID1_C2  'd'		    /* block 0 id 1 'cm' 2 */
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ #if defined(FEAT_CRYPT)
Karsten Hopp 5f67cf
+ static int id1_codes[] = {
Karsten Hopp 5f67cf
+     BLOCK0_ID1_C0,  /* CRYPT_M_ZIP */
Karsten Hopp 5f67cf
+     BLOCK0_ID1_C1,  /* CRYPT_M_BF */
Karsten Hopp 5f67cf
+     BLOCK0_ID1_C2,  /* CRYPT_M_BF2 */
Karsten Hopp 5f67cf
+ };
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
   * pointer to a block, used in a pointer block
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 151,157 ****
Karsten Hopp 5f67cf
  struct block0
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      char_u	b0_id[2];	/* id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
Karsten Hopp 5f67cf
! 				 * BLOCK0_ID1_C0, BLOCK0_ID1_C1 */
Karsten Hopp 5f67cf
      char_u	b0_version[10];	/* Vim version string */
Karsten Hopp 5f67cf
      char_u	b0_page_size[4];/* number of bytes per page */
Karsten Hopp 5f67cf
      char_u	b0_mtime[4];	/* last modification time of file */
Karsten Hopp 5f67cf
--- 160,166 ----
Karsten Hopp 5f67cf
  struct block0
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      char_u	b0_id[2];	/* id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
Karsten Hopp 5f67cf
! 				 * BLOCK0_ID1_C0, BLOCK0_ID1_C1, etc. */
Karsten Hopp 5f67cf
      char_u	b0_version[10];	/* Vim version string */
Karsten Hopp 5f67cf
      char_u	b0_page_size[4];/* number of bytes per page */
Karsten Hopp 5f67cf
      char_u	b0_mtime[4];	/* last modification time of file */
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 256,262 ****
Karsten Hopp 5f67cf
  static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! static void ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_BYTEOFF
Karsten Hopp 5f67cf
  static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
Karsten Hopp 5f67cf
--- 265,271 ----
Karsten Hopp 5f67cf
  static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! static cryptstate_T *ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_BYTEOFF
Karsten Hopp 5f67cf
  static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 359,366 ****
Karsten Hopp 5f67cf
  	b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
Karsten Hopp 5f67cf
  	long_to_char(mch_get_pid(), b0p->b0_pid);
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! 	if (*buf->b_p_key != NUL)
Karsten Hopp 5f67cf
! 	    ml_set_b0_crypt(buf, b0p);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
--- 368,374 ----
Karsten Hopp 5f67cf
  	b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
Karsten Hopp 5f67cf
  	long_to_char(mch_get_pid(), b0p->b0_pid);
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! 	ml_set_b0_crypt(buf, b0p);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 436,446 ****
Karsten Hopp 5f67cf
  	b0p->b0_id[1] = BLOCK0_ID1;
Karsten Hopp 5f67cf
      else
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	if (get_crypt_method(buf) == 0)
Karsten Hopp 5f67cf
! 	    b0p->b0_id[1] = BLOCK0_ID1_C0;
Karsten Hopp 5f67cf
! 	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
- 	    b0p->b0_id[1] = BLOCK0_ID1_C1;
Karsten Hopp 5f67cf
  	    /* Generate a seed and store it in block 0 and in the memfile. */
Karsten Hopp 5f67cf
  	    sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
Karsten Hopp 5f67cf
  	    mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
Karsten Hopp 5f67cf
--- 444,454 ----
Karsten Hopp 5f67cf
  	b0p->b0_id[1] = BLOCK0_ID1;
Karsten Hopp 5f67cf
      else
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	int method_nr = crypt_get_method_nr(buf);
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	b0p->b0_id[1] = id1_codes[method_nr];
Karsten Hopp 5f67cf
! 	if (method_nr > CRYPT_M_ZIP)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    /* Generate a seed and store it in block 0 and in the memfile. */
Karsten Hopp 5f67cf
  	    sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
Karsten Hopp 5f67cf
  	    mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 887,893 ****
Karsten Hopp 5f67cf
      if (b0p->b0_id[0] != BLOCK0_ID0
Karsten Hopp 5f67cf
  	    || (b0p->b0_id[1] != BLOCK0_ID1
Karsten Hopp 5f67cf
  		&& b0p->b0_id[1] != BLOCK0_ID1_C0
Karsten Hopp 5f67cf
! 		&& b0p->b0_id[1] != BLOCK0_ID1_C1)
Karsten Hopp 5f67cf
  	    )
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
--- 895,902 ----
Karsten Hopp 5f67cf
      if (b0p->b0_id[0] != BLOCK0_ID0
Karsten Hopp 5f67cf
  	    || (b0p->b0_id[1] != BLOCK0_ID1
Karsten Hopp 5f67cf
  		&& b0p->b0_id[1] != BLOCK0_ID1_C0
Karsten Hopp 5f67cf
! 		&& b0p->b0_id[1] != BLOCK0_ID1_C1
Karsten Hopp 5f67cf
! 		&& b0p->b0_id[1] != BLOCK0_ID1_C2)
Karsten Hopp 5f67cf
  	    )
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1255,1268 ****
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (b0p->b0_id[1] == BLOCK0_ID1_C0)
Karsten Hopp 5f67cf
! 	b0_cm = 0;
Karsten Hopp 5f67cf
!     else if (b0p->b0_id[1] == BLOCK0_ID1_C1)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	b0_cm = 1;
Karsten Hopp 5f67cf
  	mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
!     set_crypt_method(buf, b0_cm);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
      if (b0p->b0_id[1] != BLOCK0_ID1)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
--- 1264,1275 ----
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     for (i = 0; i < (int)(sizeof(id1_codes) / sizeof(int)); ++i)
Karsten Hopp 5f67cf
! 	if (id1_codes[i] == b0p->b0_id[1])
Karsten Hopp 5f67cf
! 	    b0_cm = i;
Karsten Hopp 5f67cf
!     if (b0_cm > 0)
Karsten Hopp 5f67cf
  	mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
Karsten Hopp 5f67cf
!     crypt_set_cm_option(buf, b0_cm < 0 ? 0 : b0_cm);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
      if (b0p->b0_id[1] != BLOCK0_ID1)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1389,1395 ****
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	    smsg((char_u *)_(need_key_msg), fname_used);
Karsten Hopp 5f67cf
! 	buf->b_p_key = get_crypt_key(FALSE, FALSE);
Karsten Hopp 5f67cf
  	if (buf->b_p_key == NULL)
Karsten Hopp 5f67cf
  	    buf->b_p_key = curbuf->b_p_key;
Karsten Hopp 5f67cf
  	else if (*buf->b_p_key == NUL)
Karsten Hopp 5f67cf
--- 1396,1402 ----
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	    smsg((char_u *)_(need_key_msg), fname_used);
Karsten Hopp 5f67cf
! 	buf->b_p_key = crypt_get_key(FALSE, FALSE);
Karsten Hopp 5f67cf
  	if (buf->b_p_key == NULL)
Karsten Hopp 5f67cf
  	    buf->b_p_key = curbuf->b_p_key;
Karsten Hopp 5f67cf
  	else if (*buf->b_p_key == NUL)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4816,4821 ****
Karsten Hopp 5f67cf
--- 4823,4829 ----
Karsten Hopp 5f67cf
      char_u	*text_start;
Karsten Hopp 5f67cf
      char_u	*new_data;
Karsten Hopp 5f67cf
      int		text_len;
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (dp->db_id != DATA_ID)
Karsten Hopp 5f67cf
  	return data;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4831,4840 ****
Karsten Hopp 5f67cf
      mch_memmove(new_data, dp, head_end - (char_u *)dp);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Encrypt the text. */
Karsten Hopp 5f67cf
!     crypt_push_state();
Karsten Hopp 5f67cf
!     ml_crypt_prepare(mfp, offset, FALSE);
Karsten Hopp 5f67cf
!     crypt_encode(text_start, text_len, new_data + dp->db_txt_start);
Karsten Hopp 5f67cf
!     crypt_pop_state();
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Clear the gap. */
Karsten Hopp 5f67cf
      if (head_end < text_start)
Karsten Hopp 5f67cf
--- 4839,4847 ----
Karsten Hopp 5f67cf
      mch_memmove(new_data, dp, head_end - (char_u *)dp);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Encrypt the text. */
Karsten Hopp 5f67cf
!     state = ml_crypt_prepare(mfp, offset, FALSE);
Karsten Hopp 5f67cf
!     crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start);
Karsten Hopp 5f67cf
!     crypt_free_state(state);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Clear the gap. */
Karsten Hopp 5f67cf
      if (head_end < text_start)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4857,4862 ****
Karsten Hopp 5f67cf
--- 4864,4870 ----
Karsten Hopp 5f67cf
      char_u	*head_end;
Karsten Hopp 5f67cf
      char_u	*text_start;
Karsten Hopp 5f67cf
      int		text_len;
Karsten Hopp 5f67cf
+     cryptstate_T *state;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (dp->db_id == DATA_ID)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4869,4885 ****
Karsten Hopp 5f67cf
  	    return;  /* data was messed up */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	/* Decrypt the text in place. */
Karsten Hopp 5f67cf
! 	crypt_push_state();
Karsten Hopp 5f67cf
! 	ml_crypt_prepare(mfp, offset, TRUE);
Karsten Hopp 5f67cf
! 	crypt_decode(text_start, text_len);
Karsten Hopp 5f67cf
! 	crypt_pop_state();
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
   * Prepare for encryption/decryption, using the key, seed and offset.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static void
Karsten Hopp 5f67cf
  ml_crypt_prepare(mfp, offset, reading)
Karsten Hopp 5f67cf
      memfile_T	*mfp;
Karsten Hopp 5f67cf
      off_t	offset;
Karsten Hopp 5f67cf
--- 4877,4893 ----
Karsten Hopp 5f67cf
  	    return;  /* data was messed up */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	/* Decrypt the text in place. */
Karsten Hopp 5f67cf
! 	state = ml_crypt_prepare(mfp, offset, TRUE);
Karsten Hopp 5f67cf
! 	crypt_decode_inplace(state, text_start, text_len);
Karsten Hopp 5f67cf
! 	crypt_free_state(state);
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
   * Prepare for encryption/decryption, using the key, seed and offset.
Karsten Hopp 5f67cf
+  * Return an allocated cryptstate_T *.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static cryptstate_T *
Karsten Hopp 5f67cf
  ml_crypt_prepare(mfp, offset, reading)
Karsten Hopp 5f67cf
      memfile_T	*mfp;
Karsten Hopp 5f67cf
      off_t	offset;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4887,4924 ****
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      buf_T	*buf = mfp->mf_buffer;
Karsten Hopp 5f67cf
      char_u	salt[50];
Karsten Hopp 5f67cf
!     int		method;
Karsten Hopp 5f67cf
      char_u	*key;
Karsten Hopp 5f67cf
      char_u	*seed;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (reading && mfp->mf_old_key != NULL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	/* Reading back blocks with the previous key/method/seed. */
Karsten Hopp 5f67cf
! 	method = mfp->mf_old_cm;
Karsten Hopp 5f67cf
  	key = mfp->mf_old_key;
Karsten Hopp 5f67cf
  	seed = mfp->mf_old_seed;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
      else
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	method = get_crypt_method(buf);
Karsten Hopp 5f67cf
  	key = buf->b_p_key;
Karsten Hopp 5f67cf
  	seed = mfp->mf_seed;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     use_crypt_method = method;  /* select pkzip or blowfish */
Karsten Hopp 5f67cf
!     if (method == 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
Karsten Hopp 5f67cf
! 	crypt_init_keys(salt);
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
!     else
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	/* Using blowfish, add salt and seed. We use the byte offset of the
Karsten Hopp 5f67cf
! 	 * block for the salt. */
Karsten Hopp 5f67cf
! 	vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
Karsten Hopp 5f67cf
! 	bf_key_init(key, salt, (int)STRLEN(salt));
Karsten Hopp 5f67cf
! 	bf_cfb_init(seed, MF_SEED_LEN);
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
--- 4895,4931 ----
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      buf_T	*buf = mfp->mf_buffer;
Karsten Hopp 5f67cf
      char_u	salt[50];
Karsten Hopp 5f67cf
!     int		method_nr;
Karsten Hopp 5f67cf
      char_u	*key;
Karsten Hopp 5f67cf
      char_u	*seed;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (reading && mfp->mf_old_key != NULL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	/* Reading back blocks with the previous key/method/seed. */
Karsten Hopp 5f67cf
! 	method_nr = mfp->mf_old_cm;
Karsten Hopp 5f67cf
  	key = mfp->mf_old_key;
Karsten Hopp 5f67cf
  	seed = mfp->mf_old_seed;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
      else
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	method_nr = crypt_get_method_nr(buf);
Karsten Hopp 5f67cf
  	key = buf->b_p_key;
Karsten Hopp 5f67cf
  	seed = mfp->mf_seed;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (method_nr == CRYPT_M_ZIP)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
+ 	/* For PKzip: Append the offset to the key, so that we use a different
Karsten Hopp 5f67cf
+ 	 * key for every block. */
Karsten Hopp 5f67cf
  	vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
Karsten Hopp 5f67cf
! 	return crypt_create(method_nr, salt, NULL, 0, NULL, 0);
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     /* Using blowfish or better: add salt and seed. We use the byte offset
Karsten Hopp 5f67cf
+      * of the block for the salt. */
Karsten Hopp 5f67cf
+     vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
Karsten Hopp 5f67cf
+     return crypt_create(method_nr, key, salt, (int)STRLEN(salt),
Karsten Hopp 5f67cf
+ 							   seed, MF_SEED_LEN);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/misc2.c	2014-06-25 14:39:35.106348584 +0200
Karsten Hopp 5f67cf
--- src/misc2.c	2014-08-09 15:31:32.501356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 3803,4124 ****
Karsten Hopp 5f67cf
  #endif /* CURSOR_SHAPE */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
- #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Optional encryption support.
Karsten Hopp 5f67cf
-  * Mohsin Ahmed, mosh@sasi.com, 98-09-24
Karsten Hopp 5f67cf
-  * Based on zip/crypt sources.
Karsten Hopp 5f67cf
-  *
Karsten Hopp 5f67cf
-  * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
Karsten Hopp 5f67cf
-  * most countries.  There are a few exceptions, but that still should not be a
Karsten Hopp 5f67cf
-  * problem since this code was originally created in Europe and India.
Karsten Hopp 5f67cf
-  *
Karsten Hopp 5f67cf
-  * Blowfish addition originally made by Mohsin Ahmed,
Karsten Hopp 5f67cf
-  * http://www.cs.albany.edu/~mosh 2010-03-14
Karsten Hopp 5f67cf
-  * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
Karsten Hopp 5f67cf
-  * and sha256 by Christophe Devine.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /* from zip.h */
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- typedef unsigned short ush;	/* unsigned 16-bit value */
Karsten Hopp 5f67cf
- typedef unsigned long  ulg;	/* unsigned 32-bit value */
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- static void make_crc_tab __ARGS((void));
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- static ulg crc_32_tab[256];
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Fill the CRC table.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     static void
Karsten Hopp 5f67cf
- make_crc_tab()
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     ulg		s,t,v;
Karsten Hopp 5f67cf
-     static int	done = FALSE;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     if (done)
Karsten Hopp 5f67cf
- 	return;
Karsten Hopp 5f67cf
-     for (t = 0; t < 256; t++)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	v = t;
Karsten Hopp 5f67cf
- 	for (s = 0; s < 8; s++)
Karsten Hopp 5f67cf
- 	    v = (v >> 1) ^ ((v & 1) * (ulg)0xedb88320L);
Karsten Hopp 5f67cf
- 	crc_32_tab[t] = v;
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
-     done = TRUE;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- #define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- static ulg keys[3]; /* keys defining the pseudo-random sequence */
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Return the next byte in the pseudo-random sequence.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
- #define DECRYPT_BYTE_ZIP(t) { \
Karsten Hopp 5f67cf
-     ush temp; \
Karsten Hopp 5f67cf
-  \
Karsten Hopp 5f67cf
-     temp = (ush)keys[2] | 2; \
Karsten Hopp 5f67cf
-     t = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff); \
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Update the encryption keys with the next byte of plain text.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
- #define UPDATE_KEYS_ZIP(c) { \
Karsten Hopp 5f67cf
-     keys[0] = CRC32(keys[0], (c)); \
Karsten Hopp 5f67cf
-     keys[1] += keys[0] & 0xff; \
Karsten Hopp 5f67cf
-     keys[1] = keys[1] * 134775813L + 1; \
Karsten Hopp 5f67cf
-     keys[2] = CRC32(keys[2], (int)(keys[1] >> 24)); \
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- static int crypt_busy = 0;
Karsten Hopp 5f67cf
- static ulg saved_keys[3];
Karsten Hopp 5f67cf
- static int saved_crypt_method;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Return int value for crypt method string:
Karsten Hopp 5f67cf
-  * 0 for "zip", the old method.  Also for any non-valid value.
Karsten Hopp 5f67cf
-  * 1 for "blowfish".
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     int
Karsten Hopp 5f67cf
- crypt_method_from_string(s)
Karsten Hopp 5f67cf
-     char_u  *s;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     return *s == 'b' ? 1 : 0;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Get the crypt method for buffer "buf" as a number.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     int
Karsten Hopp 5f67cf
- get_crypt_method(buf)
Karsten Hopp 5f67cf
-     buf_T *buf;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     return crypt_method_from_string(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Set the crypt method for buffer "buf" to "method" using the int value as
Karsten Hopp 5f67cf
-  * returned by crypt_method_from_string().
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- set_crypt_method(buf, method)
Karsten Hopp 5f67cf
-     buf_T   *buf;
Karsten Hopp 5f67cf
-     int	    method;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     free_string_option(buf->b_p_cm);
Karsten Hopp 5f67cf
-     buf->b_p_cm = vim_strsave((char_u *)(method == 0 ? "zip" : "blowfish"));
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Prepare for initializing encryption.  If already doing encryption then save
Karsten Hopp 5f67cf
-  * the state.
Karsten Hopp 5f67cf
-  * Must always be called symmetrically with crypt_pop_state().
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- crypt_push_state()
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     if (crypt_busy == 1)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	/* save the state */
Karsten Hopp 5f67cf
- 	if (use_crypt_method == 0)
Karsten Hopp 5f67cf
- 	{
Karsten Hopp 5f67cf
- 	    saved_keys[0] = keys[0];
Karsten Hopp 5f67cf
- 	    saved_keys[1] = keys[1];
Karsten Hopp 5f67cf
- 	    saved_keys[2] = keys[2];
Karsten Hopp 5f67cf
- 	}
Karsten Hopp 5f67cf
- 	else
Karsten Hopp 5f67cf
- 	    bf_crypt_save();
Karsten Hopp 5f67cf
- 	saved_crypt_method = use_crypt_method;
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
-     else if (crypt_busy > 1)
Karsten Hopp 5f67cf
- 	EMSG2(_(e_intern2), "crypt_push_state()");
Karsten Hopp 5f67cf
-     ++crypt_busy;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * End encryption.  If doing encryption before crypt_push_state() then restore
Karsten Hopp 5f67cf
-  * the saved state.
Karsten Hopp 5f67cf
-  * Must always be called symmetrically with crypt_push_state().
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- crypt_pop_state()
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     --crypt_busy;
Karsten Hopp 5f67cf
-     if (crypt_busy == 1)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	use_crypt_method = saved_crypt_method;
Karsten Hopp 5f67cf
- 	if (use_crypt_method == 0)
Karsten Hopp 5f67cf
- 	{
Karsten Hopp 5f67cf
- 	    keys[0] = saved_keys[0];
Karsten Hopp 5f67cf
- 	    keys[1] = saved_keys[1];
Karsten Hopp 5f67cf
- 	    keys[2] = saved_keys[2];
Karsten Hopp 5f67cf
- 	}
Karsten Hopp 5f67cf
- 	else
Karsten Hopp 5f67cf
- 	    bf_crypt_restore();
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Encrypt "from[len]" into "to[len]".
Karsten Hopp 5f67cf
-  * "from" and "to" can be equal to encrypt in place.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- crypt_encode(from, len, to)
Karsten Hopp 5f67cf
-     char_u	*from;
Karsten Hopp 5f67cf
-     size_t	len;
Karsten Hopp 5f67cf
-     char_u	*to;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     size_t	i;
Karsten Hopp 5f67cf
-     int		ztemp, t;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     if (use_crypt_method == 0)
Karsten Hopp 5f67cf
- 	for (i = 0; i < len; ++i)
Karsten Hopp 5f67cf
- 	{
Karsten Hopp 5f67cf
- 	    ztemp = from[i];
Karsten Hopp 5f67cf
- 	    DECRYPT_BYTE_ZIP(t);
Karsten Hopp 5f67cf
- 	    UPDATE_KEYS_ZIP(ztemp);
Karsten Hopp 5f67cf
- 	    to[i] = t ^ ztemp;
Karsten Hopp 5f67cf
- 	}
Karsten Hopp 5f67cf
-     else
Karsten Hopp 5f67cf
- 	bf_crypt_encode(from, len, to);
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Decrypt "ptr[len]" in place.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- crypt_decode(ptr, len)
Karsten Hopp 5f67cf
-     char_u	*ptr;
Karsten Hopp 5f67cf
-     long	len;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     char_u *p;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     if (use_crypt_method == 0)
Karsten Hopp 5f67cf
- 	for (p = ptr; p < ptr + len; ++p)
Karsten Hopp 5f67cf
- 	{
Karsten Hopp 5f67cf
- 	    ush temp;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- 	    temp = (ush)keys[2] | 2;
Karsten Hopp 5f67cf
- 	    temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
Karsten Hopp 5f67cf
- 	    UPDATE_KEYS_ZIP(*p ^= temp);
Karsten Hopp 5f67cf
- 	}
Karsten Hopp 5f67cf
-     else
Karsten Hopp 5f67cf
- 	bf_crypt_decode(ptr, len);
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Initialize the encryption keys and the random header according to
Karsten Hopp 5f67cf
-  * the given password.
Karsten Hopp 5f67cf
-  * If "passwd" is NULL or empty, don't do anything.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- crypt_init_keys(passwd)
Karsten Hopp 5f67cf
-     char_u *passwd;		/* password string with which to modify keys */
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     if (passwd != NULL && *passwd != NUL)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	if (use_crypt_method == 0)
Karsten Hopp 5f67cf
- 	{
Karsten Hopp 5f67cf
- 	    char_u *p;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- 	    make_crc_tab();
Karsten Hopp 5f67cf
- 	    keys[0] = 305419896L;
Karsten Hopp 5f67cf
- 	    keys[1] = 591751049L;
Karsten Hopp 5f67cf
- 	    keys[2] = 878082192L;
Karsten Hopp 5f67cf
- 	    for (p = passwd; *p!= NUL; ++p)
Karsten Hopp 5f67cf
- 	    {
Karsten Hopp 5f67cf
- 		UPDATE_KEYS_ZIP((int)*p);
Karsten Hopp 5f67cf
- 	    }
Karsten Hopp 5f67cf
- 	}
Karsten Hopp 5f67cf
- 	else
Karsten Hopp 5f67cf
- 	    bf_crypt_init_keys(passwd);
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Free an allocated crypt key.  Clear the text to make sure it doesn't stay
Karsten Hopp 5f67cf
-  * in memory anywhere.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     void
Karsten Hopp 5f67cf
- free_crypt_key(key)
Karsten Hopp 5f67cf
-     char_u *key;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     char_u *p;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     if (key != NULL)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	for (p = key; *p != NUL; ++p)
Karsten Hopp 5f67cf
- 	    *p = 0;
Karsten Hopp 5f67cf
- 	vim_free(key);
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Ask the user for a crypt key.
Karsten Hopp 5f67cf
-  * When "store" is TRUE, the new key is stored in the 'key' option, and the
Karsten Hopp 5f67cf
-  * 'key' option value is returned: Don't free it.
Karsten Hopp 5f67cf
-  * When "store" is FALSE, the typed key is returned in allocated memory.
Karsten Hopp 5f67cf
-  * Returns NULL on failure.
Karsten Hopp 5f67cf
-  */
Karsten Hopp 5f67cf
-     char_u *
Karsten Hopp 5f67cf
- get_crypt_key(store, twice)
Karsten Hopp 5f67cf
-     int		store;
Karsten Hopp 5f67cf
-     int		twice;	    /* Ask for the key twice. */
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     char_u	*p1, *p2 = NULL;
Karsten Hopp 5f67cf
-     int		round;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     for (round = 0; ; ++round)
Karsten Hopp 5f67cf
-     {
Karsten Hopp 5f67cf
- 	cmdline_star = TRUE;
Karsten Hopp 5f67cf
- 	cmdline_row = msg_row;
Karsten Hopp 5f67cf
- 	p1 = getcmdline_prompt(NUL, round == 0
Karsten Hopp 5f67cf
- 		? (char_u *)_("Enter encryption key: ")
Karsten Hopp 5f67cf
- 		: (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
Karsten Hopp 5f67cf
- 		NULL);
Karsten Hopp 5f67cf
- 	cmdline_star = FALSE;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- 	if (p1 == NULL)
Karsten Hopp 5f67cf
- 	    break;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- 	if (round == twice)
Karsten Hopp 5f67cf
- 	{
Karsten Hopp 5f67cf
- 	    if (p2 != NULL && STRCMP(p1, p2) != 0)
Karsten Hopp 5f67cf
- 	    {
Karsten Hopp 5f67cf
- 		MSG(_("Keys don't match!"));
Karsten Hopp 5f67cf
- 		free_crypt_key(p1);
Karsten Hopp 5f67cf
- 		free_crypt_key(p2);
Karsten Hopp 5f67cf
- 		p2 = NULL;
Karsten Hopp 5f67cf
- 		round = -1;		/* do it again */
Karsten Hopp 5f67cf
- 		continue;
Karsten Hopp 5f67cf
- 	    }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- 	    if (store)
Karsten Hopp 5f67cf
- 	    {
Karsten Hopp 5f67cf
- 		set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
Karsten Hopp 5f67cf
- 		free_crypt_key(p1);
Karsten Hopp 5f67cf
- 		p1 = curbuf->b_p_key;
Karsten Hopp 5f67cf
- 	    }
Karsten Hopp 5f67cf
- 	    break;
Karsten Hopp 5f67cf
- 	}
Karsten Hopp 5f67cf
- 	p2 = p1;
Karsten Hopp 5f67cf
-     }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     /* since the user typed this, no need to wait for return */
Karsten Hopp 5f67cf
-     if (msg_didout)
Karsten Hopp 5f67cf
- 	msg_putchar('\n');
Karsten Hopp 5f67cf
-     need_wait_return = FALSE;
Karsten Hopp 5f67cf
-     msg_didout = FALSE;
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
-     free_crypt_key(p2);
Karsten Hopp 5f67cf
-     return p1;
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- #endif /* FEAT_CRYPT */
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
  /* TODO: make some #ifdef for this */
Karsten Hopp 5f67cf
  /*--------[ file searching ]-------------------------------------------------*/
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
--- 3803,3808 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 6588,6595 ****
Karsten Hopp 5f67cf
--- 6272,6294 ----
Karsten Hopp 5f67cf
      FILE	*fd;
Karsten Hopp 5f67cf
      time_t	the_time;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
+     char_u	buf[8];
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+     time_to_bytes(the_time, buf);
Karsten Hopp 5f67cf
+     fwrite(buf, (size_t)8, (size_t)1, fd);
Karsten Hopp 5f67cf
+ }
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Write time_t to "buf[8]".
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+     void
Karsten Hopp 5f67cf
+ time_to_bytes(the_time, buf)
Karsten Hopp 5f67cf
+     time_t	the_time;
Karsten Hopp 5f67cf
+     char_u	*buf;
Karsten Hopp 5f67cf
+ {
Karsten Hopp 5f67cf
      int		c;
Karsten Hopp 5f67cf
      int		i;
Karsten Hopp 5f67cf
+     int		bi = 0;
Karsten Hopp 5f67cf
      time_t	wtime = the_time;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* time_t can be up to 8 bytes in size, more than long_u, thus we
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 6603,6609 ****
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	if (i + 1 > (int)sizeof(time_t))
Karsten Hopp 5f67cf
  	    /* ">>" doesn't work well when shifting more bits than avail */
Karsten Hopp 5f67cf
! 	    putc(0, fd);
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  #if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4
Karsten Hopp 5f67cf
--- 6302,6308 ----
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	if (i + 1 > (int)sizeof(time_t))
Karsten Hopp 5f67cf
  	    /* ">>" doesn't work well when shifting more bits than avail */
Karsten Hopp 5f67cf
! 	    buf[bi++] = 0;
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  #if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 6611,6617 ****
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
  	    c = (int)((long_u)wtime >> (i * 8));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
! 	    putc(c, fd);
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
--- 6310,6316 ----
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
  	    c = (int)((long_u)wtime >> (i * 8));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
! 	    buf[bi++] = c;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/option.c	2014-08-06 14:52:05.047236174 +0200
Karsten Hopp 5f67cf
--- src/option.c	2014-08-09 15:39:29.741352755 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 2989,2995 ****
Karsten Hopp 5f67cf
  static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
Karsten Hopp 5f67cf
  static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! static char *(p_cm_values[]) = {"zip", "blowfish", NULL};
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CMDL_COMPL
Karsten Hopp 5f67cf
  static char *(p_wop_values[]) = {"tagfile", NULL};
Karsten Hopp 5f67cf
--- 2989,2995 ----
Karsten Hopp 5f67cf
  static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
Karsten Hopp 5f67cf
  static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL};
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CMDL_COMPL
Karsten Hopp 5f67cf
  static char *(p_wop_values[]) = {"tagfile", NULL};
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 6140,6146 ****
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  	if (STRCMP(curbuf->b_p_key, oldval) != 0)
Karsten Hopp 5f67cf
  	    /* Need to update the swapfile. */
Karsten Hopp 5f67cf
! 	    ml_set_crypt_key(curbuf, oldval, get_crypt_method(curbuf));
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      else if (gvarp == &p_cm)
Karsten Hopp 5f67cf
--- 6140,6146 ----
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  	if (STRCMP(curbuf->b_p_key, oldval) != 0)
Karsten Hopp 5f67cf
  	    /* Need to update the swapfile. */
Karsten Hopp 5f67cf
! 	    ml_set_crypt_key(curbuf, oldval, crypt_get_method_nr(curbuf));
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      else if (gvarp == &p_cm)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 6151,6157 ****
Karsten Hopp 5f67cf
  	    p = p_cm;
Karsten Hopp 5f67cf
  	if (check_opt_strings(p, p_cm_values, TRUE) != OK)
Karsten Hopp 5f67cf
  	    errmsg = e_invarg;
Karsten Hopp 5f67cf
! 	else if (get_crypt_method(curbuf) > 0 && blowfish_self_test() == FAIL)
Karsten Hopp 5f67cf
  	    errmsg = e_invarg;
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
--- 6151,6157 ----
Karsten Hopp 5f67cf
  	    p = p_cm;
Karsten Hopp 5f67cf
  	if (check_opt_strings(p, p_cm_values, TRUE) != OK)
Karsten Hopp 5f67cf
  	    errmsg = e_invarg;
Karsten Hopp 5f67cf
! 	else if (crypt_self_test() == FAIL)
Karsten Hopp 5f67cf
  	    errmsg = e_invarg;
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 6177,6183 ****
Karsten Hopp 5f67cf
  		p = curbuf->b_p_cm;
Karsten Hopp 5f67cf
  	    if (STRCMP(s, p) != 0)
Karsten Hopp 5f67cf
  		ml_set_crypt_key(curbuf, curbuf->b_p_key,
Karsten Hopp 5f67cf
! 						 crypt_method_from_string(s));
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	    /* If the global value changes need to update the swapfile for all
Karsten Hopp 5f67cf
  	     * buffers using that value. */
Karsten Hopp 5f67cf
--- 6177,6183 ----
Karsten Hopp 5f67cf
  		p = curbuf->b_p_cm;
Karsten Hopp 5f67cf
  	    if (STRCMP(s, p) != 0)
Karsten Hopp 5f67cf
  		ml_set_crypt_key(curbuf, curbuf->b_p_key,
Karsten Hopp 5f67cf
! 						crypt_method_nr_from_name(s));
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	    /* If the global value changes need to update the swapfile for all
Karsten Hopp 5f67cf
  	     * buffers using that value. */
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 6188,6194 ****
Karsten Hopp 5f67cf
  		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
Karsten Hopp 5f67cf
  		    if (buf != curbuf && *buf->b_p_cm == NUL)
Karsten Hopp 5f67cf
  			ml_set_crypt_key(buf, buf->b_p_key,
Karsten Hopp 5f67cf
! 					    crypt_method_from_string(oldval));
Karsten Hopp 5f67cf
  	    }
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
--- 6188,6194 ----
Karsten Hopp 5f67cf
  		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
Karsten Hopp 5f67cf
  		    if (buf != curbuf && *buf->b_p_cm == NUL)
Karsten Hopp 5f67cf
  			ml_set_crypt_key(buf, buf->b_p_key,
Karsten Hopp 5f67cf
! 					   crypt_method_nr_from_name(oldval));
Karsten Hopp 5f67cf
  	    }
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/proto.h	2013-02-26 14:18:19.000000000 +0100
Karsten Hopp 5f67cf
--- src/proto.h	2014-08-09 15:39:39.333352686 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 70,75 ****
Karsten Hopp 5f67cf
--- 70,77 ----
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  # ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
  #  include "blowfish.pro"
Karsten Hopp 5f67cf
+ #  include "crypt.pro"
Karsten Hopp 5f67cf
+ #  include "crypt_zip.pro"
Karsten Hopp 5f67cf
  # endif
Karsten Hopp 5f67cf
  # include "buffer.pro"
Karsten Hopp 5f67cf
  # include "charset.pro"
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/proto/blowfish.pro	2014-02-11 15:23:27.938123631 +0100
Karsten Hopp 5f67cf
--- src/proto/blowfish.pro	2014-08-09 15:31:32.501356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1,10 ****
Karsten Hopp 5f67cf
  /* blowfish.c */
Karsten Hopp 5f67cf
! void bf_key_init __ARGS((char_u *password, char_u *salt, int salt_len));
Karsten Hopp 5f67cf
! void bf_cfb_init __ARGS((char_u *iv, int iv_len));
Karsten Hopp 5f67cf
! void bf_crypt_encode __ARGS((char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
! void bf_crypt_decode __ARGS((char_u *ptr, long len));
Karsten Hopp 5f67cf
! void bf_crypt_init_keys __ARGS((char_u *passwd));
Karsten Hopp 5f67cf
! void bf_crypt_save __ARGS((void));
Karsten Hopp 5f67cf
! void bf_crypt_restore __ARGS((void));
Karsten Hopp 5f67cf
  int blowfish_self_test __ARGS((void));
Karsten Hopp 5f67cf
  /* vim: set ft=c : */
Karsten Hopp 5f67cf
--- 1,6 ----
Karsten Hopp 5f67cf
  /* blowfish.c */
Karsten Hopp 5f67cf
! void crypt_blowfish_encode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
! void crypt_blowfish_decode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
! void crypt_blowfish_init __ARGS((cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len));
Karsten Hopp 5f67cf
  int blowfish_self_test __ARGS((void));
Karsten Hopp 5f67cf
  /* vim: set ft=c : */
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/proto/crypt.pro	2014-08-10 13:30:43.880787293 +0200
Karsten Hopp 5f67cf
--- src/proto/crypt.pro	2014-08-09 15:31:32.501356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 0 ****
Karsten Hopp 5f67cf
--- 1,24 ----
Karsten Hopp 5f67cf
+ /* crypt.c */
Karsten Hopp 5f67cf
+ int crypt_method_nr_from_name __ARGS((char_u *name));
Karsten Hopp 5f67cf
+ int crypt_method_nr_from_magic __ARGS((char *ptr, int len));
Karsten Hopp 5f67cf
+ int crypt_works_inplace __ARGS((cryptstate_T *state));
Karsten Hopp 5f67cf
+ int crypt_get_method_nr __ARGS((buf_T *buf));
Karsten Hopp 5f67cf
+ int crypt_whole_undofile __ARGS((int method_nr));
Karsten Hopp 5f67cf
+ int crypt_get_header_len __ARGS((int method_nr));
Karsten Hopp 5f67cf
+ void crypt_set_cm_option __ARGS((buf_T *buf, int method_nr));
Karsten Hopp 5f67cf
+ int crypt_self_test __ARGS((void));
Karsten Hopp 5f67cf
+ cryptstate_T *crypt_create __ARGS((int method_nr, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len));
Karsten Hopp 5f67cf
+ cryptstate_T *crypt_create_from_header __ARGS((int method_nr, char_u *key, char_u *header));
Karsten Hopp 5f67cf
+ cryptstate_T *crypt_create_from_file __ARGS((FILE *fp, char_u *key));
Karsten Hopp 5f67cf
+ cryptstate_T *crypt_create_for_writing __ARGS((int method_nr, char_u *key, char_u **header, int *header_len));
Karsten Hopp 5f67cf
+ void crypt_free_state __ARGS((cryptstate_T *state));
Karsten Hopp 5f67cf
+ long crypt_encode_alloc __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u **newptr));
Karsten Hopp 5f67cf
+ long crypt_decode_alloc __ARGS((cryptstate_T *state, char_u *ptr, long len, char_u **newptr));
Karsten Hopp 5f67cf
+ void crypt_encode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
+ void crypt_decode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
+ void crypt_encode_inplace __ARGS((cryptstate_T *state, char_u *buf, size_t len));
Karsten Hopp 5f67cf
+ void crypt_decode_inplace __ARGS((cryptstate_T *state, char_u *buf, size_t len));
Karsten Hopp 5f67cf
+ void crypt_free_key __ARGS((char_u *key));
Karsten Hopp 5f67cf
+ char_u *crypt_get_key __ARGS((int store, int twice));
Karsten Hopp 5f67cf
+ void crypt_append_msg __ARGS((buf_T *buf));
Karsten Hopp 5f67cf
+ /* vim: set ft=c : */
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/proto/crypt_zip.pro	2014-08-10 13:30:43.884787293 +0200
Karsten Hopp 5f67cf
--- src/proto/crypt_zip.pro	2014-08-09 15:31:32.501356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 0 ****
Karsten Hopp 5f67cf
--- 1,5 ----
Karsten Hopp 5f67cf
+ /* crypt_zip.c */
Karsten Hopp 5f67cf
+ void crypt_zip_init __ARGS((cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len));
Karsten Hopp 5f67cf
+ void crypt_zip_encode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
+ void crypt_zip_decode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
+ /* vim: set ft=c : */
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/proto/fileio.pro	2013-08-10 13:37:11.000000000 +0200
Karsten Hopp 5f67cf
--- src/proto/fileio.pro	2014-08-09 15:31:32.501356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 4,11 ****
Karsten Hopp 5f67cf
  int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
Karsten Hopp 5f67cf
  void set_file_options __ARGS((int set_options, exarg_T *eap));
Karsten Hopp 5f67cf
  void set_forced_fenc __ARGS((exarg_T *eap));
Karsten Hopp 5f67cf
- int prepare_crypt_read __ARGS((FILE *fp));
Karsten Hopp 5f67cf
- char_u *prepare_crypt_write __ARGS((buf_T *buf, int *lenp));
Karsten Hopp 5f67cf
  int check_file_readonly __ARGS((char_u *fname, int perm));
Karsten Hopp 5f67cf
  int buf_write __ARGS((buf_T *buf, char_u *fname, char_u *sfname, linenr_T start, linenr_T end, exarg_T *eap, int append, int forceit, int reset_changed, int filtering));
Karsten Hopp 5f67cf
  void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
Karsten Hopp 5f67cf
--- 4,9 ----
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/proto/misc2.pro	2014-05-07 18:35:25.669216052 +0200
Karsten Hopp 5f67cf
--- src/proto/misc2.pro	2014-08-09 15:31:32.501356185 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 84,99 ****
Karsten Hopp 5f67cf
  char_u *parse_shape_opt __ARGS((int what));
Karsten Hopp 5f67cf
  int get_shape_idx __ARGS((int mouse));
Karsten Hopp 5f67cf
  void update_mouseshape __ARGS((int shape_idx));
Karsten Hopp 5f67cf
- int crypt_method_from_string __ARGS((char_u *s));
Karsten Hopp 5f67cf
- int get_crypt_method __ARGS((buf_T *buf));
Karsten Hopp 5f67cf
- void set_crypt_method __ARGS((buf_T *buf, int method));
Karsten Hopp 5f67cf
- void crypt_push_state __ARGS((void));
Karsten Hopp 5f67cf
- void crypt_pop_state __ARGS((void));
Karsten Hopp 5f67cf
- void crypt_encode __ARGS((char_u *from, size_t len, char_u *to));
Karsten Hopp 5f67cf
- void crypt_decode __ARGS((char_u *ptr, long len));
Karsten Hopp 5f67cf
- void crypt_init_keys __ARGS((char_u *passwd));
Karsten Hopp 5f67cf
- void free_crypt_key __ARGS((char_u *key));
Karsten Hopp 5f67cf
- char_u *get_crypt_key __ARGS((int store, int twice));
Karsten Hopp 5f67cf
  void *vim_findfile_init __ARGS((char_u *path, char_u *filename, char_u *stopdirs, int level, int free_visited, int find_what, void *search_ctx_arg, int tagfile, char_u *rel_fname));
Karsten Hopp 5f67cf
  char_u *vim_findfile_stopdir __ARGS((char_u *buf));
Karsten Hopp 5f67cf
  void vim_findfile_cleanup __ARGS((void *ctx));
Karsten Hopp 5f67cf
--- 84,89 ----
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 116,120 ****
Karsten Hopp 5f67cf
--- 106,111 ----
Karsten Hopp 5f67cf
  char_u *read_string __ARGS((FILE *fd, int cnt));
Karsten Hopp 5f67cf
  int put_bytes __ARGS((FILE *fd, long_u nr, int len));
Karsten Hopp 5f67cf
  void put_time __ARGS((FILE *fd, time_t the_time));
Karsten Hopp 5f67cf
+ void time_to_bytes __ARGS((time_t the_time, char_u *buf));
Karsten Hopp 5f67cf
  int has_non_ascii __ARGS((char_u *s));
Karsten Hopp 5f67cf
  /* vim: set ft=c : */
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/structs.h	2014-06-25 14:39:35.110348584 +0200
Karsten Hopp 5f67cf
--- src/structs.h	2014-08-09 15:40:08.501352476 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1251,1256 ****
Karsten Hopp 5f67cf
--- 1251,1274 ----
Karsten Hopp 5f67cf
  } syn_time_T;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Structure to hold the type of encryption and the state of encryption or
Karsten Hopp 5f67cf
+  * decryption.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
+ typedef struct {
Karsten Hopp 5f67cf
+     int	    method_nr;
Karsten Hopp 5f67cf
+     void    *method_state;  /* method-specific state information */
Karsten Hopp 5f67cf
+ } cryptstate_T;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ /* values for method_nr */
Karsten Hopp 5f67cf
+ # define CRYPT_M_ZIP	0
Karsten Hopp 5f67cf
+ # define CRYPT_M_BF	1
Karsten Hopp 5f67cf
+ # define CRYPT_M_BF2	2
Karsten Hopp 5f67cf
+ # define CRYPT_M_COUNT	3 /* number of crypt methods */
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
   * These are items normally related to a buffer.  But when using ":ownsyntax"
Karsten Hopp 5f67cf
   * a window may have its own instance.
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1778,1784 ****
Karsten Hopp 5f67cf
      int		b_was_netbeans_file;/* TRUE if b_netbeans_file was once set */
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! };
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_DIFF
Karsten Hopp 5f67cf
--- 1796,1807 ----
Karsten Hopp 5f67cf
      int		b_was_netbeans_file;/* TRUE if b_netbeans_file was once set */
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     cryptstate_T *b_cryptstate;	/* Encryption state while reading or writing
Karsten Hopp 5f67cf
! 				 * the file. NULL when not using encryption. */
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! }; /* file_buffer */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #ifdef FEAT_DIFF
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/undo.c	2014-04-02 14:05:33.999887839 +0200
Karsten Hopp 5f67cf
--- src/undo.c	2014-08-09 16:55:40.541319903 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 81,88 ****
Karsten Hopp 5f67cf
--- 81,105 ----
Karsten Hopp 5f67cf
  #define UH_MAGIC 0x18dade	/* value for uh_magic when in use */
Karsten Hopp 5f67cf
  #define UE_MAGIC 0xabc123	/* value for ue_magic when in use */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
+ /* Size of buffer used for encryption. */
Karsten Hopp 5f67cf
+ #define CRYPT_BUF_SIZE 8192
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  #include "vim.h"
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
+ /* Structure passed around between functions.
Karsten Hopp 5f67cf
+  * Avoids passing cryptstate_T when encryption not available. */
Karsten Hopp 5f67cf
+ typedef struct {
Karsten Hopp 5f67cf
+     buf_T	*bi_buf;
Karsten Hopp 5f67cf
+     FILE	*bi_fp;
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+     cryptstate_T *bi_state;
Karsten Hopp 5f67cf
+     char_u	*bi_buffer; /* CRYPT_BUF_SIZE, NULL when not buffering */
Karsten Hopp 5f67cf
+     size_t	bi_used;    /* bytes written to/read from bi_buffer */
Karsten Hopp 5f67cf
+     size_t	bi_avail;   /* bytes available in bi_buffer */
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
+ } bufinfo_T;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  static long get_undolevel __ARGS((void));
Karsten Hopp 5f67cf
  static void u_unch_branch __ARGS((u_header_T *uhp));
Karsten Hopp 5f67cf
  static u_entry_T *u_get_headentry __ARGS((void));
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 98,115 ****
Karsten Hopp 5f67cf
  #ifdef FEAT_PERSISTENT_UNDO
Karsten Hopp 5f67cf
  static void corruption_error __ARGS((char *mesg, char_u *file_name));
Karsten Hopp 5f67cf
  static void u_free_uhp __ARGS((u_header_T *uhp));
Karsten Hopp 5f67cf
! static size_t fwrite_crypt __ARGS((buf_T *buf UNUSED, char_u *ptr, size_t len, FILE *fp));
Karsten Hopp 5f67cf
! static char_u *read_string_decrypt __ARGS((buf_T *buf UNUSED, FILE *fd, int len));
Karsten Hopp 5f67cf
! static int serialize_header __ARGS((FILE *fp, buf_T *buf, char_u *hash));
Karsten Hopp 5f67cf
! static int serialize_uhp __ARGS((FILE *fp, buf_T *buf, u_header_T *uhp));
Karsten Hopp 5f67cf
! static u_header_T *unserialize_uhp __ARGS((FILE *fp, char_u *file_name));
Karsten Hopp 5f67cf
! static int serialize_uep __ARGS((FILE *fp, buf_T *buf, u_entry_T *uep));
Karsten Hopp 5f67cf
! static u_entry_T *unserialize_uep __ARGS((FILE *fp, int *error, char_u *file_name));
Karsten Hopp 5f67cf
! static void serialize_pos __ARGS((pos_T pos, FILE *fp));
Karsten Hopp 5f67cf
! static void unserialize_pos __ARGS((pos_T *pos, FILE *fp));
Karsten Hopp 5f67cf
! static void serialize_visualinfo __ARGS((visualinfo_T *info, FILE *fp));
Karsten Hopp 5f67cf
! static void unserialize_visualinfo __ARGS((visualinfo_T *info, FILE *fp));
Karsten Hopp 5f67cf
! static void put_header_ptr __ARGS((FILE	*fp, u_header_T *uhp));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define U_ALLOC_LINE(size) lalloc((long_u)(size), FALSE)
Karsten Hopp 5f67cf
--- 115,140 ----
Karsten Hopp 5f67cf
  #ifdef FEAT_PERSISTENT_UNDO
Karsten Hopp 5f67cf
  static void corruption_error __ARGS((char *mesg, char_u *file_name));
Karsten Hopp 5f67cf
  static void u_free_uhp __ARGS((u_header_T *uhp));
Karsten Hopp 5f67cf
! static int undo_write __ARGS((bufinfo_T *bi, char_u *ptr, size_t len));
Karsten Hopp 5f67cf
! static int undo_flush __ARGS((bufinfo_T *bi));
Karsten Hopp 5f67cf
! static int fwrite_crypt __ARGS((bufinfo_T *bi, char_u *ptr, size_t len));
Karsten Hopp 5f67cf
! static int undo_write_bytes __ARGS((bufinfo_T *bi, long_u nr, int len));
Karsten Hopp 5f67cf
! static void put_header_ptr __ARGS((bufinfo_T *bi, u_header_T *uhp));
Karsten Hopp 5f67cf
! static int undo_read_4c __ARGS((bufinfo_T *bi));
Karsten Hopp 5f67cf
! static int undo_read_2c __ARGS((bufinfo_T *bi));
Karsten Hopp 5f67cf
! static int undo_read_byte __ARGS((bufinfo_T *bi));
Karsten Hopp 5f67cf
! static time_t undo_read_time __ARGS((bufinfo_T *bi));
Karsten Hopp 5f67cf
! static int undo_read __ARGS((bufinfo_T *bi, char_u *buffer, size_t size));
Karsten Hopp 5f67cf
! static char_u *read_string_decrypt __ARGS((bufinfo_T *bi, int len));
Karsten Hopp 5f67cf
! static int serialize_header __ARGS((bufinfo_T *bi, char_u *hash));
Karsten Hopp 5f67cf
! static int serialize_uhp __ARGS((bufinfo_T *bi, u_header_T *uhp));
Karsten Hopp 5f67cf
! static u_header_T *unserialize_uhp __ARGS((bufinfo_T *bi, char_u *file_name));
Karsten Hopp 5f67cf
! static int serialize_uep __ARGS((bufinfo_T *bi, u_entry_T *uep));
Karsten Hopp 5f67cf
! static u_entry_T *unserialize_uep __ARGS((bufinfo_T *bi, int *error, char_u *file_name));
Karsten Hopp 5f67cf
! static void serialize_pos __ARGS((bufinfo_T *bi, pos_T pos));
Karsten Hopp 5f67cf
! static void unserialize_pos __ARGS((bufinfo_T *bi, pos_T *pos));
Karsten Hopp 5f67cf
! static void serialize_visualinfo __ARGS((bufinfo_T *bi, visualinfo_T *info));
Karsten Hopp 5f67cf
! static void unserialize_visualinfo __ARGS((bufinfo_T *bi, visualinfo_T *info));
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  #define U_ALLOC_LINE(size) lalloc((long_u)(size), FALSE)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 859,926 ****
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Like fwrite() but crypt the bytes when 'key' is set.
Karsten Hopp 5f67cf
!  * Returns 1 if successful.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static size_t
Karsten Hopp 5f67cf
! fwrite_crypt(buf, ptr, len, fp)
Karsten Hopp 5f67cf
!     buf_T	*buf UNUSED;
Karsten Hopp 5f67cf
      char_u	*ptr;
Karsten Hopp 5f67cf
      size_t	len;
Karsten Hopp 5f67cf
-     FILE	*fp;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
      char_u  *copy;
Karsten Hopp 5f67cf
      char_u  small_buf[100];
Karsten Hopp 5f67cf
      size_t  i;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (*buf->b_p_key == NUL)
Karsten Hopp 5f67cf
! 	return fwrite(ptr, len, (size_t)1, fp);
Karsten Hopp 5f67cf
!     if (len < 100)
Karsten Hopp 5f67cf
! 	copy = small_buf;  /* no malloc()/free() for short strings */
Karsten Hopp 5f67cf
!     else
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	copy = lalloc(len, FALSE);
Karsten Hopp 5f67cf
! 	if (copy == NULL)
Karsten Hopp 5f67cf
! 	    return 0;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
!     crypt_encode(ptr, len, copy);
Karsten Hopp 5f67cf
!     i = fwrite(copy, len, (size_t)1, fp);
Karsten Hopp 5f67cf
!     if (copy != small_buf)
Karsten Hopp 5f67cf
! 	vim_free(copy);
Karsten Hopp 5f67cf
!     return i;
Karsten Hopp 5f67cf
! #else
Karsten Hopp 5f67cf
!     return fwrite(ptr, len, (size_t)1, fp);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Read a string of length "len" from "fd".
Karsten Hopp 5f67cf
!  * When 'key' is set decrypt the bytes.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static char_u *
Karsten Hopp 5f67cf
! read_string_decrypt(buf, fd, len)
Karsten Hopp 5f67cf
!     buf_T   *buf UNUSED;
Karsten Hopp 5f67cf
!     FILE    *fd;
Karsten Hopp 5f67cf
      int	    len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     char_u  *ptr;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     ptr = read_string(fd, len);
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (ptr != NULL && *buf->b_p_key != NUL)
Karsten Hopp 5f67cf
! 	crypt_decode(ptr, len);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      return ptr;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! serialize_header(fp, buf, hash)
Karsten Hopp 5f67cf
!     FILE	*fp;
Karsten Hopp 5f67cf
!     buf_T	*buf;
Karsten Hopp 5f67cf
      char_u	*hash;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     int len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Start writing, first the magic marker and undo info version. */
Karsten Hopp 5f67cf
      if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1)
Karsten Hopp 5f67cf
--- 884,1177 ----
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Write a sequence of bytes to the undo file.
Karsten Hopp 5f67cf
!  * Buffers and encrypts as needed.
Karsten Hopp 5f67cf
!  * Returns OK or FAIL.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! undo_write(bi, ptr, len)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
!     char_u	*ptr;
Karsten Hopp 5f67cf
!     size_t	len;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi->bi_buffer != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	size_t	len_todo = len;
Karsten Hopp 5f67cf
! 	char_u  *p = ptr;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	while (bi->bi_used + len_todo >= CRYPT_BUF_SIZE)
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    size_t	n = CRYPT_BUF_SIZE - bi->bi_used;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	    mch_memmove(bi->bi_buffer + bi->bi_used, p, n);
Karsten Hopp 5f67cf
! 	    len_todo -= n;
Karsten Hopp 5f67cf
! 	    p += n;
Karsten Hopp 5f67cf
! 	    bi->bi_used = CRYPT_BUF_SIZE;
Karsten Hopp 5f67cf
! 	    if (undo_flush(bi) == FAIL)
Karsten Hopp 5f67cf
! 		return FAIL;
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
! 	if (len_todo > 0)
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    mch_memmove(bi->bi_buffer + bi->bi_used, p, len_todo);
Karsten Hopp 5f67cf
! 	    bi->bi_used += len_todo;
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
! 	return OK;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
!     if (fwrite(ptr, len, (size_t)1, bi->bi_fp) != 1)
Karsten Hopp 5f67cf
! 	return FAIL;
Karsten Hopp 5f67cf
!     return OK;
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! undo_flush(bi)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
!     if (bi->bi_used > 0)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used);
Karsten Hopp 5f67cf
! 	if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1)
Karsten Hopp 5f67cf
! 	    return FAIL;
Karsten Hopp 5f67cf
! 	bi->bi_used = 0;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
!     return OK;
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! /*
Karsten Hopp 5f67cf
!  * Write "ptr[len]" and crypt the bytes when needed.
Karsten Hopp 5f67cf
!  * Returns OK or FAIL.
Karsten Hopp 5f67cf
!  */
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! fwrite_crypt(bi, ptr, len)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
      char_u	*ptr;
Karsten Hopp 5f67cf
      size_t	len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
      char_u  *copy;
Karsten Hopp 5f67cf
      char_u  small_buf[100];
Karsten Hopp 5f67cf
      size_t  i;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (bi->bi_state != NULL && bi->bi_buffer == NULL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	/* crypting every piece of text separately */
Karsten Hopp 5f67cf
! 	if (len < 100)
Karsten Hopp 5f67cf
! 	    copy = small_buf;  /* no malloc()/free() for short strings */
Karsten Hopp 5f67cf
! 	else
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    copy = lalloc(len, FALSE);
Karsten Hopp 5f67cf
! 	    if (copy == NULL)
Karsten Hopp 5f67cf
! 		return 0;
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
! 	crypt_encode(bi->bi_state, ptr, len, copy);
Karsten Hopp 5f67cf
! 	i = fwrite(copy, len, (size_t)1, bi->bi_fp);
Karsten Hopp 5f67cf
! 	if (copy != small_buf)
Karsten Hopp 5f67cf
! 	    vim_free(copy);
Karsten Hopp 5f67cf
! 	return i == 1 ? OK : FAIL;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
+     return undo_write(bi, ptr, len);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Write a number, MSB first, in "len" bytes.
Karsten Hopp 5f67cf
!  * Must match with undo_read_?c() functions.
Karsten Hopp 5f67cf
!  * Returns OK or FAIL.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! undo_write_bytes(bi, nr, len)
Karsten Hopp 5f67cf
!     bufinfo_T *bi;
Karsten Hopp 5f67cf
!     long_u  nr;
Karsten Hopp 5f67cf
      int	    len;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     char_u  buf[8];
Karsten Hopp 5f67cf
!     int	    i;
Karsten Hopp 5f67cf
!     int	    bufi = 0;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     for (i = len - 1; i >= 0; --i)
Karsten Hopp 5f67cf
! 	buf[bufi++] = nr >> (i * 8);
Karsten Hopp 5f67cf
!     return undo_write(bi, buf, (size_t)len);
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! /*
Karsten Hopp 5f67cf
!  * Write the pointer to an undo header.  Instead of writing the pointer itself
Karsten Hopp 5f67cf
!  * we use the sequence number of the header.  This is converted back to
Karsten Hopp 5f67cf
!  * pointers when reading. */
Karsten Hopp 5f67cf
!     static void
Karsten Hopp 5f67cf
! put_header_ptr(bi, uhp)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
!     u_header_T	*uhp;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4);
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! undo_read_4c(bi)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi->bi_buffer != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	char_u  buf[4];
Karsten Hopp 5f67cf
! 	int	n;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	undo_read(bi, buf, (size_t)4);
Karsten Hopp 5f67cf
! 	n = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
Karsten Hopp 5f67cf
! 	return n;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
!     return get4c(bi->bi_fp);
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! undo_read_2c(bi)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi->bi_buffer != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	char_u  buf[2];
Karsten Hopp 5f67cf
! 	int	n;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	undo_read(bi, buf, (size_t)2);
Karsten Hopp 5f67cf
! 	n = (buf[0] << 8) + buf[1];
Karsten Hopp 5f67cf
! 	return n;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
!     return get2c(bi->bi_fp);
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! undo_read_byte(bi)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi->bi_buffer != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	char_u  buf[1];
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	undo_read(bi, buf, (size_t)1);
Karsten Hopp 5f67cf
! 	return buf[0];
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
!     return getc(bi->bi_fp);
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     static time_t
Karsten Hopp 5f67cf
! undo_read_time(bi)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi->bi_buffer != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	char_u  buf[8];
Karsten Hopp 5f67cf
! 	time_t	n = 0;
Karsten Hopp 5f67cf
! 	int	i;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	undo_read(bi, buf, (size_t)8);
Karsten Hopp 5f67cf
! 	for (i = 0; i < 8; ++i)
Karsten Hopp 5f67cf
! 	    n = (n << 8) + buf[i];
Karsten Hopp 5f67cf
! 	return n;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
!     return get8ctime(bi->bi_fp);
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! /*
Karsten Hopp 5f67cf
!  * Read "buffer[size]" from the undo file.
Karsten Hopp 5f67cf
!  * Return OK or FAIL.
Karsten Hopp 5f67cf
!  */
Karsten Hopp 5f67cf
!     static int
Karsten Hopp 5f67cf
! undo_read(bi, buffer, size)
Karsten Hopp 5f67cf
!     bufinfo_T   *bi;
Karsten Hopp 5f67cf
!     char_u	*buffer;
Karsten Hopp 5f67cf
!     size_t	size;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi->bi_buffer != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	int	size_todo = size;
Karsten Hopp 5f67cf
! 	char_u	*p = buffer;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	while (size_todo > 0)
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    size_t n;
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! 	    if (bi->bi_used >= bi->bi_avail)
Karsten Hopp 5f67cf
! 	    {
Karsten Hopp 5f67cf
! 		n = fread(bi->bi_buffer, 1, (size_t)CRYPT_BUF_SIZE, bi->bi_fp);
Karsten Hopp 5f67cf
! 		if (n <= 0)
Karsten Hopp 5f67cf
! 		{
Karsten Hopp 5f67cf
! 		    /* Error may be checked for only later.  Fill with zeros,
Karsten Hopp 5f67cf
! 		     * so that the reader won't use garbage. */
Karsten Hopp 5f67cf
! 		    vim_memset(p, 0, size_todo);
Karsten Hopp 5f67cf
! 		    return FAIL;
Karsten Hopp 5f67cf
! 		}
Karsten Hopp 5f67cf
! 		bi->bi_avail = n;
Karsten Hopp 5f67cf
! 		bi->bi_used = 0;
Karsten Hopp 5f67cf
! 		crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail);
Karsten Hopp 5f67cf
! 	    }
Karsten Hopp 5f67cf
! 	    n = size_todo;
Karsten Hopp 5f67cf
! 	    if (n > bi->bi_avail - bi->bi_used)
Karsten Hopp 5f67cf
! 		n = bi->bi_avail - bi->bi_used;
Karsten Hopp 5f67cf
! 	    mch_memmove(p, bi->bi_buffer + bi->bi_used, n);
Karsten Hopp 5f67cf
! 	    bi->bi_used += n;
Karsten Hopp 5f67cf
! 	    size_todo -= n;
Karsten Hopp 5f67cf
! 	    p += n;
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
! 	return OK;
Karsten Hopp 5f67cf
!     }
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
!     if (fread(buffer, (size_t)size, 1, bi->bi_fp) != 1)
Karsten Hopp 5f67cf
! 	return FAIL;
Karsten Hopp 5f67cf
!     return OK;
Karsten Hopp 5f67cf
! }
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
! /*
Karsten Hopp 5f67cf
!  * Read a string of length "len" from "bi->bi_fd".
Karsten Hopp 5f67cf
!  * "len" can be zero to allocate an empty line.
Karsten Hopp 5f67cf
!  * Decrypt the bytes if needed.
Karsten Hopp 5f67cf
!  * Append a NUL.
Karsten Hopp 5f67cf
!  * Returns a pointer to allocated memory or NULL for failure.
Karsten Hopp 5f67cf
!  */
Karsten Hopp 5f67cf
!     static char_u *
Karsten Hopp 5f67cf
! read_string_decrypt(bi, len)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
!     int		len;
Karsten Hopp 5f67cf
! {
Karsten Hopp 5f67cf
!     char_u  *ptr = alloc((unsigned)len + 1);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (ptr != NULL)
Karsten Hopp 5f67cf
!     {
Karsten Hopp 5f67cf
! 	if (len > 0 && undo_read(bi, ptr, len) == FAIL)
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    vim_free(ptr);
Karsten Hopp 5f67cf
! 	    return NULL;
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
! 	ptr[len] = NUL;
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
! 	if (bi->bi_state != NULL && bi->bi_buffer == NULL)
Karsten Hopp 5f67cf
! 	    crypt_decode_inplace(bi->bi_state, ptr, len);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
+     }
Karsten Hopp 5f67cf
      return ptr;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
+ /*
Karsten Hopp 5f67cf
+  * Writes the (not encrypted) header and initializes encryption if needed.
Karsten Hopp 5f67cf
+  */
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! serialize_header(bi, hash)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
      char_u	*hash;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     int		len;
Karsten Hopp 5f67cf
!     buf_T	*buf = bi->bi_buf;
Karsten Hopp 5f67cf
!     FILE	*fp = bi->bi_fp;
Karsten Hopp 5f67cf
!     char_u	time_buf[8];
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Start writing, first the magic marker and undo info version. */
Karsten Hopp 5f67cf
      if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 934,1041 ****
Karsten Hopp 5f67cf
  	char_u *header;
Karsten Hopp 5f67cf
  	int    header_len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	put_bytes(fp, (long_u)UF_VERSION_CRYPT, 2);
Karsten Hopp 5f67cf
! 	header = prepare_crypt_write(buf, &header_len);
Karsten Hopp 5f67cf
! 	if (header == NULL)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
  	len = (int)fwrite(header, (size_t)header_len, (size_t)1, fp);
Karsten Hopp 5f67cf
  	vim_free(header);
Karsten Hopp 5f67cf
  	if (len != 1)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    crypt_pop_state();
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
      else
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
! 	put_bytes(fp, (long_u)UF_VERSION, 2);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Write a hash of the buffer text, so that we can verify it is still the
Karsten Hopp 5f67cf
       * same when reading the buffer text. */
Karsten Hopp 5f67cf
!     if (fwrite(hash, (size_t)UNDO_HASH_SIZE, (size_t)1, fp) != 1)
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* buffer-specific data */
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)buf->b_ml.ml_line_count, 4);
Karsten Hopp 5f67cf
      len = buf->b_u_line_ptr != NULL ? (int)STRLEN(buf->b_u_line_ptr) : 0;
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)len, 4);
Karsten Hopp 5f67cf
!     if (len > 0 && fwrite_crypt(buf, buf->b_u_line_ptr, (size_t)len, fp) != 1)
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)buf->b_u_line_lnum, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)buf->b_u_line_colnr, 4);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Undo structures header data */
Karsten Hopp 5f67cf
!     put_header_ptr(fp, buf->b_u_oldhead);
Karsten Hopp 5f67cf
!     put_header_ptr(fp, buf->b_u_newhead);
Karsten Hopp 5f67cf
!     put_header_ptr(fp, buf->b_u_curhead);
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)buf->b_u_numhead, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)buf->b_u_seq_last, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)buf->b_u_seq_cur, 4);
Karsten Hopp 5f67cf
!     put_time(fp, buf->b_u_time_cur);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional fields. */
Karsten Hopp 5f67cf
!     putc(4, fp);
Karsten Hopp 5f67cf
!     putc(UF_LAST_SAVE_NR, fp);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)buf->b_u_save_nr_last, 4);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     putc(0, fp);  /* end marker */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! serialize_uhp(fp, buf, uhp)
Karsten Hopp 5f67cf
!     FILE	*fp;
Karsten Hopp 5f67cf
!     buf_T	*buf;
Karsten Hopp 5f67cf
      u_header_T	*uhp;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int		i;
Karsten Hopp 5f67cf
      u_entry_T	*uep;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (put_bytes(fp, (long_u)UF_HEADER_MAGIC, 2) == FAIL)
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     put_header_ptr(fp, uhp->uh_next.ptr);
Karsten Hopp 5f67cf
!     put_header_ptr(fp, uhp->uh_prev.ptr);
Karsten Hopp 5f67cf
!     put_header_ptr(fp, uhp->uh_alt_next.ptr);
Karsten Hopp 5f67cf
!     put_header_ptr(fp, uhp->uh_alt_prev.ptr);
Karsten Hopp 5f67cf
!     put_bytes(fp, uhp->uh_seq, 4);
Karsten Hopp 5f67cf
!     serialize_pos(uhp->uh_cursor, fp);
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)uhp->uh_cursor_vcol, 4);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)0, 4);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)uhp->uh_flags, 2);
Karsten Hopp 5f67cf
      /* Assume NMARKS will stay the same. */
Karsten Hopp 5f67cf
      for (i = 0; i < NMARKS; ++i)
Karsten Hopp 5f67cf
! 	serialize_pos(uhp->uh_namedm[i], fp);
Karsten Hopp 5f67cf
!     serialize_visualinfo(&uhp->uh_visual, fp);
Karsten Hopp 5f67cf
!     put_time(fp, uhp->uh_time);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional fields. */
Karsten Hopp 5f67cf
!     putc(4, fp);
Karsten Hopp 5f67cf
!     putc(UHP_SAVE_NR, fp);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)uhp->uh_save_nr, 4);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     putc(0, fp);  /* end marker */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Write all the entries. */
Karsten Hopp 5f67cf
      for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	put_bytes(fp, (long_u)UF_ENTRY_MAGIC, 2);
Karsten Hopp 5f67cf
! 	if (serialize_uep(fp, buf, uep) == FAIL)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)UF_ENTRY_END_MAGIC, 2);
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static u_header_T *
Karsten Hopp 5f67cf
! unserialize_uhp(fp, file_name)
Karsten Hopp 5f67cf
!     FILE	*fp;
Karsten Hopp 5f67cf
      char_u	*file_name;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      u_header_T	*uhp;
Karsten Hopp 5f67cf
--- 1185,1308 ----
Karsten Hopp 5f67cf
  	char_u *header;
Karsten Hopp 5f67cf
  	int    header_len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	undo_write_bytes(bi, (long_u)UF_VERSION_CRYPT, 2);
Karsten Hopp 5f67cf
! 	bi->bi_state = crypt_create_for_writing(crypt_get_method_nr(buf),
Karsten Hopp 5f67cf
! 					  buf->b_p_key, &header, &header_len);
Karsten Hopp 5f67cf
! 	if (bi->bi_state == NULL)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
  	len = (int)fwrite(header, (size_t)header_len, (size_t)1, fp);
Karsten Hopp 5f67cf
  	vim_free(header);
Karsten Hopp 5f67cf
  	if (len != 1)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
! 	    crypt_free_state(bi->bi_state);
Karsten Hopp 5f67cf
! 	    bi->bi_state = NULL;
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
+ 	if (crypt_whole_undofile(crypt_get_method_nr(buf)))
Karsten Hopp 5f67cf
+ 	{
Karsten Hopp 5f67cf
+ 	    bi->bi_buffer = alloc(CRYPT_BUF_SIZE);
Karsten Hopp 5f67cf
+ 	    if (bi->bi_buffer == NULL)
Karsten Hopp 5f67cf
+ 	    {
Karsten Hopp 5f67cf
+ 		crypt_free_state(bi->bi_state);
Karsten Hopp 5f67cf
+ 		bi->bi_state = NULL;
Karsten Hopp 5f67cf
+ 		return FAIL;
Karsten Hopp 5f67cf
+ 	    }
Karsten Hopp 5f67cf
+ 	    bi->bi_used = 0;
Karsten Hopp 5f67cf
+ 	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
      else
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
! 	undo_write_bytes(bi, (long_u)UF_VERSION, 2);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Write a hash of the buffer text, so that we can verify it is still the
Karsten Hopp 5f67cf
       * same when reading the buffer text. */
Karsten Hopp 5f67cf
!     if (undo_write(bi, hash, (size_t)UNDO_HASH_SIZE) == FAIL)
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* buffer-specific data */
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)buf->b_ml.ml_line_count, 4);
Karsten Hopp 5f67cf
      len = buf->b_u_line_ptr != NULL ? (int)STRLEN(buf->b_u_line_ptr) : 0;
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)len, 4);
Karsten Hopp 5f67cf
!     if (len > 0 && fwrite_crypt(bi, buf->b_u_line_ptr, (size_t)len) == FAIL)
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)buf->b_u_line_lnum, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)buf->b_u_line_colnr, 4);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Undo structures header data */
Karsten Hopp 5f67cf
!     put_header_ptr(bi, buf->b_u_oldhead);
Karsten Hopp 5f67cf
!     put_header_ptr(bi, buf->b_u_newhead);
Karsten Hopp 5f67cf
!     put_header_ptr(bi, buf->b_u_curhead);
Karsten Hopp 5f67cf
! 
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)buf->b_u_numhead, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)buf->b_u_seq_last, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)buf->b_u_seq_cur, 4);
Karsten Hopp 5f67cf
!     time_to_bytes(buf->b_u_time_cur, time_buf);
Karsten Hopp 5f67cf
!     undo_write(bi, time_buf, 8);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional fields. */
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, 4, 1);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, UF_LAST_SAVE_NR, 1);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)buf->b_u_save_nr_last, 4);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, 0, 1);  /* end marker */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! serialize_uhp(bi, uhp)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
      u_header_T	*uhp;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int		i;
Karsten Hopp 5f67cf
      u_entry_T	*uep;
Karsten Hopp 5f67cf
+     char_u	time_buf[8];
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (undo_write_bytes(bi, (long_u)UF_HEADER_MAGIC, 2) == FAIL)
Karsten Hopp 5f67cf
  	return FAIL;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     put_header_ptr(bi, uhp->uh_next.ptr);
Karsten Hopp 5f67cf
!     put_header_ptr(bi, uhp->uh_prev.ptr);
Karsten Hopp 5f67cf
!     put_header_ptr(bi, uhp->uh_alt_next.ptr);
Karsten Hopp 5f67cf
!     put_header_ptr(bi, uhp->uh_alt_prev.ptr);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, uhp->uh_seq, 4);
Karsten Hopp 5f67cf
!     serialize_pos(bi, uhp->uh_cursor);
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)uhp->uh_cursor_vcol, 4);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)0, 4);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)uhp->uh_flags, 2);
Karsten Hopp 5f67cf
      /* Assume NMARKS will stay the same. */
Karsten Hopp 5f67cf
      for (i = 0; i < NMARKS; ++i)
Karsten Hopp 5f67cf
! 	serialize_pos(bi, uhp->uh_namedm[i]);
Karsten Hopp 5f67cf
!     serialize_visualinfo(bi, &uhp->uh_visual);
Karsten Hopp 5f67cf
!     time_to_bytes(uhp->uh_time, time_buf);
Karsten Hopp 5f67cf
!     undo_write(bi, time_buf, 8);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional fields. */
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, 4, 1);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, UHP_SAVE_NR, 1);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)uhp->uh_save_nr, 4);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, 0, 1);  /* end marker */
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Write all the entries. */
Karsten Hopp 5f67cf
      for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	undo_write_bytes(bi, (long_u)UF_ENTRY_MAGIC, 2);
Karsten Hopp 5f67cf
! 	if (serialize_uep(bi, uep) == FAIL)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)UF_ENTRY_END_MAGIC, 2);
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static u_header_T *
Karsten Hopp 5f67cf
! unserialize_uhp(bi, file_name)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
      char_u	*file_name;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      u_header_T	*uhp;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1051,1106 ****
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
      uhp->uh_magic = UH_MAGIC;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     uhp->uh_next.seq = get4c(fp);
Karsten Hopp 5f67cf
!     uhp->uh_prev.seq = get4c(fp);
Karsten Hopp 5f67cf
!     uhp->uh_alt_next.seq = get4c(fp);
Karsten Hopp 5f67cf
!     uhp->uh_alt_prev.seq = get4c(fp);
Karsten Hopp 5f67cf
!     uhp->uh_seq = get4c(fp);
Karsten Hopp 5f67cf
      if (uhp->uh_seq <= 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	corruption_error("uh_seq", file_name);
Karsten Hopp 5f67cf
  	vim_free(uhp);
Karsten Hopp 5f67cf
  	return NULL;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
!     unserialize_pos(&uhp->uh_cursor, fp);
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     uhp->uh_cursor_vcol = get4c(fp);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     (void)get4c(fp);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     uhp->uh_flags = get2c(fp);
Karsten Hopp 5f67cf
      for (i = 0; i < NMARKS; ++i)
Karsten Hopp 5f67cf
! 	unserialize_pos(&uhp->uh_namedm[i], fp);
Karsten Hopp 5f67cf
!     unserialize_visualinfo(&uhp->uh_visual, fp);
Karsten Hopp 5f67cf
!     uhp->uh_time = get8ctime(fp);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional fields. */
Karsten Hopp 5f67cf
      for (;;)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	int len = getc(fp);
Karsten Hopp 5f67cf
  	int what;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	if (len == 0)
Karsten Hopp 5f67cf
  	    break;
Karsten Hopp 5f67cf
! 	what = getc(fp);
Karsten Hopp 5f67cf
  	switch (what)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    case UHP_SAVE_NR:
Karsten Hopp 5f67cf
! 		uhp->uh_save_nr = get4c(fp);
Karsten Hopp 5f67cf
  		break;
Karsten Hopp 5f67cf
  	    default:
Karsten Hopp 5f67cf
  		/* field not supported, skip */
Karsten Hopp 5f67cf
  		while (--len >= 0)
Karsten Hopp 5f67cf
! 		    (void)getc(fp);
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Unserialize the uep list. */
Karsten Hopp 5f67cf
      last_uep = NULL;
Karsten Hopp 5f67cf
!     while ((c = get2c(fp)) == UF_ENTRY_MAGIC)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	error = FALSE;
Karsten Hopp 5f67cf
! 	uep = unserialize_uep(fp, &error, file_name);
Karsten Hopp 5f67cf
  	if (last_uep == NULL)
Karsten Hopp 5f67cf
  	    uhp->uh_entry = uep;
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
--- 1318,1373 ----
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
      uhp->uh_magic = UH_MAGIC;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     uhp->uh_next.seq = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     uhp->uh_prev.seq = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     uhp->uh_alt_next.seq = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     uhp->uh_alt_prev.seq = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     uhp->uh_seq = undo_read_4c(bi);
Karsten Hopp 5f67cf
      if (uhp->uh_seq <= 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	corruption_error("uh_seq", file_name);
Karsten Hopp 5f67cf
  	vim_free(uhp);
Karsten Hopp 5f67cf
  	return NULL;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
!     unserialize_pos(bi, &uhp->uh_cursor);
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     uhp->uh_cursor_vcol = undo_read_4c(bi);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     (void)undo_read_4c(bi);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     uhp->uh_flags = undo_read_2c(bi);
Karsten Hopp 5f67cf
      for (i = 0; i < NMARKS; ++i)
Karsten Hopp 5f67cf
! 	unserialize_pos(bi, &uhp->uh_namedm[i]);
Karsten Hopp 5f67cf
!     unserialize_visualinfo(bi, &uhp->uh_visual);
Karsten Hopp 5f67cf
!     uhp->uh_time = undo_read_time(bi);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional fields. */
Karsten Hopp 5f67cf
      for (;;)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	int len = undo_read_byte(bi);
Karsten Hopp 5f67cf
  	int what;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	if (len == 0)
Karsten Hopp 5f67cf
  	    break;
Karsten Hopp 5f67cf
! 	what = undo_read_byte(bi);
Karsten Hopp 5f67cf
  	switch (what)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    case UHP_SAVE_NR:
Karsten Hopp 5f67cf
! 		uhp->uh_save_nr = undo_read_4c(bi);
Karsten Hopp 5f67cf
  		break;
Karsten Hopp 5f67cf
  	    default:
Karsten Hopp 5f67cf
  		/* field not supported, skip */
Karsten Hopp 5f67cf
  		while (--len >= 0)
Karsten Hopp 5f67cf
! 		    (void)undo_read_byte(bi);
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Unserialize the uep list. */
Karsten Hopp 5f67cf
      last_uep = NULL;
Karsten Hopp 5f67cf
!     while ((c = undo_read_2c(bi)) == UF_ENTRY_MAGIC)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	error = FALSE;
Karsten Hopp 5f67cf
! 	uep = unserialize_uep(bi, &error, file_name);
Karsten Hopp 5f67cf
  	if (last_uep == NULL)
Karsten Hopp 5f67cf
  	    uhp->uh_entry = uep;
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1123,1157 ****
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Serialize "uep" to "fp".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! serialize_uep(fp, buf, uep)
Karsten Hopp 5f67cf
!     FILE	*fp;
Karsten Hopp 5f67cf
!     buf_T	*buf;
Karsten Hopp 5f67cf
      u_entry_T	*uep;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int		i;
Karsten Hopp 5f67cf
      size_t	len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)uep->ue_top, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)uep->ue_bot, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)uep->ue_lcount, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)uep->ue_size, 4);
Karsten Hopp 5f67cf
      for (i = 0; i < uep->ue_size; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	len = STRLEN(uep->ue_array[i]);
Karsten Hopp 5f67cf
! 	if (put_bytes(fp, (long_u)len, 4) == FAIL)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
! 	if (len > 0 && fwrite_crypt(buf, uep->ue_array[i], len, fp) != 1)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static u_entry_T *
Karsten Hopp 5f67cf
! unserialize_uep(fp, error, file_name)
Karsten Hopp 5f67cf
!     FILE	*fp;
Karsten Hopp 5f67cf
      int		*error;
Karsten Hopp 5f67cf
      char_u	*file_name;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
--- 1390,1423 ----
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Serialize "uep".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static int
Karsten Hopp 5f67cf
! serialize_uep(bi, uep)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
      u_entry_T	*uep;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
      int		i;
Karsten Hopp 5f67cf
      size_t	len;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)uep->ue_top, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)uep->ue_bot, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)uep->ue_lcount, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)uep->ue_size, 4);
Karsten Hopp 5f67cf
      for (i = 0; i < uep->ue_size; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	len = STRLEN(uep->ue_array[i]);
Karsten Hopp 5f67cf
! 	if (undo_write_bytes(bi, (long_u)len, 4) == FAIL)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
! 	if (len > 0 && fwrite_crypt(bi, uep->ue_array[i], len) == FAIL)
Karsten Hopp 5f67cf
  	    return FAIL;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
      return OK;
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      static u_entry_T *
Karsten Hopp 5f67cf
! unserialize_uep(bi, error, file_name)
Karsten Hopp 5f67cf
!     bufinfo_T	*bi;
Karsten Hopp 5f67cf
      int		*error;
Karsten Hopp 5f67cf
      char_u	*file_name;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1168,1177 ****
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
      uep->ue_magic = UE_MAGIC;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     uep->ue_top = get4c(fp);
Karsten Hopp 5f67cf
!     uep->ue_bot = get4c(fp);
Karsten Hopp 5f67cf
!     uep->ue_lcount = get4c(fp);
Karsten Hopp 5f67cf
!     uep->ue_size = get4c(fp);
Karsten Hopp 5f67cf
      if (uep->ue_size > 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
Karsten Hopp 5f67cf
--- 1434,1443 ----
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
      uep->ue_magic = UE_MAGIC;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     uep->ue_top = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     uep->ue_bot = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     uep->ue_lcount = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     uep->ue_size = undo_read_4c(bi);
Karsten Hopp 5f67cf
      if (uep->ue_size > 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1188,1196 ****
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < uep->ue_size; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	line_len = get4c(fp);
Karsten Hopp 5f67cf
  	if (line_len >= 0)
Karsten Hopp 5f67cf
! 	    line = read_string_decrypt(curbuf, fp, line_len);
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    line = NULL;
Karsten Hopp 5f67cf
--- 1454,1462 ----
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      for (i = 0; i < uep->ue_size; ++i)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	line_len = undo_read_4c(bi);
Karsten Hopp 5f67cf
  	if (line_len >= 0)
Karsten Hopp 5f67cf
! 	    line = read_string_decrypt(bi, line_len);
Karsten Hopp 5f67cf
  	else
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    line = NULL;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1207,1289 ****
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Serialize "pos" to "fp".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! serialize_pos(pos, fp)
Karsten Hopp 5f67cf
      pos_T pos;
Karsten Hopp 5f67cf
-     FILE  *fp;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)pos.lnum, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)pos.col, 4);
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)pos.coladd, 4);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)0, 4);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Unserialize the pos_T at the current position in fp.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! unserialize_pos(pos, fp)
Karsten Hopp 5f67cf
      pos_T *pos;
Karsten Hopp 5f67cf
-     FILE  *fp;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     pos->lnum = get4c(fp);
Karsten Hopp 5f67cf
      if (pos->lnum < 0)
Karsten Hopp 5f67cf
  	pos->lnum = 0;
Karsten Hopp 5f67cf
!     pos->col = get4c(fp);
Karsten Hopp 5f67cf
      if (pos->col < 0)
Karsten Hopp 5f67cf
  	pos->col = 0;
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     pos->coladd = get4c(fp);
Karsten Hopp 5f67cf
      if (pos->coladd < 0)
Karsten Hopp 5f67cf
  	pos->coladd = 0;
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     (void)get4c(fp);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Serialize "info" to "fp".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! serialize_visualinfo(info, fp)
Karsten Hopp 5f67cf
      visualinfo_T    *info;
Karsten Hopp 5f67cf
-     FILE	    *fp;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     serialize_pos(info->vi_start, fp);
Karsten Hopp 5f67cf
!     serialize_pos(info->vi_end, fp);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)info->vi_mode, 4);
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)info->vi_curswant, 4);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Unserialize the visualinfo_T at the current position in fp.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! unserialize_visualinfo(info, fp)
Karsten Hopp 5f67cf
      visualinfo_T    *info;
Karsten Hopp 5f67cf
-     FILE	    *fp;
Karsten Hopp 5f67cf
- {
Karsten Hopp 5f67cf
-     unserialize_pos(&info->vi_start, fp);
Karsten Hopp 5f67cf
-     unserialize_pos(&info->vi_end, fp);
Karsten Hopp 5f67cf
-     info->vi_mode = get4c(fp);
Karsten Hopp 5f67cf
-     info->vi_curswant = get4c(fp);
Karsten Hopp 5f67cf
- }
Karsten Hopp 5f67cf
- 
Karsten Hopp 5f67cf
- /*
Karsten Hopp 5f67cf
-  * Write the pointer to an undo header.  Instead of writing the pointer itself
Karsten Hopp 5f67cf
-  * we use the sequence number of the header.  This is converted back to
Karsten Hopp 5f67cf
-  * pointers when reading. */
Karsten Hopp 5f67cf
-     static void
Karsten Hopp 5f67cf
- put_header_ptr(fp, uhp)
Karsten Hopp 5f67cf
-     FILE	*fp;
Karsten Hopp 5f67cf
-     u_header_T	*uhp;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     put_bytes(fp, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
--- 1473,1543 ----
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Serialize "pos".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! serialize_pos(bi, pos)
Karsten Hopp 5f67cf
!     bufinfo_T *bi;
Karsten Hopp 5f67cf
      pos_T pos;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)pos.lnum, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)pos.col, 4);
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)pos.coladd, 4);
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)0, 4);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Unserialize the pos_T at the current position.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! unserialize_pos(bi, pos)
Karsten Hopp 5f67cf
!     bufinfo_T *bi;
Karsten Hopp 5f67cf
      pos_T *pos;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     pos->lnum = undo_read_4c(bi);
Karsten Hopp 5f67cf
      if (pos->lnum < 0)
Karsten Hopp 5f67cf
  	pos->lnum = 0;
Karsten Hopp 5f67cf
!     pos->col = undo_read_4c(bi);
Karsten Hopp 5f67cf
      if (pos->col < 0)
Karsten Hopp 5f67cf
  	pos->col = 0;
Karsten Hopp 5f67cf
  #ifdef FEAT_VIRTUALEDIT
Karsten Hopp 5f67cf
!     pos->coladd = undo_read_4c(bi);
Karsten Hopp 5f67cf
      if (pos->coladd < 0)
Karsten Hopp 5f67cf
  	pos->coladd = 0;
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
!     (void)undo_read_4c(bi);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Serialize "info".
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! serialize_visualinfo(bi, info)
Karsten Hopp 5f67cf
!     bufinfo_T	    *bi;
Karsten Hopp 5f67cf
      visualinfo_T    *info;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     serialize_pos(bi, info->vi_start);
Karsten Hopp 5f67cf
!     serialize_pos(bi, info->vi_end);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)info->vi_mode, 4);
Karsten Hopp 5f67cf
!     undo_write_bytes(bi, (long_u)info->vi_curswant, 4);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
!  * Unserialize the visualinfo_T at the current position.
Karsten Hopp 5f67cf
   */
Karsten Hopp 5f67cf
      static void
Karsten Hopp 5f67cf
! unserialize_visualinfo(bi, info)
Karsten Hopp 5f67cf
!     bufinfo_T	    *bi;
Karsten Hopp 5f67cf
      visualinfo_T    *info;
Karsten Hopp 5f67cf
  {
Karsten Hopp 5f67cf
!     unserialize_pos(bi, &info->vi_start);
Karsten Hopp 5f67cf
!     unserialize_pos(bi, &info->vi_end);
Karsten Hopp 5f67cf
!     info->vi_mode = undo_read_4c(bi);
Karsten Hopp 5f67cf
!     info->vi_curswant = undo_read_4c(bi);
Karsten Hopp 5f67cf
  }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  /*
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1317,1324 ****
Karsten Hopp 5f67cf
      struct stat	st_old;
Karsten Hopp 5f67cf
      struct stat	st_new;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     int		do_crypt = FALSE;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (name == NULL)
Karsten Hopp 5f67cf
--- 1571,1581 ----
Karsten Hopp 5f67cf
      struct stat	st_old;
Karsten Hopp 5f67cf
      struct stat	st_new;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
+     bufinfo_T	bi;
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     bi.bi_state = NULL;
Karsten Hopp 5f67cf
!     bi.bi_buffer = NULL;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (name == NULL)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1474,1487 ****
Karsten Hopp 5f67cf
      u_sync(TRUE);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /*
Karsten Hopp 5f67cf
!      * Write the header.
Karsten Hopp 5f67cf
       */
Karsten Hopp 5f67cf
!     if (serialize_header(fp, buf, hash) == FAIL)
Karsten Hopp 5f67cf
  	goto write_error;
Karsten Hopp 5f67cf
- #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
-     if (*buf->b_p_key != NUL)
Karsten Hopp 5f67cf
- 	do_crypt = TRUE;
Karsten Hopp 5f67cf
- #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /*
Karsten Hopp 5f67cf
       * Iteratively serialize UHPs and their UEPs from the top down.
Karsten Hopp 5f67cf
--- 1731,1742 ----
Karsten Hopp 5f67cf
      u_sync(TRUE);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /*
Karsten Hopp 5f67cf
!      * Write the header.  Initializes encryption, if enabled.
Karsten Hopp 5f67cf
       */
Karsten Hopp 5f67cf
!     bi.bi_buf = buf;
Karsten Hopp 5f67cf
!     bi.bi_fp = fp;
Karsten Hopp 5f67cf
!     if (serialize_header(&bi, hash) == FAIL)
Karsten Hopp 5f67cf
  	goto write_error;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /*
Karsten Hopp 5f67cf
       * Iteratively serialize UHPs and their UEPs from the top down.
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1497,1503 ****
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
  	    ++headers_written;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
! 	    if (serialize_uhp(fp, buf, uhp) == FAIL)
Karsten Hopp 5f67cf
  		goto write_error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
--- 1752,1758 ----
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
  	    ++headers_written;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
! 	    if (serialize_uhp(&bi, uhp) == FAIL)
Karsten Hopp 5f67cf
  		goto write_error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1516,1522 ****
Karsten Hopp 5f67cf
  	    uhp = uhp->uh_next.ptr;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (put_bytes(fp, (long_u)UF_HEADER_END_MAGIC, 2) == OK)
Karsten Hopp 5f67cf
  	write_ok = TRUE;
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
      if (headers_written != buf->b_u_numhead)
Karsten Hopp 5f67cf
--- 1771,1777 ----
Karsten Hopp 5f67cf
  	    uhp = uhp->uh_next.ptr;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (undo_write_bytes(&bi, (long_u)UF_HEADER_END_MAGIC, 2) == OK)
Karsten Hopp 5f67cf
  	write_ok = TRUE;
Karsten Hopp 5f67cf
  #ifdef U_DEBUG
Karsten Hopp 5f67cf
      if (headers_written != buf->b_u_numhead)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1526,1531 ****
Karsten Hopp 5f67cf
--- 1781,1791 ----
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+     if (bi.bi_state != NULL && undo_flush(&bi) == FAIL)
Karsten Hopp 5f67cf
+ 	write_ok = FALSE;
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
+ 
Karsten Hopp 5f67cf
  write_error:
Karsten Hopp 5f67cf
      fclose(fp);
Karsten Hopp 5f67cf
      if (!write_ok)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1551,1558 ****
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  theend:
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (do_crypt)
Karsten Hopp 5f67cf
! 	crypt_pop_state();
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      if (file_name != name)
Karsten Hopp 5f67cf
  	vim_free(file_name);
Karsten Hopp 5f67cf
--- 1811,1819 ----
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  theend:
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi.bi_state != NULL)
Karsten Hopp 5f67cf
! 	crypt_free_state(bi.bi_state);
Karsten Hopp 5f67cf
!     vim_free(bi.bi_buffer);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      if (file_name != name)
Karsten Hopp 5f67cf
  	vim_free(file_name);
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1598,1606 ****
Karsten Hopp 5f67cf
      struct stat	st_orig;
Karsten Hopp 5f67cf
      struct stat	st_undo;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
! #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     int		do_decrypt = FALSE;
Karsten Hopp 5f67cf
! #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (name == NULL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
--- 1859,1865 ----
Karsten Hopp 5f67cf
      struct stat	st_orig;
Karsten Hopp 5f67cf
      struct stat	st_undo;
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
!     bufinfo_T	bi;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      if (name == NULL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1644,1649 ****
Karsten Hopp 5f67cf
--- 1903,1914 ----
Karsten Hopp 5f67cf
  	    EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name);
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
+     bi.bi_buf = curbuf;
Karsten Hopp 5f67cf
+     bi.bi_fp = fp;
Karsten Hopp 5f67cf
+ #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
+     bi.bi_state = NULL;
Karsten Hopp 5f67cf
+     bi.bi_buffer = NULL;
Karsten Hopp 5f67cf
+ #endif
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /*
Karsten Hopp 5f67cf
       * Read the undo file header.
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1664,1675 ****
Karsten Hopp 5f67cf
  								   file_name);
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
! 	if (prepare_crypt_read(fp) == FAIL)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    EMSG2(_("E826: Undo file decryption failed: %s"), file_name);
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
! 	do_decrypt = TRUE;
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
  	EMSG2(_("E827: Undo file is encrypted: %s"), file_name);
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
--- 1929,1952 ----
Karsten Hopp 5f67cf
  								   file_name);
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
! 	bi.bi_state = crypt_create_from_file(fp, curbuf->b_p_key);
Karsten Hopp 5f67cf
! 	if (bi.bi_state == NULL)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    EMSG2(_("E826: Undo file decryption failed: %s"), file_name);
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
! 	if (crypt_whole_undofile(bi.bi_state->method_nr))
Karsten Hopp 5f67cf
! 	{
Karsten Hopp 5f67cf
! 	    bi.bi_buffer = alloc(CRYPT_BUF_SIZE);
Karsten Hopp 5f67cf
! 	    if (bi.bi_buffer == NULL)
Karsten Hopp 5f67cf
! 	    {
Karsten Hopp 5f67cf
! 		crypt_free_state(bi.bi_state);
Karsten Hopp 5f67cf
! 		bi.bi_state = NULL;
Karsten Hopp 5f67cf
! 		goto error;
Karsten Hopp 5f67cf
! 	    }
Karsten Hopp 5f67cf
! 	    bi.bi_avail = 0;
Karsten Hopp 5f67cf
! 	    bi.bi_used = 0;
Karsten Hopp 5f67cf
! 	}
Karsten Hopp 5f67cf
  #else
Karsten Hopp 5f67cf
  	EMSG2(_("E827: Undo file is encrypted: %s"), file_name);
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1681,1692 ****
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (fread(read_hash, UNDO_HASH_SIZE, 1, fp) != 1)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	corruption_error("hash", file_name);
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
!     line_count = (linenr_T)get4c(fp);
Karsten Hopp 5f67cf
      if (memcmp(hash, read_hash, UNDO_HASH_SIZE) != 0
Karsten Hopp 5f67cf
  				  || line_count != curbuf->b_ml.ml_line_count)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
--- 1958,1969 ----
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     if (undo_read(&bi, read_hash, (size_t)UNDO_HASH_SIZE) == FAIL)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	corruption_error("hash", file_name);
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
!     line_count = (linenr_T)undo_read_4c(&bi);
Karsten Hopp 5f67cf
      if (memcmp(hash, read_hash, UNDO_HASH_SIZE) != 0
Karsten Hopp 5f67cf
  				  || line_count != curbuf->b_ml.ml_line_count)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1703,1715 ****
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Read undo data for "U" command. */
Karsten Hopp 5f67cf
!     str_len = get4c(fp);
Karsten Hopp 5f67cf
      if (str_len < 0)
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
      if (str_len > 0)
Karsten Hopp 5f67cf
! 	line_ptr = read_string_decrypt(curbuf, fp, str_len);
Karsten Hopp 5f67cf
!     line_lnum = (linenr_T)get4c(fp);
Karsten Hopp 5f67cf
!     line_colnr = (colnr_T)get4c(fp);
Karsten Hopp 5f67cf
      if (line_lnum < 0 || line_colnr < 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	corruption_error("line lnum/col", file_name);
Karsten Hopp 5f67cf
--- 1980,1992 ----
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Read undo data for "U" command. */
Karsten Hopp 5f67cf
!     str_len = undo_read_4c(&bi);
Karsten Hopp 5f67cf
      if (str_len < 0)
Karsten Hopp 5f67cf
  	goto error;
Karsten Hopp 5f67cf
      if (str_len > 0)
Karsten Hopp 5f67cf
! 	line_ptr = read_string_decrypt(&bi, str_len);
Karsten Hopp 5f67cf
!     line_lnum = (linenr_T)undo_read_4c(&bi);
Karsten Hopp 5f67cf
!     line_colnr = (colnr_T)undo_read_4c(&bi);
Karsten Hopp 5f67cf
      if (line_lnum < 0 || line_colnr < 0)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	corruption_error("line lnum/col", file_name);
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1717,1748 ****
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Begin general undo data */
Karsten Hopp 5f67cf
!     old_header_seq = get4c(fp);
Karsten Hopp 5f67cf
!     new_header_seq = get4c(fp);
Karsten Hopp 5f67cf
!     cur_header_seq = get4c(fp);
Karsten Hopp 5f67cf
!     num_head = get4c(fp);
Karsten Hopp 5f67cf
!     seq_last = get4c(fp);
Karsten Hopp 5f67cf
!     seq_cur = get4c(fp);
Karsten Hopp 5f67cf
!     seq_time = get8ctime(fp);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional header fields. */
Karsten Hopp 5f67cf
      for (;;)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	int len = getc(fp);
Karsten Hopp 5f67cf
  	int what;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	if (len == 0 || len == EOF)
Karsten Hopp 5f67cf
  	    break;
Karsten Hopp 5f67cf
! 	what = getc(fp);
Karsten Hopp 5f67cf
  	switch (what)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    case UF_LAST_SAVE_NR:
Karsten Hopp 5f67cf
! 		last_save_nr = get4c(fp);
Karsten Hopp 5f67cf
  		break;
Karsten Hopp 5f67cf
  	    default:
Karsten Hopp 5f67cf
  		/* field not supported, skip */
Karsten Hopp 5f67cf
  		while (--len >= 0)
Karsten Hopp 5f67cf
! 		    (void)getc(fp);
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
--- 1994,2025 ----
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Begin general undo data */
Karsten Hopp 5f67cf
!     old_header_seq = undo_read_4c(&bi);
Karsten Hopp 5f67cf
!     new_header_seq = undo_read_4c(&bi);
Karsten Hopp 5f67cf
!     cur_header_seq = undo_read_4c(&bi);
Karsten Hopp 5f67cf
!     num_head = undo_read_4c(&bi);
Karsten Hopp 5f67cf
!     seq_last = undo_read_4c(&bi);
Karsten Hopp 5f67cf
!     seq_cur = undo_read_4c(&bi);
Karsten Hopp 5f67cf
!     seq_time = undo_read_time(&bi);
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
      /* Optional header fields. */
Karsten Hopp 5f67cf
      for (;;)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
! 	int len = undo_read_byte(&bi);
Karsten Hopp 5f67cf
  	int what;
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  	if (len == 0 || len == EOF)
Karsten Hopp 5f67cf
  	    break;
Karsten Hopp 5f67cf
! 	what = undo_read_byte(&bi);
Karsten Hopp 5f67cf
  	switch (what)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
  	    case UF_LAST_SAVE_NR:
Karsten Hopp 5f67cf
! 		last_save_nr = undo_read_4c(&bi);
Karsten Hopp 5f67cf
  		break;
Karsten Hopp 5f67cf
  	    default:
Karsten Hopp 5f67cf
  		/* field not supported, skip */
Karsten Hopp 5f67cf
  		while (--len >= 0)
Karsten Hopp 5f67cf
! 		    (void)undo_read_byte(&bi);
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1758,1764 ****
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     while ((c = get2c(fp)) == UF_HEADER_MAGIC)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	if (num_read_uhps >= num_head)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
--- 2035,2041 ----
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
      }
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
!     while ((c = undo_read_2c(&bi)) == UF_HEADER_MAGIC)
Karsten Hopp 5f67cf
      {
Karsten Hopp 5f67cf
  	if (num_read_uhps >= num_head)
Karsten Hopp 5f67cf
  	{
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1766,1772 ****
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	uhp = unserialize_uhp(fp, file_name);
Karsten Hopp 5f67cf
  	if (uhp == NULL)
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	uhp_table[num_read_uhps++] = uhp;
Karsten Hopp 5f67cf
--- 2043,2049 ----
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	}
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
! 	uhp = unserialize_uhp(&bi, file_name);
Karsten Hopp 5f67cf
  	if (uhp == NULL)
Karsten Hopp 5f67cf
  	    goto error;
Karsten Hopp 5f67cf
  	uhp_table[num_read_uhps++] = uhp;
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 1898,1905 ****
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  theend:
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (do_decrypt)
Karsten Hopp 5f67cf
! 	crypt_pop_state();
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      if (fp != NULL)
Karsten Hopp 5f67cf
  	fclose(fp);
Karsten Hopp 5f67cf
--- 2175,2183 ----
Karsten Hopp 5f67cf
  
Karsten Hopp 5f67cf
  theend:
Karsten Hopp 5f67cf
  #ifdef FEAT_CRYPT
Karsten Hopp 5f67cf
!     if (bi.bi_state != NULL)
Karsten Hopp 5f67cf
! 	crypt_free_state(bi.bi_state);
Karsten Hopp 5f67cf
!     vim_free(bi.bi_buffer);
Karsten Hopp 5f67cf
  #endif
Karsten Hopp 5f67cf
      if (fp != NULL)
Karsten Hopp 5f67cf
  	fclose(fp);
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/testdir/test71.in	2013-07-01 20:47:58.000000000 +0200
Karsten Hopp 5f67cf
--- src/testdir/test71.in	2014-08-09 15:12:57.997364196 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 13,18 ****
Karsten Hopp 5f67cf
--- 13,20 ----
Karsten Hopp 5f67cf
  :let cm0_bytes = getline('.', '.')
Karsten Hopp 5f67cf
  :/^start of cm=blowfish bytes/+1
Karsten Hopp 5f67cf
  :let cm1_bytes = getline('.', '.')
Karsten Hopp 5f67cf
+ :/^start of cm=blowfish2 bytes/+1
Karsten Hopp 5f67cf
+ :let cm2_bytes = getline('.', '.')
Karsten Hopp 5f67cf
  :bwipe!
Karsten Hopp 5f67cf
  :call append(0, text_lines)
Karsten Hopp 5f67cf
  :$d
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 36,41 ****
Karsten Hopp 5f67cf
--- 38,55 ----
Karsten Hopp 5f67cf
  :e Xtestfile
Karsten Hopp 5f67cf
  barfoo
Karsten Hopp 5f67cf
  :let cm1_read_back = getline('.', '$')
Karsten Hopp 5f67cf
+ :set key=
Karsten Hopp 5f67cf
+ :set cryptmethod=blowfish2
Karsten Hopp 5f67cf
+ :" If the blowfish test fails 'cryptmethod' will be 'zip' now.
Karsten Hopp 5f67cf
+ :%s/^/\=&cryptmethod == 'blowfish2' ? "OK " : "blowfish test failed "/
Karsten Hopp 5f67cf
+ :X
Karsten Hopp 5f67cf
+ bar2foo
Karsten Hopp 5f67cf
+ bar2foo
Karsten Hopp 5f67cf
+ :w! Xtestfile
Karsten Hopp 5f67cf
+ :bwipe!
Karsten Hopp 5f67cf
+ :e Xtestfile
Karsten Hopp 5f67cf
+ bar2foo
Karsten Hopp 5f67cf
+ :let cm2_read_back = getline('.', '$')
Karsten Hopp 5f67cf
  :bwipe!
Karsten Hopp 5f67cf
  :set bin noeol key=
Karsten Hopp 5f67cf
  :call append(0, cm0_bytes)
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 57,63 ****
Karsten Hopp 5f67cf
--- 71,90 ----
Karsten Hopp 5f67cf
  :set nobin
Karsten Hopp 5f67cf
  :e Xtestfile
Karsten Hopp 5f67cf
  barbar
Karsten Hopp 5f67cf
+ :let cm1_read_bin = getline('.', '$')
Karsten Hopp 5f67cf
+ :bwipe!
Karsten Hopp 5f67cf
+ :set bin noeol key=
Karsten Hopp 5f67cf
+ :call append(0, cm2_bytes)
Karsten Hopp 5f67cf
+ :$d
Karsten Hopp 5f67cf
+ :set fenc=latin1
Karsten Hopp 5f67cf
+ :w! Xtestfile
Karsten Hopp 5f67cf
+ :bwipe!
Karsten Hopp 5f67cf
+ :set nobin
Karsten Hopp 5f67cf
+ :e Xtestfile
Karsten Hopp 5f67cf
+ barburp
Karsten Hopp 5f67cf
+ :call append(0, cm1_read_bin)
Karsten Hopp 5f67cf
  :call append(0, cm0_read_bin)
Karsten Hopp 5f67cf
+ :call append(0, cm2_read_back)
Karsten Hopp 5f67cf
  :call append(0, cm1_read_back)
Karsten Hopp 5f67cf
  :call append(0, cm0_read_back)
Karsten Hopp 5f67cf
  :set key= fenc=latin1
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/testdir/test72.in	2014-03-12 16:51:35.060792541 +0100
Karsten Hopp 5f67cf
--- src/testdir/test72.in	2014-08-09 15:12:58.001364196 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 81,86 ****
Karsten Hopp 5f67cf
--- 81,87 ----
Karsten Hopp 5f67cf
  :"
Karsten Hopp 5f67cf
  :" With encryption, cryptmethod=blowfish
Karsten Hopp 5f67cf
  :e! Xtestfile
Karsten Hopp 5f67cf
+ rubbish
Karsten Hopp 5f67cf
  :set undofile cm=blowfish
Karsten Hopp 5f67cf
  ggdGijan
Karsten Hopp 5f67cf
  feb
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 100,105 ****
Karsten Hopp 5f67cf
--- 101,132 ----
Karsten Hopp 5f67cf
  :set key=
Karsten Hopp 5f67cf
  /bar
Karsten Hopp 5f67cf
  :.w >>test.out
Karsten Hopp 5f67cf
+ u:.w >>test.out
Karsten Hopp 5f67cf
+ u:.w >>test.out
Karsten Hopp 5f67cf
+ u:.w >>test.out
Karsten Hopp 5f67cf
+ :"
Karsten Hopp 5f67cf
+ :" With encryption, cryptmethod=blowfish2
Karsten Hopp 5f67cf
+ :e! Xtestfile
Karsten Hopp 5f67cf
+ rubbish
Karsten Hopp 5f67cf
+ :set undofile cm=blowfish2
Karsten Hopp 5f67cf
+ ggdGijan
Karsten Hopp 5f67cf
+ feb
Karsten Hopp 5f67cf
+ mar
Karsten Hopp 5f67cf
+ apr
Karsten Hopp 5f67cf
+ jun?:set ul=100
Karsten Hopp 5f67cf
+ kk0ifoo ?:set ul=100
Karsten Hopp 5f67cf
+ dd:set ul=100
Karsten Hopp 5f67cf
+ ibar ?:set ul=100
Karsten Hopp 5f67cf
+ :X
Karsten Hopp 5f67cf
+ foo2bar
Karsten Hopp 5f67cf
+ foo2bar
Karsten Hopp 5f67cf
+ :w!
Karsten Hopp 5f67cf
+ :bwipe!
Karsten Hopp 5f67cf
+ :e Xtestfile
Karsten Hopp 5f67cf
+ foo2bar
Karsten Hopp 5f67cf
+ :set key=
Karsten Hopp 5f67cf
+ /bar
Karsten Hopp 5f67cf
+ :.w >>test.out
Karsten Hopp 5f67cf
  u:.w >>test.out
Karsten Hopp 5f67cf
  u:.w >>test.out
Karsten Hopp 5f67cf
  u:.w >>test.out
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/testdir/test72.ok	2012-01-04 19:04:17.000000000 +0100
Karsten Hopp 5f67cf
--- src/testdir/test72.ok	2014-08-09 15:12:58.001364196 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 25,27 ****
Karsten Hopp 5f67cf
--- 25,31 ----
Karsten Hopp 5f67cf
  apr
Karsten Hopp 5f67cf
  foo mar
Karsten Hopp 5f67cf
  mar
Karsten Hopp 5f67cf
+ bar apr
Karsten Hopp 5f67cf
+ apr
Karsten Hopp 5f67cf
+ foo mar
Karsten Hopp 5f67cf
+ mar
Karsten Hopp 2ac034
diff -up src/testdir/test71.ok.kh src/testdir/test71.ok
Karsten Hopp 2ac034
--- src/testdir/test71.ok.kh	2014-08-12 14:21:33.301002125 +0200
Karsten Hopp 2ac034
+++ src/testdir/test71.ok	2014-08-12 14:21:06.140002788 +0200
Karsten Hopp 2ac034
@@ -4,7 +4,12 @@ line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Karsten Hopp 2ac034
 OK 01234567890123456789012345678901234567
Karsten Hopp 2ac034
 OK line 2  foo bar blah
Karsten Hopp 2ac034
 OK line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Karsten Hopp 2ac034
+OK OK 01234567890123456789012345678901234567
Karsten Hopp 2ac034
+OK OK line 2  foo bar blah
Karsten Hopp 2ac034
+OK OK line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Karsten Hopp 2ac034
 1234567890
Karsten Hopp 2ac034
 aábbccddeëff
Karsten Hopp 2ac034
 asdfasdfasdf
Karsten Hopp 2ac034
 0001112223333
Karsten Hopp 2ac034
+abcdefghijklmnopqrstuvwxyz
Karsten Hopp 2ac034
+!@#$%^&*()_+=-`~
Karsten Hopp 2ac034
diff -up src/testdir/test71a.in.kh src/testdir/test71a.in
Karsten Hopp 2ac034
--- src/testdir/test71a.in.kh	2014-08-12 14:27:34.429993316 +0200
Karsten Hopp 2ac034
+++ src/testdir/test71a.in	2014-08-12 14:26:40.114994641 +0200
Karsten Hopp 2ac034
@@ -12,3 +12,7 @@ end of cm=zip bytes
Karsten Hopp 2ac034
 start of cm=blowfish bytes
Karsten Hopp 2ac034
 VimCrypt~02!k)¾?—#?İSœõ=ºàÈ#¥M´†JÃAÍ¥M´†!€?›õ?áÒ?‚?˜÷
Ú
Karsten Hopp 2ac034
 end of cm=blowfish bytes
Karsten Hopp 2ac034
+
Karsten Hopp 2ac034
+start of cm=blowfish2 bytes
Karsten Hopp 2ac034
+VimCrypt~03!?ÑNã;ÓÀ ^C)?÷.¶«F?S?à‹6Ò[T˧…ؾ9?2?Q³Ì@—?ߚ­Ivª.ØÉîž`½$¯%Ð
Karsten Hopp 2ac034
+end of cm=blowfish2 bytes
Karsten Hopp 5f67cf
*** ../vim-7.4.398/src/version.c	2014-08-07 13:55:05.898639758 +0200
Karsten Hopp 5f67cf
--- src/version.c	2014-08-09 15:11:28.665364838 +0200
Karsten Hopp 5f67cf
***************
Karsten Hopp 5f67cf
*** 743,744 ****
Karsten Hopp 5f67cf
--- 743,746 ----
Karsten Hopp 5f67cf
  {   /* Add new patch number below this line */
Karsten Hopp 5f67cf
+ /**/
Karsten Hopp 5f67cf
+     399,
Karsten Hopp 5f67cf
  /**/
Karsten Hopp 5f67cf
Karsten Hopp 5f67cf
-- 
Karsten Hopp 5f67cf
hundred-and-one symptoms of being an internet addict:
Karsten Hopp 5f67cf
16. You step out of your room and realize that your parents have moved and
Karsten Hopp 5f67cf
    you don't have a clue when it happened.
Karsten Hopp 5f67cf
Karsten Hopp 5f67cf
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 5f67cf
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 5f67cf
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 5f67cf
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///