Annotation of coherent/b/bin/zip/crypt.c, revision 1.1.1.1

1.1       root        1: /*
                      2:    This code is not copyrighted and is put in the public domain. It
                      3:    was originally written in Europe and can be freely distributed from
                      4:    any country except the U.S.A. If this code is imported in the U.S.A,
                      5:    it cannot be re-exported from the U.S.A to another country. (This
                      6:    restriction might seem curious but this is what US law requires.)
                      7:  */
                      8: 
                      9: /* This encryption code is a direct transcription of the algorithm from
                     10:    Roger Schlafly, described by Phil Katz in the file appnote.txt. This
                     11:    file is distributed with the PKZIP program (even in the version without
                     12:    encryption capabilities).
                     13:  */
                     14: 
                     15: #include "zip.h"
                     16: 
                     17: #ifndef SKIP_TIME_H   /* time.h already included in UnZip version */
                     18: #  include <time.h>
                     19: #endif /* !SKIP_TIME_H */
                     20: 
                     21: #if ((defined(MSDOS) || defined(__MSDOS__) || defined(WIN32)) && !defined(__GO32__))
                     22: #  include <process.h>
                     23: #else
                     24:    int  getpid OF((void));
                     25: #endif
                     26: 
                     27: #ifndef __GNUC__
                     28: void srand  OF((unsigned int));
                     29: #endif
                     30: int  rand   OF((void));
                     31: 
                     32: int  decrypt_byte OF((void));
                     33: void update_keys OF((int c));
                     34: void init_keys OF((char *passwd));
                     35: int  zencode OF((int c));
                     36: int  zdecode OF((int c));
                     37: 
                     38: local ulg keys[3]; /* keys defining the pseudo random sequence */
                     39: 
                     40: /***********************************************************************
                     41:  * Return the next byte in the pseudo-random sequence
                     42:  */
                     43: int decrypt_byte()
                     44: {
                     45:    ush temp;
                     46: 
                     47:    temp = (ush)keys[2] | 2;
                     48:    return (int)(((ush)(temp * (temp ^ 1)) >> 8) & 0xff);
                     49: }
                     50: 
                     51: /***********************************************************************
                     52:  * Update the encryption keys with the next byte of plain text
                     53:  */
                     54: void update_keys(c)
                     55:     int c;                  /* byte of plain text */
                     56: {
                     57:     keys[0] = crc32(keys[0], c);
                     58:     keys[1] += keys[0] & 0xff;
                     59:     keys[1] = keys[1] * 134775813L + 1;
                     60:     keys[2] = crc32(keys[2], (int)(keys[1] >> 24));
                     61: }
                     62: 
                     63: 
                     64: /***********************************************************************
                     65:  * Initialize the encryption keys and the random header according to
                     66:  * the given password.
                     67:  */
                     68: void init_keys(passwd)
                     69:     char *passwd;             /* password string to modify keys with */
                     70: {
                     71:     keys[0] = 305419896L;
                     72:     keys[1] = 591751049L;
                     73:     keys[2] = 878082192L;
                     74:     while (*passwd != '\0') {
                     75:         update_keys((int)*passwd);
                     76:         passwd++;
                     77:     }
                     78: }
                     79: 
                     80: /***********************************************************************
                     81:  * Return the encoded value of the byte c of the plain text
                     82:  */
                     83: int zencode(c)
                     84:     int c;
                     85: {
                     86:     int temp = decrypt_byte();
                     87: 
                     88:     update_keys(c);
                     89:     return temp ^ c;
                     90: }
                     91: 
                     92: /***********************************************************************
                     93:  * Return the decoded value of the byte c of the cypher text
                     94:  */
                     95: int zdecode(c)
                     96:     int c;
                     97: {
                     98:     int temp = c ^ decrypt_byte();
                     99: 
                    100:     update_keys(temp);
                    101:     return temp;
                    102: }
                    103: 
                    104: 
                    105: /***********************************************************************
                    106:  * Write encryption header to file zfile using the password passwd
                    107:  * and the cyclic redundancy check crc. Note: we use the rand() library
                    108:  * function, which is quite bad on many systems. But since we only
                    109:  * need 10 values, this is not important.
                    110:  */
                    111: void crypthead(passwd, crc, zfile)
                    112:     char *passwd;             /* password string */
                    113:     ulg crc;                  /* crc of file being encrypted */
                    114:     FILE *zfile;              /* where to write header to */
                    115: {
                    116:     int n = 10;               /* size of random header */
                    117: 
                    118:     init_keys(passwd);
                    119: 
                    120:     /* Encrypt random header (last two bytes is high word of crc) */
                    121: 
                    122:     srand((unsigned int)time(NULL) ^ getpid()); /* initialize generator */
                    123:     while (n--) {
                    124:         putc(zencode(rand() >> 7), zfile);
                    125:     }
                    126:     putc(zencode((int)(crc >> 16) & 0xff), zfile);
                    127:     putc(zencode((int)(crc >> 24)), zfile);
                    128: }
                    129: 
                    130: 
                    131: #ifdef UTIL
                    132: 
                    133: /***********************************************************************
                    134:  * Encrypt the zip entry described by z from file source to file dest
                    135:  * using the password passwd.  Return an error code in the ZE_ class.
                    136:  */
                    137: int zipcloak(z, source, dest, passwd)
                    138:     struct zlist far *z;    /* zip entry to encrypt */
                    139:     FILE *source, *dest;    /* source and destination files */
                    140:     char *passwd;           /* password string */
                    141: {
                    142:     int c;                  /* input byte */
                    143:     int res;                /* result code */
                    144:     ulg n;                  /* holds offset and counts size */
                    145:     ush flag;               /* previous flags */
                    146: 
                    147:     /* Set encrypted bit, clear extended local header bit and write local
                    148:        header to output file */
                    149:     if ((n = ftell(dest)) == -1L) return ZE_TEMP;
                    150:     z->off = n;
                    151:     flag = z->flg;
                    152:     z->flg |= 1,  z->flg &= ~8;
                    153:     z->lflg |= 1, z->lflg &= ~8;
                    154:     z->siz += 12;
                    155:     if ((res = putlocal(z, dest)) != ZE_OK) return res;
                    156: 
                    157:     /* Initialize keys with password and write random header */
                    158:     crypthead(passwd, z->crc, dest);
                    159: 
                    160:     /* Skip local header in input file */
                    161:     if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
                    162:               SEEK_CUR)) {
                    163:         return ferror(source) ? ZE_READ : ZE_EOF;
                    164:     }
                    165: 
                    166:     /* Encrypt data */
                    167:     for (n = z->siz - 12; n; n--) {
                    168:         if ((c = getc(source)) == EOF) {
                    169:             return ferror(source) ? ZE_READ : ZE_EOF;
                    170:         }
                    171:         putc(zencode(c), dest);
                    172:     }
                    173:     /* Skip extended local header in input file if there is one */
                    174:     if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
                    175:         return ferror(source) ? ZE_READ : ZE_EOF;
                    176:     }
                    177:     if (fflush(dest) == EOF) return ZE_TEMP;
                    178:     return ZE_OK;
                    179: }
                    180: 
                    181: /***********************************************************************
                    182:  * Decrypt the zip entry described by z from file source to file dest
                    183:  * using the password passwd.  Return an error code in the ZE_ class.
                    184:  */
                    185: int zipbare(z, source, dest, passwd)
                    186:     struct zlist far *z;  /* zip entry to encrypt */
                    187:     FILE *source, *dest;  /* source and destination files */
                    188:     char *passwd;         /* password string */
                    189: {
                    190:     int c0, c1;           /* last two input bytes */
                    191:     ulg offset;           /* used for file offsets */
                    192:     ulg size;             /* size of input data */
                    193:     int r;                /* size of encryption header */
                    194:     int res;              /* return code */
                    195:     ush flag;             /* previous flags */
                    196: 
                    197:     /* Save position and skip local header in input file */
                    198:     if ((offset = ftell(source)) == -1L ||
                    199:         fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
                    200:               SEEK_CUR)) {
                    201:         return ferror(source) ? ZE_READ : ZE_EOF;
                    202:     }
                    203:     /* Initialize keys with password */
                    204:     init_keys(passwd);
                    205: 
                    206:     /* Decrypt encryption header, save last two bytes */
                    207:     c1 = 0;
                    208:     for (r = 12; r; r--) {
                    209:         c0 = c1;
                    210:         if ((c1 = zdecode(getc(source))) == EOF) {
                    211:             return ferror(source) ? ZE_READ : ZE_EOF;
                    212:         }
                    213:     }
                    214: 
                    215:     /* If last two bytes of header don't match crc (or file time in the
                    216:        case of an extended local header), back up and just copy */
                    217:     if ((ush)(c0 | (c1<<8)) !=
                    218:         (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
                    219:         if (fseek(source, offset, SEEK_SET)) {
                    220:             return ferror(source) ? ZE_READ : ZE_EOF;
                    221:         }
                    222:         if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
                    223:         return ZE_MISS;
                    224:     }
                    225: 
                    226:     /* Clear encrypted bit and local header bit, and write local header to
                    227:        output file */
                    228:     if ((offset = ftell(dest)) == -1L) return ZE_TEMP;
                    229:     z->off = offset;
                    230:     flag = z->flg;
                    231:     z->flg &= ~9;
                    232:     z->lflg &= ~9;
                    233:     z->siz -= 12;
                    234:     if ((res = putlocal(z, dest)) != ZE_OK) return res;
                    235: 
                    236:     /* Decrypt data */
                    237:     for (size = z->siz; size; size--) {
                    238:         if ((c1 = getc(source)) == EOF) {
                    239:             return ferror(source) ? ZE_READ : ZE_EOF;
                    240:         }
                    241:         putc(zdecode(c1), dest);
                    242:     }
                    243:     /* Skip extended local header in input file if there is one */
                    244:     if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
                    245:         return ferror(source) ? ZE_READ : ZE_EOF;
                    246:     }
                    247:     if (fflush(dest) == EOF) return ZE_TEMP;
                    248: 
                    249:     return ZE_OK;
                    250: }
                    251: 
                    252: 
                    253: #else /* !UTIL */
                    254: 
                    255: /***********************************************************************
                    256:  * If requested, encrypt the data in buf, and in any case call fwrite()
                    257:  * with the arguments to zfwrite().  Return what fwrite() returns.
                    258:  */
                    259: unsigned zfwrite(buf, item_size, nb, f)
                    260:     voidp *buf;                /* data buffer */
                    261:     extent item_size;          /* size of each item in bytes */
                    262:     extent nb;                 /* number of items */
                    263:     FILE *f;                   /* file to write to */
                    264: {
                    265:     if (key != (char *)NULL) { /* key is the global password pointer */
                    266:         ulg size;              /* buffer size */
                    267:         char *p = (char*)buf;  /* steps through buffer */
                    268: 
                    269:         /* Encrypt data in buffer */
                    270:         for (size = item_size*(ulg)nb; size != 0; p++, size--) {
                    271:             *p = (char)zencode(*p);
                    272:         }
                    273:     }
                    274:     /* Write the buffer out */
                    275:     return fwrite(buf, item_size, nb, f);
                    276: }
                    277: 
                    278: /***********************************************************************
                    279:  * Encrypt the byte c and then do a putc().  The macro zputc defined in
                    280:  * crypt.h checks keys and calls zfputc if needed.  Return what putc()
                    281:  * returns. This function is only provided for compatibility with zip 1.0.
                    282:  */
                    283: int zfputc(c, f)
                    284:     int c;                  /* character to write */
                    285:     FILE *f;                /* file to write it to */
                    286: {
                    287:     return putc(zencode(c), f);
                    288: }
                    289: 
                    290: #endif /* ?UTIL */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.