diff --git a/runzip.c b/runzip.c index 26abae1..20d7f78 100644 --- a/runzip.c +++ b/runzip.c @@ -376,17 +376,8 @@ i64 runzip_fd(rzip_control *control, int fd_in, int fd_out, int fd_hist, i64 exp if (unlikely(read_1g(control, fd_in, md5_stored, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) fatal("Failed to read md5 data in runzip_fd\n"); - if (ENCRYPT) { - /* Even the MD5 value is stored encrypted */ - uchar *dec_buf = malloc(MD5_DIGEST_SIZE); - - if (unlikely(aes_crypt_cbc(&control->aes_ctx, AES_DECRYPT, - MD5_DIGEST_SIZE, control->hash_iv, md5_stored, dec_buf))) - failure("Failed to aes_crypt_cbc in runzip_fd\n"); - for (i = 0; i < MD5_DIGEST_SIZE; i++) - md5_stored[i] = dec_buf[i]; - free(dec_buf); - } + if (ENCRYPT) + lrz_crypt(control, md5_stored, MD5_DIGEST_SIZE, 0, 1); for (i = 0; i < MD5_DIGEST_SIZE; i++) if (md5_stored[i] != md5_resblock[i]) { print_output("MD5 CHECK FAILED.\nStored:"); diff --git a/rzip.c b/rzip.c index 8a69940..c9e031f 100644 --- a/rzip.c +++ b/rzip.c @@ -976,19 +976,10 @@ retry: print_output("%02x", md5_resblock[j] & 0xFF); print_output("\n"); } - if (ENCRYPT) { - /* When encrypting data, we encrypt the MD5 value as well */ - uchar *enc_buf = malloc(MD5_DIGEST_SIZE); - - if (unlikely(!enc_buf)) - fatal("Failed to malloc enc_buf in rzip_fd\n"); - if (unlikely(aes_crypt_cbc(&control->aes_ctx, AES_ENCRYPT, - MD5_DIGEST_SIZE, control->hash_iv, md5_resblock, enc_buf))) - failure("Failed to aes_crypt_cbc in rzip_fd\n"); - if (unlikely(write_1g(control, enc_buf, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) - fatal("Failed to write encrypted md5 in rzip_fd\n"); - free(enc_buf); - } else if (unlikely(write_1g(control, md5_resblock, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) + /* When encrypting data, we encrypt the MD5 value as well */ + if (ENCRYPT) + lrz_crypt(control, md5_resblock, MD5_DIGEST_SIZE, 1, 1); + if (unlikely(write_1g(control, md5_resblock, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE)) fatal("Failed to write md5 in rzip_fd\n"); if (TMP_OUTBUF) diff --git a/stream.c b/stream.c index 17d12bd..9611e86 100644 --- a/stream.c +++ b/stream.c @@ -1183,32 +1183,8 @@ retry: get_rand(cti->s_buf + cti->c_len, MIN_SIZE - cti->c_len); } - if (!ret && ENCRYPT) { - /* Encryption requires CBC_LEN blocks so we can use ciphertext - * stealing to not have to pad the block */ - unsigned char ivec[CBC_LEN], tmp0[CBC_LEN], tmp1[CBC_LEN]; - i64 N, M; - - mlock(ivec, CBC_LEN); - memcpy(ivec, control->hash_iv, CBC_LEN); - M = padded_len % CBC_LEN; - N = padded_len - M; - - print_maxverbose("Encrypting block \n"); - aes_crypt_cbc(&control->aes_ctx, AES_ENCRYPT, N, ivec, - cti->s_buf, cti->s_buf); - - if (M) { - memset(tmp0, 0, sizeof(tmp0)); - memcpy(tmp0, cti->s_buf + N, M); - aes_crypt_cbc(&control->aes_ctx, AES_ENCRYPT, CBC_LEN, - ivec, tmp0, tmp1); - memcpy(cti->s_buf + N, cti->s_buf + N - CBC_LEN, M); - memcpy(cti->s_buf + N - CBC_LEN, tmp1, CBC_LEN); - } - memset(ivec, 0, CBC_LEN); - munlock(ivec, CBC_LEN); - } + if (!ret && ENCRYPT) + lrz_crypt(control, cti->s_buf, padded_len, 1, 0); /* If compression fails for whatever reason multithreaded, then wait * for the previous thread to finish, serialising the work to decrease @@ -1397,15 +1373,6 @@ retry: return 0; } -static void xor128 (void *pa, const void *pb) -{ - i64 *a = pa; - const i64 *b = pb; - - a [0] ^= b [0]; - a [1] ^= b [1]; -} - /* fill a buffer from a stream - return -1 on failure */ static int fill_buffer(rzip_control *control, struct stream_info *sinfo, int streamno) { @@ -1463,35 +1430,8 @@ fill_another: if (unlikely(read_buf(control, sinfo->fd, s_buf, padded_len))) return -1; - if (ENCRYPT) { - unsigned char ivec[CBC_LEN], tmp0[CBC_LEN], tmp1[CBC_LEN]; - i64 N, M; - - mlock(ivec, CBC_LEN); - memcpy(ivec, control->hash_iv, CBC_LEN); - M = padded_len % CBC_LEN; - N = padded_len - M; - - print_maxverbose("Decrypting block \n"); - if (M) { - aes_crypt_cbc(&control->aes_ctx, AES_DECRYPT, N - CBC_LEN, - ivec, s_buf, s_buf); - aes_crypt_ecb(&control->aes_ctx, AES_DECRYPT, - s_buf + N - CBC_LEN, tmp0); - memset(tmp1, 0, CBC_LEN); - memcpy(tmp1, s_buf + N, M); - xor128(tmp0, tmp1); - memcpy(s_buf + N, tmp0, M); - memcpy(tmp1 + M, tmp0 + M, CBC_LEN - M); - aes_crypt_ecb(&control->aes_ctx, AES_DECRYPT, tmp1, - s_buf + N - CBC_LEN); - xor128(s_buf + N - CBC_LEN, ivec); - } else - aes_crypt_cbc(&control->aes_ctx, AES_DECRYPT, padded_len, - ivec, s_buf, s_buf); - memset(ivec, 0, CBC_LEN); - munlock(ivec, CBC_LEN); - } + if (ENCRYPT) + lrz_crypt(control, s_buf, padded_len, 0, 0); ucthread[s->uthread_no].s_buf = s_buf; ucthread[s->uthread_no].c_len = c_len; diff --git a/util.c b/util.c index 12c3ad3..314b7f3 100644 --- a/util.c +++ b/util.c @@ -150,3 +150,63 @@ void get_rand(uchar *buf, int len) fatal("Failed to close fd in get_rand\n"); } } + +static void xor128 (void *pa, const void *pb) +{ + i64 *a = pa; + const i64 *b = pb; + + a [0] ^= b [0]; + a [1] ^= b [1]; +} + +void lrz_crypt(rzip_control *control, uchar *buf, i64 len, int encrypt, int carry_iv) +{ + /* Encryption requires CBC_LEN blocks so we can use ciphertext + * stealing to not have to pad the block */ + unsigned char ivec[CBC_LEN], tmp0[CBC_LEN], tmp1[CBC_LEN]; + i64 N, M; + + mlock(ivec, CBC_LEN); + memcpy(ivec, control->hash_iv, CBC_LEN); + M = len % CBC_LEN; + N = len - M; + + if (encrypt) { + print_maxverbose("Encrypting data \n"); + aes_crypt_cbc(&control->aes_ctx, AES_ENCRYPT, N, ivec, buf, buf); + + if (M) { + memset(tmp0, 0, sizeof(tmp0)); + memcpy(tmp0, buf + N, M); + aes_crypt_cbc(&control->aes_ctx, AES_ENCRYPT, CBC_LEN, + ivec, tmp0, tmp1); + memcpy(buf + N, buf + N - CBC_LEN, M); + memcpy(buf + N - CBC_LEN, tmp1, CBC_LEN); + } + } else { + print_maxverbose("Decrypting data \n"); + if (M) { + aes_crypt_cbc(&control->aes_ctx, AES_DECRYPT, N - CBC_LEN, + ivec, buf, buf); + aes_crypt_ecb(&control->aes_ctx, AES_DECRYPT, + buf + N - CBC_LEN, tmp0); + memset(tmp1, 0, CBC_LEN); + memcpy(tmp1, buf + N, M); + xor128(tmp0, tmp1); + memcpy(buf + N, tmp0, M); + memcpy(tmp1 + M, tmp0 + M, CBC_LEN - M); + aes_crypt_ecb(&control->aes_ctx, AES_DECRYPT, tmp1, + buf + N - CBC_LEN); + xor128(buf + N - CBC_LEN, ivec); + } else + aes_crypt_cbc(&control->aes_ctx, AES_DECRYPT, len, + ivec, buf, buf); + } + /* The carry_iv flag tells us if we want to update the value in + * control->hash_iv for later encryption */ + if (carry_iv) + memcpy(control->hash_iv, ivec, CBC_LEN); + memset(ivec, 0, CBC_LEN); + munlock(ivec, CBC_LEN); +} \ No newline at end of file diff --git a/util.h b/util.h index 222d81d..c6c75f3 100644 --- a/util.h +++ b/util.h @@ -29,5 +29,6 @@ void fatal(const char *format, ...); void failure(const char *format, ...); void round_to_page(i64 *size); void get_rand(uchar *buf, int len); +void lrz_crypt(rzip_control *control, uchar *buf, i64 len, int encrypt, int carry_iv); #endif