diff --git a/rhizome.h b/rhizome.h index ad4a6589..6c679769 100644 --- a/rhizome.h +++ b/rhizome.h @@ -608,7 +608,6 @@ struct rhizome_write{ int crypt; unsigned char key[RHIZOME_CRYPT_KEY_BYTES]; - // note the last 8 bytes will be reset with the current file_offest unsigned char nonce[crypto_stream_xsalsa20_NONCEBYTES]; SHA512_CTX sha512_context; @@ -620,7 +619,6 @@ struct rhizome_read{ int crypt; unsigned char key[RHIZOME_CRYPT_KEY_BYTES]; - // note the last 8 bytes will be reset with the current file_offest unsigned char nonce[crypto_stream_xsalsa20_NONCEBYTES]; int hash; @@ -642,7 +640,7 @@ int rhizome_import_file(rhizome_manifest *m, const char *filepath); int rhizome_stat_file(rhizome_manifest *m, const char *filepath); int rhizome_add_file(rhizome_manifest *m, const char *filepath); int rhizome_crypt_xor_block(unsigned char *buffer, int buffer_size, int64_t stream_offset, - const unsigned char *key, unsigned char *nonce); + const unsigned char *key, const unsigned char *nonce); int rhizome_open_read(struct rhizome_read *read, const char *fileid, int hash); int rhizome_read(struct rhizome_read *read, unsigned char *buffer, int buffer_length); int rhizome_extract_file(rhizome_manifest *m, const char *filepath); diff --git a/rhizome_crypto.c b/rhizome_crypto.c index c9e27751..42d61321 100644 --- a/rhizome_crypto.c +++ b/rhizome_crypto.c @@ -502,13 +502,31 @@ int rhizome_manifest_extract_signature(rhizome_manifest *m,int *ofs) RETURN(0); } +// add value to nonce, with the same result regardless of CPU endian order +// allowing for any carry value up to the size of the whole nonce +static void add_nonce(unsigned char *nonce, int64_t value){ + int i=crypto_stream_xsalsa20_NONCEBYTES -1; + while(i>=0 && value>0){ + int x = nonce[i]+(value & 0xFF); + nonce[i]=x&0xFF; + value = (value>>8)+(x>>8); + i--; + } +} + +/* crypt a block of a stream, allowing for offsets that don't align perfectly to block boundaries + * for efficiency the caller should use a buffer size of (n*RHIZOME_CRYPT_PAGE_SIZE) + */ int rhizome_crypt_xor_block(unsigned char *buffer, int buffer_size, int64_t stream_offset, - const unsigned char *key, unsigned char *nonce){ + const unsigned char *key, const unsigned char *nonce){ int64_t nonce_offset = stream_offset & ~(RHIZOME_CRYPT_PAGE_SIZE -1); int offset=0; + unsigned char block_nonce[crypto_stream_xsalsa20_NONCEBYTES]; + bcopy(nonce, block_nonce, sizeof(block_nonce)); + add_nonce(block_nonce, nonce_offset); + if (nonce_offset < stream_offset){ - int i; for(i=0;i<8;i++) nonce[i]=(nonce_offset>>(i*8))&0xff; int padding = stream_offset & (RHIZOME_CRYPT_PAGE_SIZE -1); int size = RHIZOME_CRYPT_PAGE_SIZE - padding; if (size>buffer_size) @@ -516,23 +534,21 @@ int rhizome_crypt_xor_block(unsigned char *buffer, int buffer_size, int64_t stre unsigned char temp[RHIZOME_CRYPT_PAGE_SIZE]; bcopy(temp + padding, buffer, size); - crypto_stream_xsalsa20_xor(temp, temp, size, nonce, key); + crypto_stream_xsalsa20_xor(temp, temp, size, block_nonce, key); bcopy(buffer, temp + padding, size); - nonce_offset+=RHIZOME_CRYPT_PAGE_SIZE; + add_nonce(block_nonce, RHIZOME_CRYPT_PAGE_SIZE); offset+=size; } while(offset < buffer_size){ - // TODO add offset to nonce instead of replacing - int i; for(i=0;i<8;i++) nonce[i]=(nonce_offset>>(i*8))&0xff; int size = buffer_size - offset; if (size>RHIZOME_CRYPT_PAGE_SIZE) size=RHIZOME_CRYPT_PAGE_SIZE; - crypto_stream_xsalsa20_xor(buffer+offset, buffer+offset, size, nonce, key); + crypto_stream_xsalsa20_xor(buffer+offset, buffer+offset, size, block_nonce, key); - nonce_offset+=RHIZOME_CRYPT_PAGE_SIZE; + add_nonce(block_nonce, RHIZOME_CRYPT_PAGE_SIZE); offset+=size; }