Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

classic Classic list List threaded Threaded
43 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Mosh-3
Resending patch for current vim 72* dev branch (from cvs).
--
 Added functionality for encrypting files with blowfish and sha2.
 Blowfish is from http://www.schneier.com/blowfish.html

 Older vim encrypted files with VimCrypt~1 header will still be
 readable by newer vim,
 but newly written files will have VimCrypt~2 in the header.

 Algorithm: key=sha2(password), blowfish in Outputfeedback mode,
 with random 64bit init vector, so same file produces a completely
 different output, every time it is saved.

Changes:

Minor changes to fileio.c misc2.c, and 4 new files blowfish.c
blowfish.h sha2.c sha2.h
Patch is based on  vim DEV branch as of  2010-03-15

thanks,
questions? mail me.
mohsin.

> === cut here ==

--- 73g/src/fileio.c 2010-03-02 03:47:35.000000000 -0800
+++ 73/src/fileio.c 2010-03-15 21:02:43.589000300 -0800
@@ -33,8 +33,17 @@
 #define SMBUFSIZE 256 /* size of emergency write buffer */

 #ifdef FEAT_CRYPT
-# define CRYPT_MAGIC "VimCrypt~01!" /* "01" is the version nr */
-# define CRYPT_MAGIC_LEN 12 /* must be multiple of 4! */
+/* CRYPT_MAGIC[0] is pkzip crypt, CRYPT_MAGIC[1] is sha2+blowfish */
+char *CRYPT_MAGIC[] = {"VimCrypt~01!","VimCrypt~02"};
+int   CRYPT_MAGIC_LEN[] = {12,12};
+int   CRYPT_SEED_LEN[] = {0,8};
+char *crypt_sig = "VimCrypt~02";
+int   magic_len =  4;   /* must be multiple of 4! */
+int   seed_len  = 8;
+static char header[32 /*magic_len+seed_len+2*/];
+
+#include "sha2.h"
+#include "blowfish.h"
 #endif

 /* Is there any system that doesn't have access()? */
@@ -1418,7 +1427,7 @@ retry:
      */
     if ((filesize == 0
 # ifdef FEAT_CRYPT
- || (filesize == CRYPT_MAGIC_LEN && cryptkey != NULL)
+                       || (filesize == (magic_len + seed_len) &&
cryptkey != NULL)
 # endif
        )
     && (fio_flags == FIO_UCSBOM
@@ -2449,7 +2458,7 @@ failed:
  c = TRUE;
 #ifdef FEAT_CRYPT
     if (cryptkey != NULL)
- msg_add_lines(c, (long)linecnt, filesize - CRYPT_MAGIC_LEN);
+ msg_add_lines(c, (long)linecnt, filesize - magic_len - seed_len );
     else
 #endif
  msg_add_lines(c, (long)linecnt, filesize);
@@ -2781,6 +2790,29 @@ check_marks_read()
  * *filesizep are updated.
  * Return the (new) encryption key, NULL for no encryption.
  */
+
+static void select_sig( int i ){
+    use_bf = i;
+    crypt_sig = CRYPT_MAGIC[i];
+    magic_len = CRYPT_MAGIC_LEN[i];
+    seed_len  = CRYPT_SEED_LEN[i];
+}
+
+static int is_crypt_sig( char *ptr, int len ){
+    int i;
+    int num_sigs = sizeof(CRYPT_MAGIC)/sizeof(CRYPT_MAGIC[0]);
+    for(i=0;i<num_sigs;i++){
+        if( len < (CRYPT_MAGIC_LEN[i] + CRYPT_SEED_LEN[i] ) )
+            continue;
+        if(memcmp(ptr, CRYPT_MAGIC[i], CRYPT_MAGIC_LEN[i]) == 0){
+            select_sig( i );
+            return 1+i; /* bool and index */
+ }
+    }
+    return 0;
+}
+
+
     static char_u *
 check_for_cryptkey(cryptkey, ptr, sizep, filesizep, newfile)
     char_u *cryptkey; /* previous encryption key or NULL */
@@ -2789,8 +2821,7 @@ check_for_cryptkey(cryptkey, ptr, sizep,
     long *filesizep; /* nr of bytes used from file */
     int newfile; /* editing a new buffer */
 {
-    if (*sizep >= CRYPT_MAGIC_LEN
-    && STRNCMP(ptr, CRYPT_MAGIC, CRYPT_MAGIC_LEN) == 0)
+    if (is_crypt_sig(ptr,*sizep))
     {
  if (cryptkey == NULL)
  {
@@ -2799,8 +2830,10 @@ check_for_cryptkey(cryptkey, ptr, sizep,
     else
     {
  /* When newfile is TRUE, store the typed key
- * in the 'key' option and don't free it. */
- cryptkey = get_crypt_key(newfile, FALSE);
+ * in the 'key' option and don't free it.
+                 * bf needs hash of the key saved.
+                 */
+                cryptkey = get_crypt_key(TRUE,FALSE);
  /* check if empty key entered */
  if (cryptkey != NULL && *cryptkey == NUL)
  {
@@ -2813,12 +2846,14 @@ check_for_cryptkey(cryptkey, ptr, sizep,

  if (cryptkey != NULL)
  {
+            bf_key_init(cryptkey);
+            bf_ofb_init( ptr+magic_len, seed_len );
     crypt_init_keys(cryptkey);

     /* Remove magic number from the text */
-    *filesizep += CRYPT_MAGIC_LEN;
-    *sizep -= CRYPT_MAGIC_LEN;
-    mch_memmove(ptr, ptr + CRYPT_MAGIC_LEN, (size_t)*sizep);
+    *filesizep += (magic_len + seed_len);
+    *sizep     -= (magic_len  + seed_len);
+    mch_memmove(ptr, ptr + magic_len + seed_len, (size_t)*sizep);
  }
     }
     /* When starting to edit a new file which does not have
@@ -4222,12 +4257,18 @@ restore_backup:
 #ifdef FEAT_CRYPT
     if (*buf->b_p_key && !filtering)
     {
+        select_sig(1);  /* for writing select bf */
+        memset(header,0,sizeof(header));
+        strncpy(header,crypt_sig,magic_len);
+        sha2_seed(&header[magic_len],seed_len); /* create iv */
+        bf_ofb_init(header+magic_len,seed_len);
+        bf_key_init(buf->b_p_key);
  crypt_init_keys(buf->b_p_key);
  /* Write magic number, so that Vim knows that this file is encrypted
  * when reading it again.  This also undergoes utf-8 to ucs-2/4
  * conversion when needed. */
- write_info.bw_buf = (char_u *)CRYPT_MAGIC;
- write_info.bw_len = CRYPT_MAGIC_LEN;
+ write_info.bw_buf = header /* (char_u *)crypt_sig */ ;
+ write_info.bw_len = magic_len + seed_len;
  write_info.bw_flags = FIO_NOCONVERT;
  if (buf_write_bytes(&write_info) == FAIL)
     end = 0;
--- 73g/src/misc2.c 2009-12-31 04:18:04.000000000 -0800
+++ 73/src/misc2.c 2010-03-15 21:09:30.948375300 -0800
@@ -3631,11 +3631,18 @@ update_mouseshape(shape_idx)
  * Mohsin Ahmed, [hidden email], 98-09-24
  * Based on zip/crypt sources.
  *
+ * Mohsin Ahmed, http://www.cs.albany.edu/~mosh 2010-03-14
+ * Based on blowfish by Bruce Schneier (http://www.schneier.com/blowfish.html)
+ * and sha2 by Brian Gladman.
+ *
  * NOTE FOR USA: Since 2000 exporting this code from the USA is allowed to
  * most countries.  There are a few exceptions, but that still should not be a
  * problem since this code was originally created in Europe and India.
  */

+#include "sha2.h"
+#include "blowfish.h"
+
 /* from zip.h */

 typedef unsigned short ush; /* unsigned 16-bit value */
@@ -3678,10 +3685,13 @@ static ulg keys[3]; /* keys defining the
 decrypt_byte()
 {
     ush temp;
-
+    if( use_bf ){
+        return temp = bf_ranbyte();
+    } else {
     temp = (ush)keys[2] | 2;
     return (int)(((unsigned)(temp * (temp ^ 1)) >> 8) & 0xff);
 }
+}

 /*
  * Update the encryption keys with the next byte of plain text
@@ -3690,10 +3700,14 @@ decrypt_byte()
 update_keys(c)
     int c; /* byte of plain text */
 {
+    if( use_bf ){
+        bf_ofb_update( (unsigned char) c);
+    } else {
     keys[0] = CRC32(keys[0], c);
     keys[1] += keys[0] & 0xff;
     keys[1] = keys[1] * 134775813L + 1;
     keys[2] = CRC32(keys[2], (int)(keys[1] >> 24));
+    }
     return c;
 }

@@ -3730,6 +3744,7 @@ get_crypt_key(store, twice)
     int twice;    /* Ask for the key twice. */
 {
     char_u *p1, *p2 = NULL;
+    char_u *phash;
     int round;

     for (round = 0; ; ++round)
@@ -3750,15 +3765,27 @@ get_crypt_key(store, twice)
     if (p2 != NULL && STRCMP(p1, p2) != 0)
     {
  MSG(_("Keys don't match!"));
+                bf_clear_key(p1);
+                bf_clear_key(p2);
  vim_free(p1);
  vim_free(p2);
  p2 = NULL;
  round = -1; /* do it again */
  continue;
     }
-    if (store)
+
+            if( use_bf ){
+                if( bf_self_test() )
+                    EMSG2(_("E000: bf_self_test() failed\n"),"");
+                phash = sha2_key(p1,512);
+            }else{
+                phash = p1; // regular password.
+            }
+
+    if (store || use_bf )
     {
- set_option_value((char_u *)"key", 0L, p1, OPT_LOCAL);
+                set_option_value((char_u *)"key", 0L, phash, OPT_LOCAL);
+                bf_clear_key(p1);
  vim_free(p1);
  p1 = curbuf->b_p_key;
     }
@@ -3771,6 +3798,7 @@ get_crypt_key(store, twice)
     need_wait_return = FALSE;
     msg_didout = FALSE;

+    bf_clear_key(p2);
     vim_free(p2);
     return p1;
 }
--- 73g/src/blowfish.c 1969-12-31 16:00:00.000000000 -0800
+++ 73/src/blowfish.c 2010-03-14 21:35:34.765625000 -0800
@@ -0,0 +1,396 @@
+/*
+ * Blowfish encryption for vim; in Blowfish output feedback mode.
+ * GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ * Based on http://www.schneier.com/blowfish.html by Bruce Schneier
+ */
+
+#define FEAT_CRYPT
+#if defined(FEAT_CRYPT)
+
+#include <stdlib.h>
+#include <string.h>
+#include "blowfish.h"
+
+#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+    #if (('1234' >> 24) == '1')
+        #define LITTLE_ENDIAN 1
+    #elif (('4321' >> 24) == '1')
+        #define BIG_ENDIAN  1
+    #endif
+#endif
+
+
+int         use_bf=1;
+
+// Blowfish code
+
+static unsigned long pax[18], ipa[18] = {
+    0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
+    0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+    0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
+};
+
+static unsigned long sbx[4][256], sbi[4][256] = {
+    0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
+    0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+    0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
+    0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+    0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
+    0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+    0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
+    0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+    0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
+    0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+    0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
+    0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+    0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
+    0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+    0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
+    0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+    0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
+    0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+    0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
+    0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+    0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
+    0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+    0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
+    0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+    0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
+    0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+    0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
+    0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+    0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
+    0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+    0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
+    0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+    0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
+    0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+    0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
+    0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+    0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
+    0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+    0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
+    0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+    0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
+    0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+    0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, 0x4b7a70e9, 0xb5b32944,
+    0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+    0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29,
+    0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+    0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26,
+    0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+    0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c,
+    0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+    0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6,
+    0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+    0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f,
+    0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+    0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810,
+    0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+    0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa,
+    0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+    0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55,
+    0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+    0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1,
+    0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+    0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78,
+    0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+    0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883,
+    0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+    0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170,
+    0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+    0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7,
+    0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+    0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099,
+    0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+    0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263,
+    0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+    0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3,
+    0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+    0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7,
+    0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+    0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d,
+    0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+    0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460,
+    0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+    0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484,
+    0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+    0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a,
+    0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+    0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a,
+    0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+    0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785,
+    0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+    0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900,
+    0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+    0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9,
+    0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+    0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397,
+    0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+    0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9,
+    0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+    0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f,
+    0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+    0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e,
+    0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+    0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd,
+    0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+    0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8,
+    0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+    0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c,
+    0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+    0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b,
+    0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+    0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386,
+    0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+    0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0,
+    0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+    0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2,
+    0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+    0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770,
+    0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+    0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c,
+    0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+    0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa,
+    0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+    0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63,
+    0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+    0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9,
+    0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+    0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4,
+    0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
+    0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
+    0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+    0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
+    0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+    0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
+    0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+    0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
+    0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+    0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
+    0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+    0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
+    0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+    0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
+    0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+    0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
+    0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+    0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
+    0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+    0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
+    0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+    0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
+    0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+    0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
+    0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+    0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
+    0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+    0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
+    0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+    0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
+    0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+    0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
+    0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+    0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
+    0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+    0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
+    0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+    0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
+    0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+    0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
+    0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+    0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
+    0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+    0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+};
+
+
+
+#define F1(i) \
+    xl ^= pax[i];\
+    xr ^= ((sbx[0][xl>>24] +\
+    sbx[1][(xl&0xFF0000)>>16]) ^ \
+    sbx[2][(xl&0xFF00)>>8]) +\
+    sbx[3][xl&0xFF];
+
+#define F2(i) \
+    xr ^= pax[i];\
+    xl ^= ((sbx[0][xr>>24] +\
+    sbx[1][(xr&0xFF0000)>>16]) ^\
+    sbx[2][(xr&0xFF00)>>8]) +\
+    sbx[3][xr&0xFF];
+
+
+static void bf_e_block(unsigned long *p_xl, unsigned long *p_xr) {
+    unsigned long temp, xl = *p_xl, xr = *p_xr;
+    F1 (0) F2 (1) F1 (2) F2 (3) F1 (4) F2 (5) F1 (6) F2 (7)
+        F1 (8) F2 (9) F1 (10) F2 (11) F1 (12) F2 (13) F1 (14) F2 (15)
+    xl ^= pax[16]; xr ^= pax[17];
+    temp = xl; xl = xr; xr = temp;
+    *p_xl = xl; *p_xr = xr;
+}
+
+static void bf_d_block(unsigned long *p_xl, unsigned long *p_xr) { // not used.
+    unsigned long temp, xl = *p_xl, xr = *p_xr;
+    F1 (17) F2 (16) F1 (15) F2 (14) F1 (13) F2 (12) F1 (11) F2 (10)
+    F1( 9) F2(8)  F1(7)  F2(6)  F1(5)  F2(4)  F1(3)  F2(2) xl ^= pax[1];
+    xr ^= pax[0];
+    temp = xl; xl = xr; xr = temp;
+    *p_xl = xl; *p_xr = xr;
+}
+
+// little_endian version of x = htonl(x).
+#define flip_long(x) \
+    x = ((( (x) &     0xffL) << 24 ) | (((x) & 0xff00L)     <<  8 ) | \
+         (( (x) & 0xff0000L) >>  8 ) | (((x) & 0xff000000L) >> 24 )  )
+
+// Can't use unaligned char[4] as long on solaris.
+typedef union _block8 {
+ unsigned long ul[2];
+ unsigned char uc[8];
+} block8;
+
+static void bf_e_cblock( unsigned char *block ){
+ block8 bk;
+    memcpy(bk.uc,block,sizeof(bk));
+    #ifdef BIG_ENDIAN
+    flip_long(bk.ul[0]); flip_long(bk.ul[1]);
+    #endif
+    bf_e_block( &bk.ul[0], &bk.ul[1] );
+    #ifdef BIG_ENDIAN
+    flip_long(bk.ul[0]); flip_long(bk.ul[1]);
+    #endif
+ memcpy(block,bk.uc,sizeof(bk));
+}
+
+
+void bf_key_init(const unsigned char *key ) {
+    int i, j, keypos = 0;
+    unsigned long val, data_l, data_r;
+
+    int keylen = strlen(key);
+
+    // Blowfish takes a variable-length key, from 32 bits to 448 bits.
+    // If larger than 64 bits keys are not allowed, truncate it.
+    // keylen = min(8, keylen);
+
+    for (i = 0; i < 256; ++i) {
+        sbx[0][i] = sbi[0][i];
+        sbx[1][i] = sbi[1][i];
+        sbx[2][i] = sbi[2][i];
+        sbx[3][i] = sbi[3][i];
+    }
+
+    for (i = 0; i < 18; ++i) {
+        val = 0;
+        for (j = 0; j < 4; ++j)
+            val = (val << 8) | (key[keypos++ % keylen] & 0xff);
+        pax[i] = ipa[i] ^ val;
+    }
+
+    data_l = data_r = 0;
+    for (i = 0; i < 18; i += 2) {
+        bf_e_block(&data_l, &data_r);
+        pax[i + 0] = data_l;
+        pax[i + 1] = data_r;
+    }
+
+    for (i = 0; i < 4; ++i) {
+        for (j = 0; j < 256; j += 2) {
+            bf_e_block(&data_l, &data_r);
+            sbx[i][j + 0] = data_l;
+            sbx[i][j + 1] = data_r;
+        }
+    }
+
+}
+
+void bf_clear_key(unsigned char *key){
+    if(!key) return;
+    while(*key){
+        *key = 0;
+        key++;
+    }
+}
+
+
+/* BF Self test for corrupted tables or instructions */
+
+static int bf_check_tables(unsigned long ipa[18],unsigned long
sbi[4][256],unsigned long val){
+    int i,j;
+    unsigned int c=0;
+    for(i=0;i<18;i++)
+        c ^= ipa[i];
+    for(i=0;i<4;i++)
+        for(j=0;j<256;j++)
+            c ^= sbi[i][j];
+    return c == val ;
+}
+
+
+typedef struct _s_bft { char key[64], in[8],out[8]; unsigned long
keysum; } s_bft;
+
+s_bft bft[] = { // bf(key,in)==out && csum(pax/sbx(key))==keysum
+    "Mohsin Ahmed http://www.cs.albany.edu/~mosh", // key
+    "testxing", // in
+    "\x14\x68\xfd\xa4\xb9\x72\x60\x45", // out
+ 0xFb3eAeBF, // keysum
+};
+
+int bf_self_test(void){
+ int i,bn, err=0;
+ block8 bk;
+    if( ! bf_check_tables(ipa,sbi,0x6ffa520a ) )
+        err++;
+ bn = sizeof(bft)/sizeof(bft[0]);
+    for(i=0;i<bn;i++){
+        bf_key_init(bft[i].key);
+        if( ! bf_check_tables(pax,sbx, bft[i].keysum) )
+            err++;
+        memcpy(bk.uc,bft[i].in,sizeof(bk)); // want to resuse bft[i].in later.
+ bf_e_cblock(bk.uc);
+ if(memcmp( bk.uc ,bft[i].out,sizeof(bft[i].in)) != 0)
+ err++;
+    }
+    return err;
+}
+
+
+/* output feedback mode */
+static int randbyte_offset=0, update_offset=0 /*,block_done=0*/;
+static unsigned char ofb_buffer[BF_OFB_LEN]; /* 64 bytes */
+
+#ifndef max
+static int max(int a, int b) { return ( a > b )? a : b; }
+#endif
+
+void bf_ofb_init( const unsigned char *iv, int iv_len ){
+    int i,mi;
+    randbyte_offset=update_offset=0;
+    memset(ofb_buffer,0,BF_OFB_LEN);
+    if( iv_len <= 0 )
+        return; /* No iv */
+  mi = max(iv_len, BF_OFB_LEN );
+    for( i=0; i< mi; i++ )
+        ofb_buffer[ i % BF_OFB_LEN ] ^= iv[i % iv_len ];
+
+}
+
+void bf_ofb_update(unsigned char c){
+    ofb_buffer[ update_offset++ % BF_OFB_LEN ] ^= c;
+}
+
+
+unsigned char bf_ranbyte(void){
+    int current_byte = randbyte_offset++ % (BF_OFB_LEN);
+    int current_block = (current_byte / (BF_BLOCK) ) * (BF_BLOCK);
+
+ if( (current_byte % (BF_BLOCK)) == 0 ){
+ bf_e_cblock( &ofb_buffer[ current_block ] );
+
+ }
+    return ofb_buffer[ current_byte ];
+}
+
+
+#endif /* FEAT_CRYPT */
--- 73g/src/blowfish.h 1969-12-31 16:00:00.000000000 -0800
+++ 73/src/blowfish.h 2010-03-14 20:35:43.468750000 -0800
@@ -0,0 +1,27 @@
+/*
+ * Blowfish encryption for vim; in Blowfish output feedback mode.
+ * GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ * Based on http://www.schneier.com/blowfish.html by Bruce Schneier
+ */
+
+#define FEAT_CRYPT
+#ifdef FEAT_CRYPT
+
+int           bf_self_test(void);
+void          bf_key_init(const unsigned char *key );
+void          bf_ofb_init( const unsigned char *iv, int iv_len );
+void          bf_ofb_update(unsigned char c);
+unsigned char bf_ranbyte(void);
+void          bf_clear_key(unsigned char *key);
+extern int    use_bf;
+
+#define BF_BLOCK    8
+#define BF_OFB_LEN    (8*(BF_BLOCK))
+
+/* encode byte c, using temp t.  Warning: c must not have side effects. */
+#define BF_ZENCODE(c, t)  (t = bf_ranbyte(), bf_ofb_update(c), t^(c))
+
+/* decode byte c in place */
+#define BF_ZDECODE(c)   bf_ofb_update(c ^= bf_ranbyte())
+
+#endif /* FEAT_CRYPT */
--- 73g/src/sha2.c 1969-12-31 16:00:00.000000000 -0800
+++ 73/src/sha2.c 2010-03-14 17:50:37.187500000 -0800
@@ -0,0 +1,983 @@
+/*
+ * SHA2 HASH for vim password hashing.
+ * GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ */
+
+#define FEAT_CRYPT
+#if defined(FEAT_CRYPT)
+
+#include <time.h>
+#include <stdio.h>
+
+
+static void sha2_check_tables(void);
+static void sha2_self_test(void);
+
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <[hidden email]>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 30/11/2002
+
+ This is a byte oriented version of SHA2 that operates on arrays of bytes
+ stored in memory. This code implements sha256, sha384 and sha512 but the
+ latter two functions rely on efficient 64-bit integer operations that
+ may not be very efficient on 32-bit machines
+
+ The sha256 functions use a type 'sha256_ctx' to hold details of the
+ current hash state and uses the following three calls:
+
+       void sha256_begin(sha256_ctx ctx[1])
+       void sha256_hash(const unsigned char data[],
+                            unsigned long len, sha256_ctx ctx[1])
+       void sha256_end(unsigned char hval[], sha256_ctx ctx[1])
+
+ The first subroutine initialises a hash computation by setting up the
+ context in the sha256_ctx context. The second subroutine hashes 8-bit
+ bytes from array data[] into the hash state withinh sha256_ctx context,
+ the number of bytes to be hashed being given by the the unsigned long
+ integer len.  The third subroutine completes the hash calculation and
+ places the resulting digest value in the array of 8-bit bytes hval[].
+
+ The sha384 and sha512 functions are similar and use the interfaces:
+
+       void sha384_begin(sha384_ctx ctx[1]);
+       void sha384_hash(const unsigned char data[],
+                            unsigned long len, sha384_ctx ctx[1]);
+       void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
+
+       void sha512_begin(sha512_ctx ctx[1]);
+       void sha512_hash(const unsigned char data[],
+                            unsigned long len, sha512_ctx ctx[1]);
+       void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
+
+ In addition there is a function sha2 that can be used to call all these
+ functions using a call with a hash length parameter as follows:
+
+       int sha2_begin(unsigned long len, sha2_ctx ctx[1]);
+       void sha2_hash(const unsigned char data[],
+                            unsigned long len, sha2_ctx ctx[1]);
+       void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
+
+ My thanks to Erik Andersen <[hidden email]> for testing this code
+ on big-endian systems and for his assistance with corrections
+*/
+
+/* define the hash functions that you need          */
+
+#define SHA_2           /* for dynamic hash length  */
+#define SHA_256
+#define SHA_384
+#define SHA_512
+
+#include <string.h>     /* for memcpy() etc.        */
+#include <stdlib.h>     /* for _lrotr with VC++     */
+
+#include "sha2.h"
+
+/*  1. PLATFORM SPECIFIC INCLUDES */
+
+#if defined(__GNU_LIBRARY__)
+#  include <byteswap.h>
+#  include <endian.h>
+#elif defined(__CRYPTLIB__)
+#  if defined( INC_ALL )
+#    include "crypt.h"
+#  elif defined( INC_CHILD )
+#    include "../crypt.h"
+#  else
+#    include "crypt.h"
+#  endif
+#  if defined(DATA_LITTLEENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#  else
+#    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#  endif
+#elif defined(_MSC_VER)
+#  include <stdlib.h>
+#elif !defined(WIN32)
+#  include <stdlib.h>
+#  if !defined (_ENDIAN_H)
+#    include <sys/param.h>
+#  else
+#    include _ENDIAN_H
+#  endif
+#endif
+
+/*  2. BYTE ORDER IN 32-BIT WORDS
+
+    To obtain the highest speed on processors with 32-bit words, this code
+    needs to determine the order in which bytes are packed into such words.
+    The following block of code is an attempt to capture the most obvious
+    ways in which various environemnts specify their endian definitions.
+    It may well fail, in which case the definitions will need to be set by
+    editing at the points marked **** EDIT HERE IF NECESSARY **** below.
+*/
+#define SHA_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+#define SHA_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
+#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    if defined(BYTE_ORDER)
+#      if   (BYTE_ORDER == LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#      elif (BYTE_ORDER == BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#  endif
+#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
+#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    if defined(_BYTE_ORDER)
+#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#      elif (_BYTE_ORDER == _BIG_ENDIAN)
+#        define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#      endif
+#    endif
+#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
+#    define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#  endif
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#elif (('1234' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER SHA_LITTLE_ENDIAN
+#elif (('4321' >> 24) == '1')
+#  define PLATFORM_BYTE_ORDER SHA_BIG_ENDIAN
+#endif
+#endif
+
+#if !defined(PLATFORM_BYTE_ORDER)
+#  error Please set undetermined byte order (lines 159 or 161 of sha2.c).
+#endif
+
+#ifdef _MSC_VER
+#pragma intrinsic(memcpy)
+#endif
+
+#define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))
+
+#if !defined(bswap_32)
+#define bswap_32(x) (rotr32((x), 24) & 0x00ff00ff | rotr32((x), 8) &
0xff00ff00)
+#endif
+
+#if (PLATFORM_BYTE_ORDER == SHA_LITTLE_ENDIAN)
+#define SWAP_BYTES
+#else
+#undef  SWAP_BYTES
+#endif
+
+#if defined(SHA_2) || defined(SHA_256)
+
+#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
+
+#if defined(SWAP_BYTES)
+#define bsw_32(p,n) { int _i = (n); while(_i--) p[_i] = bswap_32(p[_i]); }
+#else
+#define bsw_32(p,n)
+#endif
+
+/* SHA256 mixing function definitions   */
+
+#define ch(x,y,z)   (((x) & (y)) ^ (~(x) & (z)))
+#define maj(x,y,z)  (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#define s256_0(x) (rotr32((x),  2) ^ rotr32((x), 13) ^ rotr32((x), 22))
+#define s256_1(x) (rotr32((x),  6) ^ rotr32((x), 11) ^ rotr32((x), 25))
+#define g256_0(x) (rotr32((x),  7) ^ rotr32((x), 18) ^ ((x) >>  3))
+#define g256_1(x) (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
+
+/* rotated SHA256 round definition. Rather than swapping variables as in    */
+/* FIPS-180, different variables are 'rotated' on each round, returning     */
+/* to their starting positions every eight rounds                           */
+
+#define h2(i) ctx->wbuf[i & 15] += \
+    g256_1(ctx->wbuf[(i + 14) & 15]) + ctx->wbuf[(i + 9) & 15] +
g256_0(ctx->wbuf[(i + 1) & 15])
+
+#define h2_cycle(i,j)  \
+    v[(7 - i) & 7] += (j ? h2(i) : ctx->wbuf[i & 15]) + k256[i + j] \
+        + s256_1(v[(4 - i) & 7]) + ch(v[(4 - i) & 7], v[(5 - i) & 7],
v[(6 - i) & 7]); \
+    v[(3 - i) & 7] += v[(7 - i) & 7]; \
+    v[(7 - i) & 7] += s256_0(v[(0 - i) & 7]) + maj(v[(0 - i) & 7],
v[(1 - i) & 7], v[(2 - i) & 7])
+
+/* SHA256 mixing data   */
+
+const sha2_32t k256[64] = {
+    n_u32(428a2f98), n_u32(71374491), n_u32(b5c0fbcf), n_u32(e9b5dba5),
+    n_u32(3956c25b), n_u32(59f111f1), n_u32(923f82a4), n_u32(ab1c5ed5),
+    n_u32(d807aa98), n_u32(12835b01), n_u32(243185be), n_u32(550c7dc3),
+    n_u32(72be5d74), n_u32(80deb1fe), n_u32(9bdc06a7), n_u32(c19bf174),
+    n_u32(e49b69c1), n_u32(efbe4786), n_u32(0fc19dc6), n_u32(240ca1cc),
+    n_u32(2de92c6f), n_u32(4a7484aa), n_u32(5cb0a9dc), n_u32(76f988da),
+    n_u32(983e5152), n_u32(a831c66d), n_u32(b00327c8), n_u32(bf597fc7),
+    n_u32(c6e00bf3), n_u32(d5a79147), n_u32(06ca6351), n_u32(14292967),
+    n_u32(27b70a85), n_u32(2e1b2138), n_u32(4d2c6dfc), n_u32(53380d13),
+    n_u32(650a7354), n_u32(766a0abb), n_u32(81c2c92e), n_u32(92722c85),
+    n_u32(a2bfe8a1), n_u32(a81a664b), n_u32(c24b8b70), n_u32(c76c51a3),
+    n_u32(d192e819), n_u32(d6990624), n_u32(f40e3585), n_u32(106aa070),
+    n_u32(19a4c116), n_u32(1e376c08), n_u32(2748774c), n_u32(34b0bcb5),
+    n_u32(391c0cb3), n_u32(4ed8aa4a), n_u32(5b9cca4f), n_u32(682e6ff3),
+    n_u32(748f82ee), n_u32(78a5636f), n_u32(84c87814), n_u32(8cc70208),
+    n_u32(90befffa), n_u32(a4506ceb), n_u32(bef9a3f7), n_u32(c67178f2),
+};
+
+/* SHA256 initialisation data */
+
+const sha2_32t i256[8] = {
+    n_u32(6a09e667), n_u32(bb67ae85), n_u32(3c6ef372), n_u32(a54ff53a),
+    n_u32(510e527f), n_u32(9b05688c), n_u32(1f83d9ab), n_u32(5be0cd19)
+};
+
+void sha256_begin(sha256_ctx ctx[1]) {
+    ctx->count[0] = ctx->count[1] = 0;
+    memcpy(ctx->hash, i256, 8 * sizeof(sha2_32t));
+}
+
+/* Compile 64 bytes of hash data into SHA256 digest value   */
+/* NOTE: this routine assumes that the byte order in the    */
+/* ctx->wbuf[] at this point is in such an order that low   */
+/* address bytes in the ORIGINAL byte stream placed in this */
+/* buffer will now go to the high end of words on BOTH big  */
+/* and little endian systems                                */
+
+void sha256_compile(sha256_ctx ctx[1]) {
+    sha2_32t v[8], j;
+
+    memcpy(v, ctx->hash, 8 * sizeof(sha2_32t));
+
+    for(j = 0; j < 64; j += 16)
+    {
+        h2_cycle( 0, j); h2_cycle( 1, j); h2_cycle( 2, j); h2_cycle( 3, j);
+        h2_cycle( 4, j); h2_cycle( 5, j); h2_cycle( 6, j); h2_cycle( 7, j);
+        h2_cycle( 8, j); h2_cycle( 9, j); h2_cycle(10, j); h2_cycle(11, j);
+        h2_cycle(12, j); h2_cycle(13, j); h2_cycle(14, j); h2_cycle(15, j);
+    }
+
+    ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2];
ctx->hash[3] += v[3];
+    ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6];
ctx->hash[7] += v[7];
+}
+
+/* SHA256 hash data in an array of bytes into hash buffer   */
+/* and call the hash_compile function as required.          */
+
+void sha256_hash(const unsigned char data[], unsigned long len,
sha256_ctx ctx[1]) {
+    sha2_32t pos = (sha2_32t)(ctx->count[0] & SHA256_MASK),
+             space = SHA256_BLOCK_SIZE - pos;
+    const unsigned char *sp = data;
+
+    if((ctx->count[0] += len) < len)
+        ++(ctx->count[1]);
+
+    while(len >= space)     /* tranfer whole blocks while possible  */
+    {
+        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
+        sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0;
+ bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2)
+        sha256_compile(ctx);
+    }
+
+    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
+}
+
+/* SHA256 Final padding and digest calculation  */
+
+static sha2_32t  m1[4] = {
+    n_u32(00000000), n_u32(ff000000), n_u32(ffff0000), n_u32(ffffff00)
+};
+
+static sha2_32t  b1[4] = {
+    n_u32(80000000), n_u32(00800000), n_u32(00008000), n_u32(00000080)
+};
+
+void sha256_end(unsigned char hval[], sha256_ctx ctx[1]) {
+    sha2_32t    i = (sha2_32t)(ctx->count[0] & SHA256_MASK);
+
+ bsw_32(ctx->wbuf, (i + 3) >> 2)
+    /* bytes in the buffer are now in an order in which references  */
+    /* to 32-bit words will put bytes with lower addresses into the */
+    /* top of 32 bit words on BOTH big and little endian machines   */
+
+    /* we now need to mask valid bytes and add the padding which is */
+    /* a single 1 bit and as many zero bits as necessary.           */
+    ctx->wbuf[i >> 2] = (ctx->wbuf[i >> 2] & m1[i & 3]) | b1[i & 3];
+
+    /* we need 9 or more empty positions, one for the padding byte  */
+    /* (above) and eight for the length count.  If there is not     */
+    /* enough space pad and empty the buffer                        */
+    if(i > SHA256_BLOCK_SIZE - 9)
+    {
+        if(i < 60) ctx->wbuf[15] = 0;
+        sha256_compile(ctx);
+        i = 0;
+    }
+    else    /* compute a word index for the empty buffer positions  */
+        i = (i >> 2) + 1;
+
+    while(i < 14) /* and zero pad all but last two positions      */
+        ctx->wbuf[i++] = 0;
+
+    /* the following 32-bit length fields are assembled in the      */
+    /* wrong byte order on little endian machines but this is       */
+    /* corrected later since they are only ever used as 32-bit      */
+    /* word values.                                                 */
+
+    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
+    ctx->wbuf[15] = ctx->count[0] << 3;
+
+    sha256_compile(ctx);
+
+    /* extract the hash value as bytes in case the hash buffer is   */
+    /* mislaigned for 32-bit words                                  */
+    for(i = 0; i < SHA256_DIGEST_SIZE; ++i)
+        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> 8 * (~i & 3));
+}
+
+void sha256(unsigned char hval[], const unsigned char data[],
unsigned long len) {
+    sha256_ctx  cx[1];
+    sha256_begin(cx); sha256_hash(data, len, cx); sha256_end(hval, cx);
+}
+
+#endif
+
+#if defined(SHA_2) || defined(SHA_384) || defined(SHA_512)
+
+#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
+
+#define rotr64(x,n)   (((x) >> n) | ((x) << (64 - n)))
+
+#if !defined(bswap_64)
+#define bswap_64(x) (((sha2_64t)(bswap_32((sha2_32t)(x)))) << 32 |
bswap_32((sha2_32t)((x) >> 32)))
+#endif
+
+#if defined(SWAP_BYTES)
+#define bsw_64(p,n) { int _i = (n); while(_i--) p[_i] = bswap_64(p[_i]); }
+#else
+#define bsw_64(p,n)
+#endif
+
+/* SHA512 mixing function definitions   */
+
+#define s512_0(x) (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
+#define s512_1(x) (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
+#define g512_0(x) (rotr64((x),  1) ^ rotr64((x),  8) ^ ((x) >>  7))
+#define g512_1(x) (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >>  6))
+
+/* rotated SHA512 round definition. Rather than swapping variables as in    */
+/* FIPS-180, different variables are 'rotated' on each round, returning     */
+/* to their starting positions every eight rounds                           */
+
+#define h5(i) ctx->wbuf[i & 15] += \
+    g512_1(ctx->wbuf[(i + 14) & 15]) + ctx->wbuf[(i + 9) & 15] +
g512_0(ctx->wbuf[(i + 1) & 15])
+
+#define h5_cycle(i,j)  \
+    v[(7 - i) & 7] += (j ? h5(i) : ctx->wbuf[i & 15]) + k512[i + j] \
+        + s512_1(v[(4 - i) & 7]) + ch(v[(4 - i) & 7], v[(5 - i) & 7],
v[(6 - i) & 7]); \
+    v[(3 - i) & 7] += v[(7 - i) & 7]; \
+    v[(7 - i) & 7] += s512_0(v[(0 - i) & 7]) + maj(v[(0 - i) & 7],
v[(1 - i) & 7], v[(2 - i) & 7])
+
+/* SHA384/SHA512 mixing data    */
+
+const sha2_64t  k512[80] = {
+    n_u64(428a2f98d728ae22), n_u64(7137449123ef65cd),
+    n_u64(b5c0fbcfec4d3b2f), n_u64(e9b5dba58189dbbc),
+    n_u64(3956c25bf348b538), n_u64(59f111f1b605d019),
+    n_u64(923f82a4af194f9b), n_u64(ab1c5ed5da6d8118),
+    n_u64(d807aa98a3030242), n_u64(12835b0145706fbe),
+    n_u64(243185be4ee4b28c), n_u64(550c7dc3d5ffb4e2),
+    n_u64(72be5d74f27b896f), n_u64(80deb1fe3b1696b1),
+    n_u64(9bdc06a725c71235), n_u64(c19bf174cf692694),
+    n_u64(e49b69c19ef14ad2), n_u64(efbe4786384f25e3),
+    n_u64(0fc19dc68b8cd5b5), n_u64(240ca1cc77ac9c65),
+    n_u64(2de92c6f592b0275), n_u64(4a7484aa6ea6e483),
+    n_u64(5cb0a9dcbd41fbd4), n_u64(76f988da831153b5),
+    n_u64(983e5152ee66dfab), n_u64(a831c66d2db43210),
+    n_u64(b00327c898fb213f), n_u64(bf597fc7beef0ee4),
+    n_u64(c6e00bf33da88fc2), n_u64(d5a79147930aa725),
+    n_u64(06ca6351e003826f), n_u64(142929670a0e6e70),
+    n_u64(27b70a8546d22ffc), n_u64(2e1b21385c26c926),
+    n_u64(4d2c6dfc5ac42aed), n_u64(53380d139d95b3df),
+    n_u64(650a73548baf63de), n_u64(766a0abb3c77b2a8),
+    n_u64(81c2c92e47edaee6), n_u64(92722c851482353b),
+    n_u64(a2bfe8a14cf10364), n_u64(a81a664bbc423001),
+    n_u64(c24b8b70d0f89791), n_u64(c76c51a30654be30),
+    n_u64(d192e819d6ef5218), n_u64(d69906245565a910),
+    n_u64(f40e35855771202a), n_u64(106aa07032bbd1b8),
+    n_u64(19a4c116b8d2d0c8), n_u64(1e376c085141ab53),
+    n_u64(2748774cdf8eeb99), n_u64(34b0bcb5e19b48a8),
+    n_u64(391c0cb3c5c95a63), n_u64(4ed8aa4ae3418acb),
+    n_u64(5b9cca4f7763e373), n_u64(682e6ff3d6b2b8a3),
+    n_u64(748f82ee5defb2fc), n_u64(78a5636f43172f60),
+    n_u64(84c87814a1f0ab72), n_u64(8cc702081a6439ec),
+    n_u64(90befffa23631e28), n_u64(a4506cebde82bde9),
+    n_u64(bef9a3f7b2c67915), n_u64(c67178f2e372532b),
+    n_u64(ca273eceea26619c), n_u64(d186b8c721c0c207),
+    n_u64(eada7dd6cde0eb1e), n_u64(f57d4f7fee6ed178),
+    n_u64(06f067aa72176fba), n_u64(0a637dc5a2c898a6),
+    n_u64(113f9804bef90dae), n_u64(1b710b35131c471b),
+    n_u64(28db77f523047d84), n_u64(32caab7b40c72493),
+    n_u64(3c9ebe0a15c9bebc), n_u64(431d67c49c100d4c),
+    n_u64(4cc5d4becb3e42b6), n_u64(597f299cfc657e2a),
+    n_u64(5fcb6fab3ad6faec), n_u64(6c44198c4a475817)
+};
+
+/* Compile 64 bytes of hash data into SHA384/SHA512 digest value  */
+
+void sha512_compile(sha512_ctx ctx[1]) {
+    sha2_64t    v[8];
+    sha2_32t    j;
+
+    memcpy(v, ctx->hash, 8 * sizeof(sha2_64t));
+
+    for(j = 0; j < 80; j += 16) {
+        h5_cycle( 0, j); h5_cycle( 1, j); h5_cycle( 2, j); h5_cycle( 3, j);
+        h5_cycle( 4, j); h5_cycle( 5, j); h5_cycle( 6, j); h5_cycle( 7, j);
+        h5_cycle( 8, j); h5_cycle( 9, j); h5_cycle(10, j); h5_cycle(11, j);
+        h5_cycle(12, j); h5_cycle(13, j); h5_cycle(14, j); h5_cycle(15, j);
+    }
+
+    ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; ctx->hash[2] += v[2];
ctx->hash[3] += v[3];
+    ctx->hash[4] += v[4]; ctx->hash[5] += v[5]; ctx->hash[6] += v[6];
ctx->hash[7] += v[7];
+}
+
+/* Compile 128 bytes of hash data into SHA256 digest value  */
+/* NOTE: this routine assumes that the byte order in the    */
+/* ctx->wbuf[] at this point is in such an order that low   */
+/* address bytes in the ORIGINAL byte stream placed in this */
+/* buffer will now go to the high end of words on BOTH big  */
+/* and little endian systems                                */
+
+void sha512_hash(const unsigned char data[], unsigned long len,
sha512_ctx ctx[1]) {
+    sha2_32t pos = (sha2_32t)(ctx->count[0] & SHA512_MASK),
+             space = SHA512_BLOCK_SIZE - pos;
+    const unsigned char *sp = data;
+
+    if((ctx->count[0] += len) < len)
+        ++(ctx->count[1]);
+
+    while(len >= space)     /* tranfer whole blocks while possible  */
+    {
+        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
+        sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0;
+ bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3);
+        sha512_compile(ctx);
+    }
+
+    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
+}
+
+/* SHA384/512 Final padding and digest calculation  */
+
+static sha2_64t  m2[8] = {
+    n_u64(0000000000000000), n_u64(ff00000000000000),
+    n_u64(ffff000000000000), n_u64(ffffff0000000000),
+    n_u64(ffffffff00000000), n_u64(ffffffffff000000),
+    n_u64(ffffffffffff0000), n_u64(ffffffffffffff00)
+};
+
+static sha2_64t  b2[8] = {
+    n_u64(8000000000000000), n_u64(0080000000000000),
+    n_u64(0000800000000000), n_u64(0000008000000000),
+    n_u64(0000000080000000), n_u64(0000000000800000),
+    n_u64(0000000000008000), n_u64(0000000000000080)
+};
+
+static void sha_end(unsigned char hval[], sha512_ctx ctx[1], const
unsigned int hlen) {   sha2_32t    i = (sha2_32t)(ctx->count[0] &
SHA512_MASK);
+
+ bsw_64(ctx->wbuf, (i + 7) >> 3);
+
+    /* bytes in the buffer are now in an order in which references  */
+    /* to 64-bit words will put bytes with lower addresses into the */
+    /* top of 64 bit words on BOTH big and little endian machines   */
+
+    /* we now need to mask valid bytes and add the padding which is */
+    /* a single 1 bit and as many zero bits as necessary.           */
+    ctx->wbuf[i >> 3] = (ctx->wbuf[i >> 3] & m2[i & 7]) | b2[i & 7];
+
+    /* we need 17 or more empty byte positions, one for the padding */
+    /* byte (above) and sixteen for the length count.  If there is  */
+    /* not enough space pad and empty the buffer                    */
+    if(i > SHA512_BLOCK_SIZE - 17)
+    {
+        if(i < 120) ctx->wbuf[15] = 0;
+        sha512_compile(ctx);
+        i = 0;
+    }
+    else
+        i = (i >> 3) + 1;
+
+    while(i < 14)
+        ctx->wbuf[i++] = 0;
+
+    /* the following 64-bit length fields are assembled in the      */
+    /* wrong byte order on little endian machines but this is       */
+    /* corrected later since they are only ever used as 64-bit      */
+    /* word values.                                                 */
+
+    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61);
+    ctx->wbuf[15] = ctx->count[0] << 3;
+
+    sha512_compile(ctx);
+
+    /* extract the hash value as bytes in case the hash buffer is   */
+    /* misaligned for 32-bit words                                  */
+    for(i = 0; i < hlen; ++i)
+        hval[i] = (unsigned char)(ctx->hash[i >> 3] >> 8 * (~i & 7));
+}
+
+#endif
+
+#if defined(SHA_2) || defined(SHA_384)
+
+/* SHA384 initialisation data   */
+
+const sha2_64t  i384[80] = {
+    n_u64(cbbb9d5dc1059ed8), n_u64(629a292a367cd507),
+    n_u64(9159015a3070dd17), n_u64(152fecd8f70e5939),
+    n_u64(67332667ffc00b31), n_u64(8eb44a8768581511),
+    n_u64(db0c2e0d64f98fa7), n_u64(47b5481dbefa4fa4)
+};
+
+void sha384_begin(sha384_ctx ctx[1]) {
+    ctx->count[0] = ctx->count[1] = 0;
+    memcpy(ctx->hash, i384, 8 * sizeof(sha2_64t));
+}
+
+void sha384_end(unsigned char hval[], sha384_ctx ctx[1]) {
+    sha_end(hval, ctx, SHA384_DIGEST_SIZE);
+}
+
+void sha384(unsigned char hval[], const unsigned char data[],
unsigned long len) {
+    sha384_ctx  cx[1];
+    sha384_begin(cx); sha384_hash(data, len, cx); sha384_end(hval, cx);
+}
+
+#endif
+
+#if defined(SHA_2) || defined(SHA_512)
+
+/* SHA512 initialisation data   */
+
+const sha2_64t  i512[80] = {
+    n_u64(6a09e667f3bcc908), n_u64(bb67ae8584caa73b),
+    n_u64(3c6ef372fe94f82b), n_u64(a54ff53a5f1d36f1),
+    n_u64(510e527fade682d1), n_u64(9b05688c2b3e6c1f),
+    n_u64(1f83d9abfb41bd6b), n_u64(5be0cd19137e2179)
+};
+
+void sha512_begin(sha512_ctx ctx[1]) {
+    ctx->count[0] = ctx->count[1] = 0;
+    memcpy(ctx->hash, i512, 8 * sizeof(sha2_64t));
+}
+
+void sha512_end(unsigned char hval[], sha512_ctx ctx[1]) {
+    sha_end(hval, ctx, SHA512_DIGEST_SIZE);
+}
+
+void sha512(unsigned char hval[], const unsigned char data[],
unsigned long len)
+{   sha512_ctx  cx[1];
+
+    sha512_begin(cx); sha512_hash(data, len, cx); sha512_end(hval, cx);
+}
+
+#endif
+
+#if defined(SHA_2)
+
+#define CTX_256(x)  ((x)->uu->ctx256)
+#define CTX_384(x)  ((x)->uu->ctx512)
+#define CTX_512(x)  ((x)->uu->ctx512)
+
+/* SHA2 initialisation */
+
+int sha2_begin(unsigned long len, sha2_ctx ctx[1]) {
+    unsigned long   l = len;
+    static int done=0;
+
+    if(!done++){
+        sha2_check_tables();
+        sha2_self_test();
+    }
+
+    switch(len) {
+        case 256:   l = len >> 3;
+        case  32:   CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
+                    memcpy(CTX_256(ctx)->hash, i256, 32); break;
+        case 384:   l = len >> 3;
+        case  48:   CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;
+                    memcpy(CTX_384(ctx)->hash, i384, 64); break;
+        case 512:   l = len >> 3;
+        case  64:   CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;
+                    memcpy(CTX_512(ctx)->hash, i512, 64); break;
+        default:    return SHA2_BAD;
+    }
+
+    ctx->sha2_len = l; return SHA2_GOOD;
+}
+
+void sha2_hash(const unsigned char data[], unsigned long len,
sha2_ctx ctx[1]) {
+    switch(ctx->sha2_len) {
+        case 32: sha256_hash(data, len, CTX_256(ctx)); return;
+        case 48: sha384_hash(data, len, CTX_384(ctx)); return;
+        case 64: sha512_hash(data, len, CTX_512(ctx)); return;
+    }
+}
+
+void sha2_end(unsigned char hval[], sha2_ctx ctx[1]) {
+    switch(ctx->sha2_len) {
+        case 32: sha256_end(hval, CTX_256(ctx)); return;
+        case 48: sha_end(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;
+        case 64: sha_end(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;
+    }
+}
+
+int sha2(unsigned char hval[], unsigned long size,
+                                const unsigned char data[], unsigned
long len) {
+    sha2_ctx    cx[1];
+    if(sha2_begin(size, cx) == SHA2_GOOD) {
+        sha2_hash(data, len, cx); sha2_end(hval, cx); return SHA2_GOOD;
+    } else
+        return SHA2_BAD;
+}
+
+/*
+ *****************************************************
+ * Vim specific SHA2 support.                        *
+ * by Mohsin Ahmed, http://www.cs.albany.edu/~mosh   *
+ *****************************************************
+ */
+
+/* See blowfish.h for portable htonl */
+/* Portable convert int x to data[0..4] */
+void int2chars( int x, unsigned char data[] ){
+    data[0] = (unsigned char) ((x &       0xffL) >>  0 );
+    data[1] = (unsigned char) ((x &     0xff00L) >>  8 );
+    data[2] = (unsigned char) ((x &   0xff0000L) >> 16 );
+    data[3] = (unsigned char) ((x & 0xff000000L) >> 24 );
+}
+
+
+
+/*
+   set header[0..seedlen-1] = sha2_seed(rand);
+   We don't use header[..] = time(NULL) , but
+   1. The header must be completely unpredictable.
+   2. seed is not ascii.
+   3. htonl is required only for casting portably.
+*/
+
+void sha2_seed(char header[],int seed_len){
+    int i;
+    static unsigned char hval[512/8+1];
+    sha2_ctx ctx;
+    unsigned char data[1000]; /* random data */
+    srand( (unsigned)time(NULL));
+    for (i=0; i<sizeof(data)-1; i++) {
+        data[i] = (time(NULL) ^ rand()) & 0xff;
+    }
+    sha2_begin(512, &ctx);
+    sha2_hash(data, sizeof(data), &ctx);
+    sha2_end(hval, &ctx);
+    for(i=0;i<seed_len;i++){
+        header[i] = hval[i % (512/8) ];
+    }
+}
+
+/*
+ * Compute hash of data as a null terminated string for use as password.
+ * On return the password is replaced by our output.
+ * We dont do bin2hex(hash(password)) as it is easy to spot a run of
hexits in memory.
+*/
+
+unsigned char * sha2_key(const unsigned char *password, int sha_len ){
+    static unsigned char hval[512/8+1];
+    int i,k,pads,run;
+    sha2_ctx ctx;
+
+ if( ! *password ) /* no passwd means dont encrypt */
+ return "";
+    if(!strcmp(password,"0")) /* "0" means return previous hash, for
convienience. */
+        return hval;
+
+    if( sha_len != 512 && sha_len != 384 && sha_len != 256 )
+        sha_len = 256; // 32 bytes.
+
+    memset(hval,0,sizeof(hval));
+    sha2_begin(sha_len, &ctx);
+    sha2_hash(password, strlen(password), &ctx);
+    sha2_end(hval, &ctx);
+
+    /* purge '\0' in the beginning of hval, but dont pad too much */
+    pads=run=0;
+    for(i=0;i<sizeof(hval)-1;i++){
+        if(hval[i]){
+            k=hval[i];
+            run=0;
+        }else{
+            hval[i] = k|1;
+            if(++pads>=16) break;
+            if(++run>=8) break;
+        }
+    }
+    hval[sizeof(hval)-1]=0; /* its a string! */
+    return hval;
+}
+
+/* For testing hashing */
+static void sha2_check_tables(void){
+    unsigned int c=0;
+    int i;
+    static int done=0;
+    if(done++)
+        return;
+    for(i=0;i<64;i++)
+        c ^= k256[i];
+    for(i=0;i<8;i++)
+        c ^= i256[i];
+    if( c != 0x53e3fc1e ) {
+        fprintf(stderr,"sha2_check_tables failed.\n");
+        exit(1);
+    }
+}
+#endif
+
+#define TEST_SHA_LENS 4
+#if TEST_SHA_LENS
+
+/* compare sha hash of string with known hashes */
+int sha_lens[TEST_SHA_LENS] = {64,256,384,512};
+
+typedef struct _s_sht {
+ char *preset_data; unsigned int expected_hashes[TEST_SHA_LENS];
+} s_sht;
+
+s_sht sht[] = {
+    "AUTHOR: GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh",
+    0xc94ad1e7,0x0e0fff1f,0x40bfbdb5,0xe97f3f28
+};
+
+static void sha2_self_test(void){
+ int i,k,p,bn;
+    sha2_ctx ctx;
+    unsigned char hval[64], *data;
+    unsigned int c;
+ bn = sizeof(sht)/sizeof(sht[0]);
+    for(i=0;i<bn;i++){
+        for(k=0;k<TEST_SHA_LENS;k++){
+            memset(hval,0,sizeof(hval));
+            sha2_begin(sha_lens[k], &ctx);
+            data =  sht[i].preset_data;
+            sha2_hash( data, strlen(data), &ctx);
+            sha2_end(hval, &ctx);
+            c = 0;
+            for(p=0; p<sha_lens[k]/8; p++)
+                c ^= hval[p] << ((p%4)*8);
+            if( c != sht[i].expected_hashes[k] )
+                exit(1);
+        }
+    }
+}
+#endif /* TEST_SHA_LENS */
+
+#ifdef CHECK_SHA_EXE
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#else
+#include <unistd.h>
+#endif
+
+const char *hexa = "0123456789abcdef";
+int equal_hval_str(unsigned char *hval, char *s, int sha_len){
+ int i,b1,b2;
+    for(i=0;i<sha_len/8;i++){
+        b1 = ((hval[i] & 0x0f)>>0) & 0xf;
+        b2 = ((hval[i] & 0xf0)>>4) & 0xf;
+        if( hexa[b1] != s[i*2+1]  || hexa[b2] != s[i*2+0] )
+            return 0;
+    }
+ return 1;
+}
+
+char *hval_to_str(unsigned char *hval, int sha_len){
+    int i,b1,b2;
+    static char hstr[512/8*2+1];
+    memset(hstr,'\0',sizeof(hstr));
+    for(i=0;i<sha_len/8;i++){
+        b1 = ((hval[i] & 0x0f)>>0) & 0xf;
+        b2 = ((hval[i] & 0xf0)>>4) & 0xf;
+        hstr[i*2+0] = hexa[b2];
+        hstr[i*2+1] = hexa[b1];
+    }
+    return hstr;
+}
+
+/*
+    WHAT: checksum of vim.exe
+    WHY: vim will only work if correct hash is found in sha_file_list.
+      This prevents any modification to vim.exe or its location.
+    HOW: Compute and check hash of content(argv0) & location(argv0).
+        1. exit unless both sha_file_list and sha_file_update exists.
+        2. y=sha2(concat(contents(argv0),argv0)),
+            if(y is in sha_file_list) return ok.
+            else append y to sha_file_update and exit
+*/
+
+int sha2_check_argv0( void ){
+ static char prog[256];
+ static char line[256];
+    int sha_len=256;
+ FILE *fp;
+ char *sha_file_list,*sha_file_update;
+    char *hval, *hstr;
+    static int done=0;
+    if(done++)
+        return 1;
+
+    #ifdef _WIN32
+    GetModuleFileName(0,prog,sizeof(prog)-1);
+    sha_file_list = "c:/etc/1";
+    sha_file_update = "c:/tmp/1";
+    #else
+    sha_file_list = "/etc/1";
+    sha_file_update = "/tmp/1";
+    #endif
+
+ fp = fopen(sha_file_list,"r"); /* file must exists. */
+    if(!fp)
+ return 0;
+
+    hval = sha2_file(prog,sha_len,1);
+    hstr = hval_to_str(hval,sha_len);
+ while( fgets(line,sizeof(line),fp) ){
+        if( strncmp(line,hstr,strlen(hstr)) == 0 ) {
+ fclose(fp);
+ return 1; /* success, found hash in file */
+ }
+ }
+ fclose(fp);
+ /* failure, append correct hash to the file */
+ fp = fopen(sha_file_update,"r+"); /* file must exists! */
+ if(!fp)
+ return 0;
+    fprintf(fp,"%s.\n",hstr);
+    fclose(fp);
+    return 0;
+}
+
+/*
+ * Compute sha2_hash(concat(contents(filename),filename)).
+*/
+
+unsigned char *sha2_file(char *filename, int sha_len, int hash_pathname_also ){
+    int rc,fd;
+    static char fdata[512];
+    static unsigned char hval[(512/8)+1];
+    sha2_ctx ctx;
+
+    fd = _open(filename, _O_RDONLY );
+    if( fd == -1 )
+        return 0;
+    memset(hval,0,sizeof(hval));
+    sha2_begin(sha_len, &ctx);
+    do {
+        rc = _read( fd, fdata, sizeof(fdata));
+        if( rc == -1 )
+            return 0;
+        if( rc>0 )
+            sha2_hash(fdata, rc, &ctx);
+    } while( rc > 0 );
+    _close(fd);
+    if( hash_pathname_also )
+        sha2_hash(filename, strlen(filename), &ctx);
+    sha2_end(hval, &ctx);
+    return hval;
+}
+#endif
+
+#ifdef TEST_SHA
+void print_data(char *message,char *data,int data_len){
+    int i;
+    fprintf(stderr,"%s[1..%d]=",message,data_len,data);
+    for(i=0;i<data_len;i++) {
+        if(i%16) ;else fprintf(stderr,"\n  ");
+        if(i%2) ;else fprintf(stderr," ");
+        fprintf(stderr,"%02x",0xff & data[i]);
+    }
+    fprintf(stderr,".\n");
+}
+
+int sha2_main(int argc, char ** argv) {
+    int sha_len;
+    sha2_ctx ctx;
+    unsigned char hval[64];
+    int k;
+
+    if(argc<=2)
+        printf("Usage: sha2 [256|384|512] string_to_hash\n"), exit(0);
+
+    sha_len = atoi(argv[1]);
+    if( sha_len != 512 && sha_len != 384 && sha_len != 256 )
+        printf("Usage: sha [256|384|512] string_to_hash\n"), exit(0);
+
+    for(k=2;k<argc;k++){
+        int data_len;
+        char *key, *data;
+        data = argv[k];
+        data_len = strlen(data);
+        print_data("data",data,data_len);
+
+        memset(hval,0,sizeof(hval));
+        sha2_begin(sha_len, &ctx);
+        sha2_hash(data, data_len, &ctx);
+        sha2_end(hval, &ctx);
+        print_data("sha2",hval,sha_len/8);
+
+        key = sha2_key(data,sha_len);
+        print_data("sha2_key",key,sha_len/8);
+    }
+    return 0;
+}
+#endif /* TEST_SHA */
+
+
+#endif /* FEAT_CRYPT */
+
--- 73g/src/sha2.h 1969-12-31 16:00:00.000000000 -0800
+++ 73/src/sha2.h 2010-03-14 20:25:10.890625000 -0800
@@ -0,0 +1,161 @@
+/*
+ * SHA2 HASH for vim encryption (and password hashing).
+ * GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh
+ */
+
+/*
+ ---------------------------------------------------------------------------
+ Copyright (c) 2002, Dr Brian Gladman <[hidden email]>, Worcester, UK.
+ All rights reserved.
+
+ LICENSE TERMS
+
+ The free distribution and use of this software in both source and binary
+ form is allowed (with or without changes) provided that:
+
+   1. distributions of this source code include the above copyright
+      notice, this list of conditions and the following disclaimer;
+
+   2. distributions in binary form include the above copyright
+      notice, this list of conditions and the following disclaimer
+      in the documentation and/or other associated materials;
+
+   3. the copyright holder's name is not used to endorse products
+      built using this software without specific written permission.
+
+ ALTERNATIVELY, provided that this notice is retained in full, this product
+ may be distributed under the terms of the GNU General Public License (GPL),
+ in which case the provisions of the GPL apply INSTEAD OF those given above.
+
+ DISCLAIMER
+
+ This software is provided 'as is' with no explicit or implied warranties
+ in respect of its properties, including, but not limited to, correctness
+ and/or fitness for purpose.
+ ---------------------------------------------------------------------------
+ Issue Date: 30/11/2002
+*/
+
+#ifndef _SHA2_H
+#define _SHA2_H
+
+#include <limits.h>
+
+/*  Defines for suffixes to 32 and 64 bit unsigned numeric values   */
+
+#define sfx_lo(x,y) x##y
+#define sfx_hi(x,y) sfx_lo(x,y)
+#define n_u32(p)    sfx_hi(0x##p,s_u32)
+#define n_u64(p)    sfx_hi(0x##p,s_u64)
+
+/* define an unsigned 32-bit type */
+
+#if UINT_MAX == 0xffffffff
+  typedef   unsigned int     sha2_32t;
+  #define s_u32    u
+#elif ULONG_MAX == 0xffffffff
+  typedef   unsigned long    sha2_32t;
+  #define s_u32   ul
+#else
+#error Please define sha2_32t as an unsigned 32 bit type in sha2.h
+#endif
+
+/* define an unsigned 64-bit type */
+
+#if defined( _MSC_VER )
+  typedef unsigned __int64   sha2_64t;
+  #define s_u64 ui64
+#elif ULONG_MAX == 0xffffffffffffffff
+  typedef unsigned long      sha2_64t;
+  #define s_u64   ul
+#elif ULONG_MAX == 0xffffffff
+  typedef unsigned long long sha2_64t;   /* a somewhat dangerous guess */
+  #define s_u64  ull
+#else
+#error Please define sha2_64t as an unsigned 64 bit type in sha2.h
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define SHA256_DIGEST_SIZE  32
+#define SHA384_DIGEST_SIZE  48
+#define SHA512_DIGEST_SIZE  64
+
+#define SHA256_BLOCK_SIZE   64
+#define SHA384_BLOCK_SIZE  128
+#define SHA512_BLOCK_SIZE  128
+
+#define SHA2_DIGEST_SIZE        SHA256_DIGEST_SIZE
+#define SHA2_MAX_DIGEST_SIZE    SHA512_DIGEST_SIZE
+
+#define SHA2_GOOD   0
+#define SHA2_BAD    1
+
+/* type to hold the SHA256 context */
+
+typedef struct {
+    sha2_32t count[2];
+    sha2_32t hash[8];
+    sha2_32t wbuf[16];
+} sha256_ctx;
+
+/* type to hold the SHA384/512 context */
+
+typedef struct {
+    sha2_64t count[2];
+    sha2_64t hash[8];
+    sha2_64t wbuf[16];
+} sha512_ctx;
+
+typedef sha512_ctx  sha384_ctx;
+
+/* type to hold a SHA2 context (256/384/512)  */
+
+typedef struct
+{   union
+    {   sha256_ctx  ctx256[1];
+        sha512_ctx  ctx512[1];
+    } uu[1];
+    sha2_32t    sha2_len;
+} sha2_ctx;
+
+void sha256_compile(sha256_ctx ctx[1]);
+void sha512_compile(sha512_ctx ctx[1]);
+
+void sha256_begin(sha256_ctx ctx[1]);
+void sha256_hash(const unsigned char data[], unsigned long len,
sha256_ctx ctx[1]);
+void sha256_end(unsigned char hval[], sha256_ctx ctx[1]);
+void sha256(unsigned char hval[], const unsigned char data[],
unsigned long len);
+
+void sha384_begin(sha384_ctx ctx[1]);
+#define sha384_hash sha512_hash
+void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
+void sha384(unsigned char hval[], const unsigned char data[],
unsigned long len);
+
+void sha512_begin(sha512_ctx ctx[1]);
+void sha512_hash(const unsigned char data[], unsigned long len,
sha512_ctx ctx[1]);
+void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
+void sha512(unsigned char hval[], const unsigned char data[],
unsigned long len);
+
+int sha2_begin(unsigned long size, sha2_ctx ctx[1]);
+void sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]);
+void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
+int sha2(unsigned char hval[], unsigned long size, const unsigned
char data[], unsigned long len);
+
+void sha2_seed(char header[],int seed_len);
+unsigned char * sha2_key(const unsigned char *data, int sha_len );
+unsigned char * sha2_file(char *filename, int sha_len, int
hash_pathname_also );
+int sha2_check_argv0( void );
+
+#ifdef TEST_SHA
+void print_data(char *message,char *data,int data_len);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Bram Moolenaar

Mohsin wrote:

> Resending patch for current vim 72* dev branch (from cvs).
> --
>  Added functionality for encrypting files with blowfish and sha2.
>  Blowfish is from http://www.schneier.com/blowfish.html
>
>  Older vim encrypted files with VimCrypt~1 header will still be
>  readable by newer vim,
>  but newly written files will have VimCrypt~2 in the header.
>
>  Algorithm: key=sha2(password), blowfish in Outputfeedback mode,
>  with random 64bit init vector, so same file produces a completely
>  different output, every time it is saved.
>
> Changes:
>
> Minor changes to fileio.c misc2.c, and 4 new files blowfish.c
> blowfish.h sha2.c sha2.h
> Patch is based on  vim DEV branch as of  2010-03-15

Thanks.

I would very much like feedback on this patch.  Any platform where this
causes problems, such as compiler warnings?


--
Proofread carefully to see if you any words out.

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Mosh-3
On Wed, Mar 17, 2010 at 8:24 AM, Bram Moolenaar <[hidden email]> wrote:

>
> Mohsin wrote:
>
>> Resending patch for current vim 72* dev branch (from cvs).
>> --
>>  Added functionality for encrypting files with blowfish and sha2.
>>  Blowfish is from http://www.schneier.com/blowfish.html
>>
>>  Older vim encrypted files with VimCrypt~1 header will still be
>>  readable by newer vim,
>>  but newly written files will have VimCrypt~2 in the header.
>>
>>  Algorithm: key=sha2(password), blowfish in Outputfeedback mode,
>>  with random 64bit init vector, so same file produces a completely
>>  different output, every time it is saved.
>>
>> Changes:
>>
>> Minor changes to fileio.c misc2.c, and 4 new files blowfish.c
>> blowfish.h sha2.c sha2.h
>> Patch is based on  vim DEV branch as of  2010-03-15
>
> Thanks.
>
> I would very much like feedback on this patch.  Any platform where this
> causes problems, such as compiler warnings?

This has been tested these on windows 32bits, linux 32bits,
and solaris 32 bits (big endian).

Windows XP 32 bit - MS Visual studio compiler 5.0 IDE,
no compiler warnings at warning level 3.

I can rerun ms-vc++ with warning level 4 sometime.

Also the the encrypted files are cross platform (as expected).

There are some unused functions and comments that you can
remove/edit as you wish.

---

thanks,
mohsin.

>
>
> --
> Proofread carefully to see if you any words out.
>
>  /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
> ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
> \\\        download, build and distribute -- http://www.A-A-P.org        ///
>  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
>

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Benjamin Fritz
In reply to this post by Bram Moolenaar


On Mar 17, 10:24 am, Bram Moolenaar <[hidden email]> wrote:
>
> I would very much like feedback on this patch.  Any platform where this
> causes problems, such as compiler warnings?
>

Is this going to introduce any export law worries if included?

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Dominique Pellé
In reply to this post by Mosh-3
Mosh wrote:

> Resending patch for current vim 72* dev branch (from cvs).
> --
>  Added functionality for encrypting files with blowfish and sha2.
>  Blowfish is from http://www.schneier.com/blowfish.html
>
>  Older vim encrypted files with VimCrypt~1 header will still be
>  readable by newer vim,
>  but newly written files will have VimCrypt~2 in the header.
>
>  Algorithm: key=sha2(password), blowfish in Outputfeedback mode,
>  with random 64bit init vector, so same file produces a completely
>  different output, every time it is saved.
>
> Changes:
>
> Minor changes to fileio.c misc2.c, and 4 new files blowfish.c
> blowfish.h sha2.c sha2.h
> Patch is based on  vim DEV branch as of  2010-03-15
>
> thanks,
> questions? mail me.
> mohsin.


Hi Mohsin

I tried to apply your patch but I get...

patch: **** malformed patch at line 29: cryptkey !=3D NULL)

All the equal sign are replaced with =3D in the message.
I removed the 3D thing.  But then I see that your email client
probably inserted some line breaks which mess up the patch:

patch: **** malformed patch at line 29: cryptkey != NULL)

  27 -                       || (filesize == CRYPT_MAGIC_LEN &&
cryptkey != NULL)
  28 +                       || (filesize == (magic_len + seed_len) &&
  29 cryptkey != NULL)
  30  # endif

Could you submit the patch again as a file attachment?

Thanks!
-- Dominique

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Mosh-3
Dominique,
Resending as a zip file.
thanks,
mohsin

2010/3/18 Dominique Pellé <[hidden email]>:

> Mosh wrote:
>
>> Resending patch for current vim 72* dev branch (from cvs).
>> --
>>  Added functionality for encrypting files with blowfish and sha2.
>>  Blowfish is from http://www.schneier.com/blowfish.html
>>
>>  Older vim encrypted files with VimCrypt~1 header will still be
>>  readable by newer vim,
>>  but newly written files will have VimCrypt~2 in the header.
>>
>>  Algorithm: key=sha2(password), blowfish in Outputfeedback mode,
>>  with random 64bit init vector, so same file produces a completely
>>  different output, every time it is saved.
>>
>> Changes:
>>
>> Minor changes to fileio.c misc2.c, and 4 new files blowfish.c
>> blowfish.h sha2.c sha2.h
>> Patch is based on  vim DEV branch as of  2010-03-15
>>
>> thanks,
>> questions? mail me.
>> mohsin.
>
>
> Hi Mohsin
>
> I tried to apply your patch but I get...
>
> patch: **** malformed patch at line 29: cryptkey !=3D NULL)
>
> All the equal sign are replaced with =3D in the message.
> I removed the 3D thing.  But then I see that your email client
> probably inserted some line breaks which mess up the patch:
>
> patch: **** malformed patch at line 29: cryptkey != NULL)
>
>  27 -                       || (filesize == CRYPT_MAGIC_LEN &&
> cryptkey != NULL)
>  28 +                       || (filesize == (magic_len + seed_len) &&
>  29 cryptkey != NULL)
>  30  # endif
>
> Could you submit the patch again as a file attachment?
>
> Thanks!
> -- Dominique
>
> --
> You received this message from the "vim_dev" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>
> To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
>
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.

patch.zip (334K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Mosh-3
In reply to this post by Benjamin Fritz
On Thu, Mar 18, 2010 at 7:22 AM, Ben Fritz <[hidden email]> wrote:
> Is this going to introduce any export law worries if included?

Where required, enable this line of code with a compile time flag

+    // Blowfish takes a variable-length key, from 32 bits to 448 bits.
+    // If larger than 64 bits keys are not allowed, truncate it.
+    // keylen = min(8, keylen);

and warn the user of the weakened key.

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Benjamin R. Haskell-8
On Thu, 18 Mar 2010, Mosh wrote:

> On Thu, Mar 18, 2010 at 7:22 AM, Ben Fritz <[hidden email]> wrote:
> > Is this going to introduce any export law worries if included?
>
> Where required, enable this line of code with a compile time flag
>
> +    // Blowfish takes a variable-length key, from 32 bits to 448 bits.
> +    // If larger than 64 bits keys are not allowed, truncate it.
> +    // keylen = min(8, keylen);
>
> and warn the user of the weakened key.
>

Actually, the strength of the key has been a non-issue since the laws
were relaxed back in 2000.


Back to the original question from Ben F:
> > Is this going to introduce any export law worries if included?

The usual IANAL applies, etc etc.

For some reading, if anyone's inclined:

Good overview: http://en.citizendium.org/wiki/Cryptography_controversy

FWIW, the Apache project complies with US law, being hosted in the US.  
(So, too, w/ Vim being hosted mostly on SF, correct?)
Apache's export page: http://www.apache.org/licenses/exports/
Their 'internal' guide: http://www.apache.org/dev/crypto.html
(has some useful general advice, and links to the 'TSU exception')
Full text: (section 740.13): http://www.access.gpo.gov/bis/ear/txt/740.txt

Wikipedia: http://en.wikipedia.org/wiki/Export_of_cryptography_in_the_United_States

One of the citations, in reference to open source:
http://www.bis.doc.gov/encryption/pubavailencsourcecodenofify.html

An amusing snippet from that page:
"""
If your encryption source code is too large to serve as an email
attachment, you may print a copy of your email as a cover sheet and fax
the additional documents to BIS at (202) 219-9179 or -9182.
"""

My general thought would be that it would be much easier to include the
patch if it could be reworked to use some commonly-available, external
crypto library (thus Vim doesn't contain crypto software, so isn't
exporting crypto).  (e.g. use OpenSSL or ...well, OpenSSL.)

--
Best,
Ben H

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

James Vega-3
On Fri, Mar 19, 2010 at 12:50:36AM -0400, Benjamin R. Haskell wrote:
> > On Thu, Mar 18, 2010 at 7:22 AM, Ben Fritz <[hidden email]> wrote:
> > > Is this going to introduce any export law worries if included?
>
> My general thought would be that it would be much easier to include the
> patch if it could be reworked to use some commonly-available, external
> crypto library (thus Vim doesn't contain crypto software, so isn't
> exporting crypto).  (e.g. use OpenSSL or ...well, OpenSSL.)

There's also libgcrypt, which doesn't have OpenSSL's problem of being
GPL incompatible.

--
James
GPG Key: 1024D/61326D40 2003-09-02 James Vega <[hidden email]>

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Benjamin R. Haskell-8
On Fri, 19 Mar 2010, James Vega wrote:

> On Fri, Mar 19, 2010 at 12:50:36AM -0400, Benjamin R. Haskell wrote:
> > > On Thu, Mar 18, 2010 at 7:22 AM, Ben Fritz <[hidden email]> wrote:
> > > > Is this going to introduce any export law worries if included?
> >
> > My general thought would be that it would be much easier to include
> > the patch if it could be reworked to use some commonly-available,
> > external crypto library (thus Vim doesn't contain crypto software,
> > so isn't exporting crypto).  (e.g. use OpenSSL or ...well, OpenSSL.)
>
> There's also libgcrypt, which doesn't have OpenSSL's problem of being
> GPL incompatible.
>

<offtopic class="IMO">For certain values of 'problem'.  (my BSD-license
preference reared its head apparently)</offtopic>

Googling { OpenSSL GPL } came up with this explanation:
http://people.gnome.org/~markmc/openssl-and-the-gpl.html
and the OpenSSL FAQ:
http://www.openssl.org/support/faq.html#LEGAL2
both of which are slightly hand-wavy about it.  (Roughly: on most Linux
and BSD distributions, it's okay, because it can be considered "an
operating system library"; other systems, not as clear-cut.)

I thought there was a widely-used GNU crypto library, but the first
result in googling { crypto library } was the decidedly not-libgcrypt
'GNU Crypto' (now part of 'GNU Classpath'), written in Java(?!).

Yes, libgcrypt is a good choice, too.  (Just couldn't remember what it
was called.)

--
Best,
Ben

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

James Vega-3
On Fri, Mar 19, 2010 at 8:56 AM, Benjamin R. Haskell <[hidden email]> wrote:

> On Fri, 19 Mar 2010, James Vega wrote:
>
>> On Fri, Mar 19, 2010 at 12:50:36AM -0400, Benjamin R. Haskell wrote:
>> > > On Thu, Mar 18, 2010 at 7:22 AM, Ben Fritz <[hidden email]> wrote:
>> > > > Is this going to introduce any export law worries if included?
>> >
>> > My general thought would be that it would be much easier to include
>> > the patch if it could be reworked to use some commonly-available,
>> > external crypto library (thus Vim doesn't contain crypto software,
>> > so isn't exporting crypto).  (e.g. use OpenSSL or ...well, OpenSSL.)
>>
>> There's also libgcrypt, which doesn't have OpenSSL's problem of being
>> GPL incompatible.
>>
>
> <offtopic class="IMO">For certain values of 'problem'.  (my BSD-license
> preference reared its head apparently)</offtopic>

I don't disagree, but Vim is licensed in such a way that it can be
shipped under the GPL license.  As such, we need to be aware of
potential incompatibilities.

> Googling { OpenSSL GPL } came up with this explanation:
> http://people.gnome.org/~markmc/openssl-and-the-gpl.html
> and the OpenSSL FAQ:
> http://www.openssl.org/support/faq.html#LEGAL2

Also, GNU's explanation:
http://www.gnu.org/licenses/license-list.html#OpenSSL

> both of which are slightly hand-wavy about it.  (Roughly: on most Linux
> and BSD distributions, it's okay, because it can be considered "an
> operating system library"; other systems, not as clear-cut.)

I find that argument to be a bit lacking as an ssl library is in no way
required for a working system.  The "operating system library" exception
is meant for things like the C library.

Either way, the GPL also allows for exceptions so if using OpenSSL is
pursued, adding an OpenSSL exception is a viable option.

--
James
GPG Key: 1024D/61326D40 2003-09-02 James Vega <[hidden email]>

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Bram Moolenaar
In reply to this post by Benjamin Fritz

Ben Fritz wrote:

> On Mar 17, 10:24=A0am, Bram Moolenaar <[hidden email]> wrote:
> >
> > I would very much like feedback on this patch. =A0Any platform where this
> > causes problems, such as compiler warnings?
>
> Is this going to introduce any export law worries if included?

No, I'm not in the US.  I don't think the US has import laws about this.

There are some countries where _use_ of cryptography is restricted, but
that's not our problem.

These algorithms are generally available, thus adding them to Vim won't
change anything.

I don't like depending on a library, because it means there will be
platforms where the library is unavailable and there you can't edit your
encrypted file, which can be very annoying.

--
If cars evolved at the same rate as computers have, they'd cost five euro,
run for a year on a couple of liters of petrol, and explode once a day.

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Benjamin R. Haskell-8
On Sat, 20 Mar 2010, Bram Moolenaar wrote:

>
> Ben Fritz wrote:
>
> > On Mar 17, 10:24 am, Bram Moolenaar wrote:
> > >
> > > I would very much like feedback on this patch. Any platform where
> > > this causes problems, such as compiler warnings?
> >
> > Is this going to introduce any export law worries if included?
>
> No, I'm not in the US.  I don't think the US has import laws about this.

No, I don't think it does.  Unfortunately the U.S. isn't the only
country to which these idiotic restrictions apply.

(Idiotic in both principle [attempting to control software export in the
internet age] and practice [cf. 'fax us a copy of your source code' in
my previous response])

The international version is "The Wassenaar Arrangement":
http://www.wassenaar.org/

(which, incidentally, *does* appear to have key-length restrictions:)
http://www.wassenaar.org/controllists/index.html - category 5 - part 2

Also, you say you're not in the U.S., but Vim's hosted mostly on
Sourceforge (which is a U.S.-based entity), correct?


> There are some countries where _use_ of cryptography is restricted,
> but that's not our problem.
>
> These algorithms are generally available, thus adding them to Vim
> won't change anything.

I agree on both counts.  And the latter is why I think adding the code
won't cause any trouble: it would be a bizarre world indeed if Vim were
the first project with legal action pursued against it.  (based on
jurisdiction weirdness, and 'notability' in the "It's widely available
in larger software libraries" sense)

Then again, some of the ones pursued by the U.S. government are pretty
weird:
http://efoia.bis.doc.gov/exportcontrolviolations/tocexportviolations.htm
(Of note is the fact that they're universally 'hardware' of various
types.  But, come on... tape drives? [E2084])


> I don't like depending on a library, because it means there will be
> platforms where the library is unavailable and there you can't edit
> your encrypted file, which can be very annoying.

Personally, I find it slightly odd that it'd be built in to Vim.  Seems
like it'd be easier/preferable to add plugins to facilitate the use of external
tools.  But I only find it odd, not objectionable.


In any case, I feel like its inclusion is unlikely to cause trouble.  
It's just an interesting discussion (...and probably not of general
interest).  I think development effort is better focused elsewhere, so
I'll not pursue it further.

--
Best,
Ben

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Bram Moolenaar

Benjamin R. Haskell wrote:

> Also, you say you're not in the U.S., but Vim's hosted mostly on
> Sourceforge (which is a U.S.-based entity), correct?

The main Vim ftp server is in Amsterdam.  There are mirrors all over the
world.  I don't see how the location of a server, that merely forwards
bytes verbatim, would change the law that applies.

--
An indication you must be a manager:
You can explain to somebody the difference between "re-engineering",
"down-sizing", "right-sizing", and "firing people's asses".

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Benjamin R. Haskell-8
On Sun, 21 Mar 2010, Bram Moolenaar wrote:

>
> Benjamin R. Haskell wrote:
>
> > Also, you say you're not in the U.S., but Vim's hosted mostly on
> > Sourceforge (which is a U.S.-based entity), correct?
>
> The main Vim ftp server is in Amsterdam.

Okay. I was going off of www.vim.org == sourceforge.


> There are mirrors all over the world.  I don't see how the location of
> a server, that merely forwards bytes verbatim, would change the law
> that applies.
>

If you have a bunch of bytes you're forwarding verbatim, and those bytes
are subject to export laws that govern cryptography products, the
location of what's serving those bytes seems pretty germane.

It's not copyright, where it doesn't change when it changes physical
location.  It's export laws, where it matters what geopolitical borders
you're crossing.

(...but again, we're back to why I think the law is pretty idiotic in
the first place when it comes to software.)

--
Best,
Ben

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Dominique Pellé
In reply to this post by Mosh-3
Mosh wrote:

> Dominique,
> Resending as a zip file.
> thanks,
> mohsin

Hi Mosh,

I tried your blowfish patch today. Here are some remarks.

The patch is missing the changes to the Makefile (I needed
to add blowfish.c & sha2.c to the Makefile to be able to link
successfully).

I compiled with -g -O0 -Wall -Wmissing-prototypes and I see compilation
warnings:

blowfish.c:34: warning: missing braces around initializer
blowfish.c:34: warning: (near initialization for ‘sbi[0]’)
blowfish.c: In function ‘bf_key_init’:
blowfish.c:271: warning: pointer targets in passing argument 1 of
‘strlen’ differ in signedness
/usr/include/string.h:397: note: expected ‘const char *’ but argument
is of type ‘const unsigned char *’
blowfish.c: At top level:
blowfish.c:334: warning: missing braces around initializer
blowfish.c:334: warning: (near initialization for ‘bft[0]’)
blowfish.c: In function ‘bf_self_test’:
blowfish.c:347: warning: pointer targets in passing argument 1 of
‘bf_key_init’ differ in signedness
blowfish.c:267: note: expected ‘const unsigned char *’ but argument is
of type ‘char *’
blowfish.c: At top level:
blowfish.c:233: warning: ‘bf_d_block’ defined but not used


sha2.c:178:9: warning: multi-character character constant
sha2.c:180:9: warning: multi-character character constant
sha2.c:686: warning: no previous prototype for ‘int2chars’
sha2.c: In function ‘sha2_key’:
sha2.c:732: warning: pointer targets in return differ in signedness
sha2.c:733: warning: pointer targets in passing argument 1 of ‘strcmp’
differ in signedness
/usr/include/string.h:142: note: expected ‘const char *’ but argument
is of type ‘const unsigned char *’
sha2.c:741: warning: pointer targets in passing argument 1 of ‘strlen’
differ in signedness
/usr/include/string.h:397: note: expected ‘const char *’ but argument
is of type ‘const unsigned char *’
sha2.c: At top level:
sha2.c:789: warning: missing braces around initializer
sha2.c:789: warning: (near initialization for ‘sht[0]’)
sha2.c: In function ‘sha2_self_test’:
sha2.c:803: warning: pointer targets in assignment differ in signedness
sha2.c:804: warning: pointer targets in passing argument 1 of ‘strlen’
differ in signedness
/usr/include/string.h:397: note: expected ‘const char *’ but argument
is of type ‘unsigned char *’




fileio.c: In function ‘check_for_cryptkey’:
fileio.c:2824: warning: pointer targets in passing argument 1 of
‘is_crypt_sig’ differ in signedness
fileio.c:2801: note: expected ‘char *’ but argument is of type ‘char_u *’
fileio.c: In function ‘buf_write’:
fileio.c:4264: warning: pointer targets in passing argument 1 of
‘bf_ofb_init’ differ in signedness
blowfish.h:12: note: expected ‘const unsigned char *’ but argument is
of type ‘char *’
fileio.c:4270: warning: pointer targets in assignment differ in signedness


When I run Ex command  ":X"  I get the error:

   E000: bf_self_test() failed<00>

So something is broken for me (I'm using Vim-7.2.402 on Linux x86).
":X" worked before the patch.

I'm not sure why <00> appears at the end of the error message.

Instead of using EMSG2(...) for E000, you can use EMSG(...) since
there is only 1 argument.

Despite the E000 error, Vim still encrypts the file with VimCrypt~02 in
the header.  When I open the encrypted file, Vim asks for the key and
it then decrypts the file correctly.  So maybe only the self test is wrong.

I see a typo in comment at blowfish.c:350 (resuse -> reuse)

Global variable 'bft' at blowfish.c:333 could be local to function
bf_self_test()

Global variables in fileio.c  CRYPT_MAGIC, CRYPT_MAGIC_LEN (etc)
could be declared static.

Following the Vim coding style (see ":help coding-style") would
help to accept the patch (placement of curly braces, etc.)

It would be worth including a documentation patch as well.

Open questions:

Should code be in something like #ifdef FEAT_BLOWFISH. Right
now blowfish code is in #ifdef FEAT_CRYPT (which is enabled when
building vim with configure ---with-features=normal).

Should ":X" command have an argument to chose the encryption
algorithm?  (blowfish or the older algorithm).

Cheers
-- Dominique

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Patrick Texier-2
Le Sun, 21 Mar 2010 19:07:37 +0100, Dominique Pellé a écrit dans le
message <[hidden email]> :

> The patch is missing the changes to the Makefile (I needed
> to add blowfish.c & sha2.c to the Makefile to be able to link
> successfully).

Yes, I'm waiting a full patch (-c) for testing warnings on Linux/Gcc 3.2
and Borland C++5.5
--
Patrick Texier

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Mosh-3
In reply to this post by Dominique Pellé
Dominique,

The bf_self_test is important  - it checks the constants have not
been modified.  There is a similar self test in sha2.c.

I have some more ideas to enhance the feature: key strengthening,
enhance the header to include filesize, salt for password.

I would also like to run bf in cbc mode, encrypting blocks of 8 chars
at a time,
and padding the last block with NULLs, though this involves some
changes to the fileio.c

Another would be to redact visual-selection in a text file,
Here is a javascript demo of it: http://hmi-tech.com/mosh/tea4.htm

Thanks for testing it and the comments,
m

2010/3/21 Dominique Pellé <[hidden email]>:

> Mosh wrote:
>
>> Dominique,
>> Resending as a zip file.
>> thanks,
>> mohsin
>
> Hi Mosh,
>
> I tried your blowfish patch today. Here are some remarks.
>
> The patch is missing the changes to the Makefile (I needed
> to add blowfish.c & sha2.c to the Makefile to be able to link
> successfully).
>
> I compiled with -g -O0 -Wall -Wmissing-prototypes and I see compilation
> warnings:
>
> blowfish.c:34: warning: missing braces around initializer
> blowfish.c:34: warning: (near initialization for ‘sbi[0]’)
> blowfish.c: In function ‘bf_key_init’:
> blowfish.c:271: warning: pointer targets in passing argument 1 of
> ‘strlen’ differ in signedness
> /usr/include/string.h:397: note: expected ‘const char *’ but argument
> is of type ‘const unsigned char *’
> blowfish.c: At top level:
> blowfish.c:334: warning: missing braces around initializer
> blowfish.c:334: warning: (near initialization for ‘bft[0]’)
> blowfish.c: In function ‘bf_self_test’:
> blowfish.c:347: warning: pointer targets in passing argument 1 of
> ‘bf_key_init’ differ in signedness
> blowfish.c:267: note: expected ‘const unsigned char *’ but argument is
> of type ‘char *’
> blowfish.c: At top level:
> blowfish.c:233: warning: ‘bf_d_block’ defined but not used
>
>
> sha2.c:178:9: warning: multi-character character constant
> sha2.c:180:9: warning: multi-character character constant
> sha2.c:686: warning: no previous prototype for ‘int2chars’
> sha2.c: In function ‘sha2_key’:
> sha2.c:732: warning: pointer targets in return differ in signedness
> sha2.c:733: warning: pointer targets in passing argument 1 of ‘strcmp’
> differ in signedness
> /usr/include/string.h:142: note: expected ‘const char *’ but argument
> is of type ‘const unsigned char *’
> sha2.c:741: warning: pointer targets in passing argument 1 of ‘strlen’
> differ in signedness
> /usr/include/string.h:397: note: expected ‘const char *’ but argument
> is of type ‘const unsigned char *’
> sha2.c: At top level:
> sha2.c:789: warning: missing braces around initializer
> sha2.c:789: warning: (near initialization for ‘sht[0]’)
> sha2.c: In function ‘sha2_self_test’:
> sha2.c:803: warning: pointer targets in assignment differ in signedness
> sha2.c:804: warning: pointer targets in passing argument 1 of ‘strlen’
> differ in signedness
> /usr/include/string.h:397: note: expected ‘const char *’ but argument
> is of type ‘unsigned char *’
>
>
>
>
> fileio.c: In function ‘check_for_cryptkey’:
> fileio.c:2824: warning: pointer targets in passing argument 1 of
> ‘is_crypt_sig’ differ in signedness
> fileio.c:2801: note: expected ‘char *’ but argument is of type ‘char_u *’
> fileio.c: In function ‘buf_write’:
> fileio.c:4264: warning: pointer targets in passing argument 1 of
> ‘bf_ofb_init’ differ in signedness
> blowfish.h:12: note: expected ‘const unsigned char *’ but argument is
> of type ‘char *’
> fileio.c:4270: warning: pointer targets in assignment differ in signedness
>
>
> When I run Ex command  ":X"  I get the error:
>
>   E000: bf_self_test() failed<00>
>
> So something is broken for me (I'm using Vim-7.2.402 on Linux x86).
> ":X" worked before the patch.
>
> I'm not sure why <00> appears at the end of the error message.
>
> Instead of using EMSG2(...) for E000, you can use EMSG(...) since
> there is only 1 argument.
>
> Despite the E000 error, Vim still encrypts the file with VimCrypt~02 in
> the header.  When I open the encrypted file, Vim asks for the key and
> it then decrypts the file correctly.  So maybe only the self test is wrong.
>
> I see a typo in comment at blowfish.c:350 (resuse -> reuse)
>
> Global variable 'bft' at blowfish.c:333 could be local to function
> bf_self_test()
>
> Global variables in fileio.c  CRYPT_MAGIC, CRYPT_MAGIC_LEN (etc)
> could be declared static.
>
> Following the Vim coding style (see ":help coding-style") would
> help to accept the patch (placement of curly braces, etc.)
>
> It would be worth including a documentation patch as well.
>
> Open questions:
>
> Should code be in something like #ifdef FEAT_BLOWFISH. Right
> now blowfish code is in #ifdef FEAT_CRYPT (which is enabled when
> building vim with configure ---with-features=normal).
>
> Should ":X" command have an argument to chose the encryption
> algorithm?  (blowfish or the older algorithm).
>
> Cheers
> -- Dominique
>

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Patrick Texier-2
In reply to this post by Dominique Pellé
Le Sun, 21 Mar 2010 19:07:37 +0100, Dominique Pellé a écrit dans le
message <[hidden email]> :

> I compiled with -g -O0 -Wall -Wmissing-prototypes and I see compilation
> warnings:

Using Borland C++ 5.5/Windows 98, I have an error in sha2.h

Error E2176 .\sha2.h 72: Too many types in declaration

Full log is attached.
--
Patrick Texier

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.

test.log (13K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: patch for strong encryption in vim, resending patch for vim7* dev branch.

Mosh-3
Patrick,

I guess your bcc compiler is using this typedef in sha2.h:72 for
unsigned 64bit long:

     typedef unsigned long long sha2_64t;

and then it has problems with 'long long'; to fix this
add an ifdef for your compiler and a defn for sha2_64t
in sha2.h in here:

/* define an unsigned 64-bit type */

#if defined( _MSC_VER )
  typedef unsigned __int64   sha2_64t;
  #define s_u64 ui64
#elif ULONG_MAX == 0xffffffffffffffff
  typedef unsigned long      sha2_64t;
  #define s_u64   ul
#elif ULONG_MAX == 0xffffffff
  typedef unsigned long long sha2_64t;   /* a somewhat dangerous guess */
  #define s_u64  ull
#else
#error Please define sha2_64t as an unsigned 64 bit type in sha2.h
#endif


thanks,
mosh


On Tue, Mar 23, 2010 at 12:21 AM, Patrick Texier <[hidden email]> wrote:

> Le Sun, 21 Mar 2010 19:07:37 +0100, Dominique Pellé a écrit dans le
> message <[hidden email]> :
>
>> I compiled with -g -O0 -Wall -Wmissing-prototypes and I see compilation
>> warnings:
>
> Using Borland C++ 5.5/Windows 98, I have an error in sha2.h
>
> Error E2176 .\sha2.h 72: Too many types in declaration
>
> Full log is attached.
> --
> Patrick Texier
>

--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

To unsubscribe from this group, send email to vim_dev+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
123