Blame SOURCES/vim-7.4-blowfish2.patch

dea496
diff -up vim74/runtime/doc/editing.txt.blowfish2 vim74/runtime/doc/editing.txt
dea496
--- vim74/runtime/doc/editing.txt.blowfish2	2013-08-10 13:24:53.000000000 +0200
dea496
+++ vim74/runtime/doc/editing.txt	2017-09-05 14:47:34.915912305 +0200
dea496
@@ -1364,8 +1364,13 @@ The text in the swap file and the undo f
dea496
 
dea496
 Note: The text in memory is not encrypted.  A system administrator may be able
dea496
 to see your text while you are editing it.  When filtering text with
dea496
-":!filter" or using ":w !command" the text is not encrypted, this may reveal
dea496
-it to others.  The 'viminfo' file is not encrypted.
dea496
+":!filter" or using ":w !command" the text is also not encrypted, this may
dea496
+reveal it to others.  The 'viminfo' file is not encrypted.
dea496
+
dea496
+You could do this to edit very secret text: >
dea496
+       :set noundofile viminfo=
dea496
+       :noswapfile edit secrets.txt
dea496
+Keep in mind that without a swap file you risk loosing your work in a crash.
dea496
 
dea496
 WARNING: If you make a typo when entering the key and then write the file and
dea496
 exit, the text will be lost!
dea496
@@ -1392,18 +1397,24 @@ To disable the encryption, reset the 'ke
dea496
 	:set key=
dea496
 
dea496
 You can use the 'cryptmethod' option to select the type of encryption, use one
dea496
-of these two: >
dea496
-	:setlocal cm=zip       " weak method, backwards compatible
dea496
-	:setlocal cm=blowfish  " strong method
dea496
+of these: >
dea496
+       :setlocal cm=zip        " weak method, backwards compatible
dea496
+       :setlocal cm=blowfish   " method with flaws
dea496
+       :setlocal cm=blowfish2  " medium strong method
dea496
+
dea496
 Do this before writing the file.  When reading an encrypted file it will be
dea496
 set automatically to the method used when that file was written.  You can
dea496
 change 'cryptmethod' before writing that file to change the method.
dea496
 To set the default method, used for new files, use one of these in your
dea496
 |vimrc| file: >
dea496
 	set cm=zip
dea496
-	set cm=blowfish
dea496
+        set cm=blowfish2
dea496
+Use the first one if you need to be compatible with Vim 7.2 and older.  Using
dea496
+"blowfish2" is highly recommended if you can use a Vim version that supports
dea496
+it.
dea496
+
dea496
 The message given for reading and writing a file will show "[crypted]" when
dea496
-using zip, "[blowfish]" when using blowfish.
dea496
+using zip, "[blowfish]" when using blowfish, etc.
dea496
 
dea496
 When writing an undo file, the same key and method will be used for the text
dea496
 in the undo file. |persistent-undo|.
dea496
@@ -1438,7 +1449,7 @@ lines to "/etc/magic", "/usr/share/misc/
dea496
      0	string	VimCrypt~	Vim encrypted file
dea496
      >9	string	01	- "zip" cryptmethod
dea496
      >9	string	02	- "blowfish" cryptmethod
dea496
-
dea496
+     >9        string  03      - "blowfish2" cryptmethod
dea496
 
dea496
 Notes:
dea496
 - Encryption is not possible when doing conversion with 'charconvert'.
dea496
@@ -1462,6 +1473,10 @@ Notes:
dea496
 - Pkzip uses the same encryption as 'cryptmethod' "zip", and US Govt has no
dea496
   objection to its export.  Pkzip's public file APPNOTE.TXT describes this
dea496
   algorithm in detail.
dea496
+- The implementation of 'cryptmethod' "blowfish" has a flaw.  It is possible to
dea496
+  crack the first 64 bytes of a file and in some circumstances more of the
dea496
+  file. Use of it is not recommended, but it's still the strongest method
dea496
+  supported by Vim 7.3 and 7.4.  The "zip" method is even weaker.
dea496
 - Vim originates from the Netherlands.  That is where the sources come from.
dea496
   Thus the encryption code is not exported from the USA.
dea496
 
dea496
diff -up vim74/runtime/doc/options.txt.blowfish2 vim74/runtime/doc/options.txt
dea496
--- vim74/runtime/doc/options.txt.blowfish2	2017-09-05 14:47:33.976919884 +0200
dea496
+++ vim74/runtime/doc/options.txt	2017-09-05 14:47:34.925912224 +0200
dea496
@@ -2197,10 +2197,18 @@ A jump table for the options with a shor
dea496
 	   zip		PkZip compatible method.  A weak kind of encryption.
dea496
 			Backwards compatible with Vim 7.2 and older.
dea496
 							*blowfish*
dea496
-	   blowfish	Blowfish method.  Strong encryption.  Requires Vim 7.3
dea496
-			or later, files can NOT be read by Vim 7.2 and older.
dea496
-			This adds a "seed" to the file, every time you write
dea496
-			the file the encrypted bytes will be different.
dea496
+          blowfish     Blowfish method.  Medium strong encryption but it has
dea496
+                       an implementation flaw.  Requires Vim 7.3 or later,
dea496
+                       files can NOT be read by Vim 7.2 and older.  This adds
dea496
+                       a "seed" to the file, every time you write the file
dea496
+                       the encrypted bytes will be different.
dea496
+                                                       *blowfish2*
dea496
+          blowfish2    Blowfish method.  Medium strong encryption.  Requires
dea496
+                       Vim 7.4.399 or later, files can NOT be read by Vim 7.3
dea496
+                       and older.  This adds a "seed" to the file, every time
dea496
+                       you write the file the encrypted bytes will be
dea496
+                       different.  The whole undo file is encrypted, not just
dea496
+                       the pieces of text.
dea496
 
dea496
 	When reading an encrypted file 'cryptmethod' will be set automatically
dea496
 	to the detected method of the file being read.  Thus if you write it
dea496
diff -up vim74/src/blowfish.c.blowfish2 vim74/src/blowfish.c
dea496
--- vim74/src/blowfish.c.blowfish2	2010-12-17 19:58:18.000000000 +0100
dea496
+++ vim74/src/blowfish.c	2017-09-05 14:47:34.926912216 +0200
dea496
@@ -9,17 +9,25 @@
dea496
  * Blowfish encryption for Vim; in Blowfish output feedback mode.
dea496
  * Contributed by Mohsin Ahmed, http://www.cs.albany.edu/~mosh
dea496
  * Based on http://www.schneier.com/blowfish.html by Bruce Schneier.
dea496
+ *
dea496
+ * There are two variants:
dea496
+ * - The old one "blowfish" has a flaw which makes it much easier to crack the
dea496
+ *   key.  To see this, make a text file with one line of 1000 "x" characters
dea496
+ *   and write it encrypted.  Use "xxd" to inspect the bytes in the file.  You
dea496
+ *   will see that a block of 8 bytes repeats 8 times.
dea496
+ * - The new one "blowfish2" is better.  It uses an 8 byte CFB to avoid the
dea496
+ *   repeats.
dea496
  */
dea496
 
dea496
 #include "vim.h"
dea496
 
dea496
-#if defined(FEAT_CRYPT)
dea496
+#if defined(FEAT_CRYPT) || defined(PROTO)
dea496
 
dea496
 #define ARRAY_LENGTH(A)      (sizeof(A)/sizeof(A[0]))
dea496
 
dea496
 #define BF_BLOCK    8
dea496
 #define BF_BLOCK_MASK 7
dea496
-#define BF_OFB_LEN  (8*(BF_BLOCK))
dea496
+#define BF_MAX_CFB_LEN  (8 * BF_BLOCK)
dea496
 
dea496
 typedef union {
dea496
     UINT32_T ul[2];
dea496
@@ -37,14 +45,26 @@ typedef union {
dea496
 # endif
dea496
 #endif
dea496
 
dea496
-static void bf_e_block __ARGS((UINT32_T *p_xl, UINT32_T *p_xr));
dea496
-static void bf_e_cblock __ARGS((char_u *block));
dea496
-static int bf_check_tables __ARGS((UINT32_T a_ipa[18], UINT32_T a_sbi[4][256], UINT32_T val));
dea496
+/* The state of encryption, referenced by cryptstate_T. */
dea496
+typedef struct {
dea496
+    UINT32_T	pax[18];	    /* P-array */
dea496
+    UINT32_T	sbx[4][256];	    /* S-boxes */
dea496
+    int		randbyte_offset;
dea496
+    int		update_offset;
dea496
+    char_u	cfb_buffer[BF_MAX_CFB_LEN]; /* up to 64 bytes used */
dea496
+    int		cfb_len;	    /* size of cfb_buffer actually used */
dea496
+} bf_state_T;
dea496
+
dea496
+
dea496
+static void bf_e_block __ARGS((bf_state_T *state, UINT32_T *p_xl, UINT32_T *p_xr));
dea496
+static void bf_e_cblock __ARGS((bf_state_T *state, char_u *block));
dea496
+static int bf_check_tables __ARGS((UINT32_T pax[18], UINT32_T sbx[4][256], UINT32_T val));
dea496
 static int bf_self_test __ARGS((void));
dea496
+static void bf_key_init __ARGS((bf_state_T *state, char_u *password, char_u *salt, int salt_len));
dea496
+static void bf_cfb_init __ARGS((bf_state_T *state, char_u *seed, int seed_len));
dea496
 
dea496
 /* Blowfish code */
dea496
-static UINT32_T pax[18];
dea496
-static UINT32_T ipa[18] = {
dea496
+static UINT32_T pax_init[18] = {
dea496
     0x243f6a88u, 0x85a308d3u, 0x13198a2eu,
dea496
     0x03707344u, 0xa4093822u, 0x299f31d0u,
dea496
     0x082efa98u, 0xec4e6c89u, 0x452821e6u,
dea496
@@ -53,8 +73,7 @@ static UINT32_T ipa[18] = {
dea496
     0xb5470917u, 0x9216d5d9u, 0x8979fb1bu
dea496
 };
dea496
 
dea496
-static UINT32_T sbx[4][256];
dea496
-static UINT32_T sbi[4][256] = {
dea496
+static UINT32_T sbx_init[4][256] = {
dea496
    {0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u,
dea496
     0xb8e1afedu, 0x6a267e96u, 0xba7c9045u, 0xf12c7f99u,
dea496
     0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u,
dea496
@@ -314,33 +333,40 @@ static UINT32_T sbi[4][256] = {
dea496
  }
dea496
 };
dea496
 
dea496
-
dea496
 #define F1(i) \
dea496
-    xl ^= pax[i]; \
dea496
-    xr ^= ((sbx[0][xl >> 24] + \
dea496
-    sbx[1][(xl & 0xFF0000) >> 16]) ^ \
dea496
-    sbx[2][(xl & 0xFF00) >> 8]) + \
dea496
-    sbx[3][xl & 0xFF];
dea496
+    xl ^= bfs->pax[i]; \
dea496
+    xr ^= ((bfs->sbx[0][xl >> 24] + \
dea496
+    bfs->sbx[1][(xl & 0xFF0000) >> 16]) ^ \
dea496
+    bfs->sbx[2][(xl & 0xFF00) >> 8]) + \
dea496
+    bfs->sbx[3][xl & 0xFF];
dea496
 
dea496
 #define F2(i) \
dea496
-    xr ^= pax[i]; \
dea496
-    xl ^= ((sbx[0][xr >> 24] + \
dea496
-    sbx[1][(xr & 0xFF0000) >> 16]) ^ \
dea496
-    sbx[2][(xr & 0xFF00) >> 8]) + \
dea496
-    sbx[3][xr & 0xFF];
dea496
-
dea496
+    xr ^= bfs->pax[i]; \
dea496
+    xl ^= ((bfs->sbx[0][xr >> 24] + \
dea496
+    bfs->sbx[1][(xr & 0xFF0000) >> 16]) ^ \
dea496
+    bfs->sbx[2][(xr & 0xFF00) >> 8]) + \
dea496
+    bfs->sbx[3][xr & 0xFF];
dea496
 
dea496
     static void
dea496
-bf_e_block(p_xl, p_xr)
dea496
+bf_e_block(bfs, p_xl, p_xr)
dea496
+    bf_state_T *bfs;
dea496
     UINT32_T *p_xl;
dea496
     UINT32_T *p_xr;
dea496
 {
dea496
-    UINT32_T temp, xl = *p_xl, xr = *p_xr;
dea496
-
dea496
-    F1(0) F2(1) F1(2) F2(3) F1(4) F2(5) F1(6) F2(7)
dea496
-    F1(8) F2(9) F1(10) F2(11) F1(12) F2(13) F1(14) F2(15)
dea496
-    xl ^= pax[16];
dea496
-    xr ^= pax[17];
dea496
+    UINT32_T temp;
dea496
+    UINT32_T xl = *p_xl;
dea496
+    UINT32_T xr = *p_xr;
dea496
+
dea496
+    F1(0) F2(1)
dea496
+    F1(2) F2(3)
dea496
+    F1(4) F2(5)
dea496
+    F1(6) F2(7)
dea496
+    F1(8) F2(9)
dea496
+    F1(10) F2(11)
dea496
+    F1(12) F2(13)
dea496
+    F1(14) F2(15)
dea496
+    xl ^= bfs->pax[16];
dea496
+    xr ^= bfs->pax[17];
dea496
     temp = xl;
dea496
     xl = xr;
dea496
     xr = temp;
dea496
@@ -348,23 +374,6 @@ bf_e_block(p_xl, p_xr)
dea496
     *p_xr = xr;
dea496
 }
dea496
 
dea496
-#if 0  /* not used */
dea496
-    static void
dea496
-bf_d_block(p_xl, p_xr)
dea496
-    UINT32_T *p_xl;
dea496
-    UINT32_T *p_xr;
dea496
-{
dea496
-    UINT32_T temp, xl = *p_xl, xr = *p_xr;
dea496
-    F1(17) F2(16) F1(15) F2(14) F1(13) F2(12) F1(11) F2(10)
dea496
-    F1(9) F2(8) F1(7) F2(6) F1(5) F2(4) F1(3) F2(2)
dea496
-    xl ^= pax[1];
dea496
-    xr ^= pax[0];
dea496
-    temp = xl; xl = xr; xr = temp;
dea496
-    *p_xl = xl; *p_xr = xr;
dea496
-}
dea496
-#endif
dea496
-
dea496
-
dea496
 #ifdef WORDS_BIGENDIAN
dea496
 # define htonl2(x) \
dea496
     x = ((((x) &     0xffL) << 24) | (((x) & 0xff00L)     <<  8) | \
dea496
@@ -374,7 +383,8 @@ bf_d_block(p_xl, p_xr)
dea496
 #endif
dea496
 
dea496
     static void
dea496
-bf_e_cblock(block)
dea496
+bf_e_cblock(bfs, block)
dea496
+    bf_state_T *bfs;
dea496
     char_u *block;
dea496
 {
dea496
     block8	bk;
dea496
@@ -382,35 +392,22 @@ bf_e_cblock(block)
dea496
     memcpy(bk.uc, block, 8);
dea496
     htonl2(bk.ul[0]);
dea496
     htonl2(bk.ul[1]);
dea496
-    bf_e_block(&bk.ul[0], &bk.ul[1]);
dea496
+    bf_e_block(bfs, &bk.ul[0], &bk.ul[1]);
dea496
     htonl2(bk.ul[0]);
dea496
     htonl2(bk.ul[1]);
dea496
     memcpy(block, bk.uc, 8);
dea496
 }
dea496
 
dea496
-#if 0  /* not used */
dea496
-    void
dea496
-bf_d_cblock(block)
dea496
-    char_u *block;
dea496
-{
dea496
-    block8 bk;
dea496
-    memcpy(bk.uc, block, 8);
dea496
-    htonl2(bk.ul[0]); htonl2(bk.ul[1]);
dea496
-    bf_d_block(&bk.ul[0], &bk.ul[1]);
dea496
-    htonl2(bk.ul[0]); htonl2(bk.ul[1]);
dea496
-    memcpy(block, bk.uc, 8);
dea496
-}
dea496
-#endif
dea496
-
dea496
 /*
dea496
  * Initialize the crypt method using "password" as the encryption key and
dea496
  * "salt[salt_len]" as the salt.
dea496
  */
dea496
-    void
dea496
-bf_key_init(password, salt, salt_len)
dea496
-    char_u *password;
dea496
-    char_u *salt;
dea496
-    int    salt_len;
dea496
+    static void
dea496
+bf_key_init(bfs, password, salt, salt_len)
dea496
+    bf_state_T	*bfs;
dea496
+    char_u	*password;
dea496
+    char_u	*salt;
dea496
+    int		salt_len;
dea496
 {
dea496
     int      i, j, keypos = 0;
dea496
     unsigned u;
dea496
@@ -418,7 +415,7 @@ bf_key_init(password, salt, salt_len)
dea496
     char_u   *key;
dea496
     int      keylen;
dea496
 
dea496
-    /* Process the key 1000 times.
dea496
+    /* Process the key 1001 times.
dea496
      * See http://en.wikipedia.org/wiki/Key_strengthening. */
dea496
     key = sha256_key(password, salt, salt_len);
dea496
     for (i = 0; i < 1000; i++)
dea496
@@ -437,52 +434,54 @@ bf_key_init(password, salt, salt_len)
dea496
 	key[i] = u;
dea496
     }
dea496
 
dea496
-    mch_memmove(sbx, sbi, 4 * 4 * 256);
dea496
+    /* Use "key" to initialize the P-array ("pax") and S-boxes ("sbx") of
dea496
+     * Blowfish. */
dea496
+    mch_memmove(bfs->sbx, sbx_init, 4 * 4 * 256);
dea496
 
dea496
     for (i = 0; i < 18; ++i)
dea496
     {
dea496
 	val = 0;
dea496
 	for (j = 0; j < 4; ++j)
dea496
 	    val = (val << 8) | key[keypos++ % keylen];
dea496
-	pax[i] = ipa[i] ^ val;
dea496
+	bfs->pax[i] = pax_init[i] ^ val;
dea496
     }
dea496
 
dea496
     data_l = data_r = 0;
dea496
     for (i = 0; i < 18; i += 2)
dea496
     {
dea496
-	bf_e_block(&data_l, &data_r);
dea496
-	pax[i + 0] = data_l;
dea496
-	pax[i + 1] = data_r;
dea496
+	bf_e_block(bfs, &data_l, &data_r);
dea496
+	bfs->pax[i + 0] = data_l;
dea496
+	bfs->pax[i + 1] = data_r;
dea496
     }
dea496
 
dea496
     for (i = 0; i < 4; ++i)
dea496
     {
dea496
 	for (j = 0; j < 256; j += 2)
dea496
 	{
dea496
-	    bf_e_block(&data_l, &data_r);
dea496
-	    sbx[i][j + 0] = data_l;
dea496
-	    sbx[i][j + 1] = data_r;
dea496
+	    bf_e_block(bfs, &data_l, &data_r);
dea496
+	    bfs->sbx[i][j + 0] = data_l;
dea496
+	    bfs->sbx[i][j + 1] = data_r;
dea496
 	}
dea496
     }
dea496
 }
dea496
 
dea496
 /*
dea496
- * BF Self test for corrupted tables or instructions
dea496
+ * Blowfish self-test for corrupted tables or instructions.
dea496
  */
dea496
     static int
dea496
-bf_check_tables(a_ipa, a_sbi, val)
dea496
-    UINT32_T a_ipa[18];
dea496
-    UINT32_T a_sbi[4][256];
dea496
+bf_check_tables(pax, sbx, val)
dea496
+    UINT32_T pax[18];
dea496
+    UINT32_T sbx[4][256];
dea496
     UINT32_T val;
dea496
 {
dea496
     int i, j;
dea496
     UINT32_T c = 0;
dea496
 
dea496
     for (i = 0; i < 18; i++)
dea496
-	c ^= a_ipa[i];
dea496
+	c ^= pax[i];
dea496
     for (i = 0; i < 4; i++)
dea496
 	for (j = 0; j < 256; j++)
dea496
-	    c ^= a_sbi[i][j];
dea496
+	    c ^= sbx[i][j];
dea496
     return c == val;
dea496
 }
dea496
 
dea496
@@ -520,6 +519,10 @@ bf_self_test()
dea496
     int    err = 0;
dea496
     block8 bk;
dea496
     UINT32_T ui = 0xffffffffUL;
dea496
+    bf_state_T state;
dea496
+
dea496
+    vim_memset(&state, 0, sizeof(bf_state_T));
dea496
+    state.cfb_len = BF_MAX_CFB_LEN;
dea496
 
dea496
     /* We can't simply use sizeof(UINT32_T), it would generate a compiler
dea496
      * warning. */
dea496
@@ -528,21 +531,21 @@ bf_self_test()
dea496
 	EMSG(_("E820: sizeof(uint32_t) != 4"));
dea496
     }
dea496
 
dea496
-    if (!bf_check_tables(ipa, sbi, 0x6ffa520a))
dea496
+    if (!bf_check_tables(pax_init, sbx_init, 0x6ffa520a))
dea496
 	err++;
dea496
 
dea496
     bn = ARRAY_LENGTH(bf_test_data);
dea496
     for (i = 0; i < bn; i++)
dea496
     {
dea496
-	bf_key_init((char_u *)(bf_test_data[i].password),
dea496
+	bf_key_init(&state, (char_u *)(bf_test_data[i].password),
dea496
 		    bf_test_data[i].salt,
dea496
 		    (int)STRLEN(bf_test_data[i].salt));
dea496
-	if (!bf_check_tables(pax, sbx, bf_test_data[i].keysum))
dea496
+	if (!bf_check_tables(state.pax, state.sbx, bf_test_data[i].keysum))
dea496
 	    err++;
dea496
 
dea496
 	/* Don't modify bf_test_data[i].plaintxt, self test is idempotent. */
dea496
 	memcpy(bk.uc, bf_test_data[i].plaintxt, 8);
dea496
-	bf_e_cblock(bk.uc);
dea496
+	bf_e_cblock(&state, bk.uc);
dea496
 	if (memcmp(bk.uc, bf_test_data[i].cryptxt, 8) != 0)
dea496
 	{
dea496
 	    if (err == 0 && memcmp(bk.uc, bf_test_data[i].badcryptxt, 8) == 0)
dea496
@@ -554,43 +557,43 @@ bf_self_test()
dea496
     return err > 0 ? FAIL : OK;
dea496
 }
dea496
 
dea496
-/* Output feedback mode. */
dea496
-static int randbyte_offset = 0;
dea496
-static int update_offset = 0;
dea496
-static char_u ofb_buffer[BF_OFB_LEN]; /* 64 bytes */
dea496
+/*
dea496
+ * CFB: Cipher Feedback Mode.
dea496
+ */
dea496
 
dea496
 /*
dea496
- * Initialize with seed "iv[iv_len]".
dea496
+ * Initialize with seed "seed[seed_len]".
dea496
  */
dea496
-    void
dea496
-bf_ofb_init(iv, iv_len)
dea496
-    char_u *iv;
dea496
-    int    iv_len;
dea496
+    static void
dea496
+bf_cfb_init(bfs, seed, seed_len)
dea496
+    bf_state_T	*bfs;
dea496
+    char_u	*seed;
dea496
+    int		seed_len;
dea496
 {
dea496
     int i, mi;
dea496
 
dea496
-    randbyte_offset = update_offset = 0;
dea496
-    vim_memset(ofb_buffer, 0, BF_OFB_LEN);
dea496
-    if (iv_len > 0)
dea496
+    bfs->randbyte_offset = bfs->update_offset = 0;
dea496
+    vim_memset(bfs->cfb_buffer, 0, bfs->cfb_len);
dea496
+    if (seed_len > 0)
dea496
     {
dea496
-	mi = iv_len > BF_OFB_LEN ? iv_len : BF_OFB_LEN;
dea496
+	mi = seed_len > bfs->cfb_len ? seed_len : bfs->cfb_len;
dea496
 	for (i = 0; i < mi; i++)
dea496
-	    ofb_buffer[i % BF_OFB_LEN] ^= iv[i % iv_len];
dea496
+	    bfs->cfb_buffer[i % bfs->cfb_len] ^= seed[i % seed_len];
dea496
     }
dea496
 }
dea496
 
dea496
-#define BF_OFB_UPDATE(c) { \
dea496
-    ofb_buffer[update_offset] ^= (char_u)c; \
dea496
-    if (++update_offset == BF_OFB_LEN) \
dea496
-	update_offset = 0; \
dea496
+#define BF_CFB_UPDATE(bfs, c) { \
dea496
+    bfs->cfb_buffer[bfs->update_offset] ^= (char_u)c; \
dea496
+    if (++bfs->update_offset == bfs->cfb_len) \
dea496
+	bfs->update_offset = 0; \
dea496
 }
dea496
 
dea496
-#define BF_RANBYTE(t) { \
dea496
-    if ((randbyte_offset & BF_BLOCK_MASK) == 0) \
dea496
-	bf_e_cblock(&ofb_buffer[randbyte_offset]); \
dea496
-    t = ofb_buffer[randbyte_offset]; \
dea496
-    if (++randbyte_offset == BF_OFB_LEN) \
dea496
-	randbyte_offset = 0; \
dea496
+#define BF_RANBYTE(bfs, t) { \
dea496
+    if ((bfs->randbyte_offset & BF_BLOCK_MASK) == 0) \
dea496
+	bf_e_cblock(bfs, &(bfs->cfb_buffer[bfs->randbyte_offset])); \
dea496
+    t = bfs->cfb_buffer[bfs->randbyte_offset]; \
dea496
+    if (++bfs->randbyte_offset == bfs->cfb_len) \
dea496
+	bfs->randbyte_offset = 0; \
dea496
 }
dea496
 
dea496
 /*
dea496
@@ -598,90 +601,69 @@ bf_ofb_init(iv, iv_len)
dea496
  * "from" and "to" can be equal to encrypt in place.
dea496
  */
dea496
     void
dea496
-bf_crypt_encode(from, len, to)
dea496
+crypt_blowfish_encode(state, from, len, to)
dea496
+    cryptstate_T *state;
dea496
     char_u	*from;
dea496
     size_t	len;
dea496
     char_u	*to;
dea496
 {
dea496
+    bf_state_T *bfs = state->method_state;
dea496
     size_t	i;
dea496
     int		ztemp, t;
dea496
 
dea496
     for (i = 0; i < len; ++i)
dea496
     {
dea496
 	ztemp = from[i];
dea496
-	BF_RANBYTE(t);
dea496
-	BF_OFB_UPDATE(ztemp);
dea496
+	BF_RANBYTE(bfs, t);
dea496
+	BF_CFB_UPDATE(bfs, ztemp);
dea496
 	to[i] = t ^ ztemp;
dea496
     }
dea496
 }
dea496
 
dea496
 /*
dea496
- * Decrypt "ptr[len]" in place.
dea496
+ * Decrypt "from[len]" into "to[len]".
dea496
  */
dea496
     void
dea496
-bf_crypt_decode(ptr, len)
dea496
-    char_u	*ptr;
dea496
-    long	len;
dea496
+crypt_blowfish_decode(state, from, len, to)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*from;
dea496
+    size_t	len;
dea496
+    char_u	*to;
dea496
 {
dea496
-    char_u	*p;
dea496
+    bf_state_T *bfs = state->method_state;
dea496
+    size_t	i;
dea496
     int		t;
dea496
 
dea496
-    for (p = ptr; p < ptr + len; ++p)
dea496
+    for (i = 0; i < len; ++i)
dea496
     {
dea496
-	BF_RANBYTE(t);
dea496
-	*p ^= t;
dea496
-	BF_OFB_UPDATE(*p);
dea496
+	BF_RANBYTE(bfs, t);
dea496
+	to[i] = from[i] ^ t;
dea496
+	BF_CFB_UPDATE(bfs, to[i]);
dea496
     }
dea496
 }
dea496
 
dea496
-/*
dea496
- * Initialize the encryption keys and the random header according to
dea496
- * the given password.
dea496
- */
dea496
     void
dea496
-bf_crypt_init_keys(passwd)
dea496
-    char_u *passwd;		/* password string with which to modify keys */
dea496
-{
dea496
-    char_u *p;
dea496
-
dea496
-    for (p = passwd; *p != NUL; ++p)
dea496
-    {
dea496
-	BF_OFB_UPDATE(*p);
dea496
-    }
dea496
-}
dea496
+crypt_blowfish_init(state, key, salt, salt_len, seed, seed_len)
dea496
+    cryptstate_T	*state;
dea496
+    char_u*		key;
dea496
+    char_u*		salt;
dea496
+    int			salt_len;
dea496
+    char_u*		seed;
dea496
+    int			seed_len;
dea496
+{
dea496
+    bf_state_T	*bfs = (bf_state_T *)alloc_clear(sizeof(bf_state_T));
dea496
+
dea496
+    state->method_state = bfs;
dea496
+
dea496
+    /* "blowfish" uses a 64 byte buffer, causing it to repeat 8 byte groups 8
dea496
+     * times.  "blowfish2" uses a 8 byte buffer to avoid repeating. */
dea496
+    bfs->cfb_len = state->method_nr == CRYPT_M_BF ? BF_MAX_CFB_LEN : BF_BLOCK;
dea496
 
dea496
-static int save_randbyte_offset;
dea496
-static int save_update_offset;
dea496
-static char_u save_ofb_buffer[BF_OFB_LEN];
dea496
-static UINT32_T save_pax[18];
dea496
-static UINT32_T save_sbx[4][256];
dea496
-
dea496
-/*
dea496
- * Save the current crypt state.  Can only be used once before
dea496
- * bf_crypt_restore().
dea496
- */
dea496
-    void
dea496
-bf_crypt_save()
dea496
-{
dea496
-    save_randbyte_offset = randbyte_offset;
dea496
-    save_update_offset = update_offset;
dea496
-    mch_memmove(save_ofb_buffer, ofb_buffer, BF_OFB_LEN);
dea496
-    mch_memmove(save_pax, pax, 4 * 18);
dea496
-    mch_memmove(save_sbx, sbx, 4 * 4 * 256);
dea496
-}
dea496
+    if (blowfish_self_test() == FAIL)
dea496
+	return;
dea496
 
dea496
-/*
dea496
- * Restore the current crypt state.  Can only be used after
dea496
- * bf_crypt_save().
dea496
- */
dea496
-    void
dea496
-bf_crypt_restore()
dea496
-{
dea496
-    randbyte_offset = save_randbyte_offset;
dea496
-    update_offset = save_update_offset;
dea496
-    mch_memmove(ofb_buffer, save_ofb_buffer, BF_OFB_LEN);
dea496
-    mch_memmove(pax, save_pax, 4 * 18);
dea496
-    mch_memmove(sbx, save_sbx, 4 * 4 * 256);
dea496
+    bf_key_init(bfs, key, salt, salt_len);
dea496
+    bf_cfb_init(bfs, seed, seed_len);
dea496
 }
dea496
 
dea496
 /*
dea496
diff -up vim74/src/crypt.c.blowfish2 vim74/src/crypt.c
dea496
--- vim74/src/crypt.c.blowfish2	2017-09-05 14:47:34.933912159 +0200
dea496
+++ vim74/src/crypt.c	2017-09-05 14:47:34.933912159 +0200
dea496
@@ -0,0 +1,585 @@
dea496
+/* vi:set ts=8 sts=4 sw=4:
dea496
+ *
dea496
+ * VIM - Vi IMproved	by Bram Moolenaar
dea496
+ *
dea496
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
dea496
+ * Do ":help credits" in Vim to see a list of people who contributed.
dea496
+ * See README.txt for an overview of the Vim source code.
dea496
+ */
dea496
+
dea496
+/*
dea496
+ * crypt.c: Generic encryption support.
dea496
+ */
dea496
+#include "vim.h"
dea496
+
dea496
+#if defined(FEAT_CRYPT) || defined(PROTO)
dea496
+/*
dea496
+ * Optional encryption support.
dea496
+ * Mohsin Ahmed, mosh@sasi.com, 1998-09-24
dea496
+ * Based on zip/crypt sources.
dea496
+ * Refactored by David Leadbeater, 2014.
dea496
+ *
dea496
+ * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
dea496
+ * most countries.  There are a few exceptions, but that still should not be a
dea496
+ * problem since this code was originally created in Europe and India.
dea496
+ *
dea496
+ * Blowfish addition originally made by Mohsin Ahmed,
dea496
+ * http://www.cs.albany.edu/~mosh 2010-03-14
dea496
+ * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
dea496
+ * and sha256 by Christophe Devine.
dea496
+ */
dea496
+
dea496
+typedef struct {
dea496
+    char    *name;	/* encryption name as used in 'cryptmethod' */
dea496
+    char    *magic;	/* magic bytes stored in file header */
dea496
+    int	    salt_len;	/* length of salt, or 0 when not using salt */
dea496
+    int	    seed_len;	/* length of seed, or 0 when not using salt */
dea496
+    int	    works_inplace; /* encryption/decryption can be done in-place */
dea496
+    int	    whole_undofile; /* whole undo file is encrypted */
dea496
+
dea496
+    /* Optional function pointer for a self-test. */
dea496
+    int (* self_test_fn)();
dea496
+
dea496
+    /* Function pointer for initializing encryption/decription. */
dea496
+    void (* init_fn)(cryptstate_T *state, char_u *key,
dea496
+		      char_u *salt, int salt_len, char_u *seed, int seed_len);
dea496
+
dea496
+    /* Function pointers for encoding/decoding from one buffer into another.
dea496
+     * Optional, however, these or the _buffer ones should be configured. */
dea496
+    void (*encode_fn)(cryptstate_T *state, char_u *from, size_t len,
dea496
+								  char_u *to);
dea496
+    void (*decode_fn)(cryptstate_T *state, char_u *from, size_t len,
dea496
+								  char_u *to);
dea496
+
dea496
+    /* Function pointers for encoding and decoding, can buffer data if needed.
dea496
+     * Optional (however, these or the above should be configured). */
dea496
+    long (*encode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
dea496
+							     char_u **newptr);
dea496
+    long (*decode_buffer_fn)(cryptstate_T *state, char_u *from, size_t len,
dea496
+							     char_u **newptr);
dea496
+
dea496
+    /* Function pointers for in-place encoding and decoding, used for
dea496
+     * crypt_*_inplace(). "from" and "to" arguments will be equal.
dea496
+     * These may be the same as decode_fn and encode_fn above, however an
dea496
+     * algorithm may implement them in a way that is not interchangeable with
dea496
+     * the crypt_(en|de)code() interface (for example because it wishes to add
dea496
+     * padding to files).
dea496
+     * This method is used for swap and undo files which have a rigid format.
dea496
+     */
dea496
+    void (*encode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
dea496
+								  char_u *p2);
dea496
+    void (*decode_inplace_fn)(cryptstate_T *state, char_u *p1, size_t len,
dea496
+								  char_u *p2);
dea496
+} cryptmethod_T;
dea496
+
dea496
+/* index is method_nr of cryptstate_T, CRYPT_M_* */
dea496
+static cryptmethod_T cryptmethods[CRYPT_M_COUNT] = {
dea496
+    /* PK_Zip; very weak */
dea496
+    {
dea496
+	"zip",
dea496
+	"VimCrypt~01!",
dea496
+	0,
dea496
+	0,
dea496
+	TRUE,
dea496
+	FALSE,
dea496
+	NULL,
dea496
+	crypt_zip_init,
dea496
+	crypt_zip_encode, crypt_zip_decode,
dea496
+	NULL, NULL,
dea496
+	crypt_zip_encode, crypt_zip_decode,
dea496
+    },
dea496
+
dea496
+    /* Blowfish/CFB + SHA-256 custom key derivation; implementation issues. */
dea496
+    {
dea496
+	"blowfish",
dea496
+	"VimCrypt~02!",
dea496
+	8,
dea496
+	8,
dea496
+	TRUE,
dea496
+	FALSE,
dea496
+	blowfish_self_test,
dea496
+	crypt_blowfish_init,
dea496
+	crypt_blowfish_encode, crypt_blowfish_decode,
dea496
+	NULL, NULL,
dea496
+	crypt_blowfish_encode, crypt_blowfish_decode,
dea496
+    },
dea496
+
dea496
+    /* Blowfish/CFB + SHA-256 custom key derivation; fixed. */
dea496
+    {
dea496
+	"blowfish2",
dea496
+	"VimCrypt~03!",
dea496
+	8,
dea496
+	8,
dea496
+	TRUE,
dea496
+	TRUE,
dea496
+	blowfish_self_test,
dea496
+	crypt_blowfish_init,
dea496
+	crypt_blowfish_encode, crypt_blowfish_decode,
dea496
+	NULL, NULL,
dea496
+	crypt_blowfish_encode, crypt_blowfish_decode,
dea496
+    },
dea496
+};
dea496
+
dea496
+#define CRYPT_MAGIC_LEN	12	/* cannot change */
dea496
+static char	crypt_magic_head[] = "VimCrypt~";
dea496
+
dea496
+/*
dea496
+ * Return int value for crypt method name.
dea496
+ * 0 for "zip", the old method.  Also for any non-valid value.
dea496
+ * 1 for "blowfish".
dea496
+ * 2 for "blowfish2".
dea496
+ */
dea496
+    int
dea496
+crypt_method_nr_from_name(name)
dea496
+    char_u  *name;
dea496
+{
dea496
+    int i;
dea496
+
dea496
+    for (i = 0; i < CRYPT_M_COUNT; ++i)
dea496
+	if (STRCMP(name, cryptmethods[i].name) == 0)
dea496
+	    return i;
dea496
+    return 0;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Get the crypt method used for a file from "ptr[len]", the magic text at the
dea496
+ * start of the file.
dea496
+ * Returns -1 when no encryption used.
dea496
+ */
dea496
+    int
dea496
+crypt_method_nr_from_magic(ptr, len)
dea496
+    char  *ptr;
dea496
+    int   len;
dea496
+{
dea496
+    int i;
dea496
+
dea496
+    if (len < CRYPT_MAGIC_LEN)
dea496
+	return -1;
dea496
+
dea496
+    for (i = 0; i < CRYPT_M_COUNT; i++)
dea496
+	if (memcmp(ptr, cryptmethods[i].magic, CRYPT_MAGIC_LEN) == 0)
dea496
+	    return i;
dea496
+
dea496
+    i = (int)STRLEN(crypt_magic_head);
dea496
+    if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0)
dea496
+	EMSG(_("E821: File is encrypted with unknown method"));
dea496
+
dea496
+    return -1;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Return TRUE if the crypt method for "method_nr" can be done in-place.
dea496
+ */
dea496
+    int
dea496
+crypt_works_inplace(state)
dea496
+    cryptstate_T *state;
dea496
+{
dea496
+    return cryptmethods[state->method_nr].works_inplace;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Get the crypt method for buffer "buf" as a number.
dea496
+ */
dea496
+    int
dea496
+crypt_get_method_nr(buf)
dea496
+    buf_T *buf;
dea496
+{
dea496
+    return crypt_method_nr_from_name(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Return TRUE when the buffer uses an encryption method that encrypts the
dea496
+ * whole undo file, not only the text.
dea496
+ */
dea496
+    int
dea496
+crypt_whole_undofile(method_nr)
dea496
+    int method_nr;
dea496
+{
dea496
+    return cryptmethods[method_nr].whole_undofile;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Get crypt method specifc length of the file header in bytes.
dea496
+ */
dea496
+    int
dea496
+crypt_get_header_len(method_nr)
dea496
+    int method_nr;
dea496
+{
dea496
+    return CRYPT_MAGIC_LEN
dea496
+	+ cryptmethods[method_nr].salt_len
dea496
+	+ cryptmethods[method_nr].seed_len;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Set the crypt method for buffer "buf" to "method_nr" using the int value as
dea496
+ * returned by crypt_method_nr_from_name().
dea496
+ */
dea496
+    void
dea496
+crypt_set_cm_option(buf, method_nr)
dea496
+    buf_T   *buf;
dea496
+    int	    method_nr;
dea496
+{
dea496
+    free_string_option(buf->b_p_cm);
dea496
+    buf->b_p_cm = vim_strsave((char_u *)cryptmethods[method_nr].name);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * If the crypt method for the current buffer has a self-test, run it and
dea496
+ * return OK/FAIL.
dea496
+ */
dea496
+    int
dea496
+crypt_self_test()
dea496
+{
dea496
+    int method_nr = crypt_get_method_nr(curbuf);
dea496
+
dea496
+    if (cryptmethods[method_nr].self_test_fn == NULL)
dea496
+	return OK;
dea496
+    return cryptmethods[method_nr].self_test_fn();
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Allocate a crypt state and initialize it.
dea496
+ */
dea496
+    cryptstate_T *
dea496
+crypt_create(method_nr, key, salt, salt_len, seed, seed_len)
dea496
+    int		method_nr;
dea496
+    char_u	*key;
dea496
+    char_u	*salt;
dea496
+    int		salt_len;
dea496
+    char_u	*seed;
dea496
+    int		seed_len;
dea496
+{
dea496
+    cryptstate_T *state = (cryptstate_T *)alloc((int)sizeof(cryptstate_T));
dea496
+
dea496
+    state->method_nr = method_nr;
dea496
+    cryptmethods[method_nr].init_fn(state, key, salt, salt_len, seed, seed_len);
dea496
+    return state;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Allocate a crypt state from a file header and initialize it.
dea496
+ * Assumes that header contains at least the number of bytes that
dea496
+ * crypt_get_header_len() returns for "method_nr".
dea496
+ */
dea496
+    cryptstate_T *
dea496
+crypt_create_from_header(method_nr, key, header)
dea496
+    int		method_nr;
dea496
+    char_u	*key;
dea496
+    char_u	*header;
dea496
+{
dea496
+    char_u	*salt = NULL;
dea496
+    char_u	*seed = NULL;
dea496
+    int		salt_len = cryptmethods[method_nr].salt_len;
dea496
+    int		seed_len = cryptmethods[method_nr].seed_len;
dea496
+
dea496
+    if (salt_len > 0)
dea496
+	salt = header + CRYPT_MAGIC_LEN;
dea496
+    if (seed_len > 0)
dea496
+	seed = header + CRYPT_MAGIC_LEN + salt_len;
dea496
+
dea496
+    return crypt_create(method_nr, key, salt, salt_len, seed, seed_len);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Read the crypt method specific header data from "fp".
dea496
+ * Return an allocated cryptstate_T or NULL on error.
dea496
+ */
dea496
+    cryptstate_T *
dea496
+crypt_create_from_file(fp, key)
dea496
+    FILE    *fp;
dea496
+    char_u  *key;
dea496
+{
dea496
+    int		method_nr;
dea496
+    int		header_len;
dea496
+    char	magic_buffer[CRYPT_MAGIC_LEN];
dea496
+    char_u	*buffer;
dea496
+    cryptstate_T *state;
dea496
+
dea496
+    if (fread(magic_buffer, CRYPT_MAGIC_LEN, 1, fp) != 1)
dea496
+	return NULL;
dea496
+    method_nr = crypt_method_nr_from_magic(magic_buffer, CRYPT_MAGIC_LEN);
dea496
+    if (method_nr < 0)
dea496
+	return NULL;
dea496
+
dea496
+    header_len = crypt_get_header_len(method_nr);
dea496
+    if ((buffer = alloc(header_len)) == NULL)
dea496
+	return NULL;
dea496
+    mch_memmove(buffer, magic_buffer, CRYPT_MAGIC_LEN);
dea496
+    if (header_len > CRYPT_MAGIC_LEN
dea496
+	    && fread(buffer + CRYPT_MAGIC_LEN,
dea496
+				    header_len - CRYPT_MAGIC_LEN, 1, fp) != 1)
dea496
+    {
dea496
+	vim_free(buffer);
dea496
+	return NULL;
dea496
+    }
dea496
+
dea496
+    state = crypt_create_from_header(method_nr, key, buffer);
dea496
+    vim_free(buffer);
dea496
+    return state;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Allocate a cryptstate_T for writing and initialize it with "key".
dea496
+ * Allocates and fills in the header and stores it in "header", setting
dea496
+ * "header_len".  The header may include salt and seed, depending on
dea496
+ * cryptmethod.  Caller must free header.
dea496
+ * Returns the state or NULL on failure.
dea496
+ */
dea496
+    cryptstate_T *
dea496
+crypt_create_for_writing(method_nr, key, header, header_len)
dea496
+    int	    method_nr;
dea496
+    char_u  *key;
dea496
+    char_u  **header;
dea496
+    int	    *header_len;
dea496
+{
dea496
+    int	    len = crypt_get_header_len(method_nr);
dea496
+    char_u  *salt = NULL;
dea496
+    char_u  *seed = NULL;
dea496
+    int	    salt_len = cryptmethods[method_nr].salt_len;
dea496
+    int	    seed_len = cryptmethods[method_nr].seed_len;
dea496
+    cryptstate_T *state;
dea496
+
dea496
+    *header_len = len;
dea496
+    *header = alloc(len);
dea496
+    if (*header == NULL)
dea496
+	return NULL;
dea496
+
dea496
+    mch_memmove(*header, cryptmethods[method_nr].magic, CRYPT_MAGIC_LEN);
dea496
+    if (salt_len > 0 || seed_len > 0)
dea496
+    {
dea496
+	if (salt_len > 0)
dea496
+	    salt = *header + CRYPT_MAGIC_LEN;
dea496
+	if (seed_len > 0)
dea496
+	    seed = *header + CRYPT_MAGIC_LEN + salt_len;
dea496
+
dea496
+	/* TODO: Should this be crypt method specific? (Probably not worth
dea496
+	 * it).  sha2_seed is pretty bad for large amounts of entropy, so make
dea496
+	 * that into something which is suitable for anything. */
dea496
+	sha2_seed(salt, salt_len, seed, seed_len);
dea496
+    }
dea496
+
dea496
+    state = crypt_create(method_nr, key, salt, salt_len, seed, seed_len);
dea496
+    if (state == NULL)
dea496
+    {
dea496
+	vim_free(*header);
dea496
+	*header = NULL;
dea496
+    }
dea496
+    return state;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Free the crypt state.
dea496
+ */
dea496
+    void
dea496
+crypt_free_state(state)
dea496
+    cryptstate_T	*state;
dea496
+{
dea496
+    vim_free(state->method_state);
dea496
+    vim_free(state);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Encode "from[len]" and store the result in a newly allocated buffer, which
dea496
+ * is stored in "newptr".
dea496
+ * Return number of bytes in "newptr", 0 for need more or -1 on error.
dea496
+ */
dea496
+    long
dea496
+crypt_encode_alloc(state, from, len, newptr)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*from;
dea496
+    size_t	len;
dea496
+    char_u	**newptr;
dea496
+{
dea496
+    cryptmethod_T *method = &cryptmethods[state->method_nr];
dea496
+
dea496
+    if (method->encode_buffer_fn != NULL)
dea496
+	/* Has buffer function, pass through. */
dea496
+	return method->encode_buffer_fn(state, from, len, newptr);
dea496
+    if (len == 0)
dea496
+	/* Not buffering, just return EOF. */
dea496
+	return len;
dea496
+
dea496
+    *newptr = alloc(len);
dea496
+    if (*newptr == NULL)
dea496
+	return -1;
dea496
+    method->encode_fn(state, from, len, *newptr);
dea496
+    return len;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Decrypt "ptr[len]" and store the result in a newly allocated buffer, which
dea496
+ * is stored in "newptr".
dea496
+ * Return number of bytes in "newptr", 0 for need more or -1 on error.
dea496
+ */
dea496
+    long
dea496
+crypt_decode_alloc(state, ptr, len, newptr)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*ptr;
dea496
+    long	len;
dea496
+    char_u      **newptr;
dea496
+{
dea496
+    cryptmethod_T *method = &cryptmethods[state->method_nr];
dea496
+
dea496
+    if (method->decode_buffer_fn != NULL)
dea496
+	/* Has buffer function, pass through. */
dea496
+	return method->decode_buffer_fn(state, ptr, len, newptr);
dea496
+
dea496
+    if (len == 0)
dea496
+	/* Not buffering, just return EOF. */
dea496
+	return len;
dea496
+
dea496
+    *newptr = alloc(len);
dea496
+    if (*newptr == NULL)
dea496
+	return -1;
dea496
+    method->decode_fn(state, ptr, len, *newptr);
dea496
+    return len;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Encrypting "from[len]" into "to[len]".
dea496
+ */
dea496
+    void
dea496
+crypt_encode(state, from, len, to)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*from;
dea496
+    size_t	len;
dea496
+    char_u	*to;
dea496
+{
dea496
+    cryptmethods[state->method_nr].encode_fn(state, from, len, to);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * decrypting "from[len]" into "to[len]".
dea496
+ */
dea496
+    void
dea496
+crypt_decode(state, from, len, to)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*from;
dea496
+    size_t	len;
dea496
+    char_u	*to;
dea496
+{
dea496
+    cryptmethods[state->method_nr].decode_fn(state, from, len, to);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Simple inplace encryption, modifies "buf[len]" in place.
dea496
+ */
dea496
+    void
dea496
+crypt_encode_inplace(state, buf, len)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*buf;
dea496
+    size_t	len;
dea496
+{
dea496
+    cryptmethods[state->method_nr].encode_inplace_fn(state, buf, len, buf);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Simple inplace decryption, modifies "buf[len]" in place.
dea496
+ */
dea496
+    void
dea496
+crypt_decode_inplace(state, buf, len)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*buf;
dea496
+    size_t	len;
dea496
+{
dea496
+    cryptmethods[state->method_nr].decode_inplace_fn(state, buf, len, buf);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Free an allocated crypt key.  Clear the text to make sure it doesn't stay
dea496
+ * in memory anywhere.
dea496
+ */
dea496
+    void
dea496
+crypt_free_key(key)
dea496
+    char_u *key;
dea496
+{
dea496
+    char_u *p;
dea496
+
dea496
+    if (key != NULL)
dea496
+    {
dea496
+	for (p = key; *p != NUL; ++p)
dea496
+	    *p = 0;
dea496
+	vim_free(key);
dea496
+    }
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Ask the user for a crypt key.
dea496
+ * When "store" is TRUE, the new key is stored in the 'key' option, and the
dea496
+ * 'key' option value is returned: Don't free it.
dea496
+ * When "store" is FALSE, the typed key is returned in allocated memory.
dea496
+ * Returns NULL on failure.
dea496
+ */
dea496
+    char_u *
dea496
+crypt_get_key(store, twice)
dea496
+    int		store;
dea496
+    int		twice;	    /* Ask for the key twice. */
dea496
+{
dea496
+    char_u	*p1, *p2 = NULL;
dea496
+    int		round;
dea496
+
dea496
+    for (round = 0; ; ++round)
dea496
+    {
dea496
+	cmdline_star = TRUE;
dea496
+	cmdline_row = msg_row;
dea496
+	p1 = getcmdline_prompt(NUL, round == 0
dea496
+		? (char_u *)_("Enter encryption key: ")
dea496
+		: (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
dea496
+		NULL);
dea496
+	cmdline_star = FALSE;
dea496
+
dea496
+	if (p1 == NULL)
dea496
+	    break;
dea496
+
dea496
+	if (round == twice)
dea496
+	{
dea496
+	    if (p2 != NULL && STRCMP(p1, p2) != 0)
dea496
+	    {
dea496
+		MSG(_("Keys don't match!"));
dea496
+		crypt_free_key(p1);
dea496
+		crypt_free_key(p2);
dea496
+		p2 = NULL;
dea496
+		round = -1;		/* do it again */
dea496
+		continue;
dea496
+	    }
dea496
+
dea496
+	    if (store)
dea496
+	    {
dea496
+		set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
dea496
+		crypt_free_key(p1);
dea496
+		p1 = curbuf->b_p_key;
dea496
+	    }
dea496
+	    break;
dea496
+	}
dea496
+	p2 = p1;
dea496
+    }
dea496
+
dea496
+    /* since the user typed this, no need to wait for return */
dea496
+    if (msg_didout)
dea496
+	msg_putchar('\n');
dea496
+    need_wait_return = FALSE;
dea496
+    msg_didout = FALSE;
dea496
+
dea496
+    crypt_free_key(p2);
dea496
+    return p1;
dea496
+}
dea496
+
dea496
+
dea496
+/*
dea496
+ * Append a message to IObuff for the encryption/decryption method being used.
dea496
+ */
dea496
+    void
dea496
+crypt_append_msg(buf)
dea496
+    buf_T *buf;
dea496
+{
dea496
+    if (crypt_get_method_nr(buf) == 0)
dea496
+	STRCAT(IObuff, _("[crypted]"));
dea496
+    else
dea496
+    {
dea496
+	STRCAT(IObuff, "[");
dea496
+	STRCAT(IObuff, *buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
dea496
+	STRCAT(IObuff, "]");
dea496
+    }
dea496
+}
dea496
+
dea496
+#endif /* FEAT_CRYPT */
dea496
diff -up vim74/src/crypt_zip.c.blowfish2 vim74/src/crypt_zip.c
dea496
--- vim74/src/crypt_zip.c.blowfish2	2017-09-05 14:47:34.934912151 +0200
dea496
+++ vim74/src/crypt_zip.c	2017-09-05 14:47:34.934912151 +0200
dea496
@@ -0,0 +1,158 @@
dea496
+/* vi:set ts=8 sts=4 sw=4:
dea496
+ *
dea496
+ * VIM - Vi IMproved	by Bram Moolenaar
dea496
+ *
dea496
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
dea496
+ * Do ":help credits" in Vim to see a list of people who contributed.
dea496
+ * See README.txt for an overview of the Vim source code.
dea496
+ */
dea496
+
dea496
+/*
dea496
+ * crypt_zip.c: Zip encryption support.
dea496
+ */
dea496
+#include "vim.h"
dea496
+
dea496
+#if defined(FEAT_CRYPT) || defined(PROTO)
dea496
+/*
dea496
+ * Optional encryption support.
dea496
+ * Mohsin Ahmed, mosh@sasi.com, 98-09-24
dea496
+ * Based on zip/crypt sources.
dea496
+ *
dea496
+ * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
dea496
+ * most countries.  There are a few exceptions, but that still should not be a
dea496
+ * problem since this code was originally created in Europe and India.
dea496
+ */
dea496
+
dea496
+/* Need a type that should be 32 bits. 64 also works but wastes space. */
dea496
+# if VIM_SIZEOF_INT >= 4
dea496
+typedef unsigned int u32_T;	/* int is at least 32 bits */
dea496
+# else
dea496
+typedef unsigned long u32_T;	/* long should be 32 bits or more */
dea496
+# endif
dea496
+
dea496
+/* The state of encryption, referenced by cryptstate_T. */
dea496
+typedef struct {
dea496
+    u32_T keys[3];
dea496
+} zip_state_T;
dea496
+
dea496
+
dea496
+static void make_crc_tab __ARGS((void));
dea496
+
dea496
+static u32_T crc_32_table[256];
dea496
+
dea496
+/*
dea496
+ * Fill the CRC table, if not done already.
dea496
+ */
dea496
+    static void
dea496
+make_crc_tab()
dea496
+{
dea496
+    u32_T	s, t, v;
dea496
+    static int	done = FALSE;
dea496
+
dea496
+    if (done)
dea496
+	return;
dea496
+    for (t = 0; t < 256; t++)
dea496
+    {
dea496
+	v = t;
dea496
+	for (s = 0; s < 8; s++)
dea496
+	    v = (v >> 1) ^ ((v & 1) * (u32_T)0xedb88320L);
dea496
+	crc_32_table[t] = v;
dea496
+    }
dea496
+    done = TRUE;
dea496
+}
dea496
+
dea496
+#define CRC32(c, b) (crc_32_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
dea496
+
dea496
+/*
dea496
+ * Return the next byte in the pseudo-random sequence.
dea496
+ */
dea496
+#define DECRYPT_BYTE_ZIP(keys, t) { \
dea496
+    short_u temp = (short_u)keys[2] | 2; \
dea496
+    t = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff); \
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Update the encryption keys with the next byte of plain text.
dea496
+ */
dea496
+#define UPDATE_KEYS_ZIP(keys, c) { \
dea496
+    keys[0] = CRC32(keys[0], (c)); \
dea496
+    keys[1] += keys[0] & 0xff; \
dea496
+    keys[1] = keys[1] * 134775813L + 1; \
dea496
+    keys[2] = CRC32(keys[2], (int)(keys[1] >> 24)); \
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Initialize for encryption/decryption.
dea496
+ */
dea496
+    void
dea496
+crypt_zip_init(state, key, salt, salt_len, seed, seed_len)
dea496
+    cryptstate_T    *state;
dea496
+    char_u	    *key;
dea496
+    char_u	    *salt UNUSED;
dea496
+    int		    salt_len UNUSED;
dea496
+    char_u	    *seed UNUSED;
dea496
+    int		    seed_len UNUSED;
dea496
+{
dea496
+    char_u	*p;
dea496
+    zip_state_T	*zs;
dea496
+
dea496
+    zs = (zip_state_T *)alloc(sizeof(zip_state_T));
dea496
+    state->method_state = zs;
dea496
+
dea496
+    make_crc_tab();
dea496
+    zs->keys[0] = 305419896L;
dea496
+    zs->keys[1] = 591751049L;
dea496
+    zs->keys[2] = 878082192L;
dea496
+    for (p = key; *p != NUL; ++p)
dea496
+    {
dea496
+	UPDATE_KEYS_ZIP(zs->keys, (int)*p);
dea496
+    }
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Encrypt "from[len]" into "to[len]".
dea496
+ * "from" and "to" can be equal to encrypt in place.
dea496
+ */
dea496
+    void
dea496
+crypt_zip_encode(state, from, len, to)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*from;
dea496
+    size_t	len;
dea496
+    char_u	*to;
dea496
+{
dea496
+    zip_state_T *zs = state->method_state;
dea496
+    size_t	i;
dea496
+    int		ztemp, t;
dea496
+
dea496
+    for (i = 0; i < len; ++i)
dea496
+    {
dea496
+	ztemp = from[i];
dea496
+	DECRYPT_BYTE_ZIP(zs->keys, t);
dea496
+	UPDATE_KEYS_ZIP(zs->keys, ztemp);
dea496
+	to[i] = t ^ ztemp;
dea496
+    }
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Decrypt "from[len]" into "to[len]".
dea496
+ */
dea496
+    void
dea496
+crypt_zip_decode(state, from, len, to)
dea496
+    cryptstate_T *state;
dea496
+    char_u	*from;
dea496
+    size_t	len;
dea496
+    char_u	*to;
dea496
+{
dea496
+    zip_state_T *zs = state->method_state;
dea496
+    size_t	i;
dea496
+    short_u	temp;
dea496
+
dea496
+    for (i = 0; i < len; ++i)
dea496
+    {
dea496
+	temp = (short_u)zs->keys[2] | 2;
dea496
+	temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
dea496
+	UPDATE_KEYS_ZIP(zs->keys, to[i] = from[i] ^ temp);
dea496
+    }
dea496
+}
dea496
+
dea496
+#endif /* FEAT_CRYPT */
dea496
diff -up vim74/src/eval.c.blowfish2 vim74/src/eval.c
dea496
--- vim74/src/eval.c.blowfish2	2017-09-05 14:47:34.837912934 +0200
dea496
+++ vim74/src/eval.c	2017-09-05 14:47:34.939912111 +0200
dea496
@@ -12228,6 +12228,8 @@ f_has(argvars, rettv)
dea496
 #endif
dea496
 #ifdef FEAT_CRYPT
dea496
 	"cryptv",
dea496
+	"crypt-blowfish",
dea496
+	"crypt-blowfish2",
dea496
 #endif
dea496
 #ifdef FEAT_CSCOPE
dea496
 	"cscope",
dea496
diff -up vim74/src/ex_docmd.c.blowfish2 vim74/src/ex_docmd.c
dea496
--- vim74/src/ex_docmd.c.blowfish2	2017-09-05 14:47:34.782913378 +0200
dea496
+++ vim74/src/ex_docmd.c	2017-09-05 14:47:34.945912063 +0200
dea496
@@ -11497,8 +11497,7 @@ ex_match(eap)
dea496
 ex_X(eap)
dea496
     exarg_T	*eap UNUSED;
dea496
 {
dea496
-    if (get_crypt_method(curbuf) == 0 || blowfish_self_test() == OK)
dea496
-	(void)get_crypt_key(TRUE, TRUE);
dea496
+    (void)crypt_get_key(TRUE, TRUE);
dea496
 }
dea496
 #endif
dea496
 
dea496
diff -up vim74/src/fileio.c.blowfish2 vim74/src/fileio.c
dea496
--- vim74/src/fileio.c.blowfish2	2017-09-05 14:47:34.245917713 +0200
dea496
+++ vim74/src/fileio.c	2017-09-05 14:47:34.947912046 +0200
dea496
@@ -24,20 +24,6 @@
dea496
 #define BUFSIZE		8192	/* size of normal write buffer */
dea496
 #define SMBUFSIZE	256	/* size of emergency write buffer */
dea496
 
dea496
-#ifdef FEAT_CRYPT
dea496
-/* crypt_magic[0] is pkzip crypt, crypt_magic[1] is sha2+blowfish */
dea496
-static char	*crypt_magic[] = {"VimCrypt~01!", "VimCrypt~02!"};
dea496
-static char	crypt_magic_head[] = "VimCrypt~";
dea496
-# define CRYPT_MAGIC_LEN	12		/* must be multiple of 4! */
dea496
-
dea496
-/* For blowfish, after the magic header, we store 8 bytes of salt and then 8
dea496
- * bytes of seed (initialisation vector). */
dea496
-static int	crypt_salt_len[] = {0, 8};
dea496
-static int	crypt_seed_len[] = {0, 8};
dea496
-#define CRYPT_SALT_LEN_MAX 8
dea496
-#define CRYPT_SEED_LEN_MAX 8
dea496
-#endif
dea496
-
dea496
 /* Is there any system that doesn't have access()? */
dea496
 #define USE_MCH_ACCESS
dea496
 
dea496
@@ -55,7 +41,6 @@ static char_u *readfile_charconvert __AR
dea496
 static void check_marks_read __ARGS((void));
dea496
 #endif
dea496
 #ifdef FEAT_CRYPT
dea496
-static int crypt_method_from_magic __ARGS((char *ptr, int len));
dea496
 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));
dea496
 #endif
dea496
 #ifdef UNIX
dea496
@@ -116,6 +101,9 @@ struct bw_info
dea496
 #ifdef HAS_BW_FLAGS
dea496
     int		bw_flags;	/* FIO_ flags */
dea496
 #endif
dea496
+#ifdef FEAT_CRYPT
dea496
+    buf_T	*bw_buffer;	/* buffer being written */
dea496
+#endif
dea496
 #ifdef FEAT_MBYTE
dea496
     char_u	bw_rest[CONV_RESTLEN]; /* not converted bytes */
dea496
     int		bw_restlen;	/* nr of bytes in bw_rest[] */
dea496
@@ -250,7 +238,6 @@ readfile(fname, sfname, from, lines_to_s
dea496
 #ifdef FEAT_CRYPT
dea496
     char_u	*cryptkey = NULL;
dea496
     int		did_ask_for_key = FALSE;
dea496
-    int		crypt_method_used;
dea496
 #endif
dea496
 #ifdef FEAT_PERSISTENT_UNDO
dea496
     context_sha256_T sha_ctx;
dea496
@@ -966,13 +953,6 @@ retry:
dea496
 #endif
dea496
     }
dea496
 
dea496
-#ifdef FEAT_CRYPT
dea496
-    if (cryptkey != NULL)
dea496
-	/* Need to reset the state, but keep the key, don't want to ask for it
dea496
-	 * again. */
dea496
-	crypt_pop_state();
dea496
-#endif
dea496
-
dea496
     /*
dea496
      * When retrying with another "fenc" and the first time "fileformat"
dea496
      * will be reset.
dea496
@@ -1175,6 +1155,15 @@ retry:
dea496
 	if (read_undo_file)
dea496
 	    sha256_start(&sha_ctx);
dea496
 #endif
dea496
+#ifdef FEAT_CRYPT
dea496
+	if (curbuf->b_cryptstate != NULL)
dea496
+	{
dea496
+	    /* Need to free the state, but keep the key, don't want to ask for
dea496
+	     * it again. */
dea496
+	    crypt_free_state(curbuf->b_cryptstate);
dea496
+	    curbuf->b_cryptstate = NULL;
dea496
+	}
dea496
+#endif
dea496
     }
dea496
 
dea496
     while (!error && !got_int)
dea496
@@ -1339,6 +1328,76 @@ retry:
dea496
 		    size = read_eintr(fd, ptr, size);
dea496
 		}
dea496
 
dea496
+#ifdef FEAT_CRYPT
dea496
+		/*
dea496
+		 * At start of file: Check for magic number of encryption.
dea496
+		 */
dea496
+		if (filesize == 0 && size > 0)
dea496
+		    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
dea496
+						  &filesize, newfile, sfname,
dea496
+						  &did_ask_for_key);
dea496
+		/*
dea496
+		 * Decrypt the read bytes.  This is done before checking for
dea496
+		 * EOF because the crypt layer may be buffering.
dea496
+		 */
dea496
+		if (cryptkey != NULL && curbuf->b_cryptstate != NULL && size > 0)
dea496
+		{
dea496
+		    if (crypt_works_inplace(curbuf->b_cryptstate))
dea496
+		    {
dea496
+			crypt_decode_inplace(curbuf->b_cryptstate, ptr, size);
dea496
+		    }
dea496
+		    else
dea496
+		    {
dea496
+			char_u	*newptr = NULL;
dea496
+			int	decrypted_size;
dea496
+
dea496
+			decrypted_size = crypt_decode_alloc(
dea496
+				    curbuf->b_cryptstate, ptr, size, &newptr);
dea496
+
dea496
+			/* If the crypt layer is buffering, not producing
dea496
+			 * anything yet, need to read more. */
dea496
+			if (size > 0 && decrypted_size == 0)
dea496
+			    continue;
dea496
+
dea496
+			if (linerest == 0)
dea496
+			{
dea496
+			    /* Simple case: reuse returned buffer (may be
dea496
+			     * NULL, checked later). */
dea496
+			    new_buffer = newptr;
dea496
+			}
dea496
+			else
dea496
+			{
dea496
+			    long_u	new_size;
dea496
+
dea496
+			    /* Need new buffer to add bytes carried over. */
dea496
+			    new_size = (long_u)(decrypted_size + linerest + 1);
dea496
+			    new_buffer = lalloc(new_size, FALSE);
dea496
+			    if (new_buffer == NULL)
dea496
+			    {
dea496
+				do_outofmem_msg(new_size);
dea496
+				error = TRUE;
dea496
+				break;
dea496
+			    }
dea496
+
dea496
+			    mch_memmove(new_buffer, buffer, linerest);
dea496
+			    if (newptr != NULL)
dea496
+				mch_memmove(new_buffer + linerest, newptr,
dea496
+							      decrypted_size);
dea496
+			}
dea496
+
dea496
+			if (new_buffer != NULL)
dea496
+			{
dea496
+			    vim_free(buffer);
dea496
+			    buffer = new_buffer;
dea496
+			    new_buffer = NULL;
dea496
+			    line_start = buffer;
dea496
+			    ptr = buffer + linerest;
dea496
+			}
dea496
+			size = decrypted_size;
dea496
+		    }
dea496
+		}
dea496
+#endif
dea496
+
dea496
 		if (size <= 0)
dea496
 		{
dea496
 		    if (size < 0)		    /* read error */
dea496
@@ -1403,21 +1462,6 @@ retry:
dea496
 		    }
dea496
 #endif
dea496
 		}
dea496
-
dea496
-#ifdef FEAT_CRYPT
dea496
-		/*
dea496
-		 * At start of file: Check for magic number of encryption.
dea496
-		 */
dea496
-		if (filesize == 0)
dea496
-		    cryptkey = check_for_cryptkey(cryptkey, ptr, &size,
dea496
-					&filesize, newfile, sfname,
dea496
-					&did_ask_for_key);
dea496
-		/*
dea496
-		 * Decrypt the read bytes.
dea496
-		 */
dea496
-		if (cryptkey != NULL && size > 0)
dea496
-		    crypt_decode(ptr, size);
dea496
-#endif
dea496
 	    }
dea496
 	    skip_read = FALSE;
dea496
 
dea496
@@ -1430,10 +1474,9 @@ retry:
dea496
 	     */
dea496
 	    if ((filesize == 0
dea496
 # ifdef FEAT_CRYPT
dea496
-		   || (filesize == (CRYPT_MAGIC_LEN
dea496
-					   + crypt_salt_len[use_crypt_method]
dea496
-					   + crypt_seed_len[use_crypt_method])
dea496
-							  && cryptkey != NULL)
dea496
+		   || (cryptkey != NULL
dea496
+			&& filesize == crypt_get_header_len(
dea496
+						 crypt_get_method_nr(curbuf)))
dea496
 # endif
dea496
 		       )
dea496
 		    && (fio_flags == FIO_UCSBOM
dea496
@@ -2262,15 +2305,15 @@ failed:
dea496
 	save_file_ff(curbuf);		/* remember the current file format */
dea496
 
dea496
 #ifdef FEAT_CRYPT
dea496
-    crypt_method_used = use_crypt_method;
dea496
-    if (cryptkey != NULL)
dea496
+    if (curbuf->b_cryptstate != NULL)
dea496
     {
dea496
-	crypt_pop_state();
dea496
-	if (cryptkey != curbuf->b_p_key)
dea496
-	    free_crypt_key(cryptkey);
dea496
-	/* don't set cryptkey to NULL, it's used below as a flag that
dea496
-	 * encryption was used */
dea496
+	crypt_free_state(curbuf->b_cryptstate);
dea496
+	curbuf->b_cryptstate = NULL;
dea496
     }
dea496
+    if (cryptkey != NULL && cryptkey != curbuf->b_p_key)
dea496
+	crypt_free_key(cryptkey);
dea496
+    /* Don't set cryptkey to NULL, it's used below as a flag that
dea496
+     * encryption was used. */
dea496
 #endif
dea496
 
dea496
 #ifdef FEAT_MBYTE
dea496
@@ -2457,10 +2500,7 @@ failed:
dea496
 #ifdef FEAT_CRYPT
dea496
 	    if (cryptkey != NULL)
dea496
 	    {
dea496
-		if (crypt_method_used == 1)
dea496
-		    STRCAT(IObuff, _("[blowfish]"));
dea496
-		else
dea496
-		    STRCAT(IObuff, _("[crypted]"));
dea496
+		crypt_append_msg(curbuf);
dea496
 		c = TRUE;
dea496
 	    }
dea496
 #endif
dea496
@@ -2489,9 +2529,7 @@ failed:
dea496
 #ifdef FEAT_CRYPT
dea496
 	    if (cryptkey != NULL)
dea496
 		msg_add_lines(c, (long)linecnt, filesize
dea496
-			- CRYPT_MAGIC_LEN
dea496
-			- crypt_salt_len[use_crypt_method]
dea496
-			- crypt_seed_len[use_crypt_method]);
dea496
+			 - crypt_get_header_len(crypt_get_method_nr(curbuf)));
dea496
 	    else
dea496
 #endif
dea496
 		msg_add_lines(c, (long)linecnt, filesize);
dea496
@@ -2882,33 +2920,6 @@ check_marks_read()
dea496
 
dea496
 #if defined(FEAT_CRYPT) || defined(PROTO)
dea496
 /*
dea496
- * Get the crypt method used for a file from "ptr[len]", the magic text at the
dea496
- * start of the file.
dea496
- * Returns -1 when no encryption used.
dea496
- */
dea496
-    static int
dea496
-crypt_method_from_magic(ptr, len)
dea496
-    char  *ptr;
dea496
-    int   len;
dea496
-{
dea496
-    int i;
dea496
-
dea496
-    for (i = 0; i < (int)(sizeof(crypt_magic) / sizeof(crypt_magic[0])); i++)
dea496
-    {
dea496
-	if (len < (CRYPT_MAGIC_LEN + crypt_salt_len[i] + crypt_seed_len[i]))
dea496
-	    continue;
dea496
-	if (memcmp(ptr, crypt_magic[i], CRYPT_MAGIC_LEN) == 0)
dea496
-	    return i;
dea496
-    }
dea496
-
dea496
-    i = (int)STRLEN(crypt_magic_head);
dea496
-    if (len >= i && memcmp(ptr, crypt_magic_head, i) == 0)
dea496
-	EMSG(_("E821: File is encrypted with unknown method"));
dea496
-
dea496
-    return -1;
dea496
-}
dea496
-
dea496
-/*
dea496
  * Check for magic number used for encryption.  Applies to the current buffer.
dea496
  * If found, the magic number is removed from ptr[*sizep] and *sizep and
dea496
  * *filesizep are updated.
dea496
@@ -2924,7 +2935,7 @@ check_for_cryptkey(cryptkey, ptr, sizep,
dea496
     char_u	*fname;		/* file name to display */
dea496
     int		*did_ask;	/* flag: whether already asked for key */
dea496
 {
dea496
-    int method = crypt_method_from_magic((char *)ptr, *sizep);
dea496
+    int method = crypt_method_nr_from_magic((char *)ptr, *sizep);
dea496
     int b_p_ro = curbuf->b_p_ro;
dea496
 
dea496
     if (method >= 0)
dea496
@@ -2933,9 +2944,8 @@ check_for_cryptkey(cryptkey, ptr, sizep,
dea496
 	 * Avoids accidentally overwriting the file with garbage. */
dea496
 	curbuf->b_p_ro = TRUE;
dea496
 
dea496
-	set_crypt_method(curbuf, method);
dea496
-	if (method > 0)
dea496
-	    (void)blowfish_self_test();
dea496
+        /* Set the cryptmethod local to the buffer. */
dea496
+	crypt_set_cm_option(curbuf, method);
dea496
 	if (cryptkey == NULL && !*did_ask)
dea496
 	{
dea496
 	    if (*curbuf->b_p_key)
dea496
@@ -2948,7 +2958,7 @@ check_for_cryptkey(cryptkey, ptr, sizep,
dea496
 		 * Happens when retrying to detect encoding. */
dea496
 		smsg((char_u *)_(need_key_msg), fname);
dea496
 		msg_scroll = TRUE;
dea496
-		cryptkey = get_crypt_key(newfile, FALSE);
dea496
+		cryptkey = crypt_get_key(newfile, FALSE);
dea496
 		*did_ask = TRUE;
dea496
 
dea496
 		/* check if empty key entered */
dea496
@@ -2963,24 +2973,18 @@ check_for_cryptkey(cryptkey, ptr, sizep,
dea496
 
dea496
 	if (cryptkey != NULL)
dea496
 	{
dea496
-	    int seed_len = crypt_seed_len[method];
dea496
-	    int salt_len = crypt_salt_len[method];
dea496
+	    int header_len;
dea496
 
dea496
-	    crypt_push_state();
dea496
-	    use_crypt_method = method;
dea496
-	    if (method == 0)
dea496
-		crypt_init_keys(cryptkey);
dea496
-	    else
dea496
-	    {
dea496
-		bf_key_init(cryptkey, ptr + CRYPT_MAGIC_LEN, salt_len);
dea496
-		bf_ofb_init(ptr + CRYPT_MAGIC_LEN + salt_len, seed_len);
dea496
-	    }
dea496
+	    curbuf->b_cryptstate = crypt_create_from_header(
dea496
+						       method, cryptkey, ptr);
dea496
+	    crypt_set_cm_option(curbuf, method);
dea496
+
dea496
+	    /* Remove cryptmethod specific header from the text. */
dea496
+	    header_len = crypt_get_header_len(method);
dea496
+	    *filesizep += header_len;
dea496
+	    *sizep -= header_len;
dea496
+	    mch_memmove(ptr, ptr + header_len, (size_t)*sizep);
dea496
 
dea496
-	    /* Remove magic number from the text */
dea496
-	    *filesizep += CRYPT_MAGIC_LEN + salt_len + seed_len;
dea496
-	    *sizep -= CRYPT_MAGIC_LEN + salt_len + seed_len;
dea496
-	    mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN + salt_len + seed_len,
dea496
-							      (size_t)*sizep);
dea496
 	    /* Restore the read-only flag. */
dea496
 	    curbuf->b_p_ro = b_p_ro;
dea496
 	}
dea496
@@ -2992,85 +2996,6 @@ check_for_cryptkey(cryptkey, ptr, sizep,
dea496
 
dea496
     return cryptkey;
dea496
 }
dea496
-
dea496
-/*
dea496
- * Check for magic number used for encryption.  Applies to the current buffer.
dea496
- * If found and decryption is possible returns OK;
dea496
- */
dea496
-    int
dea496
-prepare_crypt_read(fp)
dea496
-    FILE	*fp;
dea496
-{
dea496
-    int		method;
dea496
-    char_u	buffer[CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
dea496
-						    + CRYPT_SEED_LEN_MAX + 2];
dea496
-
dea496
-    if (fread(buffer, CRYPT_MAGIC_LEN, 1, fp) != 1)
dea496
-	return FAIL;
dea496
-    method = crypt_method_from_magic((char *)buffer,
dea496
-					CRYPT_MAGIC_LEN +
dea496
-					CRYPT_SEED_LEN_MAX +
dea496
-					CRYPT_SALT_LEN_MAX);
dea496
-    if (method < 0 || method != get_crypt_method(curbuf))
dea496
-	return FAIL;
dea496
-
dea496
-    crypt_push_state();
dea496
-    if (method == 0)
dea496
-	crypt_init_keys(curbuf->b_p_key);
dea496
-    else
dea496
-    {
dea496
-	int salt_len = crypt_salt_len[method];
dea496
-	int seed_len = crypt_seed_len[method];
dea496
-
dea496
-	if (fread(buffer, salt_len + seed_len, 1, fp) != 1)
dea496
-	    return FAIL;
dea496
-	bf_key_init(curbuf->b_p_key, buffer, salt_len);
dea496
-	bf_ofb_init(buffer + salt_len, seed_len);
dea496
-    }
dea496
-    return OK;
dea496
-}
dea496
-
dea496
-/*
dea496
- * Prepare for writing encrypted bytes for buffer "buf".
dea496
- * Returns a pointer to an allocated header of length "*lenp".
dea496
- * When out of memory returns NULL.
dea496
- * Otherwise calls crypt_push_state(), call crypt_pop_state() later.
dea496
- */
dea496
-    char_u *
dea496
-prepare_crypt_write(buf, lenp)
dea496
-    buf_T *buf;
dea496
-    int   *lenp;
dea496
-{
dea496
-    char_u  *header;
dea496
-    int	    seed_len = crypt_seed_len[get_crypt_method(buf)];
dea496
-    int     salt_len = crypt_salt_len[get_crypt_method(buf)];
dea496
-    char_u  *salt;
dea496
-    char_u  *seed;
dea496
-
dea496
-    header = alloc_clear(CRYPT_MAGIC_LEN + CRYPT_SALT_LEN_MAX
dea496
-						    + CRYPT_SEED_LEN_MAX + 2);
dea496
-    if (header != NULL)
dea496
-    {
dea496
-	crypt_push_state();
dea496
-	use_crypt_method = get_crypt_method(buf);  /* select zip or blowfish */
dea496
-	vim_strncpy(header, (char_u *)crypt_magic[use_crypt_method],
dea496
-							     CRYPT_MAGIC_LEN);
dea496
-	if (use_crypt_method == 0)
dea496
-	    crypt_init_keys(buf->b_p_key);
dea496
-	else
dea496
-	{
dea496
-	    /* Using blowfish, add salt and seed. */
dea496
-	    salt = header + CRYPT_MAGIC_LEN;
dea496
-	    seed = salt + salt_len;
dea496
-	    sha2_seed(salt, salt_len, seed, seed_len);
dea496
-	    bf_key_init(buf->b_p_key, salt, salt_len);
dea496
-	    bf_ofb_init(seed, seed_len);
dea496
-	}
dea496
-    }
dea496
-    *lenp = CRYPT_MAGIC_LEN + salt_len + seed_len;
dea496
-    return header;
dea496
-}
dea496
-
dea496
 #endif  /* FEAT_CRYPT */
dea496
 
dea496
 #ifdef UNIX
dea496
@@ -3224,9 +3149,6 @@ buf_write(buf, fname, sfname, start, end
dea496
     int		    write_undo_file = FALSE;
dea496
     context_sha256_T sha_ctx;
dea496
 #endif
dea496
-#ifdef FEAT_CRYPT
dea496
-    int		    crypt_method_used;
dea496
-#endif
dea496
 
dea496
     if (fname == NULL || *fname == NUL)	/* safety check */
dea496
 	return FAIL;
dea496
@@ -3262,6 +3184,9 @@ buf_write(buf, fname, sfname, start, end
dea496
     write_info.bw_iconv_fd = (iconv_t)-1;
dea496
 # endif
dea496
 #endif
dea496
+#ifdef FEAT_CRYPT
dea496
+    write_info.bw_buffer = buf;
dea496
+#endif
dea496
 
dea496
     /* After writing a file changedtick changes but we don't want to display
dea496
      * the line. */
dea496
@@ -4505,17 +4430,17 @@ restore_backup:
dea496
 #ifdef FEAT_CRYPT
dea496
     if (*buf->b_p_key != NUL && !filtering)
dea496
     {
dea496
-	char_u *header;
dea496
-	int    header_len;
dea496
+	char_u		*header;
dea496
+	int		header_len;
dea496
 
dea496
-	header = prepare_crypt_write(buf, &header_len);
dea496
-	if (header == NULL)
dea496
+	buf->b_cryptstate = crypt_create_for_writing(crypt_get_method_nr(buf),
dea496
+					  buf->b_p_key, &header, &header_len);
dea496
+	if (buf->b_cryptstate == NULL || header == NULL)
dea496
 	    end = 0;
dea496
 	else
dea496
 	{
dea496
-	    /* Write magic number, so that Vim knows that this file is
dea496
-	     * encrypted when reading it again.  This also undergoes utf-8 to
dea496
-	     * ucs-2/4 conversion when needed. */
dea496
+	    /* Write magic number, so that Vim knows how this file is
dea496
+	     * encrypted when reading it back. */
dea496
 	    write_info.bw_buf = header;
dea496
 	    write_info.bw_len = header_len;
dea496
 	    write_info.bw_flags = FIO_NOCONVERT;
dea496
@@ -4769,9 +4694,11 @@ restore_backup:
dea496
 	mch_set_acl(wfname, acl);
dea496
 #endif
dea496
 #ifdef FEAT_CRYPT
dea496
-    crypt_method_used = use_crypt_method;
dea496
-    if (wb_flags & FIO_ENCRYPTED)
dea496
-	crypt_pop_state();
dea496
+    if (buf->b_cryptstate != NULL)
dea496
+    {
dea496
+	crypt_free_state(buf->b_cryptstate);
dea496
+	buf->b_cryptstate = NULL;
dea496
+    }
dea496
 #endif
dea496
 
dea496
 
dea496
@@ -4924,10 +4851,7 @@ restore_backup:
dea496
 #ifdef FEAT_CRYPT
dea496
 	if (wb_flags & FIO_ENCRYPTED)
dea496
 	{
dea496
-	    if (crypt_method_used == 1)
dea496
-		STRCAT(IObuff, _("[blowfish]"));
dea496
-	    else
dea496
-		STRCAT(IObuff, _("[crypted]"));
dea496
+	    crypt_append_msg(buf);
dea496
 	    c = TRUE;
dea496
 	}
dea496
 #endif
dea496
@@ -5740,8 +5664,26 @@ buf_write_bytes(ip)
dea496
 #endif /* FEAT_MBYTE */
dea496
 
dea496
 #ifdef FEAT_CRYPT
dea496
-    if (flags & FIO_ENCRYPTED)		/* encrypt the data */
dea496
-	crypt_encode(buf, len, buf);
dea496
+    if (flags & FIO_ENCRYPTED)
dea496
+    {
dea496
+	/* Encrypt the data. Do it in-place if possible, otherwise use an
dea496
+	 * allocated buffer. */
dea496
+	if (crypt_works_inplace(ip->bw_buffer->b_cryptstate))
dea496
+	{
dea496
+	    crypt_encode_inplace(ip->bw_buffer->b_cryptstate, buf, len);
dea496
+	}
dea496
+	else
dea496
+	{
dea496
+	    char_u *outbuf;
dea496
+
dea496
+	    len = crypt_encode_alloc(curbuf->b_cryptstate, buf, len, &outbuf);
dea496
+	    if (len == 0)
dea496
+		return OK;  /* Crypt layer is buffering, will flush later. */
dea496
+	    wlen = write_eintr(ip->bw_fd, outbuf, len);
dea496
+	    vim_free(outbuf);
dea496
+	    return (wlen < len) ? FAIL : OK;
dea496
+	}
dea496
+    }
dea496
 #endif
dea496
 
dea496
     wlen = write_eintr(ip->bw_fd, buf, len);
dea496
diff -up vim74/src/globals.h.blowfish2 vim74/src/globals.h
dea496
--- vim74/src/globals.h.blowfish2	2017-09-05 14:47:33.909920425 +0200
dea496
+++ vim74/src/globals.h	2017-09-05 14:47:34.950912022 +0200
dea496
@@ -105,10 +105,6 @@ EXTERN int	exec_from_reg INIT(= FALSE);
dea496
 
dea496
 EXTERN int	screen_cleared INIT(= FALSE);	/* screen has been cleared */
dea496
 
dea496
-#ifdef FEAT_CRYPT
dea496
-EXTERN int      use_crypt_method INIT(= 0);
dea496
-#endif
dea496
-
dea496
 /*
dea496
  * When '$' is included in 'cpoptions' option set:
dea496
  * When a change command is given that deletes only part of a line, a dollar
dea496
diff -up vim74/src/main.c.blowfish2 vim74/src/main.c
dea496
--- vim74/src/main.c.blowfish2	2017-09-05 14:47:34.571915081 +0200
dea496
+++ vim74/src/main.c	2017-09-05 14:47:34.955911982 +0200
dea496
@@ -845,8 +845,7 @@ vim_main2(int argc UNUSED, char **argv U
dea496
 #ifdef FEAT_CRYPT
dea496
     if (params.ask_for_key)
dea496
     {
dea496
-	(void)blowfish_self_test();
dea496
-	(void)get_crypt_key(TRUE, TRUE);
dea496
+	(void)crypt_get_key(TRUE, TRUE);
dea496
 	TIME_MSG("getting crypt key");
dea496
     }
dea496
 #endif
dea496
diff -up vim74/src/Makefile.blowfish2 vim74/src/Makefile
dea496
--- vim74/src/Makefile.blowfish2	2017-09-05 14:47:34.847912854 +0200
dea496
+++ vim74/src/Makefile	2017-09-05 14:47:34.956911974 +0200
dea496
@@ -1427,6 +1427,8 @@ BASIC_SRC = \
dea496
 	blowfish.c \
dea496
 	buffer.c \
dea496
 	charset.c \
dea496
+	crypt.c \
dea496
+	crypt_zip.c \
dea496
 	diff.c \
dea496
 	digraph.c \
dea496
 	edit.c \
dea496
@@ -1516,6 +1518,8 @@ OBJ_COMMON = \
dea496
 	objects/buffer.o \
dea496
 	objects/blowfish.o \
dea496
 	objects/charset.o \
dea496
+	objects/crypt.o \
dea496
+	objects/crypt_zip.o \
dea496
 	objects/diff.o \
dea496
 	objects/digraph.o \
dea496
 	objects/edit.o \
dea496
@@ -1585,6 +1589,8 @@ PRO_AUTO = \
dea496
 	blowfish.pro \
dea496
 	buffer.pro \
dea496
 	charset.pro \
dea496
+	crypt.pro \
dea496
+	crypt_zip.pro \
dea496
 	diff.pro \
dea496
 	digraph.pro \
dea496
 	edit.pro \
dea496
@@ -1745,10 +1751,11 @@ xxd/xxd$(EXEEXT): xxd/xxd.c
dea496
 languages:
dea496
 	@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
dea496
 		cd $(PODIR); \
dea496
-		CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix); \
dea496
+		  CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix); \
dea496
 	fi
dea496
 	-@if test -n "$(MAKEMO)" -a -f $(PODIR)/Makefile; then \
dea496
-		cd $(PODIR); CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix) converted; \
dea496
+		cd $(PODIR); \
dea496
+		  CC="$(CC)" $(MAKE) prefix=$(DESTDIR)$(prefix) converted; \
dea496
 	fi
dea496
 
dea496
 # Update the *.po files for changes in the sources.  Only run manually.
dea496
@@ -1874,6 +1881,12 @@ unittest unittests: $(UNITTEST_TARGETS)
dea496
 
dea496
 # Run individual test, assuming that Vim was already compiled.
dea496
 test1 test2 test3 test4 test5 test6 test7 test8 test9 \
dea496
+	test_breakindent \
dea496
+	test_changelist \
dea496
+	test_insertcount \
dea496
+	test_listlbr \
dea496
+	test_listlbr_utf8 \
dea496
+	test_qf_title \
dea496
 	test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 \
dea496
 	test20 test21 test22 test23 test24 test25 test26 test27 test28 test29 \
dea496
 	test30 test31 test32 test33 test34 test35 test36 test37 test38 test39 \
dea496
@@ -2494,6 +2507,12 @@ objects/buffer.o: buffer.c
dea496
 objects/charset.o: charset.c
dea496
 	$(CCC) -o $@ charset.c
dea496
 
dea496
+objects/crypt.o: crypt.c
dea496
+	$(CCC) -o $@ crypt.c
dea496
+
dea496
+objects/crypt_zip.o: crypt_zip.c
dea496
+	$(CCC) -o $@ crypt_zip.c
dea496
+
dea496
 objects/diff.o: diff.c
dea496
 	$(CCC) -o $@ diff.c
dea496
 
dea496
@@ -2843,6 +2862,14 @@ objects/charset.o: charset.c vim.h auto/
dea496
  ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
dea496
  gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
dea496
  arabic.h
dea496
+objects/crypt.o: crypt.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \
dea496
+ ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
dea496
+ gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
dea496
+ arabic.h
dea496
+objects/crypt_zip.o: crypt_zip.c vim.h auto/config.h feature.h os_unix.h \
dea496
+ auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
dea496
+ regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
dea496
+ globals.h farsi.h arabic.h
dea496
 objects/diff.o: diff.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \
dea496
  ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
dea496
  gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
dea496
diff -up vim74/src/memline.c.blowfish2 vim74/src/memline.c
dea496
--- vim74/src/memline.c.blowfish2	2017-09-05 14:47:34.217917939 +0200
dea496
+++ vim74/src/memline.c	2017-09-05 14:47:34.957911966 +0200
dea496
@@ -63,6 +63,15 @@ typedef struct pointer_entry	PTR_EN;
dea496
 #define BLOCK0_ID1     '0'		    /* block 0 id 1 */
dea496
 #define BLOCK0_ID1_C0  'c'		    /* block 0 id 1 'cm' 0 */
dea496
 #define BLOCK0_ID1_C1  'C'		    /* block 0 id 1 'cm' 1 */
dea496
+#define BLOCK0_ID1_C2  'd'		    /* block 0 id 1 'cm' 2 */
dea496
+
dea496
+#if defined(FEAT_CRYPT)
dea496
+static int id1_codes[] = {
dea496
+    BLOCK0_ID1_C0,  /* CRYPT_M_ZIP */
dea496
+    BLOCK0_ID1_C1,  /* CRYPT_M_BF */
dea496
+    BLOCK0_ID1_C2,  /* CRYPT_M_BF2 */
dea496
+};
dea496
+#endif
dea496
 
dea496
 /*
dea496
  * pointer to a block, used in a pointer block
dea496
@@ -151,7 +160,7 @@ struct data_block
dea496
 struct block0
dea496
 {
dea496
     char_u	b0_id[2];	/* id for block 0: BLOCK0_ID0 and BLOCK0_ID1,
dea496
-				 * BLOCK0_ID1_C0, BLOCK0_ID1_C1 */
dea496
+				 * BLOCK0_ID1_C0, BLOCK0_ID1_C1, etc. */
dea496
     char_u	b0_version[10];	/* Vim version string */
dea496
     char_u	b0_page_size[4];/* number of bytes per page */
dea496
     char_u	b0_mtime[4];	/* last modification time of file */
dea496
@@ -226,6 +235,7 @@ typedef enum {
dea496
 } upd_block0_T;
dea496
 
dea496
 #ifdef FEAT_CRYPT
dea496
+static void ml_set_mfp_crypt __ARGS((buf_T *buf));
dea496
 static void ml_set_b0_crypt __ARGS((buf_T *buf, ZERO_BL *b0p));
dea496
 #endif
dea496
 static int ml_check_b0_id __ARGS((ZERO_BL *b0p));
dea496
@@ -256,7 +266,7 @@ static long char_to_long __ARGS((char_u
dea496
 static char_u *make_percent_swname __ARGS((char_u *dir, char_u *name));
dea496
 #endif
dea496
 #ifdef FEAT_CRYPT
dea496
-static void ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
dea496
+static cryptstate_T *ml_crypt_prepare __ARGS((memfile_T *mfp, off_t offset, int reading));
dea496
 #endif
dea496
 #ifdef FEAT_BYTEOFF
dea496
 static void ml_updatechunk __ARGS((buf_T *buf, long line, long len, int updtype));
dea496
@@ -356,8 +366,7 @@ ml_open(buf)
dea496
 	b0p->b0_hname[B0_HNAME_SIZE - 1] = NUL;
dea496
 	long_to_char(mch_get_pid(), b0p->b0_pid);
dea496
 #ifdef FEAT_CRYPT
dea496
-	if (*buf->b_p_key != NUL)
dea496
-	    ml_set_b0_crypt(buf, b0p);
dea496
+	ml_set_b0_crypt(buf, b0p);
dea496
 #endif
dea496
     }
dea496
 
dea496
@@ -422,6 +431,25 @@ error:
dea496
 
dea496
 #if defined(FEAT_CRYPT) || defined(PROTO)
dea496
 /*
dea496
+ * Prepare encryption for "buf" for the current key and method.
dea496
+ */
dea496
+    static void
dea496
+ml_set_mfp_crypt(buf)
dea496
+    buf_T	*buf;
dea496
+{
dea496
+    if (*buf->b_p_key != NUL)
dea496
+    {
dea496
+	int method_nr = crypt_get_method_nr(buf);
dea496
+
dea496
+	if (method_nr > CRYPT_M_ZIP)
dea496
+	{
dea496
+	    /* Generate a seed and store it in the memfile. */
dea496
+	    sha2_seed(buf->b_ml.ml_mfp->mf_seed, MF_SEED_LEN, NULL, 0);
dea496
+	}
dea496
+    }
dea496
+}
dea496
+
dea496
+/*
dea496
  * Prepare encryption for "buf" with block 0 "b0p".
dea496
  */
dea496
     static void
dea496
@@ -433,11 +461,11 @@ ml_set_b0_crypt(buf, b0p)
dea496
 	b0p->b0_id[1] = BLOCK0_ID1;
dea496
     else
dea496
     {
dea496
-	if (get_crypt_method(buf) == 0)
dea496
-	    b0p->b0_id[1] = BLOCK0_ID1_C0;
dea496
-	else
dea496
+	int method_nr = crypt_get_method_nr(buf);
dea496
+
dea496
+	b0p->b0_id[1] = id1_codes[method_nr];
dea496
+	if (method_nr > CRYPT_M_ZIP)
dea496
 	{
dea496
-	    b0p->b0_id[1] = BLOCK0_ID1_C1;
dea496
 	    /* Generate a seed and store it in block 0 and in the memfile. */
dea496
 	    sha2_seed(&b0p->b0_seed, MF_SEED_LEN, NULL, 0);
dea496
 	    mch_memmove(buf->b_ml.ml_mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
dea496
@@ -884,7 +912,8 @@ ml_check_b0_id(b0p)
dea496
     if (b0p->b0_id[0] != BLOCK0_ID0
dea496
 	    || (b0p->b0_id[1] != BLOCK0_ID1
dea496
 		&& b0p->b0_id[1] != BLOCK0_ID1_C0
dea496
-		&& b0p->b0_id[1] != BLOCK0_ID1_C1)
dea496
+		&& b0p->b0_id[1] != BLOCK0_ID1_C1
dea496
+		&& b0p->b0_id[1] != BLOCK0_ID1_C2)
dea496
 	    )
dea496
 	return FAIL;
dea496
     return OK;
dea496
@@ -903,8 +932,19 @@ ml_upd_block0(buf, what)
dea496
     ZERO_BL	*b0p;
dea496
 
dea496
     mfp = buf->b_ml.ml_mfp;
dea496
-    if (mfp == NULL || (hp = mf_get(mfp, (blocknr_T)0, 1)) == NULL)
dea496
+    if (mfp == NULL)
dea496
+	return;
dea496
+    hp = mf_get(mfp, (blocknr_T)0, 1);
dea496
+    if (hp == NULL)
dea496
+    {
dea496
+#ifdef FEAT_CRYPT
dea496
+	/* Possibly update the seed in the memfile before there is a block0. */
dea496
+	if (what == UB_CRYPT)
dea496
+	    ml_set_mfp_crypt(buf);
dea496
+#endif
dea496
 	return;
dea496
+    }
dea496
+
dea496
     b0p = (ZERO_BL *)(hp->bh_data);
dea496
     if (ml_check_b0_id(b0p) == FAIL)
dea496
 	EMSG(_("E304: ml_upd_block0(): Didn't get block 0??"));
dea496
@@ -1252,14 +1292,12 @@ ml_recover()
dea496
     }
dea496
 
dea496
 #ifdef FEAT_CRYPT
dea496
-    if (b0p->b0_id[1] == BLOCK0_ID1_C0)
dea496
-	b0_cm = 0;
dea496
-    else if (b0p->b0_id[1] == BLOCK0_ID1_C1)
dea496
-    {
dea496
-	b0_cm = 1;
dea496
+    for (i = 0; i < (int)(sizeof(id1_codes) / sizeof(int)); ++i)
dea496
+	if (id1_codes[i] == b0p->b0_id[1])
dea496
+	    b0_cm = i;
dea496
+    if (b0_cm > 0)
dea496
 	mch_memmove(mfp->mf_seed, &b0p->b0_seed, MF_SEED_LEN);
dea496
-    }
dea496
-    set_crypt_method(buf, b0_cm);
dea496
+    crypt_set_cm_option(buf, b0_cm < 0 ? 0 : b0_cm);
dea496
 #else
dea496
     if (b0p->b0_id[1] != BLOCK0_ID1)
dea496
     {
dea496
@@ -1386,7 +1424,7 @@ ml_recover()
dea496
 	}
dea496
 	else
dea496
 	    smsg((char_u *)_(need_key_msg), fname_used);
dea496
-	buf->b_p_key = get_crypt_key(FALSE, FALSE);
dea496
+	buf->b_p_key = crypt_get_key(FALSE, FALSE);
dea496
 	if (buf->b_p_key == NULL)
dea496
 	    buf->b_p_key = curbuf->b_p_key;
dea496
 	else if (*buf->b_p_key == NUL)
dea496
@@ -4813,6 +4851,7 @@ ml_encrypt_data(mfp, data, offset, size)
dea496
     char_u	*text_start;
dea496
     char_u	*new_data;
dea496
     int		text_len;
dea496
+    cryptstate_T *state;
dea496
 
dea496
     if (dp->db_id != DATA_ID)
dea496
 	return data;
dea496
@@ -4828,10 +4867,9 @@ ml_encrypt_data(mfp, data, offset, size)
dea496
     mch_memmove(new_data, dp, head_end - (char_u *)dp);
dea496
 
dea496
     /* Encrypt the text. */
dea496
-    crypt_push_state();
dea496
-    ml_crypt_prepare(mfp, offset, FALSE);
dea496
-    crypt_encode(text_start, text_len, new_data + dp->db_txt_start);
dea496
-    crypt_pop_state();
dea496
+    state = ml_crypt_prepare(mfp, offset, FALSE);
dea496
+    crypt_encode(state, text_start, text_len, new_data + dp->db_txt_start);
dea496
+    crypt_free_state(state);
dea496
 
dea496
     /* Clear the gap. */
dea496
     if (head_end < text_start)
dea496
@@ -4854,6 +4892,7 @@ ml_decrypt_data(mfp, data, offset, size)
dea496
     char_u	*head_end;
dea496
     char_u	*text_start;
dea496
     int		text_len;
dea496
+    cryptstate_T *state;
dea496
 
dea496
     if (dp->db_id == DATA_ID)
dea496
     {
dea496
@@ -4866,17 +4905,17 @@ ml_decrypt_data(mfp, data, offset, size)
dea496
 	    return;  /* data was messed up */
dea496
 
dea496
 	/* Decrypt the text in place. */
dea496
-	crypt_push_state();
dea496
-	ml_crypt_prepare(mfp, offset, TRUE);
dea496
-	crypt_decode(text_start, text_len);
dea496
-	crypt_pop_state();
dea496
+	state = ml_crypt_prepare(mfp, offset, TRUE);
dea496
+	crypt_decode_inplace(state, text_start, text_len);
dea496
+	crypt_free_state(state);
dea496
     }
dea496
 }
dea496
 
dea496
 /*
dea496
  * Prepare for encryption/decryption, using the key, seed and offset.
dea496
+ * Return an allocated cryptstate_T *.
dea496
  */
dea496
-    static void
dea496
+    static cryptstate_T *
dea496
 ml_crypt_prepare(mfp, offset, reading)
dea496
     memfile_T	*mfp;
dea496
     off_t	offset;
dea496
@@ -4884,38 +4923,37 @@ ml_crypt_prepare(mfp, offset, reading)
dea496
 {
dea496
     buf_T	*buf = mfp->mf_buffer;
dea496
     char_u	salt[50];
dea496
-    int		method;
dea496
+    int		method_nr;
dea496
     char_u	*key;
dea496
     char_u	*seed;
dea496
 
dea496
     if (reading && mfp->mf_old_key != NULL)
dea496
     {
dea496
 	/* Reading back blocks with the previous key/method/seed. */
dea496
-	method = mfp->mf_old_cm;
dea496
+	method_nr = mfp->mf_old_cm;
dea496
 	key = mfp->mf_old_key;
dea496
 	seed = mfp->mf_old_seed;
dea496
     }
dea496
     else
dea496
     {
dea496
-	method = get_crypt_method(buf);
dea496
+	method_nr = crypt_get_method_nr(buf);
dea496
 	key = buf->b_p_key;
dea496
 	seed = mfp->mf_seed;
dea496
     }
dea496
 
dea496
-    use_crypt_method = method;  /* select pkzip or blowfish */
dea496
-    if (method == 0)
dea496
+    if (method_nr == CRYPT_M_ZIP)
dea496
     {
dea496
+	/* For PKzip: Append the offset to the key, so that we use a different
dea496
+	 * key for every block. */
dea496
 	vim_snprintf((char *)salt, sizeof(salt), "%s%ld", key, (long)offset);
dea496
-	crypt_init_keys(salt);
dea496
-    }
dea496
-    else
dea496
-    {
dea496
-	/* Using blowfish, add salt and seed. We use the byte offset of the
dea496
-	 * block for the salt. */
dea496
-	vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
dea496
-	bf_key_init(key, salt, (int)STRLEN(salt));
dea496
-	bf_ofb_init(seed, MF_SEED_LEN);
dea496
+	return crypt_create(method_nr, salt, NULL, 0, NULL, 0);
dea496
     }
dea496
+
dea496
+    /* Using blowfish or better: add salt and seed. We use the byte offset
dea496
+     * of the block for the salt. */
dea496
+    vim_snprintf((char *)salt, sizeof(salt), "%ld", (long)offset);
dea496
+    return crypt_create(method_nr, key, salt, (int)STRLEN(salt),
dea496
+							   seed, MF_SEED_LEN);
dea496
 }
dea496
 
dea496
 #endif
dea496
diff -up vim74/src/misc2.c.blowfish2 vim74/src/misc2.c
dea496
--- vim74/src/misc2.c.blowfish2	2017-09-05 14:47:34.461915969 +0200
dea496
+++ vim74/src/misc2.c	2017-09-05 14:47:34.959911949 +0200
dea496
@@ -3803,322 +3803,6 @@ update_mouseshape(shape_idx)
dea496
 #endif /* CURSOR_SHAPE */
dea496
 
dea496
 
dea496
-#ifdef FEAT_CRYPT
dea496
-/*
dea496
- * Optional encryption support.
dea496
- * Mohsin Ahmed, mosh@sasi.com, 98-09-24
dea496
- * Based on zip/crypt sources.
dea496
- *
dea496
- * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
dea496
- * most countries.  There are a few exceptions, but that still should not be a
dea496
- * problem since this code was originally created in Europe and India.
dea496
- *
dea496
- * Blowfish addition originally made by Mohsin Ahmed,
dea496
- * http://www.cs.albany.edu/~mosh 2010-03-14
dea496
- * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
dea496
- * and sha256 by Christophe Devine.
dea496
- */
dea496
-
dea496
-/* from zip.h */
dea496
-
dea496
-typedef unsigned short ush;	/* unsigned 16-bit value */
dea496
-typedef unsigned long  ulg;	/* unsigned 32-bit value */
dea496
-
dea496
-static void make_crc_tab __ARGS((void));
dea496
-
dea496
-static ulg crc_32_tab[256];
dea496
-
dea496
-/*
dea496
- * Fill the CRC table.
dea496
- */
dea496
-    static void
dea496
-make_crc_tab()
dea496
-{
dea496
-    ulg		s,t,v;
dea496
-    static int	done = FALSE;
dea496
-
dea496
-    if (done)
dea496
-	return;
dea496
-    for (t = 0; t < 256; t++)
dea496
-    {
dea496
-	v = t;
dea496
-	for (s = 0; s < 8; s++)
dea496
-	    v = (v >> 1) ^ ((v & 1) * (ulg)0xedb88320L);
dea496
-	crc_32_tab[t] = v;
dea496
-    }
dea496
-    done = TRUE;
dea496
-}
dea496
-
dea496
-#define CRC32(c, b) (crc_32_tab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
dea496
-
dea496
-static ulg keys[3]; /* keys defining the pseudo-random sequence */
dea496
-
dea496
-/*
dea496
- * Return the next byte in the pseudo-random sequence.
dea496
- */
dea496
-#define DECRYPT_BYTE_ZIP(t) { \
dea496
-    ush temp; \
dea496
- \
dea496
-    temp = (ush)keys[2] | 2; \
dea496
-    t = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff); \
dea496
-}
dea496
-
dea496
-/*
dea496
- * Update the encryption keys with the next byte of plain text.
dea496
- */
dea496
-#define UPDATE_KEYS_ZIP(c) { \
dea496
-    keys[0] = CRC32(keys[0], (c)); \
dea496
-    keys[1] += keys[0] & 0xff; \
dea496
-    keys[1] = keys[1] * 134775813L + 1; \
dea496
-    keys[2] = CRC32(keys[2], (int)(keys[1] >> 24)); \
dea496
-}
dea496
-
dea496
-static int crypt_busy = 0;
dea496
-static ulg saved_keys[3];
dea496
-static int saved_crypt_method;
dea496
-
dea496
-/*
dea496
- * Return int value for crypt method string:
dea496
- * 0 for "zip", the old method.  Also for any non-valid value.
dea496
- * 1 for "blowfish".
dea496
- */
dea496
-    int
dea496
-crypt_method_from_string(s)
dea496
-    char_u  *s;
dea496
-{
dea496
-    return *s == 'b' ? 1 : 0;
dea496
-}
dea496
-
dea496
-/*
dea496
- * Get the crypt method for buffer "buf" as a number.
dea496
- */
dea496
-    int
dea496
-get_crypt_method(buf)
dea496
-    buf_T *buf;
dea496
-{
dea496
-    return crypt_method_from_string(*buf->b_p_cm == NUL ? p_cm : buf->b_p_cm);
dea496
-}
dea496
-
dea496
-/*
dea496
- * Set the crypt method for buffer "buf" to "method" using the int value as
dea496
- * returned by crypt_method_from_string().
dea496
- */
dea496
-    void
dea496
-set_crypt_method(buf, method)
dea496
-    buf_T   *buf;
dea496
-    int	    method;
dea496
-{
dea496
-    free_string_option(buf->b_p_cm);
dea496
-    buf->b_p_cm = vim_strsave((char_u *)(method == 0 ? "zip" : "blowfish"));
dea496
-}
dea496
-
dea496
-/*
dea496
- * Prepare for initializing encryption.  If already doing encryption then save
dea496
- * the state.
dea496
- * Must always be called symmetrically with crypt_pop_state().
dea496
- */
dea496
-    void
dea496
-crypt_push_state()
dea496
-{
dea496
-    if (crypt_busy == 1)
dea496
-    {
dea496
-	/* save the state */
dea496
-	if (use_crypt_method == 0)
dea496
-	{
dea496
-	    saved_keys[0] = keys[0];
dea496
-	    saved_keys[1] = keys[1];
dea496
-	    saved_keys[2] = keys[2];
dea496
-	}
dea496
-	else
dea496
-	    bf_crypt_save();
dea496
-	saved_crypt_method = use_crypt_method;
dea496
-    }
dea496
-    else if (crypt_busy > 1)
dea496
-	EMSG2(_(e_intern2), "crypt_push_state()");
dea496
-    ++crypt_busy;
dea496
-}
dea496
-
dea496
-/*
dea496
- * End encryption.  If doing encryption before crypt_push_state() then restore
dea496
- * the saved state.
dea496
- * Must always be called symmetrically with crypt_push_state().
dea496
- */
dea496
-    void
dea496
-crypt_pop_state()
dea496
-{
dea496
-    --crypt_busy;
dea496
-    if (crypt_busy == 1)
dea496
-    {
dea496
-	use_crypt_method = saved_crypt_method;
dea496
-	if (use_crypt_method == 0)
dea496
-	{
dea496
-	    keys[0] = saved_keys[0];
dea496
-	    keys[1] = saved_keys[1];
dea496
-	    keys[2] = saved_keys[2];
dea496
-	}
dea496
-	else
dea496
-	    bf_crypt_restore();
dea496
-    }
dea496
-}
dea496
-
dea496
-/*
dea496
- * Encrypt "from[len]" into "to[len]".
dea496
- * "from" and "to" can be equal to encrypt in place.
dea496
- */
dea496
-    void
dea496
-crypt_encode(from, len, to)
dea496
-    char_u	*from;
dea496
-    size_t	len;
dea496
-    char_u	*to;
dea496
-{
dea496
-    size_t	i;
dea496
-    int		ztemp, t;
dea496
-
dea496
-    if (use_crypt_method == 0)
dea496
-	for (i = 0; i < len; ++i)
dea496
-	{
dea496
-	    ztemp = from[i];
dea496
-	    DECRYPT_BYTE_ZIP(t);
dea496
-	    UPDATE_KEYS_ZIP(ztemp);
dea496
-	    to[i] = t ^ ztemp;
dea496
-	}
dea496
-    else
dea496
-	bf_crypt_encode(from, len, to);
dea496
-}
dea496
-
dea496
-/*
dea496
- * Decrypt "ptr[len]" in place.
dea496
- */
dea496
-    void
dea496
-crypt_decode(ptr, len)
dea496
-    char_u	*ptr;
dea496
-    long	len;
dea496
-{
dea496
-    char_u *p;
dea496
-
dea496
-    if (use_crypt_method == 0)
dea496
-	for (p = ptr; p < ptr + len; ++p)
dea496
-	{
dea496
-	    ush temp;
dea496
-
dea496
-	    temp = (ush)keys[2] | 2;
dea496
-	    temp = (int)(((unsigned)(temp * (temp ^ 1U)) >> 8) & 0xff);
dea496
-	    UPDATE_KEYS_ZIP(*p ^= temp);
dea496
-	}
dea496
-    else
dea496
-	bf_crypt_decode(ptr, len);
dea496
-}
dea496
-
dea496
-/*
dea496
- * Initialize the encryption keys and the random header according to
dea496
- * the given password.
dea496
- * If "passwd" is NULL or empty, don't do anything.
dea496
- */
dea496
-    void
dea496
-crypt_init_keys(passwd)
dea496
-    char_u *passwd;		/* password string with which to modify keys */
dea496
-{
dea496
-    if (passwd != NULL && *passwd != NUL)
dea496
-    {
dea496
-	if (use_crypt_method == 0)
dea496
-	{
dea496
-	    char_u *p;
dea496
-
dea496
-	    make_crc_tab();
dea496
-	    keys[0] = 305419896L;
dea496
-	    keys[1] = 591751049L;
dea496
-	    keys[2] = 878082192L;
dea496
-	    for (p = passwd; *p!= NUL; ++p)
dea496
-	    {
dea496
-		UPDATE_KEYS_ZIP((int)*p);
dea496
-	    }
dea496
-	}
dea496
-	else
dea496
-	    bf_crypt_init_keys(passwd);
dea496
-    }
dea496
-}
dea496
-
dea496
-/*
dea496
- * Free an allocated crypt key.  Clear the text to make sure it doesn't stay
dea496
- * in memory anywhere.
dea496
- */
dea496
-    void
dea496
-free_crypt_key(key)
dea496
-    char_u *key;
dea496
-{
dea496
-    char_u *p;
dea496
-
dea496
-    if (key != NULL)
dea496
-    {
dea496
-	for (p = key; *p != NUL; ++p)
dea496
-	    *p = 0;
dea496
-	vim_free(key);
dea496
-    }
dea496
-}
dea496
-
dea496
-/*
dea496
- * Ask the user for a crypt key.
dea496
- * When "store" is TRUE, the new key is stored in the 'key' option, and the
dea496
- * 'key' option value is returned: Don't free it.
dea496
- * When "store" is FALSE, the typed key is returned in allocated memory.
dea496
- * Returns NULL on failure.
dea496
- */
dea496
-    char_u *
dea496
-get_crypt_key(store, twice)
dea496
-    int		store;
dea496
-    int		twice;	    /* Ask for the key twice. */
dea496
-{
dea496
-    char_u	*p1, *p2 = NULL;
dea496
-    int		round;
dea496
-
dea496
-    for (round = 0; ; ++round)
dea496
-    {
dea496
-	cmdline_star = TRUE;
dea496
-	cmdline_row = msg_row;
dea496
-	p1 = getcmdline_prompt(NUL, round == 0
dea496
-		? (char_u *)_("Enter encryption key: ")
dea496
-		: (char_u *)_("Enter same key again: "), 0, EXPAND_NOTHING,
dea496
-		NULL);
dea496
-	cmdline_star = FALSE;
dea496
-
dea496
-	if (p1 == NULL)
dea496
-	    break;
dea496
-
dea496
-	if (round == twice)
dea496
-	{
dea496
-	    if (p2 != NULL && STRCMP(p1, p2) != 0)
dea496
-	    {
dea496
-		MSG(_("Keys don't match!"));
dea496
-		free_crypt_key(p1);
dea496
-		free_crypt_key(p2);
dea496
-		p2 = NULL;
dea496
-		round = -1;		/* do it again */
dea496
-		continue;
dea496
-	    }
dea496
-
dea496
-	    if (store)
dea496
-	    {
dea496
-		set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
dea496
-		free_crypt_key(p1);
dea496
-		p1 = curbuf->b_p_key;
dea496
-	    }
dea496
-	    break;
dea496
-	}
dea496
-	p2 = p1;
dea496
-    }
dea496
-
dea496
-    /* since the user typed this, no need to wait for return */
dea496
-    if (msg_didout)
dea496
-	msg_putchar('\n');
dea496
-    need_wait_return = FALSE;
dea496
-    msg_didout = FALSE;
dea496
-
dea496
-    free_crypt_key(p2);
dea496
-    return p1;
dea496
-}
dea496
-
dea496
-#endif /* FEAT_CRYPT */
dea496
-
dea496
 /* TODO: make some #ifdef for this */
dea496
 /*--------[ file searching ]-------------------------------------------------*/
dea496
 /*
dea496
@@ -6588,8 +6272,23 @@ put_time(fd, the_time)
dea496
     FILE	*fd;
dea496
     time_t	the_time;
dea496
 {
dea496
+    char_u	buf[8];
dea496
+
dea496
+    time_to_bytes(the_time, buf);
dea496
+    fwrite(buf, (size_t)8, (size_t)1, fd);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Write time_t to "buf[8]".
dea496
+ */
dea496
+    void
dea496
+time_to_bytes(the_time, buf)
dea496
+    time_t	the_time;
dea496
+    char_u	*buf;
dea496
+{
dea496
     int		c;
dea496
     int		i;
dea496
+    int		bi = 0;
dea496
     time_t	wtime = the_time;
dea496
 
dea496
     /* time_t can be up to 8 bytes in size, more than long_u, thus we
dea496
@@ -6603,7 +6302,7 @@ put_time(fd, the_time)
dea496
     {
dea496
 	if (i + 1 > (int)sizeof(time_t))
dea496
 	    /* ">>" doesn't work well when shifting more bits than avail */
dea496
-	    putc(0, fd);
dea496
+	    buf[bi++] = 0;
dea496
 	else
dea496
 	{
dea496
 #if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4
dea496
@@ -6611,7 +6310,7 @@ put_time(fd, the_time)
dea496
 #else
dea496
 	    c = (int)((long_u)wtime >> (i * 8));
dea496
 #endif
dea496
-	    putc(c, fd);
dea496
+	    buf[bi++] = c;
dea496
 	}
dea496
     }
dea496
 }
dea496
diff -up vim74/src/option.c.blowfish2 vim74/src/option.c
dea496
--- vim74/src/option.c.blowfish2	2017-09-05 14:47:34.899912434 +0200
dea496
+++ vim74/src/option.c	2017-09-05 14:47:34.961911933 +0200
dea496
@@ -2969,7 +2969,7 @@ static char *(p_bg_values[]) = {"light",
dea496
 static char *(p_nf_values[]) = {"octal", "hex", "alpha", NULL};
dea496
 static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
dea496
 #ifdef FEAT_CRYPT
dea496
-static char *(p_cm_values[]) = {"zip", "blowfish", NULL};
dea496
+static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2", NULL};
dea496
 #endif
dea496
 #ifdef FEAT_CMDL_COMPL
dea496
 static char *(p_wop_values[]) = {"tagfile", NULL};
dea496
@@ -6156,7 +6156,7 @@ did_set_string_option(opt_idx, varp, new
dea496
 # endif
dea496
 	if (STRCMP(curbuf->b_p_key, oldval) != 0)
dea496
 	    /* Need to update the swapfile. */
dea496
-	    ml_set_crypt_key(curbuf, oldval, get_crypt_method(curbuf));
dea496
+	    ml_set_crypt_key(curbuf, oldval, crypt_get_method_nr(curbuf));
dea496
     }
dea496
 
dea496
     else if (gvarp == &p_cm)
dea496
@@ -6167,7 +6167,7 @@ did_set_string_option(opt_idx, varp, new
dea496
 	    p = p_cm;
dea496
 	if (check_opt_strings(p, p_cm_values, TRUE) != OK)
dea496
 	    errmsg = e_invarg;
dea496
-	else if (get_crypt_method(curbuf) > 0 && blowfish_self_test() == FAIL)
dea496
+	else if (crypt_self_test() == FAIL)
dea496
 	    errmsg = e_invarg;
dea496
 	else
dea496
 	{
dea496
@@ -6179,6 +6179,14 @@ did_set_string_option(opt_idx, varp, new
dea496
 		p_cm = vim_strsave((char_u *)"zip");
dea496
 		new_value_alloced = TRUE;
dea496
 	    }
dea496
+	    /* When using ":set cm=name" the local value is going to be empty.
dea496
+	     * Do that here, otherwise the crypt functions will still use the
dea496
+	     * local value. */
dea496
+	    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
dea496
+	    {
dea496
+		free_string_option(curbuf->b_p_cm);
dea496
+		curbuf->b_p_cm = empty_option;
dea496
+	    }
dea496
 
dea496
 	    /* Need to update the swapfile when the effective method changed.
dea496
 	     * Set "s" to the effective old value, "p" to the effective new
dea496
@@ -6193,7 +6201,7 @@ did_set_string_option(opt_idx, varp, new
dea496
 		p = curbuf->b_p_cm;
dea496
 	    if (STRCMP(s, p) != 0)
dea496
 		ml_set_crypt_key(curbuf, curbuf->b_p_key,
dea496
-						 crypt_method_from_string(s));
dea496
+						crypt_method_nr_from_name(s));
dea496
 
dea496
 	    /* If the global value changes need to update the swapfile for all
dea496
 	     * buffers using that value. */
dea496
@@ -6204,7 +6212,7 @@ did_set_string_option(opt_idx, varp, new
dea496
 		for (buf = firstbuf; buf != NULL; buf = buf->b_next)
dea496
 		    if (buf != curbuf && *buf->b_p_cm == NUL)
dea496
 			ml_set_crypt_key(buf, buf->b_p_key,
dea496
-					    crypt_method_from_string(oldval));
dea496
+					   crypt_method_nr_from_name(oldval));
dea496
 	    }
dea496
 	}
dea496
     }
dea496
diff -up vim74/src/proto/blowfish.pro.blowfish2 vim74/src/proto/blowfish.pro
dea496
--- vim74/src/proto/blowfish.pro.blowfish2	2013-08-10 13:37:06.000000000 +0200
dea496
+++ vim74/src/proto/blowfish.pro	2017-09-05 14:47:34.964911909 +0200
dea496
@@ -1,10 +1,6 @@
dea496
 /* blowfish.c */
dea496
-void bf_key_init __ARGS((char_u *password, char_u *salt, int salt_len));
dea496
-void bf_ofb_init __ARGS((char_u *iv, int iv_len));
dea496
-void bf_crypt_encode __ARGS((char_u *from, size_t len, char_u *to));
dea496
-void bf_crypt_decode __ARGS((char_u *ptr, long len));
dea496
-void bf_crypt_init_keys __ARGS((char_u *passwd));
dea496
-void bf_crypt_save __ARGS((void));
dea496
-void bf_crypt_restore __ARGS((void));
dea496
+void crypt_blowfish_encode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
dea496
+void crypt_blowfish_decode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
dea496
+void crypt_blowfish_init __ARGS((cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len));
dea496
 int blowfish_self_test __ARGS((void));
dea496
 /* vim: set ft=c : */
dea496
diff -up vim74/src/proto/crypt.pro.blowfish2 vim74/src/proto/crypt.pro
dea496
--- vim74/src/proto/crypt.pro.blowfish2	2017-09-05 14:47:34.965911901 +0200
dea496
+++ vim74/src/proto/crypt.pro	2017-09-05 14:47:34.965911901 +0200
dea496
@@ -0,0 +1,24 @@
dea496
+/* crypt.c */
dea496
+int crypt_method_nr_from_name __ARGS((char_u *name));
dea496
+int crypt_method_nr_from_magic __ARGS((char *ptr, int len));
dea496
+int crypt_works_inplace __ARGS((cryptstate_T *state));
dea496
+int crypt_get_method_nr __ARGS((buf_T *buf));
dea496
+int crypt_whole_undofile __ARGS((int method_nr));
dea496
+int crypt_get_header_len __ARGS((int method_nr));
dea496
+void crypt_set_cm_option __ARGS((buf_T *buf, int method_nr));
dea496
+int crypt_self_test __ARGS((void));
dea496
+cryptstate_T *crypt_create __ARGS((int method_nr, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len));
dea496
+cryptstate_T *crypt_create_from_header __ARGS((int method_nr, char_u *key, char_u *header));
dea496
+cryptstate_T *crypt_create_from_file __ARGS((FILE *fp, char_u *key));
dea496
+cryptstate_T *crypt_create_for_writing __ARGS((int method_nr, char_u *key, char_u **header, int *header_len));
dea496
+void crypt_free_state __ARGS((cryptstate_T *state));
dea496
+long crypt_encode_alloc __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u **newptr));
dea496
+long crypt_decode_alloc __ARGS((cryptstate_T *state, char_u *ptr, long len, char_u **newptr));
dea496
+void crypt_encode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
dea496
+void crypt_decode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
dea496
+void crypt_encode_inplace __ARGS((cryptstate_T *state, char_u *buf, size_t len));
dea496
+void crypt_decode_inplace __ARGS((cryptstate_T *state, char_u *buf, size_t len));
dea496
+void crypt_free_key __ARGS((char_u *key));
dea496
+char_u *crypt_get_key __ARGS((int store, int twice));
dea496
+void crypt_append_msg __ARGS((buf_T *buf));
dea496
+/* vim: set ft=c : */
dea496
diff -up vim74/src/proto/crypt_zip.pro.blowfish2 vim74/src/proto/crypt_zip.pro
dea496
--- vim74/src/proto/crypt_zip.pro.blowfish2	2017-09-05 14:47:34.965911901 +0200
dea496
+++ vim74/src/proto/crypt_zip.pro	2017-09-05 14:47:34.965911901 +0200
dea496
@@ -0,0 +1,5 @@
dea496
+/* crypt_zip.c */
dea496
+void crypt_zip_init __ARGS((cryptstate_T *state, char_u *key, char_u *salt, int salt_len, char_u *seed, int seed_len));
dea496
+void crypt_zip_encode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
dea496
+void crypt_zip_decode __ARGS((cryptstate_T *state, char_u *from, size_t len, char_u *to));
dea496
+/* vim: set ft=c : */
dea496
diff -up vim74/src/proto/fileio.pro.blowfish2 vim74/src/proto/fileio.pro
dea496
--- vim74/src/proto/fileio.pro.blowfish2	2013-08-10 13:37:11.000000000 +0200
dea496
+++ vim74/src/proto/fileio.pro	2017-09-05 14:47:34.965911901 +0200
dea496
@@ -4,8 +4,6 @@ int readfile __ARGS((char_u *fname, char
dea496
 int prep_exarg __ARGS((exarg_T *eap, buf_T *buf));
dea496
 void set_file_options __ARGS((int set_options, exarg_T *eap));
dea496
 void set_forced_fenc __ARGS((exarg_T *eap));
dea496
-int prepare_crypt_read __ARGS((FILE *fp));
dea496
-char_u *prepare_crypt_write __ARGS((buf_T *buf, int *lenp));
dea496
 int check_file_readonly __ARGS((char_u *fname, int perm));
dea496
 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));
dea496
 void msg_add_fname __ARGS((buf_T *buf, char_u *fname));
dea496
diff -up vim74/src/proto.h.blowfish2 vim74/src/proto.h
dea496
--- vim74/src/proto.h.blowfish2	2013-02-26 14:18:19.000000000 +0100
dea496
+++ vim74/src/proto.h	2017-09-05 14:47:34.966911893 +0200
dea496
@@ -70,6 +70,8 @@ extern int _stricoll __ARGS((char *a, ch
dea496
 
dea496
 # ifdef FEAT_CRYPT
dea496
 #  include "blowfish.pro"
dea496
+#  include "crypt.pro"
dea496
+#  include "crypt_zip.pro"
dea496
 # endif
dea496
 # include "buffer.pro"
dea496
 # include "charset.pro"
dea496
diff -up vim74/src/proto/misc2.pro.blowfish2 vim74/src/proto/misc2.pro
dea496
--- vim74/src/proto/misc2.pro.blowfish2	2013-08-10 13:37:20.000000000 +0200
dea496
+++ vim74/src/proto/misc2.pro	2017-09-05 14:47:34.966911893 +0200
dea496
@@ -84,16 +84,6 @@ int illegal_slash __ARGS((char *name));
dea496
 char_u *parse_shape_opt __ARGS((int what));
dea496
 int get_shape_idx __ARGS((int mouse));
dea496
 void update_mouseshape __ARGS((int shape_idx));
dea496
-int crypt_method_from_string __ARGS((char_u *s));
dea496
-int get_crypt_method __ARGS((buf_T *buf));
dea496
-void set_crypt_method __ARGS((buf_T *buf, int method));
dea496
-void crypt_push_state __ARGS((void));
dea496
-void crypt_pop_state __ARGS((void));
dea496
-void crypt_encode __ARGS((char_u *from, size_t len, char_u *to));
dea496
-void crypt_decode __ARGS((char_u *ptr, long len));
dea496
-void crypt_init_keys __ARGS((char_u *passwd));
dea496
-void free_crypt_key __ARGS((char_u *key));
dea496
-char_u *get_crypt_key __ARGS((int store, int twice));
dea496
 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));
dea496
 char_u *vim_findfile_stopdir __ARGS((char_u *buf));
dea496
 void vim_findfile_cleanup __ARGS((void *ctx));
dea496
@@ -116,5 +106,6 @@ time_t get8ctime __ARGS((FILE *fd));
dea496
 char_u *read_string __ARGS((FILE *fd, int cnt));
dea496
 int put_bytes __ARGS((FILE *fd, long_u nr, int len));
dea496
 void put_time __ARGS((FILE *fd, time_t the_time));
dea496
+void time_to_bytes __ARGS((time_t the_time, char_u *buf));
dea496
 int has_non_ascii __ARGS((char_u *s));
dea496
 /* vim: set ft=c : */
dea496
diff -up vim74/src/structs.h.blowfish2 vim74/src/structs.h
dea496
--- vim74/src/structs.h.blowfish2	2017-09-05 14:47:34.839912918 +0200
dea496
+++ vim74/src/structs.h	2017-09-05 14:47:34.967911885 +0200
dea496
@@ -1240,6 +1240,24 @@ typedef struct {
dea496
 } syn_time_T;
dea496
 #endif
dea496
 
dea496
+#ifdef FEAT_CRYPT
dea496
+/*
dea496
+ * Structure to hold the type of encryption and the state of encryption or
dea496
+ * decryption.
dea496
+ */
dea496
+typedef struct {
dea496
+    int	    method_nr;
dea496
+    void    *method_state;  /* method-specific state information */
dea496
+} cryptstate_T;
dea496
+
dea496
+/* values for method_nr */
dea496
+# define CRYPT_M_ZIP	0
dea496
+# define CRYPT_M_BF	1
dea496
+# define CRYPT_M_BF2	2
dea496
+# define CRYPT_M_COUNT	3 /* number of crypt methods */
dea496
+#endif
dea496
+
dea496
+
dea496
 /*
dea496
  * These are items normally related to a buffer.  But when using ":ownsyntax"
dea496
  * a window may have its own instance.
dea496
@@ -1765,7 +1783,12 @@ struct file_buffer
dea496
     int		b_was_netbeans_file;/* TRUE if b_netbeans_file was once set */
dea496
 #endif
dea496
 
dea496
-};
dea496
+#ifdef FEAT_CRYPT
dea496
+    cryptstate_T *b_cryptstate;	/* Encryption state while reading or writing
dea496
+				 * the file. NULL when not using encryption. */
dea496
+#endif
dea496
+
dea496
+}; /* file_buffer */
dea496
 
dea496
 
dea496
 #ifdef FEAT_DIFF
dea496
diff -up vim74/src/testdir/test72.in.blowfish2 vim74/src/testdir/test72.in
dea496
--- vim74/src/testdir/test72.in.blowfish2	2012-01-04 19:04:17.000000000 +0100
dea496
+++ vim74/src/testdir/test72.in	2017-09-05 15:23:47.590060199 +0200
dea496
@@ -4,6 +4,7 @@ undo-able pieces.  Do that by setting 'u
dea496
 
dea496
 STARTTEST
dea496
 :so small.vim
dea496
+:set belloff=all
dea496
 :"
dea496
 :" Test 'undofile': first a simple one-line change.
dea496
 :set nocompatible viminfo+=nviminfo visualbell
dea496
@@ -25,7 +26,6 @@ u:.w! test.out
dea496
 :set undofile
dea496
 :bwipe!
dea496
 :e Xtestfile
dea496
-:" TODO: this beeps
dea496
 u:.w >>test.out
dea496
 :"
dea496
 :" Test 'undofile', add 10 lines, delete 6 lines, undo 3
dea496
@@ -81,7 +81,8 @@ uu:w >>test.out
dea496
 :"
dea496
 :" With encryption, cryptmethod=blowfish
dea496
 :e! Xtestfile
dea496
-:set undofile cm=blowfish
dea496
+rubbish
dea496
+:set undofile cm=blowfish ff&
dea496
 ggdGijan
dea496
 feb
dea496
 mar
dea496
@@ -104,8 +105,38 @@ u:.w >>test.out
dea496
 u:.w >>test.out
dea496
 u:.w >>test.out
dea496
 :"
dea496
+:" With encryption, cryptmethod=blowfish2
dea496
+:e! Xtestfile
dea496
+rubbish
dea496
+:set undofile cm=blowfish2 ff&
dea496
+ggdGijan
dea496
+feb
dea496
+mar
dea496
+apr
dea496
+jun?:set ul=100
dea496
+kk0ifoo ?:set ul=100
dea496
+dd:set ul=100
dea496
+ibar ?:set ul=100
dea496
+:X
dea496
+foo2bar
dea496
+foo2bar
dea496
+:w!
dea496
+:bwipe!
dea496
+:e Xtestfile
dea496
+foo2bar
dea496
+:set key=
dea496
+/bar
dea496
+:.w >>test.out
dea496
+u:.w >>test.out
dea496
+u:.w >>test.out
dea496
+u:.w >>test.out
dea496
+:"
dea496
 :" Rename the undo file so that it gets cleaned up.
dea496
-:call rename(".Xtestfile.un~", "Xtestundo")
dea496
+:if has("vms")
dea496
+: call rename("_un_Xtestfile", "Xtestundo")
dea496
+:else
dea496
+: call rename(".Xtestfile.un~", "Xtestundo")
dea496
+:endif
dea496
 :qa!
dea496
 ENDTEST
dea496
 
dea496
diff -up vim74/src/testdir/test72.ok.blowfish2 vim74/src/testdir/test72.ok
dea496
--- vim74/src/testdir/test72.ok.blowfish2	2012-01-04 19:04:17.000000000 +0100
dea496
+++ vim74/src/testdir/test72.ok	2017-09-05 15:23:47.596060147 +0200
dea496
@@ -25,3 +25,7 @@ bar apr
dea496
 apr
dea496
 foo mar
dea496
 mar
dea496
+bar apr
dea496
+apr
dea496
+foo mar
dea496
+mar
dea496
diff -up vim74/src/undo.c.blowfish2 vim74/src/undo.c
dea496
--- vim74/src/undo.c.blowfish2	2017-09-05 14:47:34.740913717 +0200
dea496
+++ vim74/src/undo.c	2017-09-05 14:47:34.973911836 +0200
dea496
@@ -81,8 +81,25 @@
dea496
 #define UH_MAGIC 0x18dade	/* value for uh_magic when in use */
dea496
 #define UE_MAGIC 0xabc123	/* value for ue_magic when in use */
dea496
 
dea496
+/* Size of buffer used for encryption. */
dea496
+#define CRYPT_BUF_SIZE 8192
dea496
+
dea496
 #include "vim.h"
dea496
 
dea496
+/* Structure passed around between functions.
dea496
+ * Avoids passing cryptstate_T when encryption not available. */
dea496
+typedef struct {
dea496
+    buf_T	*bi_buf;
dea496
+    FILE	*bi_fp;
dea496
+#ifdef FEAT_CRYPT
dea496
+    cryptstate_T *bi_state;
dea496
+    char_u	*bi_buffer; /* CRYPT_BUF_SIZE, NULL when not buffering */
dea496
+    size_t	bi_used;    /* bytes written to/read from bi_buffer */
dea496
+    size_t	bi_avail;   /* bytes available in bi_buffer */
dea496
+#endif
dea496
+} bufinfo_T;
dea496
+
dea496
+
dea496
 static long get_undolevel __ARGS((void));
dea496
 static void u_unch_branch __ARGS((u_header_T *uhp));
dea496
 static u_entry_T *u_get_headentry __ARGS((void));
dea496
@@ -98,18 +115,26 @@ static void u_freeentry __ARGS((u_entry_
dea496
 #ifdef FEAT_PERSISTENT_UNDO
dea496
 static void corruption_error __ARGS((char *mesg, char_u *file_name));
dea496
 static void u_free_uhp __ARGS((u_header_T *uhp));
dea496
-static size_t fwrite_crypt __ARGS((buf_T *buf UNUSED, char_u *ptr, size_t len, FILE *fp));
dea496
-static char_u *read_string_decrypt __ARGS((buf_T *buf UNUSED, FILE *fd, int len));
dea496
-static int serialize_header __ARGS((FILE *fp, buf_T *buf, char_u *hash));
dea496
-static int serialize_uhp __ARGS((FILE *fp, buf_T *buf, u_header_T *uhp));
dea496
-static u_header_T *unserialize_uhp __ARGS((FILE *fp, char_u *file_name));
dea496
-static int serialize_uep __ARGS((FILE *fp, buf_T *buf, u_entry_T *uep));
dea496
-static u_entry_T *unserialize_uep __ARGS((FILE *fp, int *error, char_u *file_name));
dea496
-static void serialize_pos __ARGS((pos_T pos, FILE *fp));
dea496
-static void unserialize_pos __ARGS((pos_T *pos, FILE *fp));
dea496
-static void serialize_visualinfo __ARGS((visualinfo_T *info, FILE *fp));
dea496
-static void unserialize_visualinfo __ARGS((visualinfo_T *info, FILE *fp));
dea496
-static void put_header_ptr __ARGS((FILE	*fp, u_header_T *uhp));
dea496
+static int undo_write __ARGS((bufinfo_T *bi, char_u *ptr, size_t len));
dea496
+static int undo_flush __ARGS((bufinfo_T *bi));
dea496
+static int fwrite_crypt __ARGS((bufinfo_T *bi, char_u *ptr, size_t len));
dea496
+static int undo_write_bytes __ARGS((bufinfo_T *bi, long_u nr, int len));
dea496
+static void put_header_ptr __ARGS((bufinfo_T *bi, u_header_T *uhp));
dea496
+static int undo_read_4c __ARGS((bufinfo_T *bi));
dea496
+static int undo_read_2c __ARGS((bufinfo_T *bi));
dea496
+static int undo_read_byte __ARGS((bufinfo_T *bi));
dea496
+static time_t undo_read_time __ARGS((bufinfo_T *bi));
dea496
+static int undo_read __ARGS((bufinfo_T *bi, char_u *buffer, size_t size));
dea496
+static char_u *read_string_decrypt __ARGS((bufinfo_T *bi, int len));
dea496
+static int serialize_header __ARGS((bufinfo_T *bi, char_u *hash));
dea496
+static int serialize_uhp __ARGS((bufinfo_T *bi, u_header_T *uhp));
dea496
+static u_header_T *unserialize_uhp __ARGS((bufinfo_T *bi, char_u *file_name));
dea496
+static int serialize_uep __ARGS((bufinfo_T *bi, u_entry_T *uep));
dea496
+static u_entry_T *unserialize_uep __ARGS((bufinfo_T *bi, int *error, char_u *file_name));
dea496
+static void serialize_pos __ARGS((bufinfo_T *bi, pos_T pos));
dea496
+static void unserialize_pos __ARGS((bufinfo_T *bi, pos_T *pos));
dea496
+static void serialize_visualinfo __ARGS((bufinfo_T *bi, visualinfo_T *info));
dea496
+static void unserialize_visualinfo __ARGS((bufinfo_T *bi, visualinfo_T *info));
dea496
 #endif
dea496
 
dea496
 #define U_ALLOC_LINE(size) lalloc((long_u)(size), FALSE)
dea496
@@ -850,68 +875,294 @@ u_free_uhp(uhp)
dea496
 }
dea496
 
dea496
 /*
dea496
- * Like fwrite() but crypt the bytes when 'key' is set.
dea496
- * Returns 1 if successful.
dea496
+ * Write a sequence of bytes to the undo file.
dea496
+ * Buffers and encrypts as needed.
dea496
+ * Returns OK or FAIL.
dea496
  */
dea496
-    static size_t
dea496
-fwrite_crypt(buf, ptr, len, fp)
dea496
-    buf_T	*buf UNUSED;
dea496
+    static int
dea496
+undo_write(bi, ptr, len)
dea496
+    bufinfo_T	*bi;
dea496
+    char_u	*ptr;
dea496
+    size_t	len;
dea496
+{
dea496
+#ifdef FEAT_CRYPT
dea496
+    if (bi->bi_buffer != NULL)
dea496
+    {
dea496
+	size_t	len_todo = len;
dea496
+	char_u  *p = ptr;
dea496
+
dea496
+	while (bi->bi_used + len_todo >= CRYPT_BUF_SIZE)
dea496
+	{
dea496
+	    size_t	n = CRYPT_BUF_SIZE - bi->bi_used;
dea496
+
dea496
+	    mch_memmove(bi->bi_buffer + bi->bi_used, p, n);
dea496
+	    len_todo -= n;
dea496
+	    p += n;
dea496
+	    bi->bi_used = CRYPT_BUF_SIZE;
dea496
+	    if (undo_flush(bi) == FAIL)
dea496
+		return FAIL;
dea496
+	}
dea496
+	if (len_todo > 0)
dea496
+	{
dea496
+	    mch_memmove(bi->bi_buffer + bi->bi_used, p, len_todo);
dea496
+	    bi->bi_used += len_todo;
dea496
+	}
dea496
+	return OK;
dea496
+    }
dea496
+#endif
dea496
+    if (fwrite(ptr, len, (size_t)1, bi->bi_fp) != 1)
dea496
+	return FAIL;
dea496
+    return OK;
dea496
+}
dea496
+
dea496
+#ifdef FEAT_CRYPT
dea496
+    static int
dea496
+undo_flush(bi)
dea496
+    bufinfo_T	*bi;
dea496
+{
dea496
+    if (bi->bi_buffer != NULL && bi->bi_state != NULL && bi->bi_used > 0)
dea496
+    {
dea496
+	crypt_encode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_used);
dea496
+	if (fwrite(bi->bi_buffer, bi->bi_used, (size_t)1, bi->bi_fp) != 1)
dea496
+	    return FAIL;
dea496
+	bi->bi_used = 0;
dea496
+    }
dea496
+    return OK;
dea496
+}
dea496
+#endif
dea496
+
dea496
+/*
dea496
+ * Write "ptr[len]" and crypt the bytes when needed.
dea496
+ * Returns OK or FAIL.
dea496
+ */
dea496
+    static int
dea496
+fwrite_crypt(bi, ptr, len)
dea496
+    bufinfo_T	*bi;
dea496
     char_u	*ptr;
dea496
     size_t	len;
dea496
-    FILE	*fp;
dea496
 {
dea496
 #ifdef FEAT_CRYPT
dea496
     char_u  *copy;
dea496
     char_u  small_buf[100];
dea496
     size_t  i;
dea496
 
dea496
-    if (*buf->b_p_key == NUL)
dea496
-	return fwrite(ptr, len, (size_t)1, fp);
dea496
-    if (len < 100)
dea496
-	copy = small_buf;  /* no malloc()/free() for short strings */
dea496
-    else
dea496
+    if (bi->bi_state != NULL && bi->bi_buffer == NULL)
dea496
     {
dea496
-	copy = lalloc(len, FALSE);
dea496
-	if (copy == NULL)
dea496
-	    return 0;
dea496
-    }
dea496
-    crypt_encode(ptr, len, copy);
dea496
-    i = fwrite(copy, len, (size_t)1, fp);
dea496
-    if (copy != small_buf)
dea496
-	vim_free(copy);
dea496
-    return i;
dea496
-#else
dea496
-    return fwrite(ptr, len, (size_t)1, fp);
dea496
+	/* crypting every piece of text separately */
dea496
+	if (len < 100)
dea496
+	    copy = small_buf;  /* no malloc()/free() for short strings */
dea496
+	else
dea496
+	{
dea496
+	    copy = lalloc(len, FALSE);
dea496
+	    if (copy == NULL)
dea496
+		return 0;
dea496
+	}
dea496
+	crypt_encode(bi->bi_state, ptr, len, copy);
dea496
+	i = fwrite(copy, len, (size_t)1, bi->bi_fp);
dea496
+	if (copy != small_buf)
dea496
+	    vim_free(copy);
dea496
+	return i == 1 ? OK : FAIL;
dea496
+    }
dea496
 #endif
dea496
+    return undo_write(bi, ptr, len);
dea496
 }
dea496
 
dea496
 /*
dea496
- * Read a string of length "len" from "fd".
dea496
- * When 'key' is set decrypt the bytes.
dea496
+ * Write a number, MSB first, in "len" bytes.
dea496
+ * Must match with undo_read_?c() functions.
dea496
+ * Returns OK or FAIL.
dea496
  */
dea496
-    static char_u *
dea496
-read_string_decrypt(buf, fd, len)
dea496
-    buf_T   *buf UNUSED;
dea496
-    FILE    *fd;
dea496
+    static int
dea496
+undo_write_bytes(bi, nr, len)
dea496
+    bufinfo_T *bi;
dea496
+    long_u  nr;
dea496
     int	    len;
dea496
 {
dea496
-    char_u  *ptr;
dea496
+    char_u  buf[8];
dea496
+    int	    i;
dea496
+    int	    bufi = 0;
dea496
+
dea496
+    for (i = len - 1; i >= 0; --i)
dea496
+	buf[bufi++] = nr >> (i * 8);
dea496
+    return undo_write(bi, buf, (size_t)len);
dea496
+}
dea496
 
dea496
-    ptr = read_string(fd, len);
dea496
+/*
dea496
+ * Write the pointer to an undo header.  Instead of writing the pointer itself
dea496
+ * we use the sequence number of the header.  This is converted back to
dea496
+ * pointers when reading. */
dea496
+    static void
dea496
+put_header_ptr(bi, uhp)
dea496
+    bufinfo_T	*bi;
dea496
+    u_header_T	*uhp;
dea496
+{
dea496
+    undo_write_bytes(bi, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4);
dea496
+}
dea496
+
dea496
+    static int
dea496
+undo_read_4c(bi)
dea496
+    bufinfo_T	*bi;
dea496
+{
dea496
 #ifdef FEAT_CRYPT
dea496
-    if (ptr != NULL && *buf->b_p_key != NUL)
dea496
-	crypt_decode(ptr, len);
dea496
+    if (bi->bi_buffer != NULL)
dea496
+    {
dea496
+	char_u  buf[4];
dea496
+	int	n;
dea496
+
dea496
+	undo_read(bi, buf, (size_t)4);
dea496
+	n = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
dea496
+	return n;
dea496
+    }
dea496
 #endif
dea496
+    return get4c(bi->bi_fp);
dea496
+}
dea496
+
dea496
+    static int
dea496
+undo_read_2c(bi)
dea496
+    bufinfo_T	*bi;
dea496
+{
dea496
+#ifdef FEAT_CRYPT
dea496
+    if (bi->bi_buffer != NULL)
dea496
+    {
dea496
+	char_u  buf[2];
dea496
+	int	n;
dea496
+
dea496
+	undo_read(bi, buf, (size_t)2);
dea496
+	n = (buf[0] << 8) + buf[1];
dea496
+	return n;
dea496
+    }
dea496
+#endif
dea496
+    return get2c(bi->bi_fp);
dea496
+}
dea496
+
dea496
+    static int
dea496
+undo_read_byte(bi)
dea496
+    bufinfo_T	*bi;
dea496
+{
dea496
+#ifdef FEAT_CRYPT
dea496
+    if (bi->bi_buffer != NULL)
dea496
+    {
dea496
+	char_u  buf[1];
dea496
+
dea496
+	undo_read(bi, buf, (size_t)1);
dea496
+	return buf[0];
dea496
+    }
dea496
+#endif
dea496
+    return getc(bi->bi_fp);
dea496
+}
dea496
+
dea496
+    static time_t
dea496
+undo_read_time(bi)
dea496
+    bufinfo_T	*bi;
dea496
+{
dea496
+#ifdef FEAT_CRYPT
dea496
+    if (bi->bi_buffer != NULL)
dea496
+    {
dea496
+	char_u  buf[8];
dea496
+	time_t	n = 0;
dea496
+	int	i;
dea496
+
dea496
+	undo_read(bi, buf, (size_t)8);
dea496
+	for (i = 0; i < 8; ++i)
dea496
+	    n = (n << 8) + buf[i];
dea496
+	return n;
dea496
+    }
dea496
+#endif
dea496
+    return get8ctime(bi->bi_fp);
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Read "buffer[size]" from the undo file.
dea496
+ * Return OK or FAIL.
dea496
+ */
dea496
+    static int
dea496
+undo_read(bi, buffer, size)
dea496
+    bufinfo_T   *bi;
dea496
+    char_u	*buffer;
dea496
+    size_t	size;
dea496
+{
dea496
+#ifdef FEAT_CRYPT
dea496
+    if (bi->bi_buffer != NULL)
dea496
+    {
dea496
+	int	size_todo = size;
dea496
+	char_u	*p = buffer;
dea496
+
dea496
+	while (size_todo > 0)
dea496
+	{
dea496
+	    size_t n;
dea496
+
dea496
+	    if (bi->bi_used >= bi->bi_avail)
dea496
+	    {
dea496
+		n = fread(bi->bi_buffer, 1, (size_t)CRYPT_BUF_SIZE, bi->bi_fp);
dea496
+		if (n <= 0)
dea496
+		{
dea496
+		    /* Error may be checked for only later.  Fill with zeros,
dea496
+		     * so that the reader won't use garbage. */
dea496
+		    vim_memset(p, 0, size_todo);
dea496
+		    return FAIL;
dea496
+		}
dea496
+		bi->bi_avail = n;
dea496
+		bi->bi_used = 0;
dea496
+		crypt_decode_inplace(bi->bi_state, bi->bi_buffer, bi->bi_avail);
dea496
+	    }
dea496
+	    n = size_todo;
dea496
+	    if (n > bi->bi_avail - bi->bi_used)
dea496
+		n = bi->bi_avail - bi->bi_used;
dea496
+	    mch_memmove(p, bi->bi_buffer + bi->bi_used, n);
dea496
+	    bi->bi_used += n;
dea496
+	    size_todo -= n;
dea496
+	    p += n;
dea496
+	}
dea496
+	return OK;
dea496
+    }
dea496
+#endif
dea496
+    if (fread(buffer, (size_t)size, 1, bi->bi_fp) != 1)
dea496
+	return FAIL;
dea496
+    return OK;
dea496
+}
dea496
+
dea496
+/*
dea496
+ * Read a string of length "len" from "bi->bi_fd".
dea496
+ * "len" can be zero to allocate an empty line.
dea496
+ * Decrypt the bytes if needed.
dea496
+ * Append a NUL.
dea496
+ * Returns a pointer to allocated memory or NULL for failure.
dea496
+ */
dea496
+    static char_u *
dea496
+read_string_decrypt(bi, len)
dea496
+    bufinfo_T	*bi;
dea496
+    int		len;
dea496
+{
dea496
+    char_u  *ptr = alloc((unsigned)len + 1);
dea496
+
dea496
+    if (ptr != NULL)
dea496
+    {
dea496
+	if (len > 0 && undo_read(bi, ptr, len) == FAIL)
dea496
+	{
dea496
+	    vim_free(ptr);
dea496
+	    return NULL;
dea496
+	}
dea496
+	ptr[len] = NUL;
dea496
+#ifdef FEAT_CRYPT
dea496
+	if (bi->bi_state != NULL && bi->bi_buffer == NULL)
dea496
+	    crypt_decode_inplace(bi->bi_state, ptr, len);
dea496
+#endif
dea496
+    }
dea496
     return ptr;
dea496
 }
dea496
 
dea496
+/*
dea496
+ * Writes the (not encrypted) header and initializes encryption if needed.
dea496
+ */
dea496
     static int
dea496
-serialize_header(fp, buf, hash)
dea496
-    FILE	*fp;
dea496
-    buf_T	*buf;
dea496
+serialize_header(bi, hash)
dea496
+    bufinfo_T	*bi;
dea496
     char_u	*hash;
dea496
 {
dea496
-    int len;
dea496
+    int		len;
dea496
+    buf_T	*buf = bi->bi_buf;
dea496
+    FILE	*fp = bi->bi_fp;
dea496
+    char_u	time_buf[8];
dea496
 
dea496
     /* Start writing, first the magic marker and undo info version. */
dea496
     if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1)
dea496
@@ -925,117 +1176,124 @@ serialize_header(fp, buf, hash)
dea496
 	char_u *header;
dea496
 	int    header_len;
dea496
 
dea496
-	put_bytes(fp, (long_u)UF_VERSION_CRYPT, 2);
dea496
-	header = prepare_crypt_write(buf, &header_len);
dea496
-	if (header == NULL)
dea496
+	undo_write_bytes(bi, (long_u)UF_VERSION_CRYPT, 2);
dea496
+	bi->bi_state = crypt_create_for_writing(crypt_get_method_nr(buf),
dea496
+					  buf->b_p_key, &header, &header_len);
dea496
+	if (bi->bi_state == NULL)
dea496
 	    return FAIL;
dea496
 	len = (int)fwrite(header, (size_t)header_len, (size_t)1, fp);
dea496
 	vim_free(header);
dea496
 	if (len != 1)
dea496
 	{
dea496
-	    crypt_pop_state();
dea496
+	    crypt_free_state(bi->bi_state);
dea496
+	    bi->bi_state = NULL;
dea496
 	    return FAIL;
dea496
 	}
dea496
+
dea496
+	if (crypt_whole_undofile(crypt_get_method_nr(buf)))
dea496
+	{
dea496
+	    bi->bi_buffer = alloc(CRYPT_BUF_SIZE);
dea496
+	    if (bi->bi_buffer == NULL)
dea496
+	    {
dea496
+		crypt_free_state(bi->bi_state);
dea496
+		bi->bi_state = NULL;
dea496
+		return FAIL;
dea496
+	    }
dea496
+	    bi->bi_used = 0;
dea496
+	}
dea496
     }
dea496
     else
dea496
 #endif
dea496
-	put_bytes(fp, (long_u)UF_VERSION, 2);
dea496
+	undo_write_bytes(bi, (long_u)UF_VERSION, 2);
dea496
 
dea496
 
dea496
     /* Write a hash of the buffer text, so that we can verify it is still the
dea496
      * same when reading the buffer text. */
dea496
-    if (fwrite(hash, (size_t)UNDO_HASH_SIZE, (size_t)1, fp) != 1)
dea496
+    if (undo_write(bi, hash, (size_t)UNDO_HASH_SIZE) == FAIL)
dea496
 	return FAIL;
dea496
 
dea496
     /* buffer-specific data */
dea496
-    put_bytes(fp, (long_u)buf->b_ml.ml_line_count, 4);
dea496
+    undo_write_bytes(bi, (long_u)buf->b_ml.ml_line_count, 4);
dea496
     len = buf->b_u_line_ptr != NULL ? (int)STRLEN(buf->b_u_line_ptr) : 0;
dea496
-    put_bytes(fp, (long_u)len, 4);
dea496
-    if (len > 0 && fwrite_crypt(buf, buf->b_u_line_ptr, (size_t)len, fp) != 1)
dea496
+    undo_write_bytes(bi, (long_u)len, 4);
dea496
+    if (len > 0 && fwrite_crypt(bi, buf->b_u_line_ptr, (size_t)len) == FAIL)
dea496
 	return FAIL;
dea496
-    put_bytes(fp, (long_u)buf->b_u_line_lnum, 4);
dea496
-    put_bytes(fp, (long_u)buf->b_u_line_colnr, 4);
dea496
+    undo_write_bytes(bi, (long_u)buf->b_u_line_lnum, 4);
dea496
+    undo_write_bytes(bi, (long_u)buf->b_u_line_colnr, 4);
dea496
 
dea496
     /* Undo structures header data */
dea496
-    put_header_ptr(fp, buf->b_u_oldhead);
dea496
-    put_header_ptr(fp, buf->b_u_newhead);
dea496
-    put_header_ptr(fp, buf->b_u_curhead);
dea496
-
dea496
-    put_bytes(fp, (long_u)buf->b_u_numhead, 4);
dea496
-    put_bytes(fp, (long_u)buf->b_u_seq_last, 4);
dea496
-    put_bytes(fp, (long_u)buf->b_u_seq_cur, 4);
dea496
-    put_time(fp, buf->b_u_time_cur);
dea496
+    put_header_ptr(bi, buf->b_u_oldhead);
dea496
+    put_header_ptr(bi, buf->b_u_newhead);
dea496
+    put_header_ptr(bi, buf->b_u_curhead);
dea496
+
dea496
+    undo_write_bytes(bi, (long_u)buf->b_u_numhead, 4);
dea496
+    undo_write_bytes(bi, (long_u)buf->b_u_seq_last, 4);
dea496
+    undo_write_bytes(bi, (long_u)buf->b_u_seq_cur, 4);
dea496
+    time_to_bytes(buf->b_u_time_cur, time_buf);
dea496
+    undo_write(bi, time_buf, 8);
dea496
 
dea496
     /* Optional fields. */
dea496
-    putc(4, fp);
dea496
-    putc(UF_LAST_SAVE_NR, fp);
dea496
-    put_bytes(fp, (long_u)buf->b_u_save_nr_last, 4);
dea496
+    undo_write_bytes(bi, 4, 1);
dea496
+    undo_write_bytes(bi, UF_LAST_SAVE_NR, 1);
dea496
+    undo_write_bytes(bi, (long_u)buf->b_u_save_nr_last, 4);
dea496
 
dea496
-    putc(0, fp);  /* end marker */
dea496
+    undo_write_bytes(bi, 0, 1);  /* end marker */
dea496
 
dea496
     return OK;
dea496
 }
dea496
 
dea496
     static int
dea496
-serialize_uhp(fp, buf, uhp)
dea496
-    FILE	*fp;
dea496
-    buf_T	*buf;
dea496
+serialize_uhp(bi, uhp)
dea496
+    bufinfo_T	*bi;
dea496
     u_header_T	*uhp;
dea496
 {
dea496
     int		i;
dea496
     u_entry_T	*uep;
dea496
+    char_u	time_buf[8];
dea496
 
dea496
-    if (put_bytes(fp, (long_u)UF_HEADER_MAGIC, 2) == FAIL)
dea496
+    if (undo_write_bytes(bi, (long_u)UF_HEADER_MAGIC, 2) == FAIL)
dea496
 	return FAIL;
dea496
 
dea496
-    put_header_ptr(fp, uhp->uh_next.ptr);
dea496
-    put_header_ptr(fp, uhp->uh_prev.ptr);
dea496
-    put_header_ptr(fp, uhp->uh_alt_next.ptr);
dea496
-    put_header_ptr(fp, uhp->uh_alt_prev.ptr);
dea496
-    put_bytes(fp, uhp->uh_seq, 4);
dea496
-    serialize_pos(uhp->uh_cursor, fp);
dea496
+    put_header_ptr(bi, uhp->uh_next.ptr);
dea496
+    put_header_ptr(bi, uhp->uh_prev.ptr);
dea496
+    put_header_ptr(bi, uhp->uh_alt_next.ptr);
dea496
+    put_header_ptr(bi, uhp->uh_alt_prev.ptr);
dea496
+    undo_write_bytes(bi, uhp->uh_seq, 4);
dea496
+    serialize_pos(bi, uhp->uh_cursor);
dea496
 #ifdef FEAT_VIRTUALEDIT
dea496
-    put_bytes(fp, (long_u)uhp->uh_cursor_vcol, 4);
dea496
+    undo_write_bytes(bi, (long_u)uhp->uh_cursor_vcol, 4);
dea496
 #else
dea496
-    put_bytes(fp, (long_u)0, 4);
dea496
+    undo_write_bytes(bi, (long_u)0, 4);
dea496
 #endif
dea496
-    put_bytes(fp, (long_u)uhp->uh_flags, 2);
dea496
+    undo_write_bytes(bi, (long_u)uhp->uh_flags, 2);
dea496
     /* Assume NMARKS will stay the same. */
dea496
     for (i = 0; i < NMARKS; ++i)
dea496
-	serialize_pos(uhp->uh_namedm[i], fp);
dea496
-#ifdef FEAT_VISUAL
dea496
-    serialize_visualinfo(&uhp->uh_visual, fp);
dea496
-#else
dea496
-    {
dea496
-	visualinfo_T info;
dea496
-
dea496
-	memset(&info, 0, sizeof(visualinfo_T));
dea496
-	serialize_visualinfo(&info, fp);
dea496
-    }
dea496
-#endif
dea496
-    put_time(fp, uhp->uh_time);
dea496
+	serialize_pos(bi, uhp->uh_namedm[i]);
dea496
+    serialize_visualinfo(bi, &uhp->uh_visual);
dea496
+    time_to_bytes(uhp->uh_time, time_buf);
dea496
+    undo_write(bi, time_buf, 8);
dea496
 
dea496
     /* Optional fields. */
dea496
-    putc(4, fp);
dea496
-    putc(UHP_SAVE_NR, fp);
dea496
-    put_bytes(fp, (long_u)uhp->uh_save_nr, 4);
dea496
+    undo_write_bytes(bi, 4, 1);
dea496
+    undo_write_bytes(bi, UHP_SAVE_NR, 1);
dea496
+    undo_write_bytes(bi, (long_u)uhp->uh_save_nr, 4);
dea496
 
dea496
-    putc(0, fp);  /* end marker */
dea496
+    undo_write_bytes(bi, 0, 1);  /* end marker */
dea496
 
dea496
     /* Write all the entries. */
dea496
     for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
dea496
     {
dea496
-	put_bytes(fp, (long_u)UF_ENTRY_MAGIC, 2);
dea496
-	if (serialize_uep(fp, buf, uep) == FAIL)
dea496
+	undo_write_bytes(bi, (long_u)UF_ENTRY_MAGIC, 2);
dea496
+	if (serialize_uep(bi, uep) == FAIL)
dea496
 	    return FAIL;
dea496
     }
dea496
-    put_bytes(fp, (long_u)UF_ENTRY_END_MAGIC, 2);
dea496
+    undo_write_bytes(bi, (long_u)UF_ENTRY_END_MAGIC, 2);
dea496
     return OK;
dea496
 }
dea496
 
dea496
     static u_header_T *
dea496
-unserialize_uhp(fp, file_name)
dea496
-    FILE	*fp;
dea496
+unserialize_uhp(bi, file_name)
dea496
+    bufinfo_T	*bi;
dea496
     char_u	*file_name;
dea496
 {
dea496
     u_header_T	*uhp;
dea496
@@ -1051,63 +1309,56 @@ unserialize_uhp(fp, file_name)
dea496
 #ifdef U_DEBUG
dea496
     uhp->uh_magic = UH_MAGIC;
dea496
 #endif
dea496
-    uhp->uh_next.seq = get4c(fp);
dea496
-    uhp->uh_prev.seq = get4c(fp);
dea496
-    uhp->uh_alt_next.seq = get4c(fp);
dea496
-    uhp->uh_alt_prev.seq = get4c(fp);
dea496
-    uhp->uh_seq = get4c(fp);
dea496
+    uhp->uh_next.seq = undo_read_4c(bi);
dea496
+    uhp->uh_prev.seq = undo_read_4c(bi);
dea496
+    uhp->uh_alt_next.seq = undo_read_4c(bi);
dea496
+    uhp->uh_alt_prev.seq = undo_read_4c(bi);
dea496
+    uhp->uh_seq = undo_read_4c(bi);
dea496
     if (uhp->uh_seq <= 0)
dea496
     {
dea496
 	corruption_error("uh_seq", file_name);
dea496
 	vim_free(uhp);
dea496
 	return NULL;
dea496
     }
dea496
-    unserialize_pos(&uhp->uh_cursor, fp);
dea496
+    unserialize_pos(bi, &uhp->uh_cursor);
dea496
 #ifdef FEAT_VIRTUALEDIT
dea496
-    uhp->uh_cursor_vcol = get4c(fp);
dea496
+    uhp->uh_cursor_vcol = undo_read_4c(bi);
dea496
 #else
dea496
-    (void)get4c(fp);
dea496
+    (void)undo_read_4c(bi);
dea496
 #endif
dea496
-    uhp->uh_flags = get2c(fp);
dea496
+    uhp->uh_flags = undo_read_2c(bi);
dea496
     for (i = 0; i < NMARKS; ++i)
dea496
-	unserialize_pos(&uhp->uh_namedm[i], fp);
dea496
-#ifdef FEAT_VISUAL
dea496
-    unserialize_visualinfo(&uhp->uh_visual, fp);
dea496
-#else
dea496
-    {
dea496
-	visualinfo_T info;
dea496
-	unserialize_visualinfo(&info, fp);
dea496
-    }
dea496
-#endif
dea496
-    uhp->uh_time = get8ctime(fp);
dea496
+	unserialize_pos(bi, &uhp->uh_namedm[i]);
dea496
+    unserialize_visualinfo(bi, &uhp->uh_visual);
dea496
+    uhp->uh_time = undo_read_time(bi);
dea496
 
dea496
     /* Optional fields. */
dea496
     for (;;)
dea496
     {
dea496
-	int len = getc(fp);
dea496
+	int len = undo_read_byte(bi);
dea496
 	int what;
dea496
 
dea496
 	if (len == 0)
dea496
 	    break;
dea496
-	what = getc(fp);
dea496
+	what = undo_read_byte(bi);
dea496
 	switch (what)
dea496
 	{
dea496
 	    case UHP_SAVE_NR:
dea496
-		uhp->uh_save_nr = get4c(fp);
dea496
+		uhp->uh_save_nr = undo_read_4c(bi);
dea496
 		break;
dea496
 	    default:
dea496
 		/* field not supported, skip */
dea496
 		while (--len >= 0)
dea496
-		    (void)getc(fp);
dea496
+		    (void)undo_read_byte(bi);
dea496
 	}
dea496
     }
dea496
 
dea496
     /* Unserialize the uep list. */
dea496
     last_uep = NULL;
dea496
-    while ((c = get2c(fp)) == UF_ENTRY_MAGIC)
dea496
+    while ((c = undo_read_2c(bi)) == UF_ENTRY_MAGIC)
dea496
     {
dea496
 	error = FALSE;
dea496
-	uep = unserialize_uep(fp, &error, file_name);
dea496
+	uep = unserialize_uep(bi, &error, file_name);
dea496
 	if (last_uep == NULL)
dea496
 	    uhp->uh_entry = uep;
dea496
 	else
dea496
@@ -1130,35 +1381,34 @@ unserialize_uhp(fp, file_name)
dea496
 }
dea496
 
dea496
 /*
dea496
- * Serialize "uep" to "fp".
dea496
+ * Serialize "uep".
dea496
  */
dea496
     static int
dea496
-serialize_uep(fp, buf, uep)
dea496
-    FILE	*fp;
dea496
-    buf_T	*buf;
dea496
+serialize_uep(bi, uep)
dea496
+    bufinfo_T	*bi;
dea496
     u_entry_T	*uep;
dea496
 {
dea496
     int		i;
dea496
     size_t	len;
dea496
 
dea496
-    put_bytes(fp, (long_u)uep->ue_top, 4);
dea496
-    put_bytes(fp, (long_u)uep->ue_bot, 4);
dea496
-    put_bytes(fp, (long_u)uep->ue_lcount, 4);
dea496
-    put_bytes(fp, (long_u)uep->ue_size, 4);
dea496
+    undo_write_bytes(bi, (long_u)uep->ue_top, 4);
dea496
+    undo_write_bytes(bi, (long_u)uep->ue_bot, 4);
dea496
+    undo_write_bytes(bi, (long_u)uep->ue_lcount, 4);
dea496
+    undo_write_bytes(bi, (long_u)uep->ue_size, 4);
dea496
     for (i = 0; i < uep->ue_size; ++i)
dea496
     {
dea496
 	len = STRLEN(uep->ue_array[i]);
dea496
-	if (put_bytes(fp, (long_u)len, 4) == FAIL)
dea496
+	if (undo_write_bytes(bi, (long_u)len, 4) == FAIL)
dea496
 	    return FAIL;
dea496
-	if (len > 0 && fwrite_crypt(buf, uep->ue_array[i], len, fp) != 1)
dea496
+	if (len > 0 && fwrite_crypt(bi, uep->ue_array[i], len) == FAIL)
dea496
 	    return FAIL;
dea496
     }
dea496
     return OK;
dea496
 }
dea496
 
dea496
     static u_entry_T *
dea496
-unserialize_uep(fp, error, file_name)
dea496
-    FILE	*fp;
dea496
+unserialize_uep(bi, error, file_name)
dea496
+    bufinfo_T	*bi;
dea496
     int		*error;
dea496
     char_u	*file_name;
dea496
 {
dea496
@@ -1175,10 +1425,10 @@ unserialize_uep(fp, error, file_name)
dea496
 #ifdef U_DEBUG
dea496
     uep->ue_magic = UE_MAGIC;
dea496
 #endif
dea496
-    uep->ue_top = get4c(fp);
dea496
-    uep->ue_bot = get4c(fp);
dea496
-    uep->ue_lcount = get4c(fp);
dea496
-    uep->ue_size = get4c(fp);
dea496
+    uep->ue_top = undo_read_4c(bi);
dea496
+    uep->ue_bot = undo_read_4c(bi);
dea496
+    uep->ue_lcount = undo_read_4c(bi);
dea496
+    uep->ue_size = undo_read_4c(bi);
dea496
     if (uep->ue_size > 0)
dea496
     {
dea496
 	array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
dea496
@@ -1195,9 +1445,9 @@ unserialize_uep(fp, error, file_name)
dea496
 
dea496
     for (i = 0; i < uep->ue_size; ++i)
dea496
     {
dea496
-	line_len = get4c(fp);
dea496
+	line_len = undo_read_4c(bi);
dea496
 	if (line_len >= 0)
dea496
-	    line = read_string_decrypt(curbuf, fp, line_len);
dea496
+	    line = read_string_decrypt(bi, line_len);
dea496
 	else
dea496
 	{
dea496
 	    line = NULL;
dea496
@@ -1214,83 +1464,71 @@ unserialize_uep(fp, error, file_name)
dea496
 }
dea496
 
dea496
 /*
dea496
- * Serialize "pos" to "fp".
dea496
+ * Serialize "pos".
dea496
  */
dea496
     static void
dea496
-serialize_pos(pos, fp)
dea496
+serialize_pos(bi, pos)
dea496
+    bufinfo_T *bi;
dea496
     pos_T pos;
dea496
-    FILE  *fp;
dea496
 {
dea496
-    put_bytes(fp, (long_u)pos.lnum, 4);
dea496
-    put_bytes(fp, (long_u)pos.col, 4);
dea496
+    undo_write_bytes(bi, (long_u)pos.lnum, 4);
dea496
+    undo_write_bytes(bi, (long_u)pos.col, 4);
dea496
 #ifdef FEAT_VIRTUALEDIT
dea496
-    put_bytes(fp, (long_u)pos.coladd, 4);
dea496
+    undo_write_bytes(bi, (long_u)pos.coladd, 4);
dea496
 #else
dea496
-    put_bytes(fp, (long_u)0, 4);
dea496
+    undo_write_bytes(bi, (long_u)0, 4);
dea496
 #endif
dea496
 }
dea496
 
dea496
 /*
dea496
- * Unserialize the pos_T at the current position in fp.
dea496
+ * Unserialize the pos_T at the current position.
dea496
  */
dea496
     static void
dea496
-unserialize_pos(pos, fp)
dea496
+unserialize_pos(bi, pos)
dea496
+    bufinfo_T *bi;
dea496
     pos_T *pos;
dea496
-    FILE  *fp;
dea496
 {
dea496
-    pos->lnum = get4c(fp);
dea496
+    pos->lnum = undo_read_4c(bi);
dea496
     if (pos->lnum < 0)
dea496
 	pos->lnum = 0;
dea496
-    pos->col = get4c(fp);
dea496
+    pos->col = undo_read_4c(bi);
dea496
     if (pos->col < 0)
dea496
 	pos->col = 0;
dea496
 #ifdef FEAT_VIRTUALEDIT
dea496
-    pos->coladd = get4c(fp);
dea496
+    pos->coladd = undo_read_4c(bi);
dea496
     if (pos->coladd < 0)
dea496
 	pos->coladd = 0;
dea496
 #else
dea496
-    (void)get4c(fp);
dea496
+    (void)undo_read_4c(bi);
dea496
 #endif
dea496
 }
dea496
 
dea496
 /*
dea496
- * Serialize "info" to "fp".
dea496
+ * Serialize "info".
dea496
  */
dea496
     static void
dea496
-serialize_visualinfo(info, fp)
dea496
+serialize_visualinfo(bi, info)
dea496
+    bufinfo_T	    *bi;
dea496
     visualinfo_T    *info;
dea496
-    FILE	    *fp;
dea496
 {
dea496
-    serialize_pos(info->vi_start, fp);
dea496
-    serialize_pos(info->vi_end, fp);
dea496
-    put_bytes(fp, (long_u)info->vi_mode, 4);
dea496
-    put_bytes(fp, (long_u)info->vi_curswant, 4);
dea496
+    serialize_pos(bi, info->vi_start);
dea496
+    serialize_pos(bi, info->vi_end);
dea496
+    undo_write_bytes(bi, (long_u)info->vi_mode, 4);
dea496
+    undo_write_bytes(bi, (long_u)info->vi_curswant, 4);
dea496
 }
dea496
 
dea496
 /*
dea496
- * Unserialize the visualinfo_T at the current position in fp.
dea496
+ * Unserialize the visualinfo_T at the current position.
dea496
  */
dea496
     static void
dea496
-unserialize_visualinfo(info, fp)
dea496
+unserialize_visualinfo(bi, info)
dea496
+    bufinfo_T	    *bi;
dea496
     visualinfo_T    *info;
dea496
-    FILE	    *fp;
dea496
-{
dea496
-    unserialize_pos(&info->vi_start, fp);
dea496
-    unserialize_pos(&info->vi_end, fp);
dea496
-    info->vi_mode = get4c(fp);
dea496
-    info->vi_curswant = get4c(fp);
dea496
-}
dea496
-
dea496
-/*
dea496
- * Write the pointer to an undo header.  Instead of writing the pointer itself
dea496
- * we use the sequence number of the header.  This is converted back to
dea496
- * pointers when reading. */
dea496
-    static void
dea496
-put_header_ptr(fp, uhp)
dea496
-    FILE	*fp;
dea496
-    u_header_T	*uhp;
dea496
 {
dea496
-    put_bytes(fp, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4);
dea496
+    unserialize_pos(bi, &info->vi_start);
dea496
+    unserialize_pos(bi, &info->vi_end);
dea496
+    info->vi_mode = undo_read_4c(bi);
dea496
+    info->vi_curswant = undo_read_4c(bi);
dea496
 }
dea496
 
dea496
 /*
dea496
@@ -1324,9 +1562,9 @@ u_write_undo(name, forceit, buf, hash)
dea496
     struct stat	st_old;
dea496
     struct stat	st_new;
dea496
 #endif
dea496
-#ifdef FEAT_CRYPT
dea496
-    int		do_crypt = FALSE;
dea496
-#endif
dea496
+    bufinfo_T	bi;
dea496
+
dea496
+    vim_memset(&bi, 0, sizeof(bi));
dea496
 
dea496
     if (name == NULL)
dea496
     {
dea496
@@ -1481,14 +1719,12 @@ u_write_undo(name, forceit, buf, hash)
dea496
     u_sync(TRUE);
dea496
 
dea496
     /*
dea496
-     * Write the header.
dea496
+     * Write the header.  Initializes encryption, if enabled.
dea496
      */
dea496
-    if (serialize_header(fp, buf, hash) == FAIL)
dea496
+    bi.bi_buf = buf;
dea496
+    bi.bi_fp = fp;
dea496
+    if (serialize_header(&bi, hash) == FAIL)
dea496
 	goto write_error;
dea496
-#ifdef FEAT_CRYPT
dea496
-    if (*buf->b_p_key != NUL)
dea496
-	do_crypt = TRUE;
dea496
-#endif
dea496
 
dea496
     /*
dea496
      * Iteratively serialize UHPs and their UEPs from the top down.
dea496
@@ -1504,7 +1740,7 @@ u_write_undo(name, forceit, buf, hash)
dea496
 #ifdef U_DEBUG
dea496
 	    ++headers_written;
dea496
 #endif
dea496
-	    if (serialize_uhp(fp, buf, uhp) == FAIL)
dea496
+	    if (serialize_uhp(&bi, uhp) == FAIL)
dea496
 		goto write_error;
dea496
 	}
dea496
 
dea496
@@ -1523,7 +1759,7 @@ u_write_undo(name, forceit, buf, hash)
dea496
 	    uhp = uhp->uh_next.ptr;
dea496
     }
dea496
 
dea496
-    if (put_bytes(fp, (long_u)UF_HEADER_END_MAGIC, 2) == OK)
dea496
+    if (undo_write_bytes(&bi, (long_u)UF_HEADER_END_MAGIC, 2) == OK)
dea496
 	write_ok = TRUE;
dea496
 #ifdef U_DEBUG
dea496
     if (headers_written != buf->b_u_numhead)
dea496
@@ -1533,6 +1769,11 @@ u_write_undo(name, forceit, buf, hash)
dea496
     }
dea496
 #endif
dea496
 
dea496
+#ifdef FEAT_CRYPT
dea496
+    if (bi.bi_state != NULL && undo_flush(&bi) == FAIL)
dea496
+	write_ok = FALSE;
dea496
+#endif
dea496
+
dea496
 write_error:
dea496
     fclose(fp);
dea496
     if (!write_ok)
dea496
@@ -1558,8 +1799,9 @@ write_error:
dea496
 
dea496
 theend:
dea496
 #ifdef FEAT_CRYPT
dea496
-    if (do_crypt)
dea496
-	crypt_pop_state();
dea496
+    if (bi.bi_state != NULL)
dea496
+	crypt_free_state(bi.bi_state);
dea496
+    vim_free(bi.bi_buffer);
dea496
 #endif
dea496
     if (file_name != name)
dea496
 	vim_free(file_name);
dea496
@@ -1605,10 +1847,9 @@ u_read_undo(name, hash, orig_name)
dea496
     struct stat	st_orig;
dea496
     struct stat	st_undo;
dea496
 #endif
dea496
-#ifdef FEAT_CRYPT
dea496
-    int		do_decrypt = FALSE;
dea496
-#endif
dea496
+    bufinfo_T	bi;
dea496
 
dea496
+    vim_memset(&bi, 0, sizeof(bi));
dea496
     if (name == NULL)
dea496
     {
dea496
 	file_name = u_get_undo_file_name(curbuf->b_ffname, TRUE);
dea496
@@ -1651,6 +1892,8 @@ u_read_undo(name, hash, orig_name)
dea496
 	    EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name);
dea496
 	goto error;
dea496
     }
dea496
+    bi.bi_buf = curbuf;
dea496
+    bi.bi_fp = fp;
dea496
 
dea496
     /*
dea496
      * Read the undo file header.
dea496
@@ -1671,12 +1914,24 @@ u_read_undo(name, hash, orig_name)
dea496
 								   file_name);
dea496
 	    goto error;
dea496
 	}
dea496
-	if (prepare_crypt_read(fp) == FAIL)
dea496
+	bi.bi_state = crypt_create_from_file(fp, curbuf->b_p_key);
dea496
+	if (bi.bi_state == NULL)
dea496
 	{
dea496
 	    EMSG2(_("E826: Undo file decryption failed: %s"), file_name);
dea496
 	    goto error;
dea496
 	}
dea496
-	do_decrypt = TRUE;
dea496
+	if (crypt_whole_undofile(bi.bi_state->method_nr))
dea496
+	{
dea496
+	    bi.bi_buffer = alloc(CRYPT_BUF_SIZE);
dea496
+	    if (bi.bi_buffer == NULL)
dea496
+	    {
dea496
+		crypt_free_state(bi.bi_state);
dea496
+		bi.bi_state = NULL;
dea496
+		goto error;
dea496
+	    }
dea496
+	    bi.bi_avail = 0;
dea496
+	    bi.bi_used = 0;
dea496
+	}
dea496
 #else
dea496
 	EMSG2(_("E827: Undo file is encrypted: %s"), file_name);
dea496
 	goto error;
dea496
@@ -1688,12 +1943,12 @@ u_read_undo(name, hash, orig_name)
dea496
 	goto error;
dea496
     }
dea496
 
dea496
-    if (fread(read_hash, UNDO_HASH_SIZE, 1, fp) != 1)
dea496
+    if (undo_read(&bi, read_hash, (size_t)UNDO_HASH_SIZE) == FAIL)
dea496
     {
dea496
 	corruption_error("hash", file_name);
dea496
 	goto error;
dea496
     }
dea496
-    line_count = (linenr_T)get4c(fp);
dea496
+    line_count = (linenr_T)undo_read_4c(&bi);
dea496
     if (memcmp(hash, read_hash, UNDO_HASH_SIZE) != 0
dea496
 				  || line_count != curbuf->b_ml.ml_line_count)
dea496
     {
dea496
@@ -1710,13 +1965,13 @@ u_read_undo(name, hash, orig_name)
dea496
     }
dea496
 
dea496
     /* Read undo data for "U" command. */
dea496
-    str_len = get4c(fp);
dea496
+    str_len = undo_read_4c(&bi);
dea496
     if (str_len < 0)
dea496
 	goto error;
dea496
     if (str_len > 0)
dea496
-	line_ptr = read_string_decrypt(curbuf, fp, str_len);
dea496
-    line_lnum = (linenr_T)get4c(fp);
dea496
-    line_colnr = (colnr_T)get4c(fp);
dea496
+	line_ptr = read_string_decrypt(&bi, str_len);
dea496
+    line_lnum = (linenr_T)undo_read_4c(&bi);
dea496
+    line_colnr = (colnr_T)undo_read_4c(&bi);
dea496
     if (line_lnum < 0 || line_colnr < 0)
dea496
     {
dea496
 	corruption_error("line lnum/col", file_name);
dea496
@@ -1724,32 +1979,32 @@ u_read_undo(name, hash, orig_name)
dea496
     }
dea496
 
dea496
     /* Begin general undo data */
dea496
-    old_header_seq = get4c(fp);
dea496
-    new_header_seq = get4c(fp);
dea496
-    cur_header_seq = get4c(fp);
dea496
-    num_head = get4c(fp);
dea496
-    seq_last = get4c(fp);
dea496
-    seq_cur = get4c(fp);
dea496
-    seq_time = get8ctime(fp);
dea496
+    old_header_seq = undo_read_4c(&bi);
dea496
+    new_header_seq = undo_read_4c(&bi);
dea496
+    cur_header_seq = undo_read_4c(&bi);
dea496
+    num_head = undo_read_4c(&bi);
dea496
+    seq_last = undo_read_4c(&bi);
dea496
+    seq_cur = undo_read_4c(&bi);
dea496
+    seq_time = undo_read_time(&bi);
dea496
 
dea496
     /* Optional header fields. */
dea496
     for (;;)
dea496
     {
dea496
-	int len = getc(fp);
dea496
+	int len = undo_read_byte(&bi);
dea496
 	int what;
dea496
 
dea496
 	if (len == 0 || len == EOF)
dea496
 	    break;
dea496
-	what = getc(fp);
dea496
+	what = undo_read_byte(&bi);
dea496
 	switch (what)
dea496
 	{
dea496
 	    case UF_LAST_SAVE_NR:
dea496
-		last_save_nr = get4c(fp);
dea496
+		last_save_nr = undo_read_4c(&bi);
dea496
 		break;
dea496
 	    default:
dea496
 		/* field not supported, skip */
dea496
 		while (--len >= 0)
dea496
-		    (void)getc(fp);
dea496
+		    (void)undo_read_byte(&bi);
dea496
 	}
dea496
     }
dea496
 
dea496
@@ -1765,7 +2020,7 @@ u_read_undo(name, hash, orig_name)
dea496
 	    goto error;
dea496
     }
dea496
 
dea496
-    while ((c = get2c(fp)) == UF_HEADER_MAGIC)
dea496
+    while ((c = undo_read_2c(&bi)) == UF_HEADER_MAGIC)
dea496
     {
dea496
 	if (num_read_uhps >= num_head)
dea496
 	{
dea496
@@ -1773,7 +2028,7 @@ u_read_undo(name, hash, orig_name)
dea496
 	    goto error;
dea496
 	}
dea496
 
dea496
-	uhp = unserialize_uhp(fp, file_name);
dea496
+	uhp = unserialize_uhp(&bi, file_name);
dea496
 	if (uhp == NULL)
dea496
 	    goto error;
dea496
 	uhp_table[num_read_uhps++] = uhp;
dea496
@@ -1905,8 +2160,9 @@ error:
dea496
 
dea496
 theend:
dea496
 #ifdef FEAT_CRYPT
dea496
-    if (do_decrypt)
dea496
-	crypt_pop_state();
dea496
+    if (bi.bi_state != NULL)
dea496
+	crypt_free_state(bi.bi_state);
dea496
+    vim_free(bi.bi_buffer);
dea496
 #endif
dea496
     if (fp != NULL)
dea496
 	fclose(fp);
dea496
diff -up vim74/src/version.c.blowfish2 vim74/src/version.c
dea496
--- vim74/src/version.c.blowfish2	2017-09-05 14:47:34.768913491 +0200
dea496
+++ vim74/src/version.c	2017-09-05 14:47:34.973911836 +0200
dea496
@@ -739,6 +739,14 @@ static char *(features[]) =
dea496
 static int included_patches[] =
dea496
 {   /* Add new patch number below this line */
dea496
 /**/
dea496
+    1099,
dea496
+/**/
dea496
+    403,
dea496
+/**/
dea496
+    402,
dea496
+/**/
dea496
+    399,
dea496
+/**/
dea496
     160,
dea496
 /**/
dea496
     159,