mirror of
https://github.com/status-im/sqlcipher.git
synced 2025-02-23 09:18:11 +00:00
Adjustment to ltc crypto provider and cipher_add_random
This commit is contained in:
parent
4b31a37006
commit
200b3146a3
@ -91,7 +91,7 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
|
|||||||
|
|
||||||
if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
|
if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
|
||||||
if(ctx) {
|
if(ctx) {
|
||||||
char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight));
|
char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
|
||||||
codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
|
codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
|
||||||
sqlite3_free(add_random_status);
|
sqlite3_free(add_random_status);
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx)
|
|||||||
|
|
||||||
const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx);
|
const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx);
|
||||||
int sqlcipher_codec_ctx_migrate(codec_ctx *ctx);
|
int sqlcipher_codec_ctx_migrate(codec_ctx *ctx);
|
||||||
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data);
|
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data, int random_sz);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/* END SQLCIPHER */
|
/* END SQLCIPHER */
|
||||||
|
@ -1124,20 +1124,23 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight){
|
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz){
|
||||||
int random_sz = strlen(zRight);
|
|
||||||
const char *suffix = &zRight[random_sz-1];
|
const char *suffix = &zRight[random_sz-1];
|
||||||
if (sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 && sqlite3StrNICmp(suffix, "'", 1) == 0) {
|
int n = random_sz - 3; /* adjust for leading x' and tailing ' */
|
||||||
|
if (n > 0 &&
|
||||||
|
sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 &&
|
||||||
|
sqlite3StrNICmp(suffix, "'", 1) == 0 &&
|
||||||
|
n % 2 == 0) {
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
int buffer_sz = n / 2;
|
||||||
unsigned char *random;
|
unsigned char *random;
|
||||||
int n = random_sz - 3; /* adjust for leading x' and tailing ' */
|
|
||||||
const unsigned char *z = (const unsigned char *)zRight + 2; /* adjust lead offset of x' */
|
const unsigned char *z = (const unsigned char *)zRight + 2; /* adjust lead offset of x' */
|
||||||
CODEC_TRACE(("sqlcipher_codec_add_random: using raw random blob from hex\n"));
|
CODEC_TRACE(("sqlcipher_codec_add_random: using raw random blob from hex\n"));
|
||||||
random = sqlcipher_malloc(n);
|
random = sqlcipher_malloc(buffer_sz);
|
||||||
memset(random, 0, n);
|
memset(random, 0, buffer_sz);
|
||||||
cipher_hex2bin(z, n, random);
|
cipher_hex2bin(z, n, random);
|
||||||
rc = ctx->read_ctx->provider->add_random(ctx->read_ctx->provider_ctx, random, n);
|
rc = ctx->read_ctx->provider->add_random(ctx->read_ctx->provider_ctx, random, buffer_sz);
|
||||||
sqlcipher_free(random, n);
|
sqlcipher_free(random, buffer_sz);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
|
@ -35,8 +35,8 @@
|
|||||||
#include "sqlcipher.h"
|
#include "sqlcipher.h"
|
||||||
#include <tomcrypt.h>
|
#include <tomcrypt.h>
|
||||||
|
|
||||||
|
#define FORTUNA_MAX_SZ 32
|
||||||
static prng_state prng;
|
static prng_state prng;
|
||||||
static unsigned int random_block_sz = 32;
|
|
||||||
static unsigned int ltc_init = 0;
|
static unsigned int ltc_init = 0;
|
||||||
static unsigned int ltc_ref_count = 0;
|
static unsigned int ltc_ref_count = 0;
|
||||||
static sqlite3_mutex* ltc_rand_mutex = NULL;
|
static sqlite3_mutex* ltc_rand_mutex = NULL;
|
||||||
@ -44,7 +44,7 @@ static sqlite3_mutex* ltc_rand_mutex = NULL;
|
|||||||
static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
|
static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int data_to_read = length;
|
int data_to_read = length;
|
||||||
int block_sz = data_to_read < random_block_sz ? data_to_read : random_block_sz;
|
int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
|
||||||
const unsigned char * data = (const unsigned char *)buffer;
|
const unsigned char * data = (const unsigned char *)buffer;
|
||||||
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
||||||
sqlite3_mutex_enter(ltc_rand_mutex);
|
sqlite3_mutex_enter(ltc_rand_mutex);
|
||||||
@ -56,10 +56,8 @@ static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
data_to_read -= block_sz;
|
data_to_read -= block_sz;
|
||||||
if(data_to_read > 0){
|
data += block_sz;
|
||||||
block_sz = data_to_read < random_block_sz ? data_to_read : random_block_sz;
|
block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
|
||||||
data += block_sz;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fortuna_ready(&prng);
|
fortuna_ready(&prng);
|
||||||
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
||||||
@ -69,42 +67,56 @@ static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int sqlcipher_ltc_activate(void *ctx) {
|
static int sqlcipher_ltc_activate(void *ctx) {
|
||||||
int random_buffer_sz = sizeof(char) * 32;
|
unsigned char random_buffer[FORTUNA_MAX_SZ];
|
||||||
unsigned char *random_buffer = sqlcipher_malloc(random_buffer_sz);
|
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
||||||
sqlcipher_memset(random_buffer, 0, random_buffer_sz);
|
if(ltc_rand_mutex == NULL){
|
||||||
|
ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||||
|
}
|
||||||
|
sqlite3_mutex_enter(ltc_rand_mutex);
|
||||||
|
#endif
|
||||||
|
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
|
||||||
if(ltc_init == 0) {
|
if(ltc_init == 0) {
|
||||||
if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR;
|
if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR;
|
||||||
if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR;
|
if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR;
|
||||||
if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
|
if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
|
||||||
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
|
||||||
if(ltc_rand_mutex == NULL){
|
|
||||||
ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(fortuna_start(&prng) != CRYPT_OK) {
|
if(fortuna_start(&prng) != CRYPT_OK) {
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
ltc_init = 1;
|
ltc_init = 1;
|
||||||
}
|
}
|
||||||
sqlite3_randomness(random_buffer_sz, random_buffer);
|
ltc_ref_count++;
|
||||||
if(sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz) != SQLITE_OK) {
|
#ifndef SQLCIPHER_TEST
|
||||||
|
sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
|
||||||
|
#endif
|
||||||
|
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
||||||
|
sqlite3_mutex_leave(ltc_rand_mutex);
|
||||||
|
#endif
|
||||||
|
if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
sqlcipher_free(random_buffer, random_buffer_sz);
|
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
|
||||||
ltc_ref_count++;
|
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sqlcipher_ltc_deactivate(void *ctx) {
|
static int sqlcipher_ltc_deactivate(void *ctx) {
|
||||||
|
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
||||||
|
sqlite3_mutex_enter(ltc_rand_mutex);
|
||||||
|
#endif
|
||||||
ltc_ref_count--;
|
ltc_ref_count--;
|
||||||
if(ltc_ref_count == 0){
|
if(ltc_ref_count == 0){
|
||||||
fortuna_done(&prng);
|
fortuna_done(&prng);
|
||||||
|
sqlcipher_memset((void *)&prng, 0, sizeof(prng));
|
||||||
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
||||||
|
sqlite3_mutex_leave(ltc_rand_mutex);
|
||||||
sqlite3_mutex_free(ltc_rand_mutex);
|
sqlite3_mutex_free(ltc_rand_mutex);
|
||||||
ltc_rand_mutex = NULL;
|
ltc_rand_mutex = NULL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
|
||||||
|
else {
|
||||||
|
sqlite3_mutex_leave(ltc_rand_mutex);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,21 @@ proc if_built_with_commoncrypto {name cmd expected} {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc cmpFilesChunked {file1 file2 {chunksize 16384}} {
|
||||||
|
set f1 [open $file1]; fconfigure $f1 -translation binary
|
||||||
|
set f2 [open $file2]; fconfigure $f2 -translation binary
|
||||||
|
while {1} {
|
||||||
|
set d1 [read $f1 $chunksize]
|
||||||
|
set d2 [read $f2 $chunksize]
|
||||||
|
set diff [string compare $d1 $d2]
|
||||||
|
if {$diff != 0 || [eof $f1] || [eof $f2]} {
|
||||||
|
close $f1; close $f2
|
||||||
|
return $diff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# The database is initially empty.
|
# The database is initially empty.
|
||||||
# set an hex key create some basic data
|
# set an hex key create some basic data
|
||||||
# create table and insert operations should work
|
# create table and insert operations should work
|
||||||
@ -413,9 +428,9 @@ file delete -force test.db
|
|||||||
setup test.db "'testkey'"
|
setup test.db "'testkey'"
|
||||||
do_test attach-database-with-default-key {
|
do_test attach-database-with-default-key {
|
||||||
sqlite_orig db2 test2.db
|
sqlite_orig db2 test2.db
|
||||||
|
|
||||||
execsql {
|
execsql {
|
||||||
PRAGMA key = 'testkey';
|
PRAGMA key = 'testkey';
|
||||||
|
PRAGMA cipher_add_random = "x'deadbaad'";
|
||||||
CREATE TABLE t2(a,b);
|
CREATE TABLE t2(a,b);
|
||||||
INSERT INTO t2 VALUES ('test1', 'test2');
|
INSERT INTO t2 VALUES ('test1', 'test2');
|
||||||
} db2
|
} db2
|
||||||
@ -2114,5 +2129,39 @@ db close
|
|||||||
file delete -force test.db
|
file delete -force test.db
|
||||||
file delete -force new.db
|
file delete -force new.db
|
||||||
|
|
||||||
|
# Requires SQLCipher to be built with -DSQLCIPHER_TEST
|
||||||
|
if_built_with_libtomcrypt verify-random-data-alters-file-content {
|
||||||
|
file delete -force test.db
|
||||||
|
file delete -force test2.db
|
||||||
|
file delete -force test3.db
|
||||||
|
set rc {}
|
||||||
|
|
||||||
|
sqlite_orig db test.db
|
||||||
|
execsql {
|
||||||
|
PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
|
||||||
|
create table t1(a,b);
|
||||||
|
}
|
||||||
|
db close
|
||||||
|
sqlite_orig db test2.db
|
||||||
|
execsql {
|
||||||
|
PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
|
||||||
|
create table t1(a,b);
|
||||||
|
}
|
||||||
|
db close
|
||||||
|
sqlite_orig db test3.db
|
||||||
|
execsql {
|
||||||
|
PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
|
||||||
|
PRAGMA cipher_add_random = "x'deadbaad'";
|
||||||
|
create table t1(a,b);
|
||||||
|
}
|
||||||
|
db close
|
||||||
|
lappend rc [cmpFilesChunked test.db test2.db]
|
||||||
|
lappend rc [cmpFilesChunked test2.db test3.db]
|
||||||
|
} {0 1}
|
||||||
|
file delete -force test.db
|
||||||
|
file delete -force test2.db
|
||||||
|
file delete -force test3.db
|
||||||
|
|
||||||
|
|
||||||
sqlite3_test_control_pending_byte $old_pending_byte
|
sqlite3_test_control_pending_byte $old_pending_byte
|
||||||
finish_test
|
finish_test
|
||||||
|
Loading…
x
Reference in New Issue
Block a user