Add encryption support to writing of rhizome content

This commit is contained in:
Jeremy Lakeman 2012-12-21 10:53:47 +10:30
parent 50b216da96
commit 72bc597e92
5 changed files with 58 additions and 7 deletions

View File

@ -1269,7 +1269,7 @@ int app_rhizome_extract_file(int argc, const char *const *argv, const struct com
|| cli_arg(argc, argv, o, "filepath", &filepath, NULL, "") == -1)
return -1;
cli_arg(argc, argv, o, "key", &keyhex, cli_optional_bundle_crypt_key, "");
unsigned char key[RHIZOME_CRYPT_KEY_STRLEN + 1];
unsigned char key[RHIZOME_CRYPT_KEY_BYTES];
if (keyhex[0] && fromhexstr(key, keyhex, RHIZOME_CRYPT_KEY_BYTES) == -1)
return -1;
/* Ensure the Rhizome database exists and is open */

View File

@ -44,6 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define RHIZOME_CRYPT_KEY_BYTES crypto_stream_xsalsa20_ref_KEYBYTES
#define RHIZOME_CRYPT_KEY_STRLEN (RHIZOME_CRYPT_KEY_BYTES * 2)
// assumed to always be 2^n
#define RHIZOME_CRYPT_PAGE_SIZE 4096
#define RHIZOME_HTTP_PORT 4110
@ -593,7 +595,6 @@ struct http_response_parts {
int unpack_http_response(char *response, struct http_response_parts *parts);
/* Rhizome file storage api */
struct rhizome_write{
char id[SHA512_DIGEST_STRING_LENGTH+1];
@ -606,6 +607,11 @@ struct rhizome_write{
int64_t file_offset;
int64_t file_length;
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 crypt;
SHA512_CTX sha512_context;
int64_t blob_rowid;
};
@ -619,5 +625,7 @@ int rhizome_finish_write(struct rhizome_write *write);
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);
#endif //__SERVALDNA__RHIZOME_H

View File

@ -493,3 +493,41 @@ int rhizome_manifest_extract_signature(rhizome_manifest *m,int *ofs)
(*ofs)+=len;
RETURN(0);
}
int rhizome_crypt_xor_block(unsigned char *buffer, int buffer_size, int64_t stream_offset,
const unsigned char *key, unsigned char *nonce){
int64_t nonce_offset = stream_offset & ~(RHIZOME_CRYPT_PAGE_SIZE -1);
int offset=0;
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)
size=buffer_size;
unsigned char temp[RHIZOME_CRYPT_PAGE_SIZE];
bcopy(temp + padding, buffer, size);
crypto_stream_xsalsa20_xor(temp, temp, size, nonce, key);
bcopy(buffer, temp + padding, size);
nonce_offset+=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);
nonce_offset+=RHIZOME_CRYPT_PAGE_SIZE;
offset+=size;
}
return 0;
}

View File

@ -1412,7 +1412,7 @@ int rhizome_retrieve_file(const char *fileid, const char *filepath, const unsign
*/
long long offset;
unsigned char nonce[crypto_stream_xsalsa20_NONCEBYTES];
bzero(nonce,crypto_stream_xsalsa20_NONCEBYTES);
bzero(nonce, crypto_stream_xsalsa20_NONCEBYTES);
unsigned char buffer[RHIZOME_CRYPT_PAGE_SIZE];
for (offset = 0; offset < length; offset += RHIZOME_CRYPT_PAGE_SIZE) {
long long count=length-offset;
@ -1421,15 +1421,18 @@ int rhizome_retrieve_file(const char *fileid, const char *filepath, const unsign
ret = 0;
WHYF("query failed, %s: %s", sqlite3_errmsg(rhizome_db), sqlite3_sql(statement));
WHYF("Error reading %lld bytes of data from blob at offset 0x%llx", count, offset);
break;
}
if (key) {
/* calculate block nonce */
int i; for(i=0;i<8;i++) nonce[i]=(offset>>(i*8))&0xff;
crypto_stream_xsalsa20_xor(&buffer[0],&buffer[0],count, nonce,key);
if(rhizome_crypt_xor_block(buffer, count, offset, key, nonce)){
ret=0;
break;
}
}
if (write(fd,buffer,count)!=count) {
ret =0;
WHY("Failed to write data to file");
break;
}
}
sqlite3_blob_close(blob);

View File

@ -105,7 +105,9 @@ int rhizome_flush(struct rhizome_write *write){
if (write->data_size<=0)
return WHY("No content supplied");
// TODO encryption?
if (write->crypt){
rhizome_crypt_xor_block(write->buffer, write->data_size, write->file_offset, write->key, write->nonce);
}
sqlite3_blob *blob;
int ret = sqlite3_blob_open(rhizome_db, "main", "FILEBLOBS", "data", write->blob_rowid, 1 /* read/write */, &blob);