From 6dc5fde6b6fc58b31580dbe4591307ec324809f2 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Fri, 19 Jul 2013 16:15:05 +0930 Subject: [PATCH] Fix xor encryption for journal bundles and unaligned read/write ops --- rhizome_crypto.c | 12 ++++----- rhizome_store.c | 66 +++++++++++++++++++++++++----------------------- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/rhizome_crypto.c b/rhizome_crypto.c index 8c7e8c5a..4908e5fd 100644 --- a/rhizome_crypto.c +++ b/rhizome_crypto.c @@ -585,9 +585,9 @@ int rhizome_crypt_xor_block(unsigned char *buffer, int buffer_size, int64_t stre size=buffer_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); + crypto_stream_xsalsa20_xor(temp, temp, size+padding, block_nonce, key); + bcopy(temp + padding, buffer, size); add_nonce(block_nonce, RHIZOME_CRYPT_PAGE_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); } - // 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)]; - - write_uint64(&raw_nonce[0], m->version); + write_uint64(&raw_nonce[0], m->journalTail>=0?0:m->version); 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]; diff --git a/rhizome_store.c b/rhizome_store.c index 0c81ef68..42dccb27 100644 --- a/rhizome_store.c +++ b/rhizome_store.c @@ -374,7 +374,6 @@ int rhizome_write_file(struct rhizome_write *write, const char *filename){ ret = WHY_perror("fread"); goto end; } - DEBUGF("Read %d from file", r); if (rhizome_write_buffer(write, buffer, r)){ ret=-1; 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) { - 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 (rhizome_derive_key(m, bsk)) return -1; + if (config.debug.rhizome) + DEBUGF("Encrypting payload contents"); + + write->crypt=1; bcopy(m->payloadKey, write->key, sizeof(write->key)); bcopy(m->payloadNonce, write->nonce, sizeof(write->nonce)); 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)) return -1; - if (m->payloadEncryption){ - if (rhizome_write_derive_key(m, NULL, &write)) - return -1; - - if (config.debug.rhizome) - DEBUGF("Encrypting file contents"); - } + if (rhizome_write_derive_key(m, NULL, &write)) + return -1; + if (rhizome_write_file(&write, filepath)){ rhizome_fail_write(&write); return -1; @@ -774,25 +775,29 @@ static int write_file(struct rhizome_read *read, const char *filepath){ 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){ // for now, always hash the file int ret = rhizome_open_read(read_state, m->fileHexHash, hash); - if (ret == 0) { - 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)); - } - } + if (ret == 0) + ret = read_derive_key(m, bsk, read_state); return ret; } @@ -849,7 +854,7 @@ static int rhizome_pipe(struct rhizome_read *read, struct rhizome_write *write, return r; length -= r; - DEBUGF("Piping %d bytes", r); + if (rhizome_write_buffer(write, buffer, r)) return -1; } @@ -885,7 +890,8 @@ int rhizome_write_open_journal(struct rhizome_write *write, rhizome_manifest *m, if (copy_length>0){ struct rhizome_read 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) goto failure; @@ -896,11 +902,9 @@ int rhizome_write_open_journal(struct rhizome_write *write, rhizome_manifest *m, goto failure; } - if (m->payloadEncryption){ - ret = rhizome_write_derive_key(m, bsk, write); - if (ret) - goto failure; - } + ret = rhizome_write_derive_key(m, bsk, write); + if (ret) + goto failure; return 0;