Use HMAC on header and encrypted data, avoid regular digest when encrypting.
This commit is contained in:
parent
6e9ca97bdf
commit
817e16cce6
1 changed files with 45 additions and 29 deletions
42
main.c
42
main.c
|
@ -318,8 +318,7 @@ redo:
|
||||||
memset(tdat->compressed_chunk + cksum_bytes, 0, mac_bytes);
|
memset(tdat->compressed_chunk + cksum_bytes, 0, mac_bytes);
|
||||||
hmac_reinit(&tdat->chunk_hmac);
|
hmac_reinit(&tdat->chunk_hmac);
|
||||||
hmac_update(&tdat->chunk_hmac, (uchar_t *)&tdat->len_cmp_be, sizeof (tdat->len_cmp_be));
|
hmac_update(&tdat->chunk_hmac, (uchar_t *)&tdat->len_cmp_be, sizeof (tdat->len_cmp_be));
|
||||||
hmac_update(&tdat->chunk_hmac, tdat->compressed_chunk,
|
hmac_update(&tdat->chunk_hmac, tdat->compressed_chunk, tdat->rbytes);
|
||||||
cksum_bytes + mac_bytes + CHUNK_FLAG_SZ);
|
|
||||||
if (HDR & CHSIZE_MASK) {
|
if (HDR & CHSIZE_MASK) {
|
||||||
uchar_t *rseg;
|
uchar_t *rseg;
|
||||||
rseg = tdat->compressed_chunk + tdat->rbytes;
|
rseg = tdat->compressed_chunk + tdat->rbytes;
|
||||||
|
@ -378,13 +377,13 @@ redo:
|
||||||
sem_post(&tdat->cmp_done_sem);
|
sem_post(&tdat->cmp_done_sem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now that HMAC (if any) was verified, recover the stored message
|
* Now that header CRC32 was verified, recover the stored message
|
||||||
* digest.
|
* digest.
|
||||||
*/
|
*/
|
||||||
deserialize_checksum(tdat->checksum, tdat->compressed_chunk, cksum_bytes);
|
deserialize_checksum(tdat->checksum, tdat->compressed_chunk, cksum_bytes);
|
||||||
|
}
|
||||||
|
|
||||||
if ((enable_rabin_scan || enable_fixed_scan) && (HDR & CHUNK_FLAG_DEDUP)) {
|
if ((enable_rabin_scan || enable_fixed_scan) && (HDR & CHUNK_FLAG_DEDUP)) {
|
||||||
uchar_t *cmpbuf, *ubuf;
|
uchar_t *cmpbuf, *ubuf;
|
||||||
|
@ -471,6 +470,7 @@ redo:
|
||||||
tdat->cmp_seg = tdat->uncompressed_chunk;
|
tdat->cmp_seg = tdat->uncompressed_chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!encrypt_type) {
|
||||||
/*
|
/*
|
||||||
* Re-compute checksum of original uncompressed chunk.
|
* Re-compute checksum of original uncompressed chunk.
|
||||||
* If it does not match we set length of chunk to 0 to indicate
|
* If it does not match we set length of chunk to 0 to indicate
|
||||||
|
@ -481,6 +481,7 @@ redo:
|
||||||
tdat->len_cmp = 0;
|
tdat->len_cmp = 0;
|
||||||
fprintf(stderr, "ERROR: Chunk %d, checksums do not match.\n", tdat->id);
|
fprintf(stderr, "ERROR: Chunk %d, checksums do not match.\n", tdat->id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cont:
|
cont:
|
||||||
sem_post(&tdat->cmp_done_sem);
|
sem_post(&tdat->cmp_done_sem);
|
||||||
|
@ -666,6 +667,11 @@ start_decompress(const char *filename, const char *to_filename)
|
||||||
unsigned short d1;
|
unsigned short d1;
|
||||||
unsigned int d2;
|
unsigned int d2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In encrypted files we do not have a normal digest. The HMAC
|
||||||
|
* is computed over header and encrypted data.
|
||||||
|
*/
|
||||||
|
cksum_bytes = 0;
|
||||||
compressed_chunksize += mac_bytes;
|
compressed_chunksize += mac_bytes;
|
||||||
encrypt_type = flags & MASK_CRYPTO_ALG;
|
encrypt_type = flags & MASK_CRYPTO_ALG;
|
||||||
if (Read(compfd, &saltlen, sizeof (saltlen)) < sizeof (saltlen)) {
|
if (Read(compfd, &saltlen, sizeof (saltlen)) < sizeof (saltlen)) {
|
||||||
|
@ -758,7 +764,7 @@ start_decompress(const char *filename, const char *to_filename)
|
||||||
memset(pw, 0, MAX_PW_LEN);
|
memset(pw, 0, MAX_PW_LEN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verify header HMAC.
|
* Verify file header HMAC.
|
||||||
*/
|
*/
|
||||||
if (hmac_init(&hdr_mac, cksum, &crypto_ctx) == -1) {
|
if (hmac_init(&hdr_mac, cksum, &crypto_ctx) == -1) {
|
||||||
close(uncompfd); unlink(to_filename);
|
close(uncompfd); unlink(to_filename);
|
||||||
|
@ -1071,6 +1077,7 @@ redo:
|
||||||
* into uncompressed_chunk so that compress transforms uncompressed_chunk
|
* into uncompressed_chunk so that compress transforms uncompressed_chunk
|
||||||
* back into cmp_seg. Avoids an extra memcpy().
|
* back into cmp_seg. Avoids an extra memcpy().
|
||||||
*/
|
*/
|
||||||
|
if (!encrypt_type)
|
||||||
compute_checksum(tdat->checksum, cksum, tdat->cmp_seg, tdat->rbytes);
|
compute_checksum(tdat->checksum, cksum, tdat->cmp_seg, tdat->rbytes);
|
||||||
|
|
||||||
rctx = tdat->rctx;
|
rctx = tdat->rctx;
|
||||||
|
@ -1085,6 +1092,7 @@ redo:
|
||||||
/*
|
/*
|
||||||
* Compute checksum of original uncompressed chunk.
|
* Compute checksum of original uncompressed chunk.
|
||||||
*/
|
*/
|
||||||
|
if (!encrypt_type)
|
||||||
compute_checksum(tdat->checksum, cksum, tdat->uncompressed_chunk, tdat->rbytes);
|
compute_checksum(tdat->checksum, cksum, tdat->uncompressed_chunk, tdat->rbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1206,6 +1214,7 @@ plain_compress:
|
||||||
*/
|
*/
|
||||||
len_cmp = tdat->len_cmp;
|
len_cmp = tdat->len_cmp;
|
||||||
*((typeof (len_cmp) *)(tdat->cmp_seg)) = htonll(tdat->len_cmp);
|
*((typeof (len_cmp) *)(tdat->cmp_seg)) = htonll(tdat->len_cmp);
|
||||||
|
if (!encrypt_type)
|
||||||
serialize_checksum(tdat->checksum, tdat->cmp_seg + sizeof (tdat->len_cmp), cksum_bytes);
|
serialize_checksum(tdat->checksum, tdat->cmp_seg + sizeof (tdat->len_cmp), cksum_bytes);
|
||||||
tdat->len_cmp += CHUNK_FLAG_SZ;
|
tdat->len_cmp += CHUNK_FLAG_SZ;
|
||||||
tdat->len_cmp += sizeof (len_cmp);
|
tdat->len_cmp += sizeof (len_cmp);
|
||||||
|
@ -1231,7 +1240,7 @@ plain_compress:
|
||||||
*(tdat->compressed_chunk) = type;
|
*(tdat->compressed_chunk) = type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If encrypting, compute HMAC for chunk header and trailer.
|
* If encrypting, compute HMAC for full chunk including header.
|
||||||
*/
|
*/
|
||||||
if (encrypt_type) {
|
if (encrypt_type) {
|
||||||
uchar_t *mac_ptr;
|
uchar_t *mac_ptr;
|
||||||
|
@ -1242,11 +1251,7 @@ plain_compress:
|
||||||
mac_ptr = tdat->cmp_seg + sizeof (tdat->len_cmp) + cksum_bytes;
|
mac_ptr = tdat->cmp_seg + sizeof (tdat->len_cmp) + cksum_bytes;
|
||||||
memset(mac_ptr, 0, mac_bytes);
|
memset(mac_ptr, 0, mac_bytes);
|
||||||
hmac_reinit(&tdat->chunk_hmac);
|
hmac_reinit(&tdat->chunk_hmac);
|
||||||
hmac_update(&tdat->chunk_hmac, tdat->cmp_seg, rbytes);
|
hmac_update(&tdat->chunk_hmac, tdat->cmp_seg, tdat->len_cmp);
|
||||||
if (type & CHSIZE_MASK)
|
|
||||||
hmac_update(&tdat->chunk_hmac,
|
|
||||||
tdat->cmp_seg + tdat->len_cmp - 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 {
|
} else {
|
||||||
|
@ -1257,7 +1262,7 @@ plain_compress:
|
||||||
unsigned int hlen;
|
unsigned int hlen;
|
||||||
uint32_t crc;
|
uint32_t crc;
|
||||||
|
|
||||||
/* Clean out mac_bytes to 0 for stable HMAC. */
|
/* Clean out mac_bytes to 0 for stable CRC32. */
|
||||||
mac_ptr = tdat->cmp_seg + sizeof (tdat->len_cmp) + cksum_bytes;
|
mac_ptr = tdat->cmp_seg + sizeof (tdat->len_cmp) + cksum_bytes;
|
||||||
memset(mac_ptr, 0, mac_bytes);
|
memset(mac_ptr, 0, mac_bytes);
|
||||||
crc = lzma_crc32(tdat->cmp_seg, rbytes, 0);
|
crc = lzma_crc32(tdat->cmp_seg, rbytes, 0);
|
||||||
|
@ -2185,8 +2190,19 @@ main(int argc, char *argv[])
|
||||||
if (cksum == 0)
|
if (cksum == 0)
|
||||||
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) {
|
||||||
|
/*
|
||||||
|
* If not encrypting we compute a header CRC32.
|
||||||
|
*/
|
||||||
mac_bytes = sizeof (uint32_t); // CRC32 in non-crypto mode
|
mac_bytes = sizeof (uint32_t); // CRC32 in non-crypto mode
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* When encrypting we do not compute a normal digest. The HMAC
|
||||||
|
* is computed over header and encrypted data.
|
||||||
|
*/
|
||||||
|
cksum_bytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the main routines.
|
* Start the main routines.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue