-
-
Notifications
You must be signed in to change notification settings - Fork 434
/
mz_crypt.c
182 lines (152 loc) · 7.42 KB
/
mz_crypt.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* mz_crypt.c -- Crypto/hash functions
part of the minizip-ng project
Copyright (C) Nathan Moinvaziri
https://github.com/zlib-ng/minizip-ng
This program is distributed under the terms of the same license as zlib.
See the accompanying LICENSE file for the full text of the license.
*/
#include "mz.h"
#include "mz_os.h"
#include "mz_crypt.h"
#if defined(HAVE_ZLIB)
# if !defined(ZLIB_COMPAT)
# include "zlib-ng.h"
# define ZLIB_PREFIX(x) zng_##x
# else
# include "zlib.h"
# define ZLIB_PREFIX(x) x
# endif
#elif defined(HAVE_LZMA)
# include "lzma.h"
#endif
/***************************************************************************/
#if defined(MZ_ZIP_NO_CRYPTO)
int32_t mz_crypt_rand(uint8_t *buf, int32_t size) {
return mz_os_rand(buf, size);
}
#endif
uint32_t mz_crypt_crc32_update(uint32_t value, const uint8_t *buf, int32_t size) {
#if defined(HAVE_ZLIB)
# ifndef ZLIB_VERNUM
/* HAVE_ZLIB but no ZLIB_VERNUM? */
typedef uint32_t z_crc_t;
# elif (ZLIB_VERNUM & 0xf != 0xf) && (ZLIB_VERNUM < 0x1270)
/* Define z_crc_t in zlib 1.2.6 and less */
typedef unsigned long z_crc_t;
# elif (ZLIB_VERNUM & 0xf == 0xf) && (ZLIB_VERNUM < 0x12df)
/* Define z_crc_t in zlib-ng 2.0.7 and less */
typedef unsigned int z_crc_t;
# endif
return (uint32_t)ZLIB_PREFIX(crc32)((z_crc_t)value, buf, (uInt)size);
#elif defined(HAVE_LZMA)
return (uint32_t)lzma_crc32(buf, (size_t)size, (uint32_t)value);
#else
static uint32_t crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832,
0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab,
0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4,
0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074,
0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76,
0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6,
0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7,
0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330,
0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
value = ~value;
while (size > 0) {
value = (value >> 8) ^ crc32_table[(value ^ *buf) & 0xFF];
buf += 1;
size -= 1;
}
return ~value;
#endif
}
#if defined(HAVE_WZAES)
int32_t mz_crypt_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt, int32_t salt_length,
uint32_t iteration_count, uint8_t *key, uint16_t key_length) {
void *hmac1 = NULL;
void *hmac2 = NULL;
void *hmac3 = NULL;
int32_t err = MZ_OK;
uint16_t i = 0;
uint32_t j = 0;
uint16_t k = 0;
uint16_t block_count = 0;
uint8_t uu[MZ_HASH_SHA1_SIZE];
uint8_t ux[MZ_HASH_SHA1_SIZE];
if (!password || !salt || !key)
return MZ_PARAM_ERROR;
memset(key, 0, key_length);
hmac1 = mz_crypt_hmac_create();
hmac2 = mz_crypt_hmac_create();
hmac3 = mz_crypt_hmac_create();
if (!hmac1 || !hmac2 || !hmac3) {
err = MZ_MEM_ERROR;
goto pbkdf2_cleanup;
}
mz_crypt_hmac_set_algorithm(hmac1, MZ_HASH_SHA1);
mz_crypt_hmac_set_algorithm(hmac2, MZ_HASH_SHA1);
mz_crypt_hmac_set_algorithm(hmac3, MZ_HASH_SHA1);
err = mz_crypt_hmac_init(hmac1, password, password_length);
if (err == MZ_OK)
err = mz_crypt_hmac_init(hmac2, password, password_length);
if (err == MZ_OK)
err = mz_crypt_hmac_update(hmac2, salt, salt_length);
block_count = 1 + ((uint16_t)key_length - 1) / MZ_HASH_SHA1_SIZE;
for (i = 0; (err == MZ_OK) && (i < block_count); i += 1) {
memset(ux, 0, sizeof(ux));
err = mz_crypt_hmac_copy(hmac2, hmac3);
if (err != MZ_OK)
break;
uu[0] = (uint8_t)((i + 1) >> 24);
uu[1] = (uint8_t)((i + 1) >> 16);
uu[2] = (uint8_t)((i + 1) >> 8);
uu[3] = (uint8_t)(i + 1);
for (j = 0, k = 4; j < iteration_count; j += 1) {
err = mz_crypt_hmac_update(hmac3, uu, k);
if (err == MZ_OK)
err = mz_crypt_hmac_end(hmac3, uu, sizeof(uu));
if (err != MZ_OK)
break;
for (k = 0; k < MZ_HASH_SHA1_SIZE; k += 1)
ux[k] ^= uu[k];
err = mz_crypt_hmac_copy(hmac1, hmac3);
if (err != MZ_OK)
break;
}
if (err != MZ_OK)
break;
j = 0;
k = i * MZ_HASH_SHA1_SIZE;
while (j < MZ_HASH_SHA1_SIZE && k < key_length)
key[k++] = ux[j++];
}
pbkdf2_cleanup:
/* hmac3 uses the same provider as hmac2, so it must be deleted
before the context is destroyed. */
mz_crypt_hmac_delete(&hmac3);
mz_crypt_hmac_delete(&hmac1);
mz_crypt_hmac_delete(&hmac2);
return err;
}
#endif
/***************************************************************************/