Skip to content

Commit

Permalink
make memory deallocation less lazy; ...
Browse files Browse the repository at this point in the history
 * Make memory deallocation less lazy by cleaning up as much as possible
   on both normal and error paths. There is no strict requirement to do
   this as the memory will be properly cleaned up eventually anyway, but
   it does reduce the memory footprint.

 * Add first part of the backup header logic. Now backup headers are
   generated on volume creation, but not yet written.
  • Loading branch information
bwalex committed Jul 22, 2011
1 parent 92f96b8 commit 8e1782a
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 59 deletions.
31 changes: 29 additions & 2 deletions crypto.c
Expand Up @@ -88,13 +88,29 @@ tc_cipher_chain_populate_keys(struct tc_cipher_chain *cipher_chain,
return 0;
}

int
tc_cipher_chain_free_keys(struct tc_cipher_chain *cipher_chain)
{
for (; cipher_chain != NULL; cipher_chain = cipher_chain->next) {
if (cipher_chain->key != NULL) {
free_safe_mem(cipher_chain->key);
cipher_chain->key = NULL;
}
}

return 0;
}

int
tc_encrypt(struct tc_cipher_chain *cipher_chain, unsigned char *key,
unsigned char *iv,
unsigned char *in, int in_len, unsigned char *out)
{
struct tc_cipher_chain *chain_start;
int err;

chain_start = cipher_chain;

if ((err = tc_cipher_chain_populate_keys(cipher_chain, key)))
return err;

Expand All @@ -119,13 +135,17 @@ tc_encrypt(struct tc_cipher_chain *cipher_chain, unsigned char *key,
/* Deallocate this key, since we won't need it anymore */
free_safe_mem(cipher_chain->key);

if (err != 0)
if (err != 0) {
tc_cipher_chain_free_keys(chain_start);
return err;
}

/* Set next input buffer as current output buffer */
in = out;
}

tc_cipher_chain_free_keys(chain_start);

return 0;
}

Expand All @@ -134,8 +154,11 @@ tc_decrypt(struct tc_cipher_chain *cipher_chain, unsigned char *key,
unsigned char *iv,
unsigned char *in, int in_len, unsigned char *out)
{
struct tc_cipher_chain *chain_start;
int err;

chain_start = cipher_chain;

if ((err = tc_cipher_chain_populate_keys(cipher_chain, key)))
return err;

Expand Down Expand Up @@ -163,13 +186,17 @@ tc_decrypt(struct tc_cipher_chain *cipher_chain, unsigned char *key,
/* Deallocate this key, since we won't need it anymore */
free_safe_mem(cipher_chain->key);

if (err != 0)
if (err != 0) {
tc_cipher_chain_free_keys(chain_start);
return err;
}

/* Set next input buffer as current output buffer */
in = out;
}

tc_cipher_chain_free_keys(chain_start);

return 0;
}

Expand Down
85 changes: 74 additions & 11 deletions hdr.c
Expand Up @@ -128,47 +128,79 @@ struct tchdr_enc *
create_hdr(unsigned char *pass, int passlen, struct pbkdf_prf_algo *prf_algo,
struct tc_cipher_chain *cipher_chain, size_t sec_sz,
size_t total_blocks __unused,
off_t offset, size_t blocks, int hidden)
off_t offset, size_t blocks, int hidden, struct tchdr_enc **backup_hdr)
{
struct tchdr_enc *ehdr;
struct tchdr_enc *ehdr, *ehdr_backup;
struct tchdr_dec *dhdr;
unsigned char *key;
unsigned char *key, *key_backup;
unsigned char iv[128];
int error;

key = key_backup = NULL;
dhdr = NULL;
ehdr = ehdr_backup = NULL;

if (backup_hdr != NULL)
*backup_hdr = NULL;

if ((dhdr = (struct tchdr_dec *)alloc_safe_mem(sizeof(*dhdr))) == NULL) {
tc_log(1, "could not allocate safe dhdr memory\n");
return NULL;
goto error;
}

if ((ehdr = (struct tchdr_enc *)alloc_safe_mem(sizeof(*ehdr))) == NULL) {
tc_log(1, "could not allocate safe ehdr memory\n");
return NULL;
goto error;
}

if ((ehdr_backup = (struct tchdr_enc *)alloc_safe_mem
(sizeof(*ehdr_backup))) == NULL) {
tc_log(1, "could not allocate safe ehdr_backup memory\n");
goto error;
}

if ((key = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
tc_log(1, "could not allocate safe key memory\n");
return NULL;
goto error;
}

if ((key_backup = alloc_safe_mem(MAX_KEYSZ)) == NULL) {
tc_log(1, "could not allocate safe backup key memory\n");
goto error;
}

if ((error = get_random(ehdr->salt, sizeof(ehdr->salt))) != 0) {
tc_log(1, "could not get salt\n");
return NULL;
goto error;
}

if ((error = get_random(ehdr_backup->salt, sizeof(ehdr_backup->salt)))
!= 0) {
tc_log(1, "could not get salt for backup header\n");
goto error;
}

error = pbkdf2(prf_algo, (char *)pass, passlen,
ehdr->salt, sizeof(ehdr->salt),
MAX_KEYSZ, key);
if (error) {
tc_log(1, "could not derive key\n");
return NULL;
goto error;
}

error = pbkdf2(prf_algo, (char *)pass, passlen,
ehdr_backup->salt, sizeof(ehdr_backup->salt),
MAX_KEYSZ, key_backup);
if (error) {
tc_log(1, "could not derive backup key\n");
goto error;
}

memset(dhdr, 0, sizeof(*dhdr));

if ((error = get_random(dhdr->keys, sizeof(dhdr->keys))) != 0) {
tc_log(1, "could not get key random bits\n");
return NULL;
goto error;
}

memcpy(dhdr->tc_str, "TRUE", 4);
Expand Down Expand Up @@ -201,10 +233,41 @@ create_hdr(unsigned char *pass, int passlen, struct pbkdf_prf_algo *prf_algo,
sizeof(struct tchdr_dec), ehdr->enc);
if (error) {
tc_log(1, "Header encryption failed\n");
free_safe_mem(dhdr);
return NULL;
goto error;
}

memset(iv, 0, sizeof(iv));
error = tc_encrypt(cipher_chain, key_backup, iv,
(unsigned char *)dhdr,
sizeof(struct tchdr_dec), ehdr_backup->enc);
if (error) {
tc_log(1, "Backup header encryption failed\n");
goto error;
}

free_safe_mem(key);
free_safe_mem(key_backup);
free_safe_mem(dhdr);

if (backup_hdr != NULL)
*backup_hdr = ehdr_backup;
else
free_safe_mem(ehdr_backup);

return ehdr;
/* NOT REACHED */

error:
if (key)
free_safe_mem(key);
if (key_backup)
free_safe_mem(key_backup);
if (dhdr)
free_safe_mem(dhdr);
if (ehdr)
free_safe_mem(ehdr);
if (ehdr_backup)
free_safe_mem(ehdr_backup);

return NULL;
}
3 changes: 2 additions & 1 deletion io.c
Expand Up @@ -126,7 +126,8 @@ get_random(unsigned char *buf, size_t len)
sz = (len - rd);

if ((r = read(fd, buf+rd, sz)) < 0) {
tc_log(1, "Error reading from /dev/random\n");
tc_log(1, "Error reading from /dev/random(%d): %s\n",
fd, strerror(errno));
close(fd);
summary_fn = NULL;
return -1;
Expand Down

0 comments on commit 8e1782a

Please sign in to comment.