mirror of
https://github.com/ckolivas/lrzip.git
synced 2026-01-20 07:10:22 +01:00
Implement the actual aes cbc encryption and decryption.
This commit is contained in:
parent
acb023988f
commit
c5938c6a8b
17
lrzip.c
17
lrzip.c
|
|
@ -44,6 +44,7 @@
|
|||
#include "stream.h"
|
||||
#include "liblrzip.h" /* flag defines */
|
||||
#include "sha4.h"
|
||||
#include "aes.h"
|
||||
|
||||
#define MAGIC_LEN (39)
|
||||
|
||||
|
|
@ -479,6 +480,7 @@ retry_pass:
|
|||
goto retry_pass;
|
||||
}
|
||||
}
|
||||
print_output("\n");
|
||||
termios_p.c_lflag |= ECHO;
|
||||
tcsetattr(fileno(stdin), 0, &termios_p);
|
||||
free(testphrase);
|
||||
|
|
@ -486,10 +488,10 @@ retry_pass:
|
|||
|
||||
memcpy(passphrase + PASS_LEN - SALT_LEN, control->salt, SALT_LEN);
|
||||
sha4(passphrase, PASS_LEN, control->hash, 0);
|
||||
/* Copy the first hashed passphrase and use it to xor every
|
||||
* cycle */
|
||||
/* Copy the first hashed passphrase and use it to xor every cycle */
|
||||
memcpy(passphrase, control->hash, HASH_LEN);
|
||||
|
||||
print_maxverbose("Hashing passphrase %lld times\n", control->encloops);
|
||||
for (i = 0; i < control->encloops; i++) {
|
||||
for (j = 0; j < HASH_LEN; j++)
|
||||
control->hash[j] ^= passphrase[j];
|
||||
|
|
@ -634,8 +636,11 @@ void decompress_file(rzip_control *control)
|
|||
print_verbose("CRC32 ");
|
||||
print_verbose("being used for integrity testing.\n");
|
||||
|
||||
if (ENCRYPT)
|
||||
if (ENCRYPT) {
|
||||
get_hash(control, 0);
|
||||
if (unlikely(aes_setkey_dec(&control->aes_ctx, control->hash, 128)))
|
||||
failure("Failed to aes_setkey_dec in decompress_file\n");
|
||||
}
|
||||
|
||||
print_progress("Decompressing...\n");
|
||||
|
||||
|
|
@ -921,9 +926,11 @@ void compress_file(rzip_control *control)
|
|||
int fd_in, fd_out;
|
||||
char header[MAGIC_LEN];
|
||||
|
||||
if (ENCRYPT)
|
||||
if (ENCRYPT) {
|
||||
get_hash(control, 1);
|
||||
|
||||
if (unlikely(aes_setkey_enc(&control->aes_ctx, control->hash, 128)))
|
||||
failure("Failed to aes_setkey_enc in compress_file\n");
|
||||
}
|
||||
memset(header, 0, sizeof(header));
|
||||
|
||||
if (!STDIN) {
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ typedef uint32_t u32;
|
|||
|
||||
typedef struct rzip_control rzip_control;
|
||||
typedef struct md5_ctx md5_ctx;
|
||||
#include "aes.h" // for aes_context
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
# define mremap fake_mremap
|
||||
|
|
@ -138,6 +139,7 @@ typedef struct md5_ctx md5_ctx;
|
|||
#define PASS_LEN 512
|
||||
#define HASH_LEN 64
|
||||
#define SALT_LEN 16
|
||||
#define CBC_LEN 16
|
||||
|
||||
/* Needs to be less than 31 bits and page aligned on 32 bits */
|
||||
#define two_gig ((1ull << 31) - 4096)
|
||||
|
|
@ -197,12 +199,11 @@ struct rzip_control {
|
|||
int fd_out;
|
||||
int fd_hist;
|
||||
i64 encloops;
|
||||
uchar loop_byte1;
|
||||
uchar loop_byte2;
|
||||
i64 secs;
|
||||
uchar salt[16];
|
||||
uchar *hash;
|
||||
uchar *hash_iv;
|
||||
aes_context aes_ctx;
|
||||
unsigned char eof;
|
||||
unsigned char magic_written;
|
||||
md5_ctx ctx;
|
||||
|
|
|
|||
78
stream.c
78
stream.c
|
|
@ -1134,6 +1134,7 @@ static void *compthread(void *data)
|
|||
struct compress_thread *cti;
|
||||
struct stream_info *ctis;
|
||||
int waited = 0, ret = 0;
|
||||
i64 padded_len;
|
||||
|
||||
/* Make sure this thread doesn't already exist */
|
||||
|
||||
|
|
@ -1165,6 +1166,33 @@ retry:
|
|||
else failure("Dunno wtf compression to use!\n");
|
||||
}
|
||||
|
||||
if (!ret && ENCRYPT) {
|
||||
int encrypt_pad = 0;
|
||||
uchar *enc_buf;
|
||||
|
||||
/* We must pad the block length to a mutliple of CBC_LEN to be
|
||||
* able to encrypt. We pad it with random data */
|
||||
if (cti->c_len % CBC_LEN)
|
||||
encrypt_pad = CBC_LEN - (cti->c_len % CBC_LEN);
|
||||
padded_len = cti->c_len + encrypt_pad;
|
||||
enc_buf = malloc(padded_len);
|
||||
if (unlikely(!enc_buf))
|
||||
fatal("Failed to malloc enc_buf in compthread\n");
|
||||
if (encrypt_pad) {
|
||||
cti->s_buf = realloc(cti->s_buf, padded_len);
|
||||
if (unlikely(!cti->s_buf))
|
||||
fatal("Failed to realloc s_buf in compthread with encrypt_pad\n");
|
||||
get_rand(cti->s_buf + cti->c_len, encrypt_pad);
|
||||
}
|
||||
print_maxverbose("Encrypting block \n");
|
||||
if (unlikely(aes_crypt_cbc(&control->aes_ctx, AES_ENCRYPT,
|
||||
padded_len, control->hash_iv, cti->s_buf, enc_buf)))
|
||||
failure("Failed to aes_crypt_cbc in compthread\n");
|
||||
free(cti->s_buf);
|
||||
cti->s_buf = enc_buf;
|
||||
} else
|
||||
padded_len = cti->c_len;
|
||||
|
||||
/* If compression fails for whatever reason multithreaded, then wait
|
||||
* for the previous thread to finish, serialising the work to decrease
|
||||
* the memory requirements, increasing the chance of success */
|
||||
|
|
@ -1224,6 +1252,7 @@ retry:
|
|||
fatal("Failed to seekto cur_pos in compthread %d\n", i);
|
||||
|
||||
print_maxverbose("Thread %ld writing %lld compressed bytes from stream %d\n", i, cti->c_len, cti->streamno);
|
||||
/* We store the real length even if it's padded longer */
|
||||
if (unlikely(write_u8(control, ctis->fd, cti->c_type) ||
|
||||
write_i64(control, ctis->fd, cti->c_len) ||
|
||||
write_i64(control, ctis->fd, cti->s_len) ||
|
||||
|
|
@ -1232,10 +1261,10 @@ retry:
|
|||
}
|
||||
ctis->cur_pos += 25;
|
||||
|
||||
if (unlikely(write_buf(control, ctis->fd, cti->s_buf, cti->c_len)))
|
||||
if (unlikely(write_buf(control, ctis->fd, cti->s_buf, padded_len)))
|
||||
fatal("Failed to write_buf in compthread %d\n", i);
|
||||
|
||||
ctis->cur_pos += cti->c_len;
|
||||
ctis->cur_pos += padded_len;
|
||||
free(cti->s_buf);
|
||||
|
||||
lock_mutex(&output_lock);
|
||||
|
|
@ -1357,6 +1386,7 @@ static int fill_buffer(rzip_control *control, struct stream_info *sinfo, int str
|
|||
struct stream *s = &sinfo->s[streamno];
|
||||
uchar c_type, *s_buf;
|
||||
stream_thread_struct *st;
|
||||
i64 padded_len;
|
||||
|
||||
if (s->buf)
|
||||
free(s->buf);
|
||||
|
|
@ -1400,15 +1430,47 @@ fill_another:
|
|||
|
||||
fsync(control->fd_out);
|
||||
|
||||
s_buf = malloc(u_len);
|
||||
if (unlikely(u_len && !s_buf))
|
||||
fatal("Unable to malloc buffer of size %lld in fill_buffer\n", u_len);
|
||||
sinfo->ram_alloced += u_len;
|
||||
s_buf = malloc(c_len);
|
||||
if (unlikely(c_len && !s_buf))
|
||||
fatal("Unable to malloc buffer of size %lld in fill_buffer\n", c_len);
|
||||
sinfo->ram_alloced += c_len;
|
||||
|
||||
if (unlikely(read_buf(control, sinfo->fd, s_buf, c_len)))
|
||||
if (ENCRYPT) {
|
||||
/* If the data was encrypted, we need to read the padded data
|
||||
* at the end and then discard it once it's decrypted */
|
||||
int decrypt_pad = 0;
|
||||
|
||||
if (c_len % CBC_LEN)
|
||||
decrypt_pad = CBC_LEN - (c_len % CBC_LEN);
|
||||
padded_len = c_len + decrypt_pad;
|
||||
if (decrypt_pad) {
|
||||
s_buf = realloc(s_buf, padded_len);
|
||||
if (unlikely(!s_buf))
|
||||
fatal("Failed to 1st realloc s_buf in fill_buffer\n");
|
||||
}
|
||||
} else
|
||||
padded_len = c_len;
|
||||
|
||||
if (unlikely(read_buf(control, sinfo->fd, s_buf, padded_len)))
|
||||
return -1;
|
||||
|
||||
sinfo->total_read += c_len;
|
||||
sinfo->total_read += padded_len;
|
||||
|
||||
if (ENCRYPT) {
|
||||
uchar *dec_buf;
|
||||
|
||||
dec_buf = malloc(padded_len);
|
||||
if (unlikely(!dec_buf))
|
||||
fatal("Failed to malloc dec_buf in fill_buffer\n");
|
||||
print_maxverbose("Decrypting block \n");
|
||||
if (unlikely(aes_crypt_cbc(&control->aes_ctx, AES_DECRYPT,
|
||||
padded_len, control->hash_iv, s_buf, dec_buf)))
|
||||
failure("Failed to aes_crypt_cbc in fill_buffer\n");
|
||||
free(s_buf);
|
||||
s_buf = realloc(dec_buf, c_len);
|
||||
if (unlikely(!s_buf))
|
||||
fatal("Failed to 2nd realloc s_buf in fill_buffer\n");
|
||||
}
|
||||
|
||||
ucthread[s->uthread_no].s_buf = s_buf;
|
||||
ucthread[s->uthread_no].c_len = c_len;
|
||||
|
|
|
|||
Loading…
Reference in a new issue