mirror of
https://github.com/ckolivas/lrzip.git
synced 2026-01-20 15:20:15 +01:00
lrz_crypt tweaks courtesy of Serge Belyshev.
This commit is contained in:
parent
95f8b9fd90
commit
8c8f5bdd48
20
lrzip.c
20
lrzip.c
|
|
@ -433,7 +433,7 @@ void close_tmpinbuf(rzip_control *control)
|
|||
free(control->tmp_inbuf);
|
||||
}
|
||||
|
||||
static void get_pass(char *s)
|
||||
static int get_pass(char *s)
|
||||
{
|
||||
int len;
|
||||
|
||||
|
|
@ -448,6 +448,7 @@ static void get_pass(char *s)
|
|||
len = strlen(s);
|
||||
if (unlikely(0 == len))
|
||||
failure("Empty passphrase\n");
|
||||
return len;
|
||||
}
|
||||
|
||||
static void get_hash(rzip_control *control, int make_hash)
|
||||
|
|
@ -459,13 +460,13 @@ static void get_hash(rzip_control *control, int make_hash)
|
|||
|
||||
passphrase = calloc(PASS_LEN, 1);
|
||||
testphrase = calloc(PASS_LEN, 1);
|
||||
control->pass_hash = calloc(HASH_LEN, 1);
|
||||
control->salt_pass = calloc(PASS_LEN, 1);
|
||||
control->hash = calloc(HASH_LEN, 1);
|
||||
if (unlikely(!passphrase || !testphrase || !control->pass_hash || !control->hash))
|
||||
if (unlikely(!passphrase || !testphrase || !control->salt_pass || !control->hash))
|
||||
fatal("Failed to calloc encrypt buffers in compress_file\n");
|
||||
mlock(passphrase, PASS_LEN);
|
||||
mlock(testphrase, PASS_LEN);
|
||||
mlock(control->pass_hash, HASH_LEN);
|
||||
mlock(control->salt_pass, PASS_LEN);
|
||||
mlock(control->hash, HASH_LEN);
|
||||
|
||||
/* Disable stdin echo to screen */
|
||||
|
|
@ -474,7 +475,7 @@ static void get_hash(rzip_control *control, int make_hash)
|
|||
tcsetattr(fileno(stdin), 0, &termios_p);
|
||||
retry_pass:
|
||||
print_output("Enter passphrase: ");
|
||||
get_pass(passphrase);
|
||||
control->salt_pass_len = get_pass(passphrase) + SALT_LEN;
|
||||
print_output("\n");
|
||||
if (make_hash) {
|
||||
print_output("Re-enter passphrase: ");
|
||||
|
|
@ -491,8 +492,9 @@ retry_pass:
|
|||
munlock(testphrase, PASS_LEN);
|
||||
free(testphrase);
|
||||
|
||||
memcpy(passphrase + PASS_LEN - SALT_LEN, control->salt, SALT_LEN);
|
||||
lrz_keygen(control, passphrase);
|
||||
memcpy(control->salt_pass, control->salt, SALT_LEN);
|
||||
memcpy(control->salt_pass + SALT_LEN, passphrase, PASS_LEN - SALT_LEN);
|
||||
lrz_stretch(control);
|
||||
memset(passphrase, 0, PASS_LEN);
|
||||
munlock(passphrase, PASS_LEN);
|
||||
free(passphrase);
|
||||
|
|
@ -500,10 +502,10 @@ retry_pass:
|
|||
|
||||
static void release_hashes(rzip_control *control)
|
||||
{
|
||||
memset(control->pass_hash, 0, HASH_LEN);
|
||||
memset(control->salt_pass, 0, PASS_LEN);
|
||||
memset(control->hash, 0, SALT_LEN);
|
||||
munlockall();
|
||||
free(control->pass_hash);
|
||||
free(control->salt_pass);
|
||||
free(control->hash);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -199,8 +199,9 @@ struct rzip_control {
|
|||
int fd_hist;
|
||||
i64 encloops;
|
||||
i64 secs;
|
||||
uchar salt[16];
|
||||
uchar *pass_hash;
|
||||
uchar salt[8];
|
||||
uchar *salt_pass;
|
||||
int salt_pass_len;
|
||||
uchar *hash;
|
||||
unsigned char eof;
|
||||
unsigned char magic_written;
|
||||
|
|
|
|||
2
runzip.c
2
runzip.c
|
|
@ -377,7 +377,7 @@ 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)
|
||||
lrz_decrypt(control, md5_stored, MD5_DIGEST_SIZE, control->pass_hash);
|
||||
lrz_decrypt(control, md5_stored, MD5_DIGEST_SIZE, control->salt_pass);
|
||||
for (i = 0; i < MD5_DIGEST_SIZE; i++)
|
||||
if (md5_stored[i] != md5_resblock[i]) {
|
||||
print_output("MD5 CHECK FAILED.\nStored:");
|
||||
|
|
|
|||
2
rzip.c
2
rzip.c
|
|
@ -987,7 +987,7 @@ retry:
|
|||
}
|
||||
/* When encrypting data, we encrypt the MD5 value as well */
|
||||
if (ENCRYPT)
|
||||
lrz_encrypt(control, md5_resblock, MD5_DIGEST_SIZE, control->pass_hash);
|
||||
lrz_encrypt(control, md5_resblock, MD5_DIGEST_SIZE, control->salt_pass);
|
||||
if (unlikely(write_1g(control, md5_resblock, MD5_DIGEST_SIZE) != MD5_DIGEST_SIZE))
|
||||
fatal("Failed to write md5 in rzip_fd\n");
|
||||
|
||||
|
|
|
|||
81
util.c
81
util.c
|
|
@ -52,12 +52,10 @@
|
|||
#include <fcntl.h>
|
||||
#include "lrzip_private.h"
|
||||
#include "liblrzip.h"
|
||||
#include "util.h"
|
||||
#include "sha4.h"
|
||||
#include "aes.h"
|
||||
|
||||
#define LRZ_DECRYPT (0)
|
||||
#define LRZ_ENCRYPT (1)
|
||||
|
||||
static const char *infile = NULL;
|
||||
static char delete_infile = 0;
|
||||
static const char *outfile = NULL;
|
||||
|
|
@ -166,11 +164,30 @@ static void xor128 (void *pa, const void *pb)
|
|||
a [1] ^= b [1];
|
||||
}
|
||||
|
||||
static void lrz_crypt(rzip_control *control, uchar *buf, i64 len, uchar *salt, int encrypt)
|
||||
static void lrz_keygen(const rzip_control *control, const uchar *salt, uchar *key, uchar *iv)
|
||||
{
|
||||
uchar buf [HASH_LEN + SALT_LEN + PASS_LEN];
|
||||
mlock(buf, HASH_LEN + SALT_LEN + PASS_LEN);
|
||||
|
||||
memcpy(buf, control->hash, HASH_LEN);
|
||||
memcpy(buf + HASH_LEN, salt, SALT_LEN);
|
||||
memcpy(buf + HASH_LEN + SALT_LEN, control->salt_pass, control->salt_pass_len);
|
||||
sha4(buf, HASH_LEN + SALT_LEN + control->salt_pass_len, key, 0);
|
||||
|
||||
memcpy(buf, key, HASH_LEN);
|
||||
memcpy(buf + HASH_LEN, salt, SALT_LEN);
|
||||
memcpy(buf + HASH_LEN + SALT_LEN, control->salt_pass, control->salt_pass_len);
|
||||
sha4(buf, HASH_LEN + SALT_LEN + control->salt_pass_len, iv, 0);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
munlock(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void lrz_crypt(const rzip_control *control, uchar *buf, i64 len, const uchar *salt, int encrypt)
|
||||
{
|
||||
/* Encryption requires CBC_LEN blocks so we can use ciphertext
|
||||
* stealing to not have to pad the block */
|
||||
uchar key[HASH_LEN + SALT_LEN], iv[HASH_LEN + SALT_LEN];
|
||||
uchar key[HASH_LEN], iv[HASH_LEN];
|
||||
uchar tmp0[CBC_LEN], tmp1[CBC_LEN];
|
||||
aes_context aes_ctx;
|
||||
i64 N, M;
|
||||
|
|
@ -178,16 +195,10 @@ static void lrz_crypt(rzip_control *control, uchar *buf, i64 len, uchar *salt, i
|
|||
|
||||
/* Generate unique key and IV for each block of data based on salt */
|
||||
mlock(&aes_ctx, sizeof(aes_ctx));
|
||||
mlock(key, HASH_LEN + SALT_LEN);
|
||||
mlock(iv, HASH_LEN + SALT_LEN);
|
||||
for (i = 0; i < HASH_LEN; i++)
|
||||
key[i] = control->pass_hash[i] ^ control->hash[i];
|
||||
memcpy(key + HASH_LEN, salt, SALT_LEN);
|
||||
sha4(key, HASH_LEN + SALT_LEN, key, 0);
|
||||
for (i = 0; i < HASH_LEN; i++)
|
||||
iv[i] = key[i] ^ control->pass_hash[i];
|
||||
memcpy(iv + HASH_LEN, salt, SALT_LEN);
|
||||
sha4(iv, HASH_LEN + SALT_LEN, iv, 0);
|
||||
mlock(key, HASH_LEN);
|
||||
mlock(iv, HASH_LEN);
|
||||
|
||||
lrz_keygen(control, salt, key, iv);
|
||||
|
||||
M = len % CBC_LEN;
|
||||
N = len - M;
|
||||
|
|
@ -229,33 +240,29 @@ static void lrz_crypt(rzip_control *control, uchar *buf, i64 len, uchar *salt, i
|
|||
}
|
||||
|
||||
memset(&aes_ctx, 0, sizeof(aes_ctx));
|
||||
memset(iv, 0, HASH_LEN + SALT_LEN);
|
||||
memset(key, 0, HASH_LEN + SALT_LEN);
|
||||
memset(iv, 0, HASH_LEN);
|
||||
memset(key, 0, HASH_LEN);
|
||||
munlock(&aes_ctx, sizeof(aes_ctx));
|
||||
munlock(iv, HASH_LEN + SALT_LEN);
|
||||
munlock(key, HASH_LEN + SALT_LEN);
|
||||
munlock(iv, HASH_LEN);
|
||||
munlock(key, HASH_LEN);
|
||||
}
|
||||
|
||||
inline void lrz_encrypt(rzip_control *control, uchar *buf, i64 len, uchar *salt)
|
||||
void lrz_stretch(rzip_control *control)
|
||||
{
|
||||
lrz_crypt(control, buf, len, salt, LRZ_ENCRYPT);
|
||||
}
|
||||
sha4_context ctx;
|
||||
i64 j, n, counter;
|
||||
|
||||
inline void lrz_decrypt(rzip_control *control, uchar *buf, i64 len, uchar *salt)
|
||||
{
|
||||
lrz_crypt(control, buf, len, salt, LRZ_DECRYPT);
|
||||
}
|
||||
mlock(&ctx, sizeof(ctx));
|
||||
sha4_starts(&ctx, 0);
|
||||
|
||||
void lrz_keygen(rzip_control *control, const uchar *passphrase)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
sha4(passphrase, PASS_LEN, control->pass_hash, 0);
|
||||
|
||||
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] ^= control->pass_hash[j];
|
||||
sha4(control->hash, HASH_LEN, control->hash, 0);
|
||||
n = control->encloops * HASH_LEN / (control->salt_pass_len + sizeof(i64));
|
||||
print_maxverbose("Hashing passphrase %lld (%lld) times \n", control->encloops, n);
|
||||
for (j = 0; j < n; j ++) {
|
||||
counter = htole64(j);
|
||||
sha4_update(&ctx, (uchar *)&counter, sizeof(counter));
|
||||
sha4_update(&ctx, control->salt_pass, control->salt_pass_len);
|
||||
}
|
||||
sha4_finish(&ctx, control->hash);
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
munlock(&ctx, sizeof(ctx));
|
||||
}
|
||||
|
|
|
|||
19
util.h
19
util.h
|
|
@ -29,8 +29,21 @@ void fatal(const char *format, ...);
|
|||
void failure(const char *format, ...);
|
||||
void round_to_page(i64 *size);
|
||||
void get_rand(uchar *buf, int len);
|
||||
inline void lrz_encrypt(rzip_control *control, uchar *buf, i64 len, uchar *salt);
|
||||
inline void lrz_decrypt(rzip_control *control, uchar *buf, i64 len, uchar *salt);
|
||||
void lrz_keygen(rzip_control *control, const uchar *passphrase);
|
||||
void lrz_stretch(rzip_control *control);
|
||||
void lrz_stretch2(rzip_control *control);
|
||||
void lrz_crypt(const rzip_control *control, uchar *buf, i64 len, const uchar *salt, int encrypt);
|
||||
|
||||
#define LRZ_DECRYPT (0)
|
||||
#define LRZ_ENCRYPT (1)
|
||||
|
||||
static void lrz_encrypt(const rzip_control *control, uchar *buf, i64 len, const uchar *salt)
|
||||
{
|
||||
lrz_crypt(control, buf, len, salt, LRZ_ENCRYPT);
|
||||
}
|
||||
|
||||
static void lrz_decrypt(const rzip_control *control, uchar *buf, i64 len, const uchar *salt)
|
||||
{
|
||||
lrz_crypt(control, buf, len, salt, LRZ_DECRYPT);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue