Add CRC32 header checksums in non-cryptographic mode.

This commit is contained in:
Moinak Ghosh 2012-11-23 00:00:39 +05:30
parent d054e0f713
commit 6e9ca97bdf
2 changed files with 88 additions and 4 deletions

View file

@ -58,8 +58,9 @@ PPMDSRCS = lzma/Ppmd8.c lzma/Ppmd8Enc.c lzma/Ppmd8Dec.c
PPMDHDRS = lzma/Ppmd.h lzma/Ppmd8.h PPMDHDRS = lzma/Ppmd.h lzma/Ppmd8.h
PPMDOBJS = $(PPMDSRCS:.c=.o) PPMDOBJS = $(PPMDSRCS:.c=.o)
CRCSRCS = lzma/crc64_fast.c lzma/crc64_table.c CRCSRCS = lzma/crc64_fast.c lzma/crc64_table.c lzma/crc32_fast.c lzma/crc32_table.c
CRCHDRS = lzma/crc64_table_le.h lzma/crc64_table_be.h lzma/crc_macros.h CRCHDRS = lzma/crc64_table_le.h lzma/crc64_table_be.h lzma/crc_macros.h \
lzma/crc32_table_le.h lzma/crc32_table_be.h
CRCOBJS = $(CRCSRCS:.c=.o) CRCOBJS = $(CRCSRCS:.c=.o)
LZPSRCS = lzp/lzp.c LZPSRCS = lzp/lzp.c

87
main.c
View file

@ -63,6 +63,7 @@ struct wdata {
static void * writer_thread(void *dat); static void * writer_thread(void *dat);
static int init_algo(const char *algo, int bail); static int init_algo(const char *algo, int bail);
extern uint32_t lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc);
static compress_func_ptr _compress_func; static compress_func_ptr _compress_func;
static compress_func_ptr _decompress_func; static compress_func_ptr _decompress_func;
@ -350,6 +351,33 @@ redo:
sem_post(&tdat->cmp_done_sem); sem_post(&tdat->cmp_done_sem);
return; return;
} }
} else {
/*
* Verify header CRC32 in non-crypto mode.
*/
uint32_t crc1, crc2;
crc1 = htonl(*((uint32_t *)(tdat->compressed_chunk + cksum_bytes)));
memset(tdat->compressed_chunk + cksum_bytes, 0, mac_bytes);
crc2 = lzma_crc32((uchar_t *)&tdat->len_cmp_be, sizeof (tdat->len_cmp_be), 0);
crc2 = lzma_crc32(tdat->compressed_chunk,
cksum_bytes + mac_bytes + CHUNK_FLAG_SZ, crc2);
if (HDR & CHSIZE_MASK) {
uchar_t *rseg;
rseg = tdat->compressed_chunk + tdat->rbytes;
crc2 = lzma_crc32(rseg, ORIGINAL_CHUNKSZ, crc2);
}
if (crc1 != crc2) {
/*
* Header CRC32 verification failure is fatal.
*/
fprintf(stderr, "Chunk %d, Header CRC verification failed\n", tdat->id);
main_cancel = 1;
tdat->len_cmp = 0;
sem_post(&tdat->cmp_done_sem);
return;
}
} }
/* /*
@ -752,7 +780,35 @@ start_decompress(const char *filename, const char *to_filename)
err_exit(0, "Header verification failed! File tampered or wrong password.\n"); err_exit(0, "Header verification failed! File tampered or wrong password.\n");
} }
} else { } else {
mac_bytes = 0; uint32_t crc1, crc2;
unsigned int hlen;
unsigned short d1;
unsigned int d2;
uint64_t ch;
/*
* Verify file header CRC32 in non-crypto mode.
*/
if (Read(compfd, &crc1, sizeof (crc1)) < sizeof (crc1)) {
perror("Read: ");
UNCOMP_BAIL;
}
crc1 = htonl(crc1);
mac_bytes = sizeof (uint32_t);
crc2 = lzma_crc32((uchar_t *)algo, ALGO_SZ, 0);
d1 = htons(version);
crc2 = lzma_crc32((uchar_t *)&d1, sizeof (version), crc2);
d1 = htons(flags);
crc2 = lzma_crc32((uchar_t *)&d1, sizeof (version), crc2);
ch = htonll(chunksize);
crc2 = lzma_crc32((uchar_t *)&ch, sizeof (ch), crc2);
d2 = htonl(level);
crc2 = lzma_crc32((uchar_t *)&d2, sizeof (level), crc2);
if (crc1 != crc2) {
close(uncompfd); unlink(to_filename);
err_exit(0, "Header verification failed! File tampered or wrong password.\n");
}
} }
nprocs = sysconf(_SC_NPROCESSORS_ONLN); nprocs = sysconf(_SC_NPROCESSORS_ONLN);
@ -1193,7 +1249,24 @@ plain_compress:
ORIGINAL_CHUNKSZ); ORIGINAL_CHUNKSZ);
hmac_final(&tdat->chunk_hmac, chash, &hlen); hmac_final(&tdat->chunk_hmac, chash, &hlen);
serialize_checksum(chash, mac_ptr, hlen); serialize_checksum(chash, mac_ptr, hlen);
} else {
/*
* Compute header CRC32 in non-crypto mode.
*/
uchar_t *mac_ptr;
unsigned int hlen;
uint32_t crc;
/* Clean out mac_bytes to 0 for stable HMAC. */
mac_ptr = tdat->cmp_seg + sizeof (tdat->len_cmp) + cksum_bytes;
memset(mac_ptr, 0, mac_bytes);
crc = lzma_crc32(tdat->cmp_seg, rbytes, 0);
if (type & CHSIZE_MASK)
crc = lzma_crc32(tdat->cmp_seg + tdat->len_cmp - ORIGINAL_CHUNKSZ,
ORIGINAL_CHUNKSZ, crc);
*((uint32_t *)mac_ptr) = htonl(crc);
} }
cont: cont:
sem_post(&tdat->cmp_done_sem); sem_post(&tdat->cmp_done_sem);
goto redo; goto redo;
@ -1563,6 +1636,16 @@ start_compress(const char *filename, uint64_t chunksize, int level)
perror("Write "); perror("Write ");
COMP_BAIL; COMP_BAIL;
} }
} else {
/*
* Compute header CRC32 and store that. Only archive version 5 and above.
*/
uint32_t crc = lzma_crc32(cread_buf, pos - cread_buf, 0);
*((uint32_t *)cread_buf) = htonl(crc);
if (Write(compfd, cread_buf, sizeof (uint32_t)) != sizeof (uint32_t)) {
perror("Write ");
COMP_BAIL;
}
} }
/* /*
@ -2103,7 +2186,7 @@ main(int argc, char *argv[])
get_checksum_props(DEFAULT_CKSUM, &cksum, &cksum_bytes, &mac_bytes); get_checksum_props(DEFAULT_CKSUM, &cksum, &cksum_bytes, &mac_bytes);
if (!encrypt_type) if (!encrypt_type)
mac_bytes = 0; mac_bytes = sizeof (uint32_t); // CRC32 in non-crypto mode
/* /*
* Start the main routines. * Start the main routines.
*/ */