Skip to content

Commit 200b314

Browse files
Adjustment to ltc crypto provider and cipher_add_random
1 parent 4b31a37 commit 200b314

5 files changed

Lines changed: 95 additions & 31 deletions

File tree

src/crypto.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLef
9191

9292
if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){
9393
if(ctx) {
94-
char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight));
94+
char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight)));
9595
codec_vdbe_return_static_string(pParse, "cipher_add_random", add_random_status);
9696
sqlite3_free(add_random_status);
9797
}

src/crypto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx)
213213

214214
const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx);
215215
int sqlcipher_codec_ctx_migrate(codec_ctx *ctx);
216-
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data);
216+
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data, int random_sz);
217217
#endif
218218
#endif
219219
/* END SQLCIPHER */

src/crypto_impl.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,20 +1124,23 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) {
11241124
return rc;
11251125
}
11261126

1127-
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight){
1128-
int random_sz = strlen(zRight);
1127+
int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz){
11291128
const char *suffix = &zRight[random_sz-1];
1130-
if (sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 && sqlite3StrNICmp(suffix, "'", 1) == 0) {
1129+
int n = random_sz - 3; /* adjust for leading x' and tailing ' */
1130+
if (n > 0 &&
1131+
sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 &&
1132+
sqlite3StrNICmp(suffix, "'", 1) == 0 &&
1133+
n % 2 == 0) {
11311134
int rc = 0;
1135+
int buffer_sz = n / 2;
11321136
unsigned char *random;
1133-
int n = random_sz - 3; /* adjust for leading x' and tailing ' */
11341137
const unsigned char *z = (const unsigned char *)zRight + 2; /* adjust lead offset of x' */
11351138
CODEC_TRACE(("sqlcipher_codec_add_random: using raw random blob from hex\n"));
1136-
random = sqlcipher_malloc(n);
1137-
memset(random, 0, n);
1139+
random = sqlcipher_malloc(buffer_sz);
1140+
memset(random, 0, buffer_sz);
11381141
cipher_hex2bin(z, n, random);
1139-
rc = ctx->read_ctx->provider->add_random(ctx->read_ctx->provider_ctx, random, n);
1140-
sqlcipher_free(random, n);
1142+
rc = ctx->read_ctx->provider->add_random(ctx->read_ctx->provider_ctx, random, buffer_sz);
1143+
sqlcipher_free(random, buffer_sz);
11411144
return rc;
11421145
}
11431146
return SQLITE_ERROR;

src/crypto_libtomcrypt.c

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@
3535
#include "sqlcipher.h"
3636
#include <tomcrypt.h>
3737

38+
#define FORTUNA_MAX_SZ 32
3839
static prng_state prng;
39-
static unsigned int random_block_sz = 32;
4040
static unsigned int ltc_init = 0;
4141
static unsigned int ltc_ref_count = 0;
4242
static sqlite3_mutex* ltc_rand_mutex = NULL;
4343

4444
static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
4545
int rc = 0;
4646
int data_to_read = length;
47-
int block_sz = data_to_read < random_block_sz ? data_to_read : random_block_sz;
47+
int block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
4848
const unsigned char * data = (const unsigned char *)buffer;
4949
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
5050
sqlite3_mutex_enter(ltc_rand_mutex);
@@ -56,10 +56,8 @@ static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
5656
break;
5757
}
5858
data_to_read -= block_sz;
59-
if(data_to_read > 0){
60-
block_sz = data_to_read < random_block_sz ? data_to_read : random_block_sz;
61-
data += block_sz;
62-
}
59+
data += block_sz;
60+
block_sz = data_to_read < FORTUNA_MAX_SZ ? data_to_read : FORTUNA_MAX_SZ;
6361
}
6462
fortuna_ready(&prng);
6563
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
@@ -69,42 +67,56 @@ static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
6967
}
7068

7169
static int sqlcipher_ltc_activate(void *ctx) {
72-
int random_buffer_sz = sizeof(char) * 32;
73-
unsigned char *random_buffer = sqlcipher_malloc(random_buffer_sz);
74-
sqlcipher_memset(random_buffer, 0, random_buffer_sz);
75-
70+
unsigned char random_buffer[FORTUNA_MAX_SZ];
71+
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
72+
if(ltc_rand_mutex == NULL){
73+
ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
74+
}
75+
sqlite3_mutex_enter(ltc_rand_mutex);
76+
#endif
77+
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
7678
if(ltc_init == 0) {
7779
if(register_prng(&fortuna_desc) != CRYPT_OK) return SQLITE_ERROR;
7880
if(register_cipher(&rijndael_desc) != CRYPT_OK) return SQLITE_ERROR;
7981
if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
80-
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
81-
if(ltc_rand_mutex == NULL){
82-
ltc_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
83-
}
84-
#endif
8582
if(fortuna_start(&prng) != CRYPT_OK) {
8683
return SQLITE_ERROR;
8784
}
8885
ltc_init = 1;
8986
}
90-
sqlite3_randomness(random_buffer_sz, random_buffer);
91-
if(sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz) != SQLITE_OK) {
87+
ltc_ref_count++;
88+
#ifndef SQLCIPHER_TEST
89+
sqlite3_randomness(FORTUNA_MAX_SZ, random_buffer);
90+
#endif
91+
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
92+
sqlite3_mutex_leave(ltc_rand_mutex);
93+
#endif
94+
if(sqlcipher_ltc_add_random(ctx, random_buffer, FORTUNA_MAX_SZ) != SQLITE_OK) {
9295
return SQLITE_ERROR;
9396
}
94-
sqlcipher_free(random_buffer, random_buffer_sz);
95-
ltc_ref_count++;
97+
sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
9698
return SQLITE_OK;
9799
}
98100

99101
static int sqlcipher_ltc_deactivate(void *ctx) {
102+
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
103+
sqlite3_mutex_enter(ltc_rand_mutex);
104+
#endif
100105
ltc_ref_count--;
101106
if(ltc_ref_count == 0){
102107
fortuna_done(&prng);
108+
sqlcipher_memset((void *)&prng, 0, sizeof(prng));
103109
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
110+
sqlite3_mutex_leave(ltc_rand_mutex);
104111
sqlite3_mutex_free(ltc_rand_mutex);
105112
ltc_rand_mutex = NULL;
106113
#endif
107114
}
115+
#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
116+
else {
117+
sqlite3_mutex_leave(ltc_rand_mutex);
118+
}
119+
#endif
108120
return SQLITE_OK;
109121
}
110122

test/crypto.test

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,21 @@ proc if_built_with_commoncrypto {name cmd expected} {
8787
}
8888
}
8989

90+
proc cmpFilesChunked {file1 file2 {chunksize 16384}} {
91+
set f1 [open $file1]; fconfigure $f1 -translation binary
92+
set f2 [open $file2]; fconfigure $f2 -translation binary
93+
while {1} {
94+
set d1 [read $f1 $chunksize]
95+
set d2 [read $f2 $chunksize]
96+
set diff [string compare $d1 $d2]
97+
if {$diff != 0 || [eof $f1] || [eof $f2]} {
98+
close $f1; close $f2
99+
return $diff
100+
}
101+
}
102+
return 0
103+
}
104+
90105
# The database is initially empty.
91106
# set an hex key create some basic data
92107
# create table and insert operations should work
@@ -413,17 +428,17 @@ file delete -force test.db
413428
setup test.db "'testkey'"
414429
do_test attach-database-with-default-key {
415430
sqlite_orig db2 test2.db
416-
417431
execsql {
418432
PRAGMA key = 'testkey';
433+
PRAGMA cipher_add_random = "x'deadbaad'";
419434
CREATE TABLE t2(a,b);
420435
INSERT INTO t2 VALUES ('test1', 'test2');
421436
} db2
422437

423438
catchsql {
424439
ATTACH 'test.db' AS db;
425440
} db2
426-
441+
427442
} {1 {file is encrypted or is not a database}}
428443
db2 close
429444
file delete -force test.db
@@ -2114,5 +2129,39 @@ db close
21142129
file delete -force test.db
21152130
file delete -force new.db
21162131

2132+
# Requires SQLCipher to be built with -DSQLCIPHER_TEST
2133+
if_built_with_libtomcrypt verify-random-data-alters-file-content {
2134+
file delete -force test.db
2135+
file delete -force test2.db
2136+
file delete -force test3.db
2137+
set rc {}
2138+
2139+
sqlite_orig db test.db
2140+
execsql {
2141+
PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
2142+
create table t1(a,b);
2143+
}
2144+
db close
2145+
sqlite_orig db test2.db
2146+
execsql {
2147+
PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
2148+
create table t1(a,b);
2149+
}
2150+
db close
2151+
sqlite_orig db test3.db
2152+
execsql {
2153+
PRAGMA key="x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
2154+
PRAGMA cipher_add_random = "x'deadbaad'";
2155+
create table t1(a,b);
2156+
}
2157+
db close
2158+
lappend rc [cmpFilesChunked test.db test2.db]
2159+
lappend rc [cmpFilesChunked test2.db test3.db]
2160+
} {0 1}
2161+
file delete -force test.db
2162+
file delete -force test2.db
2163+
file delete -force test3.db
2164+
2165+
21172166
sqlite3_test_control_pending_byte $old_pending_byte
21182167
finish_test

0 commit comments

Comments
 (0)