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