diff --git a/lrzip.c b/lrzip.c index 621af5a..e0a515d 100644 --- a/lrzip.c +++ b/lrzip.c @@ -473,12 +473,14 @@ static void get_hash(rzip_control *control, int make_hash) testphrase = calloc(PASS_LEN, 1); control->hash = calloc(HASH_LEN, 1); control->hash_iv = calloc(SALT_LEN, 1); - if (unlikely(!passphrase || !testphrase || !control->hash || !control->hash_iv)) + control->rehash_iv = calloc(SALT_LEN, 1); + if (unlikely(!passphrase || !testphrase || !control->hash || !control->hash_iv || !control->rehash_iv)) fatal("Failed to calloc encrypt buffers in compress_file\n"); mlock(passphrase, PASS_LEN); mlock(testphrase, PASS_LEN); mlock(control->hash, HASH_LEN); mlock(control->hash_iv, SALT_LEN); + mlock(control->rehash_iv, SALT_LEN); /* Disable stdin echo to screen */ tcgetattr(fileno(stdin), &termios_p); @@ -516,6 +518,7 @@ retry_pass: control->hash_iv[j] = control->hash[j]; } } + memcpy(control->rehash_iv, control->hash_iv, SALT_LEN); memset(control->hash + SALT_LEN, 0, HASH_LEN - SALT_LEN); munlock(control->hash + SALT_LEN, HASH_LEN - SALT_LEN); @@ -527,6 +530,17 @@ retry_pass: free(passphrase); } +static void release_hashes(rzip_control *control) +{ + memset(control->hash, 0, SALT_LEN); + memset(control->hash_iv, 0, SALT_LEN); + memset(control->rehash_iv, 0, SALT_LEN); + munlockall(); + free(control->hash); + free(control->hash_iv); + free(control->rehash_iv); +} + /* decompress one file from the command line */ @@ -691,13 +705,8 @@ void decompress_file(rzip_control *control) fatal("Failed to unlink %s\n", infilecopy); } - if (ENCRYPT) { - memset(control->hash, 0, SALT_LEN); - memset(control->hash_iv, 0, SALT_LEN); - munlockall(); - free(control->hash); - free(control->hash_iv); - } + if (ENCRYPT) + release_hashes(control); free(control->outfile); free(infilecopy); @@ -1038,13 +1047,8 @@ void compress_file(rzip_control *control) if (!STDOUT) write_magic(control, fd_in, fd_out); - if (ENCRYPT) { - memset(control->hash, 0, SALT_LEN); - memset(control->hash_iv, 0, SALT_LEN); - munlockall(); - free(control->hash); - free(control->hash_iv); - } + if (ENCRYPT) + release_hashes(control); if (unlikely(close(fd_in))) fatal("Failed to close fd_in\n"); diff --git a/lrzip_private.h b/lrzip_private.h index 080d8a7..58d6e6f 100644 --- a/lrzip_private.h +++ b/lrzip_private.h @@ -203,6 +203,7 @@ struct rzip_control { uchar salt[16]; uchar *hash; uchar *hash_iv; + uchar *rehash_iv; aes_context aes_ctx; unsigned char eof; unsigned char magic_written; diff --git a/util.c b/util.c index 314b7f3..2fdce65 100644 --- a/util.c +++ b/util.c @@ -168,7 +168,10 @@ void lrz_crypt(rzip_control *control, uchar *buf, i64 len, int encrypt, int carr i64 N, M; mlock(ivec, CBC_LEN); - memcpy(ivec, control->hash_iv, CBC_LEN); + if (carry_iv) + memcpy(ivec, control->rehash_iv, CBC_LEN); + else + memcpy(ivec, control->hash_iv, CBC_LEN); M = len % CBC_LEN; N = len - M; @@ -204,9 +207,9 @@ void lrz_crypt(rzip_control *control, uchar *buf, i64 len, int encrypt, int carr ivec, buf, buf); } /* The carry_iv flag tells us if we want to update the value in - * control->hash_iv for later encryption */ + * control->rehash_iv for later encryption */ if (carry_iv) - memcpy(control->hash_iv, ivec, CBC_LEN); + memcpy(control->rehash_iv, ivec, CBC_LEN); memset(ivec, 0, CBC_LEN); munlock(ivec, CBC_LEN); } \ No newline at end of file