added iOS source code
[wl-app.git] / iOS / Pods / SSZipArchive / SSZipArchive / minizip / crypt.c
1 /* crypt.c -- base code for traditional PKWARE encryption
2    Version 1.2.0, September 16th, 2017
3
4    Copyright (C) 2012-2017 Nathan Moinvaziri
5      https://github.com/nmoinvaz/minizip
6    Copyright (C) 1998-2005 Gilles Vollant
7      Modifications for Info-ZIP crypting
8      http://www.winimage.com/zLibDll/minizip.html
9    Copyright (C) 2003 Terry Thorsen
10
11    This code is a modified version of crypting code in Info-ZIP distribution
12
13    Copyright (C) 1990-2000 Info-ZIP.  All rights reserved.
14
15    This program is distributed under the terms of the same license as zlib.
16    See the accompanying LICENSE file for the full text of the license.
17
18    This encryption code is a direct transcription of the algorithm from
19    Roger Schlafly, described by Phil Katz in the file appnote.txt. This
20    file (appnote.txt) is distributed with the PKZIP program (even in the
21    version without encryption capabilities).
22
23    If you don't need crypting in your application, just define symbols
24    NOCRYPT and NOUNCRYPT.
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdint.h>
30 #include <time.h>
31
32 #ifdef _WIN32
33 #  include <windows.h>
34 #  include <wincrypt.h>
35 #else
36 #  include <sys/stat.h>
37 #  include <fcntl.h>
38 #  include <unistd.h>
39 #endif
40
41 #include "zlib.h"
42
43 #include "crypt.h"
44
45 /***************************************************************************/
46
47 #define CRC32(c, b) ((*(pcrc_32_tab+(((uint32_t)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
48
49 /***************************************************************************/
50
51 uint8_t decrypt_byte(uint32_t *pkeys)
52 {
53     unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
54                      * unpredictable manner on 16-bit systems; not a problem
55                      * with any known compiler so far, though */
56
57     temp = ((uint32_t)(*(pkeys+2)) & 0xffff) | 2;
58     return (uint8_t)(((temp * (temp ^ 1)) >> 8) & 0xff);
59 }
60
61 uint8_t update_keys(uint32_t *pkeys, const z_crc_t *pcrc_32_tab, int32_t c)
62 {
63     (*(pkeys+0)) = (uint32_t)CRC32((*(pkeys+0)), c);
64     (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
65     (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
66     {
67         register int32_t keyshift = (int32_t)((*(pkeys + 1)) >> 24);
68         (*(pkeys+2)) = (uint32_t)CRC32((*(pkeys+2)), keyshift);
69     }
70     return c;
71 }
72
73 void init_keys(const char *passwd, uint32_t *pkeys, const z_crc_t *pcrc_32_tab)
74 {
75     *(pkeys+0) = 305419896L;
76     *(pkeys+1) = 591751049L;
77     *(pkeys+2) = 878082192L;
78     while (*passwd != 0)
79     {
80         update_keys(pkeys, pcrc_32_tab, *passwd);
81         passwd += 1;
82     }
83 }
84
85 /***************************************************************************/
86
87 int cryptrand(unsigned char *buf, unsigned int len)
88 {
89 #ifdef _WIN32
90     HCRYPTPROV provider;
91     unsigned __int64 pentium_tsc[1];
92     int rlen = 0;
93     int result = 0;
94
95
96     if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
97     {
98         result = CryptGenRandom(provider, len, buf);
99         CryptReleaseContext(provider, 0);
100         if (result)
101             return len;
102     }
103
104     for (rlen = 0; rlen < (int)len; ++rlen)
105     {
106         if (rlen % 8 == 0)
107             QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc);
108         buf[rlen] = ((unsigned char*)pentium_tsc)[rlen % 8];
109     }
110
111     return rlen;
112 #else
113     arc4random_buf(buf, len);
114     return len;
115 #endif
116 }
117
118 int crypthead(const char *passwd, uint8_t *buf, int buf_size, uint32_t *pkeys,
119               const z_crc_t *pcrc_32_tab, uint8_t verify1, uint8_t verify2)
120 {
121     uint8_t n = 0;                      /* index in random header */
122     uint8_t header[RAND_HEAD_LEN-2];    /* random header */
123     uint16_t t = 0;                     /* temporary */
124
125     if (buf_size < RAND_HEAD_LEN)
126         return 0;
127
128     init_keys(passwd, pkeys, pcrc_32_tab);
129
130     /* First generate RAND_HEAD_LEN-2 random bytes. */
131     cryptrand(header, RAND_HEAD_LEN-2);
132
133     /* Encrypt random header (last two bytes is high word of crc) */
134     init_keys(passwd, pkeys, pcrc_32_tab);
135
136     for (n = 0; n < RAND_HEAD_LEN-2; n++)
137         buf[n] = (uint8_t)zencode(pkeys, pcrc_32_tab, header[n], t);
138
139     buf[n++] = (uint8_t)zencode(pkeys, pcrc_32_tab, verify1, t);
140     buf[n++] = (uint8_t)zencode(pkeys, pcrc_32_tab, verify2, t);
141     return n;
142 }
143
144 /***************************************************************************/