Annotation of coherent/b/bin/zip/crypt.c, revision 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.