Moved crc hashing and pbkdf2 to crypt.

Provide backup crc32 function if zlib or lzma not used.
Fixed check for no signing in minizip.
This commit is contained in:
Nathan Moinvaziri 2018-11-03 19:45:41 -07:00
parent 24280b68e8
commit e63d231fa5
14 changed files with 41 additions and 174 deletions

View File

@ -133,10 +133,10 @@ endif()
# Initial source files
set(MINIZIP_SRC
mz_crypt.c
mz_os.c
mz_strm.c
mz_strm_buf.c
mz_strm_crc32.c
mz_strm_mem.c
mz_strm_split.c
mz_zip.c
@ -149,7 +149,6 @@ set(MINIZIP_PUBLIC_HEADERS
mz_crypt.h
mz_strm.h
mz_strm_buf.h
mz_strm_crc32.h
mz_strm_mem.h
mz_strm_split.h
mz_strm_os.h

View File

@ -92,15 +92,14 @@ cmake --build .
| mz_strm.\* | Stream interface | Yes |
| mz_strm_buf.\* | Buffered stream | No |
| mz_strm_bzip.\* | BZIP2 stream using libbzip2 | No |
| mz_strm_crc32.\* | CRC32 stream | Yes |
| mz_strm_libcomp.\* | Apple compression stream | No |
| mz_strm_lzma.\* | LZMA stream using liblzma | zlib or liblzma |
| mz_strm_lzma.\* | LZMA stream using liblzma | No |
| mz_strm_mem.\* | Memory stream | Yes |
| mz_strm_split.\* | Disk splitting stream | No |
| mz_strm_pkcrypt.\* | PKWARE traditional encryption stream | No |
| mz_strm_os\* | Platform specific file stream | Yes |
| mz_strm_wzaes.\* | WinZIP AES stream | No |
| mz_strm_zlib.\* | Deflate stream using zlib | zlib or liblzma |
| mz_strm_zlib.\* | Deflate stream using zlib | No |
| mz_zip.\* | Zip format | Yes |
| mz_zip_rw.\* | Zip reader/writer | No |

View File

@ -40,7 +40,7 @@ typedef struct minizip_opt_s {
#ifdef HAVE_AES
uint8_t aes;
#endif
#ifndef MZ_NO_ZIP_SIGNING
#ifndef MZ_ZIP_NO_SIGNING
const char *cert_path;
const char *cert_pwd;
#endif
@ -526,7 +526,7 @@ int32_t minizip_erase(const char *src_path, const char *target_path, int32_t arg
/***************************************************************************/
#if !defined(MZ_NO_MAIN)
#if !defined(MZ_ZIP_NO_MAIN)
int main(int argc, const char *argv[])
{
minizip_opt options;
@ -597,7 +597,7 @@ int main(int argc, const char *argv[])
else if ((c == 's') || (c == 'S'))
options.aes = 1;
#endif
#ifndef MZ_NO_ZIP_SIGNING
#ifndef MZ_ZIP_NO_SIGNING
else if (((c == 'h') || (c == 'H')) && (i + 1 < argc))
{
options.cert_path = argv[i + 1];

View File

@ -20,6 +20,13 @@ extern "C" {
/***************************************************************************/
uint32_t mz_crypt_crc32_update(uint32_t value, const uint8_t *buf, int32_t size);
int32_t mz_crypt_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt,
int32_t salt_length, int32_t iteration_count, uint8_t *key, int32_t key_length);
/***************************************************************************/
int32_t mz_crypt_rand(uint8_t *buf, int32_t size);
void mz_crypt_sha_reset(void *handle);

16
mz_os.c
View File

@ -17,6 +17,7 @@
#include <ctype.h>
#include "mz.h"
#include "mz_crypt.h"
#include "mz_os.h"
#include "mz_strm.h"
#include "mz_strm_crc32.h"
@ -291,7 +292,7 @@ int32_t mz_dir_make(const char *path)
int32_t mz_file_get_crc(const char *path, uint32_t *result_crc)
{
void *stream = NULL;
void *crc32_stream = NULL;
uint32_t crc32 = 0;
int32_t read = 0;
int32_t err = MZ_OK;
uint8_t buf[16384];
@ -300,31 +301,26 @@ int32_t mz_file_get_crc(const char *path, uint32_t *result_crc)
err = mz_stream_os_open(stream, path, MZ_OPEN_MODE_READ);
mz_stream_crc32_create(&crc32_stream);
mz_stream_crc32_open(crc32_stream, NULL, MZ_OPEN_MODE_READ);
mz_stream_set_base(crc32_stream, stream);
if (err == MZ_OK)
{
do
{
read = mz_stream_crc32_read(crc32_stream, buf, sizeof(buf));
read = mz_stream_os_read(stream, buf, sizeof(buf));
if (read < 0)
{
err = read;
break;
}
crc32 = mz_crypt_crc32_update(crc32, buf, read);
}
while ((err == MZ_OK) && (read > 0));
mz_stream_os_close(stream);
}
mz_stream_crc32_close(crc32_stream);
*result_crc = mz_stream_crc32_get_value(crc32_stream);
mz_stream_crc32_delete(&crc32_stream);
*result_crc = crc32;
mz_stream_os_delete(&stream);

View File

@ -15,7 +15,7 @@
#include <stdbool.h>
#include <string.h>
#include <lzma.h>
#include "lzma.h"
#include "mz.h"
#include "mz_strm.h"
@ -430,13 +430,3 @@ void *mz_stream_lzma_get_interface(void)
{
return (void *)&mz_stream_lzma_vtbl;
}
static int64_t mz_stream_lzma_crc32(int64_t value, const void *buf, int32_t size)
{
return (int64_t)lzma_crc32(buf, (size_t)size, (uint32_t)value);
}
void *mz_stream_lzma_get_crc32_update(void)
{
return (void *)mz_stream_lzma_crc32;
}

View File

@ -36,7 +36,6 @@ void* mz_stream_lzma_create(void **stream);
void mz_stream_lzma_delete(void **stream);
void* mz_stream_lzma_get_interface(void);
void* mz_stream_lzma_get_crc32_update(void);
/***************************************************************************/

View File

@ -67,8 +67,6 @@ typedef struct mz_stream_pkcrypt_s {
uint8_t verify1;
uint8_t verify2;
const char *password;
mz_stream_crc32_update
crc32_update;
} mz_stream_pkcrypt;
/***************************************************************************/
@ -100,14 +98,14 @@ static uint8_t mz_stream_pkcrypt_update_keys(void *stream, uint8_t c)
mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream;
uint8_t buf = c;
pkcrypt->keys[0] = (uint32_t)~pkcrypt->crc32_update(~pkcrypt->keys[0], &buf, 1);
pkcrypt->keys[0] = (uint32_t)~mz_crypt_crc32_update(~pkcrypt->keys[0], &buf, 1);
pkcrypt->keys[1] += pkcrypt->keys[0] & 0xff;
pkcrypt->keys[1] *= 134775813L;
pkcrypt->keys[1] += 1;
buf = (uint8_t)(pkcrypt->keys[1] >> 24);
pkcrypt->keys[2] = (uint32_t)~pkcrypt->crc32_update(~pkcrypt->keys[2], &buf, 1);
pkcrypt->keys[2] = (uint32_t)~mz_crypt_crc32_update(~pkcrypt->keys[2], &buf, 1);
return (uint8_t)c;
}
@ -151,9 +149,6 @@ int32_t mz_stream_pkcrypt_open(void *stream, const char *path, int32_t mode)
if (password == NULL)
return MZ_PARAM_ERROR;
if (mz_stream_crc32_get_update_func(&pkcrypt->crc32_update) != MZ_OK)
return MZ_PARAM_ERROR;
mz_stream_pkcrypt_init_keys(stream, password);
if (mode & MZ_OPEN_MODE_WRITE)

View File

@ -68,83 +68,6 @@ typedef struct mz_stream_wzaes_s {
/***************************************************************************/
int32_t mz_stream_wzaes_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt,
int32_t salt_length, int32_t iteration_count, uint8_t *key, int32_t key_length)
{
void *hmac1 = NULL;
void *hmac2 = NULL;
void *hmac3 = NULL;
int32_t err = MZ_OK;
uint16_t i = 0;
uint16_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 == NULL || salt == NULL || key == NULL)
return MZ_PARAM_ERROR;
memset(key, 0, key_length);
mz_crypt_hmac_create(&hmac1);
mz_crypt_hmac_create(&hmac2);
mz_crypt_hmac_create(&hmac3);
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);
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);
err = mz_crypt_hmac_end(hmac3, uu, sizeof(uu));
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++];
}
mz_crypt_hmac_delete(&hmac1);
mz_crypt_hmac_delete(&hmac2);
mz_crypt_hmac_delete(&hmac3);
return err;
}
/***************************************************************************/
int32_t mz_stream_wzaes_open(void *stream, const char *path, int32_t mode)
@ -200,7 +123,7 @@ int32_t mz_stream_wzaes_open(void *stream, const char *path, int32_t mode)
key_length = MZ_AES_KEY_LENGTH(wzaes->encryption_mode);
// Derive the encryption and authentication keys and the password verifier
mz_stream_wzaes_pbkdf2((uint8_t *)password, password_length, salt_value, salt_length,
mz_crypt_pbkdf2((uint8_t *)password, password_length, salt_value, salt_length,
MZ_AES_KEYING_ITERATIONS, kbuf, 2 * key_length + MZ_AES_PW_VERIFY_SIZE);
// Initialize the encryption nonce and buffer pos

View File

@ -20,9 +20,6 @@ extern "C" {
/***************************************************************************/
int32_t mz_stream_wzaes_pbkdf2(uint8_t *password, int32_t password_length, uint8_t *salt,
int32_t salt_length, int32_t iteration_count, uint8_t *key, int32_t key_length);
int32_t mz_stream_wzaes_open(void *stream, const char *filename, int32_t mode);
int32_t mz_stream_wzaes_is_open(void *stream);
int32_t mz_stream_wzaes_read(void *stream, void *buf, int32_t size);

View File

@ -22,15 +22,6 @@
/***************************************************************************/
// Define z_crc_t in zlib 1.2.5 and less or if using zlib-ng
#if defined(ZLIBNG_VERNUM)
typedef uint32_t z_crc_t;
#elif (ZLIB_VERNUM < 0x1270)
typedef unsigned long z_crc_t;
#endif
/***************************************************************************/
#ifndef DEF_MEM_LEVEL
# if MAX_MEM_LEVEL >= 8
# define DEF_MEM_LEVEL 8
@ -415,13 +406,3 @@ void *mz_stream_zlib_get_interface(void)
{
return (void *)&mz_stream_zlib_vtbl;
}
static int64_t mz_stream_zlib_crc32(int64_t value, const void *buf, int32_t size)
{
return crc32((z_crc_t)value, buf, size);
}
void *mz_stream_zlib_get_crc32_update(void)
{
return (void *)mz_stream_zlib_crc32;
}

View File

@ -36,7 +36,6 @@ void* mz_stream_zlib_create(void **stream);
void mz_stream_zlib_delete(void **stream);
void* mz_stream_zlib_get_interface(void);
void* mz_stream_zlib_get_crc32_update(void);
/***************************************************************************/

View File

@ -76,7 +76,6 @@ typedef struct mz_zip_s
void *cd_stream; // pointer to the stream with the cd
void *cd_mem_stream; // memory stream for central directory
void *compress_stream; // compression stream
void *crc32_stream; // crc32 stream
void *crypt_stream; // encryption stream
void *file_info_stream; // memory stream for storing file info
void *local_file_info_stream; // memory stream for storing local file info
@ -94,6 +93,7 @@ typedef struct mz_zip_s
uint8_t entry_scanned; // entry header information read ok
uint8_t entry_opened; // entry is open for read/write
uint8_t entry_raw; // entry opened with raw mode
uint32_t entry_crc32; // entry crc32
uint64_t number_entry;
@ -1435,17 +1435,10 @@ static int32_t mz_zip_entry_open_int(void *handle, uint8_t raw, int16_t compress
err = mz_stream_open(zip->compress_stream, NULL, zip->open_mode);
}
if (err == MZ_OK)
{
mz_stream_crc32_create(&zip->crc32_stream);
mz_stream_set_base(zip->crc32_stream, zip->compress_stream);
err = mz_stream_open(zip->crc32_stream, NULL, zip->open_mode);
}
if (err == MZ_OK)
{
zip->entry_opened = 1;
zip->entry_crc32 = 0;
}
return err;
@ -1631,7 +1624,9 @@ int32_t mz_zip_entry_read(void *handle, void *buf, int32_t len)
// Read entire entry even if uncompressed_size = 0, otherwise
// aes encryption validation will fail if compressed_size > 0
read = mz_stream_read(zip->crc32_stream, buf, len);
read = mz_stream_read(zip->compress_stream, buf, len);
if (read > 0)
zip->entry_crc32 = mz_crypt_crc32_update(zip->entry_crc32, buf, read);
return read;
}
@ -1642,7 +1637,9 @@ int32_t mz_zip_entry_write(void *handle, const void *buf, int32_t len)
if (zip == NULL || mz_zip_entry_is_open(handle) != MZ_OK)
return MZ_PARAM_ERROR;
written = mz_stream_write(zip->crc32_stream, buf, len);
written = mz_stream_write(zip->compress_stream, buf, len);
if (written > 0)
zip->entry_crc32 = mz_crypt_crc32_update(zip->entry_crc32, buf, written);
return written;
}
@ -1702,11 +1699,11 @@ int32_t mz_zip_entry_close_raw(void *handle, int64_t uncompressed_size, uint32_t
mz_stream_close(zip->compress_stream);
if (!zip->entry_raw)
crc32 = mz_stream_crc32_get_value(zip->crc32_stream);
crc32 = zip->entry_crc32;
if ((zip->open_mode & MZ_OPEN_MODE_WRITE) == 0)
{
mz_stream_get_prop_int64(zip->crc32_stream, MZ_STREAM_PROP_TOTAL_IN, &total_in);
mz_stream_get_prop_int64(zip->compress_stream, MZ_STREAM_PROP_TOTAL_IN, &total_in);
// If entire entry was not read verification will fail
if ((total_in > 0) && (!zip->entry_raw))
@ -1724,7 +1721,7 @@ int32_t mz_zip_entry_close_raw(void *handle, int64_t uncompressed_size, uint32_t
mz_stream_get_prop_int64(zip->compress_stream, MZ_STREAM_PROP_TOTAL_OUT, &compressed_size);
if (!zip->entry_raw)
mz_stream_get_prop_int64(zip->crc32_stream, MZ_STREAM_PROP_TOTAL_OUT, &uncompressed_size);
mz_stream_get_prop_int64(zip->compress_stream, MZ_STREAM_PROP_TOTAL_IN, &uncompressed_size);
if (zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED)
{
@ -1737,8 +1734,6 @@ int32_t mz_zip_entry_close_raw(void *handle, int64_t uncompressed_size, uint32_t
mz_stream_delete(&zip->crypt_stream);
mz_stream_delete(&zip->compress_stream);
mz_stream_close(zip->crc32_stream);
mz_stream_crc32_delete(&zip->crc32_stream);
if (zip->open_mode & MZ_OPEN_MODE_WRITE)
{

View File

@ -164,7 +164,6 @@ void test_compress(char *method, mz_stream_create_cb create_compress)
int16_t read = 0;
int64_t total_in = 0;
int64_t total_out = 0;
void *crc_in_stream = NULL;
void *in_stream = NULL;
void *out_stream = NULL;
void *deflate_stream = NULL;
@ -178,13 +177,9 @@ void test_compress(char *method, mz_stream_create_cb create_compress)
if (mz_stream_os_open(in_stream, "LICENSE", MZ_OPEN_MODE_READ) == MZ_OK)
{
mz_stream_crc32_create(&crc_in_stream);
mz_stream_set_base(crc_in_stream, in_stream);
mz_stream_crc32_open(crc_in_stream, NULL, MZ_OPEN_MODE_READ);
read = mz_stream_read(crc_in_stream, buf, UINT16_MAX);
crc32 = mz_stream_crc32_get_value(crc_in_stream);
mz_stream_close(crc_in_stream);
mz_stream_crc32_delete(&crc_in_stream);
read = mz_stream_os_read(in_stream, buf, UINT16_MAX);
if (read > 0)
crc32 = mz_crypt_crc32_update(crc32, buf, read);
mz_stream_os_close(in_stream);
}
@ -246,20 +241,12 @@ void test_compress(char *method, mz_stream_create_cb create_compress)
mz_stream_os_delete(&in_stream);
mz_stream_os_create(&out_stream);
crc32 = 0;
snprintf(filename, sizeof(filename), "LICENSE.inflate.%s", method);
if (mz_stream_os_open(out_stream, filename, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE) == MZ_OK)
{
mz_stream_crc32_create(&crc_in_stream);
mz_stream_crc32_open(crc_in_stream, NULL, MZ_OPEN_MODE_WRITE);
mz_stream_set_base(crc_in_stream, in_stream);
if (mz_stream_write(crc_in_stream, buf, read) != read)
printf("Failed to write %s\n", filename);
crc32 = mz_stream_crc32_get_value(crc_in_stream);
mz_stream_close(crc_in_stream);
mz_stream_delete(&crc_in_stream);
crc32 = mz_crypt_crc32_update(crc32, buf, read);
mz_stream_os_close(out_stream);
@ -297,7 +284,7 @@ void test_stream_wzaes(void)
printf("Pbkdf2 password - %s\n", password);
printf("Pbkdf2 salt - %s\n", salt);
err = mz_stream_wzaes_pbkdf2((uint8_t *)password, (int32_t)strlen(password),
err = mz_crypt_pbkdf2((uint8_t *)password, (int32_t)strlen(password),
(uint8_t *)salt, (int32_t)strlen(salt), iteration_count, key, sizeof(key));
if (err == MZ_OK)