Fix xor encryption for journal bundles and unaligned read/write ops

This commit is contained in:
Jeremy Lakeman 2013-07-19 16:15:05 +09:30
parent e808fb0872
commit 6dc5fde6b6
2 changed files with 41 additions and 37 deletions

View File

@ -585,9 +585,9 @@ int rhizome_crypt_xor_block(unsigned char *buffer, int buffer_size, int64_t stre
size=buffer_size; size=buffer_size;
unsigned char temp[RHIZOME_CRYPT_PAGE_SIZE]; unsigned char temp[RHIZOME_CRYPT_PAGE_SIZE];
bcopy(temp + padding, buffer, size);
crypto_stream_xsalsa20_xor(temp, temp, size, block_nonce, key);
bcopy(buffer, temp + padding, size); bcopy(buffer, temp + padding, size);
crypto_stream_xsalsa20_xor(temp, temp, size+padding, block_nonce, key);
bcopy(temp + padding, buffer, size);
add_nonce(block_nonce, RHIZOME_CRYPT_PAGE_SIZE); add_nonce(block_nonce, RHIZOME_CRYPT_PAGE_SIZE);
offset+=size; offset+=size;
@ -659,12 +659,12 @@ int rhizome_derive_key(rhizome_manifest *m, rhizome_bk_t *bsk)
bcopy(hash, m->payloadKey, RHIZOME_CRYPT_KEY_BYTES); bcopy(hash, m->payloadKey, RHIZOME_CRYPT_KEY_BYTES);
} }
// generate nonce from version#bundle id#version; // journal bundles must always have the same nonce, regardless of version.
// otherwise, generate nonce from version#bundle id#version;
unsigned char raw_nonce[8+8+sizeof(m->cryptoSignPublic)]; unsigned char raw_nonce[8+8+sizeof(m->cryptoSignPublic)];
write_uint64(&raw_nonce[0], m->journalTail>=0?0:m->version);
write_uint64(&raw_nonce[0], m->version);
bcopy(m->cryptoSignPublic, &raw_nonce[8], sizeof(m->cryptoSignPublic)); bcopy(m->cryptoSignPublic, &raw_nonce[8], sizeof(m->cryptoSignPublic));
write_uint64(&raw_nonce[8+sizeof(m->cryptoSignPublic)], m->version); write_uint64(&raw_nonce[8+sizeof(m->cryptoSignPublic)], m->journalTail>=0?0:m->version);
unsigned char hash[crypto_hash_sha512_BYTES]; unsigned char hash[crypto_hash_sha512_BYTES];

View File

@ -374,7 +374,6 @@ int rhizome_write_file(struct rhizome_write *write, const char *filename){
ret = WHY_perror("fread"); ret = WHY_perror("fread");
goto end; goto end;
} }
DEBUGF("Read %d from file", r);
if (rhizome_write_buffer(write, buffer, r)){ if (rhizome_write_buffer(write, buffer, r)){
ret=-1; ret=-1;
goto end; goto end;
@ -578,11 +577,17 @@ int rhizome_stat_file(rhizome_manifest *m, const char *filepath)
static int rhizome_write_derive_key(rhizome_manifest *m, rhizome_bk_t *bsk, struct rhizome_write *write) static int rhizome_write_derive_key(rhizome_manifest *m, rhizome_bk_t *bsk, struct rhizome_write *write)
{ {
write->crypt=1; if (!m->payloadEncryption)
return 0;
// if the manifest specifies encryption, make sure we can generate the payload key and encrypt the contents as we go // if the manifest specifies encryption, make sure we can generate the payload key and encrypt the contents as we go
if (rhizome_derive_key(m, bsk)) if (rhizome_derive_key(m, bsk))
return -1; return -1;
if (config.debug.rhizome)
DEBUGF("Encrypting payload contents");
write->crypt=1;
bcopy(m->payloadKey, write->key, sizeof(write->key)); bcopy(m->payloadKey, write->key, sizeof(write->key));
bcopy(m->payloadNonce, write->nonce, sizeof(write->nonce)); bcopy(m->payloadNonce, write->nonce, sizeof(write->nonce));
return 0; return 0;
@ -599,13 +604,9 @@ int rhizome_add_file(rhizome_manifest *m, const char *filepath)
if (rhizome_open_write(&write, NULL, m->fileLength, RHIZOME_PRIORITY_DEFAULT)) if (rhizome_open_write(&write, NULL, m->fileLength, RHIZOME_PRIORITY_DEFAULT))
return -1; return -1;
if (m->payloadEncryption){ if (rhizome_write_derive_key(m, NULL, &write))
if (rhizome_write_derive_key(m, NULL, &write)) return -1;
return -1;
if (config.debug.rhizome)
DEBUGF("Encrypting file contents");
}
if (rhizome_write_file(&write, filepath)){ if (rhizome_write_file(&write, filepath)){
rhizome_fail_write(&write); rhizome_fail_write(&write);
return -1; return -1;
@ -774,25 +775,29 @@ static int write_file(struct rhizome_read *read, const char *filepath){
return ret; return ret;
} }
static int read_derive_key(rhizome_manifest *m, rhizome_bk_t *bsk, struct rhizome_read *read_state){
read_state->crypt=m->payloadEncryption;
if (read_state->crypt){
// if the manifest specifies encryption, make sure we can generate the payload key and encrypt
// the contents as we go
if (rhizome_derive_key(m, bsk)) {
rhizome_read_close(read_state);
return WHY("Unable to decrypt bundle, valid key not found");
}
if (config.debug.rhizome)
DEBUGF("Decrypting file contents");
bcopy(m->payloadKey, read_state->key, sizeof(read_state->key));
bcopy(m->payloadNonce, read_state->nonce, sizeof(read_state->nonce));
}
return 0;
}
int rhizome_open_decrypt_read(rhizome_manifest *m, rhizome_bk_t *bsk, struct rhizome_read *read_state, int hash){ int rhizome_open_decrypt_read(rhizome_manifest *m, rhizome_bk_t *bsk, struct rhizome_read *read_state, int hash){
// for now, always hash the file // for now, always hash the file
int ret = rhizome_open_read(read_state, m->fileHexHash, hash); int ret = rhizome_open_read(read_state, m->fileHexHash, hash);
if (ret == 0) { if (ret == 0)
read_state->crypt=m->payloadEncryption; ret = read_derive_key(m, bsk, read_state);
if (read_state->crypt){
// if the manifest specifies encryption, make sure we can generate the payload key and encrypt
// the contents as we go
if (rhizome_derive_key(m, bsk)) {
rhizome_read_close(read_state);
return WHY("Unable to decrypt bundle, valid key not found");
}
if (config.debug.rhizome)
DEBUGF("Decrypting file contents");
bcopy(m->payloadKey, read_state->key, sizeof(read_state->key));
bcopy(m->payloadNonce, read_state->nonce, sizeof(read_state->nonce));
}
}
return ret; return ret;
} }
@ -849,7 +854,7 @@ static int rhizome_pipe(struct rhizome_read *read, struct rhizome_write *write,
return r; return r;
length -= r; length -= r;
DEBUGF("Piping %d bytes", r);
if (rhizome_write_buffer(write, buffer, r)) if (rhizome_write_buffer(write, buffer, r))
return -1; return -1;
} }
@ -885,7 +890,8 @@ int rhizome_write_open_journal(struct rhizome_write *write, rhizome_manifest *m,
if (copy_length>0){ if (copy_length>0){
struct rhizome_read read_state; struct rhizome_read read_state;
bzero(&read_state, sizeof read_state); bzero(&read_state, sizeof read_state);
ret = rhizome_open_decrypt_read(m, bsk, &read_state, 1); // don't bother to decrypt the existing journal payload
ret = rhizome_open_read(&read_state, m->fileHexHash, 1);
if (ret) if (ret)
goto failure; goto failure;
@ -896,11 +902,9 @@ int rhizome_write_open_journal(struct rhizome_write *write, rhizome_manifest *m,
goto failure; goto failure;
} }
if (m->payloadEncryption){ ret = rhizome_write_derive_key(m, bsk, write);
ret = rhizome_write_derive_key(m, bsk, write); if (ret)
if (ret) goto failure;
goto failure;
}
return 0; return 0;