"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/libzip/zip_source_pkware.c" (10 Oct 2018, 5971 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "zip_source_pkware.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.21_Source_vs_1.22_Source.

    1 /*
    2   zip_source_pkware.c -- Traditional PKWARE de/encryption routines
    3   Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner
    4 
    5   This file is part of libzip, a library to manipulate ZIP archives.
    6   The authors can be contacted at <libzip@nih.at>
    7 
    8   Redistribution and use in source and binary forms, with or without
    9   modification, are permitted provided that the following conditions
   10   are met:
   11   1. Redistributions of source code must retain the above copyright
   12      notice, this list of conditions and the following disclaimer.
   13   2. Redistributions in binary form must reproduce the above copyright
   14      notice, this list of conditions and the following disclaimer in
   15      the documentation and/or other materials provided with the
   16      distribution.
   17   3. The names of the authors may not be used to endorse or promote
   18      products derived from this software without specific prior
   19      written permission.
   20 
   21   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
   22   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
   25   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   27   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   29   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   30   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
   31   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32 */
   33 
   34 
   35 #include <stdlib.h>
   36 #include <string.h>
   37 
   38 #include "zipint.h"
   39 
   40 struct trad_pkware {
   41     zip_error_t error;
   42     zip_uint32_t key[3];
   43 };
   44 
   45 #define HEADERLEN 12
   46 #define KEY0 305419896
   47 #define KEY1 591751049
   48 #define KEY2 878082192
   49 
   50 
   51 static void decrypt(struct trad_pkware *, zip_uint8_t *, const zip_uint8_t *, zip_uint64_t, int);
   52 static int decrypt_header(zip_source_t *, struct trad_pkware *);
   53 static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
   54 static void pkware_free(struct trad_pkware *);
   55 
   56 
   57 zip_source_t *
   58 zip_source_pkware(zip_t *za, zip_source_t *src, zip_uint16_t em, int flags, const char *password) {
   59     struct trad_pkware *ctx;
   60     zip_source_t *s2;
   61 
   62     if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
   63     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
   64     return NULL;
   65     }
   66     if (flags & ZIP_CODEC_ENCODE) {
   67     zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
   68     return NULL;
   69     }
   70 
   71     if ((ctx = (struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
   72     zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
   73     return NULL;
   74     }
   75 
   76     zip_error_init(&ctx->error);
   77 
   78     ctx->key[0] = KEY0;
   79     ctx->key[1] = KEY1;
   80     ctx->key[2] = KEY2;
   81     decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
   82 
   83     if ((s2 = zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
   84     pkware_free(ctx);
   85     return NULL;
   86     }
   87 
   88     return s2;
   89 }
   90 
   91 
   92 static void
   93 decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in, zip_uint64_t len, int update_only) {
   94     zip_uint16_t tmp;
   95     zip_uint64_t i;
   96     Bytef b;
   97 
   98     for (i = 0; i < len; i++) {
   99     b = in[i];
  100 
  101     if (!update_only) {
  102         /* decrypt next byte */
  103         tmp = (zip_uint16_t)(ctx->key[2] | 2);
  104         tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
  105         b ^= (Bytef)tmp;
  106     }
  107 
  108     /* store cleartext */
  109     if (out)
  110         out[i] = b;
  111 
  112     /* update keys */
  113     ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
  114     ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
  115     b = (Bytef)(ctx->key[1] >> 24);
  116     ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
  117     }
  118 }
  119 
  120 
  121 static int
  122 decrypt_header(zip_source_t *src, struct trad_pkware *ctx) {
  123     zip_uint8_t header[HEADERLEN];
  124     struct zip_stat st;
  125     zip_int64_t n;
  126     unsigned short dostime, dosdate;
  127 
  128     if ((n = zip_source_read(src, header, HEADERLEN)) < 0) {
  129     _zip_error_set_from_source(&ctx->error, src);
  130     return -1;
  131     }
  132 
  133     if (n != HEADERLEN) {
  134     zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
  135     return -1;
  136     }
  137 
  138     decrypt(ctx, header, header, HEADERLEN, 0);
  139 
  140     if (zip_source_stat(src, &st) < 0) {
  141     /* stat failed, skip password validation */
  142     return 0;
  143     }
  144 
  145     _zip_u2d_time(st.mtime, &dostime, &dosdate);
  146 
  147     if (header[HEADERLEN - 1] != st.crc >> 24 && header[HEADERLEN - 1] != dostime >> 8) {
  148     zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
  149     return -1;
  150     }
  151 
  152     return 0;
  153 }
  154 
  155 
  156 static zip_int64_t
  157 pkware_decrypt(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
  158     struct trad_pkware *ctx;
  159     zip_int64_t n;
  160 
  161     ctx = (struct trad_pkware *)ud;
  162 
  163     switch (cmd) {
  164     case ZIP_SOURCE_OPEN:
  165     if (decrypt_header(src, ctx) < 0)
  166         return -1;
  167     return 0;
  168 
  169     case ZIP_SOURCE_READ:
  170     if ((n = zip_source_read(src, data, len)) < 0) {
  171         _zip_error_set_from_source(&ctx->error, src);
  172         return -1;
  173     }
  174 
  175     decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0);
  176     return n;
  177 
  178     case ZIP_SOURCE_CLOSE:
  179     return 0;
  180 
  181     case ZIP_SOURCE_STAT: {
  182     zip_stat_t *st;
  183 
  184     st = (zip_stat_t *)data;
  185 
  186     st->encryption_method = ZIP_EM_NONE;
  187     st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
  188     /* TODO: deduce HEADERLEN from size for uncompressed */
  189     if (st->valid & ZIP_STAT_COMP_SIZE)
  190         st->comp_size -= HEADERLEN;
  191 
  192     return 0;
  193     }
  194 
  195     case ZIP_SOURCE_SUPPORTS:
  196     return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
  197 
  198     case ZIP_SOURCE_ERROR:
  199     return zip_error_to_data(&ctx->error, data, len);
  200 
  201     case ZIP_SOURCE_FREE:
  202     pkware_free(ctx);
  203     return 0;
  204 
  205     default:
  206     zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
  207     return -1;
  208     }
  209 }
  210 
  211 
  212 static void
  213 pkware_free(struct trad_pkware *ctx) {
  214     free(ctx);
  215 }