misc/quazip/crypt.h
branchphysfslayer
changeset 8055 04dd8b7fb605
parent 8052 845b5ae03841
child 8056 d5d5e1698554
child 8057 93e16240f178
equal deleted inserted replaced
8052:845b5ae03841 8055:04dd8b7fb605
     1 /* crypt.h -- base code for crypt/uncrypt ZIPfile
       
     2 
       
     3 
       
     4    Version 1.01e, February 12th, 2005
       
     5 
       
     6    Copyright (C) 1998-2005 Gilles Vollant
       
     7 
       
     8    This code is a modified version of crypting code in Infozip distribution
       
     9 
       
    10    The encryption/decryption parts of this source code (as opposed to the
       
    11    non-echoing password parts) were originally written in Europe.  The
       
    12    whole source package can be freely distributed, including from the USA.
       
    13    (Prior to January 2000, re-export from the US was a violation of US law.)
       
    14 
       
    15    This encryption code is a direct transcription of the algorithm from
       
    16    Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
       
    17    file (appnote.txt) is distributed with the PKZIP program (even in the
       
    18    version without encryption capabilities).
       
    19 
       
    20    If you don't need crypting in your application, just define symbols
       
    21    NOCRYPT and NOUNCRYPT.
       
    22 
       
    23    This code support the "Traditional PKWARE Encryption".
       
    24 
       
    25    The new AES encryption added on Zip format by Winzip (see the page
       
    26    http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
       
    27    Encryption is not supported.
       
    28 */
       
    29 
       
    30 #include "quazip_global.h"
       
    31 
       
    32 #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
       
    33 
       
    34 /***********************************************************************
       
    35  * Return the next byte in the pseudo-random sequence
       
    36  */
       
    37 static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab UNUSED)
       
    38 {
       
    39     //(void) pcrc_32_tab; /* avoid "unused parameter" warning */
       
    40     unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
       
    41                      * unpredictable manner on 16-bit systems; not a problem
       
    42                      * with any known compiler so far, though */
       
    43 
       
    44     temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
       
    45     return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
       
    46 }
       
    47 
       
    48 /***********************************************************************
       
    49  * Update the encryption keys with the next byte of plain text
       
    50  */
       
    51 static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c)
       
    52 {
       
    53     (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
       
    54     (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
       
    55     (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
       
    56     {
       
    57       register int keyshift = (int)((*(pkeys+1)) >> 24);
       
    58       (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
       
    59     }
       
    60     return c;
       
    61 }
       
    62 
       
    63 
       
    64 /***********************************************************************
       
    65  * Initialize the encryption keys and the random header according to
       
    66  * the given password.
       
    67  */
       
    68 static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab)
       
    69 {
       
    70     *(pkeys+0) = 305419896L;
       
    71     *(pkeys+1) = 591751049L;
       
    72     *(pkeys+2) = 878082192L;
       
    73     while (*passwd != '\0') {
       
    74         update_keys(pkeys,pcrc_32_tab,(int)*passwd);
       
    75         passwd++;
       
    76     }
       
    77 }
       
    78 
       
    79 #define zdecode(pkeys,pcrc_32_tab,c) \
       
    80     (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
       
    81 
       
    82 #define zencode(pkeys,pcrc_32_tab,c,t) \
       
    83     (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
       
    84 
       
    85 #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
       
    86 
       
    87 #define RAND_HEAD_LEN  12
       
    88    /* "last resort" source for second part of crypt seed pattern */
       
    89 #  ifndef ZCR_SEED2
       
    90 #    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
       
    91 #  endif
       
    92 
       
    93 static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
       
    94     const char *passwd;         /* password string */
       
    95     unsigned char *buf;         /* where to write header */
       
    96     int bufSize;
       
    97     unsigned long* pkeys;
       
    98     const unsigned long* pcrc_32_tab;
       
    99     unsigned long crcForCrypting;
       
   100 {
       
   101     int n;                       /* index in random header */
       
   102     int t;                       /* temporary */
       
   103     int c;                       /* random byte */
       
   104     unsigned char header[RAND_HEAD_LEN-2]; /* random header */
       
   105     static unsigned calls = 0;   /* ensure different random header each time */
       
   106 
       
   107     if (bufSize<RAND_HEAD_LEN)
       
   108       return 0;
       
   109 
       
   110     /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
       
   111      * output of rand() to get less predictability, since rand() is
       
   112      * often poorly implemented.
       
   113      */
       
   114     if (++calls == 1)
       
   115     {
       
   116         srand((unsigned)(time(NULL) ^ ZCR_SEED2));
       
   117     }
       
   118     init_keys(passwd, pkeys, pcrc_32_tab);
       
   119     for (n = 0; n < RAND_HEAD_LEN-2; n++)
       
   120     {
       
   121         c = (rand() >> 7) & 0xff;
       
   122         header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
       
   123     }
       
   124     /* Encrypt random header (last two bytes is high word of crc) */
       
   125     init_keys(passwd, pkeys, pcrc_32_tab);
       
   126     for (n = 0; n < RAND_HEAD_LEN-2; n++)
       
   127     {
       
   128         buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
       
   129     }
       
   130     buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
       
   131     buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
       
   132     return n;
       
   133 }
       
   134 
       
   135 #endif