Loading ...
Sorry, an error occurred while loading the content.
 

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

Expand Messages
  • Mosh
    Resending patch for current vim 72* dev branch (from cvs). -- Added functionality for encrypting files with blowfish and sha2. Blowfish is from
    Message 1 of 42 , Mar 15, 2010
      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, mosh@..., 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 <brg@...>, 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 <andersen@...> 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 <brg@...>, 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 <br/><br/>(Message over 64 KB, truncated)
    • Tony Mechelynck
      ... Well, isn t that clause there to ensure that further dissemination won t be stopped, and that copyright restrictions (which expressly don t remove software
      Message 42 of 42 , May 17, 2010
        On 17/05/10 02:04, Jordan Lewis wrote:
        >
        >
        > On Sun, May 16, 2010 at 6:54 PM, Tony Mechelynck
        > <antoine.mechelynck@... <mailto:antoine.mechelynck@...>> wrote:
        >
        > 2. "In the public domain".
        > </quote>
        >
        > This looks promising; but one part has a "note" in lawyerese and the
        > other a "defined term" in quotes, let us see... ah, I think this
        > clinches it, and since there is an "or" clause, no need (I think) to
        > check the other:
        >
        > <quote>
        > GTN "In the public domain"
        > GSN This means "technology" or "software" which has been made
        > available
        > ML 22 without restrictions upon its further dissemination.
        > Note Copyright restrictions do not remove
        > "technology" or "software" from being "in the public domain".
        > </quote>
        >
        > I believe that Vim is "in the public domain" within the definitions
        > used in that document (but of course, IANAL, nor do I play one on TV).
        >
        >
        > No, I don't think that Vim is "in the public domain" at all or even
        > according to this document. The definition you quoted has the key phrase
        > "without restrictions upon its further dissemination." Even the first
        > clause of Vim's license agreement here
        > http://vimdoc.sourceforge.net/htmldoc/uganda.html#license requires
        > distributing the license itself alongside of any part of Vim that you
        > choose to distribute yourself. I believe that this requirement, although
        > trivial, constitutes a restriction upon further dissemination, which
        > removes it from the public domain classification.
        >
        > I am similarly NAL, though.
        >
        > - Jordan Lewis

        Well, isn't that clause there to ensure that further dissemination won't
        be stopped, and that copyright restrictions (which expressly don't
        remove software from the "public domain" as defined in that document)
        will be obeyed? All open-source software has similar requirements about
        the license being distributed together with it, it doesn't prevent
        further distribution.

        Oh well, IANAL, YANAL, I suppose that's the kind of red tape which means
        Bram had maybe better find a friendly Dutch lawyer knowing about
        cryptology software distribution out of Amsterdam.


        Best regards,
        Tony.
        --
        `When any government, or any church for that matter, undertakes to say to
        its subjects, "This you may not read, this you must not see, this you are
        forbidden to know," the end result is tyranny and oppression no matter how
        holy the motives' -- Robert A Heinlein, "If this goes on --"

        --
        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
      Your message has been successfully submitted and would be delivered to recipients shortly.