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