Skip to content

Commit a45a181

Browse files
committed
switch digest to sha256 (requires sha256 support in openssl); allow setting a passphrase instead of raw blob key; update readme
1 parent 11dd40d commit a45a181

6 files changed

Lines changed: 101 additions & 167 deletions

File tree

Makefile.in

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#
1818
TOP = @srcdir@
1919

20+
2021
# C Compiler and options for use in building executables that
2122
# will run on the platform that is doing the build.
2223
#
@@ -122,6 +123,13 @@ USE_GCOV = @USE_GCOV@
122123
LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV))
123124
LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV))
124125

126+
# BEGIN CRYPTO
127+
CRYPTOLIBOBJ = \
128+
crypto.lo
129+
130+
CRYPTOSRC = \
131+
$(TOP)/src/crypto.c
132+
# END CRYPTO
125133

126134
# The directory into which to store package information for
127135

@@ -160,7 +168,7 @@ OBJS0 = alter.lo analyze.lo attach.lo auth.lo bitvec.lo btmutex.lo \
160168
select.lo status.lo table.lo tokenize.lo trigger.lo update.lo \
161169
util.lo vacuum.lo \
162170
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbefifo.lo vdbemem.lo \
163-
where.lo utf.lo legacy.lo vtab.lo
171+
where.lo utf.lo legacy.lo vtab.lo $(CRYPTOLIBOBJ)
164172

165173
# Object files for the amalgamation.
166174
#
@@ -175,6 +183,7 @@ LIBOBJ = $(OBJS$(USE_AMALGAMATION))
175183
# All of the source code files.
176184
#
177185
SRC = \
186+
$(CRYPTOSRC) \
178187
$(TOP)/src/alter.c \
179188
$(TOP)/src/analyze.c \
180189
$(TOP)/src/attach.c \
@@ -464,6 +473,11 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
464473
sqlite3.lo: sqlite3.c
465474
$(LTCOMPILE) -c sqlite3.c
466475

476+
# BEGIN CRYPTO
477+
crypto.lo: $(TOP)/src/crypto.c $(HDR)
478+
$(LTCOMPILE) -c $(TOP)/src/crypto.c
479+
# END CRYPTO
480+
467481
# Rules to build individual files
468482
#
469483
alter.lo: $(TOP)/src/alter.c $(HDR)

README

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
== SQLite Cipher Introduction ==
2+
3+
SQLite Cipher is an SQLite extension that provides transparent 256 bit AES encryption of database files.
4+
Pages are encrypted before being written to disk and are decrypted when read back.
5+
6+
Encryption is provided by the OpenSSL crypto library.
7+
8+
Static linking (replace /opt/local/lib with the path to libcrypto.a)
9+
./configure --disable-amalgamation CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="/opt/local/lib/libcrypto.a"
10+
make
11+
12+
Dynamic linking
13+
./configure --disable-amalgamation CFLAGS="-DSQLITE_HAS_CODEC -lcrypto"
14+
make
15+
16+
== End Introduction ==
17+
118
This directory contains source code to
219

320
SQLite: An Embeddable SQL Database Engine

sqlite3.def

Lines changed: 0 additions & 150 deletions
This file was deleted.

src/crypto.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/* BEGIN CRYPTO */
22
#if defined(SQLITE_HAS_CODEC)
33

4-
#include "sqliteInt.h"
5-
#include "btreeInt.h"
4+
#include <assert.h>
65
#include <openssl/evp.h>
76
#include <openssl/rand.h>
7+
#include "sqliteInt.h"
8+
#include "btreeInt.h"
89
#include "crypto.h"
910

1011
typedef struct {
@@ -16,18 +17,17 @@ typedef struct {
1617
void *buffer;
1718
} codec_ctx;
1819

19-
static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLen) {
20+
static int codec_page_hash(Pgno pgno, void *in, int inLen, void *out, int *outLen) {
2021
EVP_MD_CTX mdctx;
2122
unsigned int md_sz;
2223
unsigned char md_value[EVP_MAX_MD_SIZE];
2324

2425
EVP_MD_CTX_init(&mdctx);
2526
EVP_DigestInit_ex(&mdctx, DIGEST, NULL);
2627

27-
if(ctx->rand)
28-
EVP_DigestUpdate(&mdctx, ctx->rand, 16);
28+
EVP_DigestUpdate(&mdctx, in, inLen); /* add random "salt" data to hash*/
29+
EVP_DigestUpdate(&mdctx, &pgno, sizeof(pgno));
2930

30-
EVP_DigestUpdate(&mdctx, in, inLen);
3131
EVP_DigestFinal_ex(&mdctx, md_value, &md_sz);
3232

3333
memcpy(out, md_value, md_sz);
@@ -37,6 +37,21 @@ static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLe
3737
*outLen = md_sz;
3838
}
3939

40+
static int codec_passphrase_hash(void *in, int inLen, void *out, int *outLen) {
41+
EVP_MD_CTX mdctx;
42+
unsigned int md_sz;
43+
unsigned char md_value[EVP_MAX_MD_SIZE];
44+
45+
EVP_MD_CTX_init(&mdctx);
46+
EVP_DigestInit_ex(&mdctx, DIGEST, NULL);
47+
EVP_DigestUpdate(&mdctx, in, inLen);
48+
EVP_DigestFinal_ex(&mdctx, md_value, &md_sz);
49+
memcpy(out, md_value, md_sz);
50+
EVP_MD_CTX_cleanup(&mdctx);
51+
memset(md_value, 0, md_sz);
52+
*outLen = md_sz;
53+
}
54+
4055
/*
4156
* ctx - codec context
4257
* pgno - page number in database
@@ -45,12 +60,16 @@ static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLe
4560
* in - pointer to input bytes
4661
* out - pouter to output bytes
4762
*/
48-
static int codec_cipher(codec_ctx *ctx, int pgno, int mode, int size, void *in, void *out) {
63+
static int codec_cipher(codec_ctx *ctx, Pgno pgno, int mode, int size, void *in, void *out) {
4964
EVP_CIPHER_CTX ectx;
5065
unsigned char iv[EVP_MAX_MD_SIZE];
5166
int iv_sz, tmp_csz, csz;
5267

53-
codec_hash(ctx, iv, &iv_sz, &pgno, sizeof(pgno));
68+
/* the initilization vector is created from the hash of the
69+
16 byte database random salt and the page number. This will
70+
ensure that each page in the database has a unique initialization
71+
vector */
72+
codec_page_hash(pgno, ctx->rand, 16, iv, &iv_sz);
5473

5574
EVP_CipherInit(&ectx, CIPHER, NULL, NULL, mode);
5675
EVP_CIPHER_CTX_set_padding(&ectx, 0);
@@ -64,11 +83,6 @@ static int codec_cipher(codec_ctx *ctx, int pgno, int mode, int size, void *in,
6483
assert(size == csz);
6584
}
6685

67-
68-
void sqlite3_activate_see(const char* in) {
69-
/* do nothing, security enhancements are always active */
70-
}
71-
7286
/*
7387
* sqlite3Codec can be called in multiple modes.
7488
* encrypt mode - expected to return a pointer to the
@@ -152,12 +166,22 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
152166
operations to avoid overhead of multiple memory allocations*/
153167
ctx->buffer = sqlite3_malloc(sqlite3BtreeGetPageSize(ctx->pBt));
154168

155-
/* if key string starts with x' then this is a blob literal key*/
169+
ctx->key_sz = EVP_CIPHER_key_length(CIPHER);
170+
171+
/* if key string starts with x' then assume this is a blob literal key*/
156172
if(sqlite3StrNICmp(zKey,"x'", 2) == 0) {
157173
int n = nKey - 3; /* adjust for leading x' and tailing ' */
158174
const char *z = zKey + 2; /* adjust lead offset of x' */
159-
ctx->key_sz = EVP_CIPHER_key_length(CIPHER);
175+
176+
assert((n/2) == ctx->key_sz); /* keylength after hex decode should equal cipher key length */
160177
ctx->key = sqlite3HexToBlob(db, z, n);
178+
179+
/* otherwise the key is provided as a string so hash it to get key data */
180+
} else {
181+
int key_sz;
182+
ctx->key = sqlite3_malloc(ctx->key_sz);
183+
codec_passphrase_hash(zKey, nKey, ctx->key, &key_sz);
184+
assert(key_sz == ctx->key_sz);
161185
}
162186

163187
sqlite3pager_set_codec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, (void *) ctx);

src/crypto.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
11
/*
2+
** SQLite Security Enh
23
** crypto.h developed by Stephen Lombardo (Zetetic LLC)
34
** sjlombardo at zetetic dot net
45
** http://zetetic.net
6+
**
7+
** July 30, 2008
58
**
9+
10+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16+
THE SOFTWARE.
17+
18+
**
619
*/
720
/* BEGIN CRYPTO */
821
#ifndef CRYPTO_H
922
#define CRYPTO_H
1023

1124
#define CIPHER EVP_aes_256_cfb()
12-
#define DIGEST EVP_sha1()
25+
#define DIGEST EVP_sha256()
1326

1427
/* HDR_SIZE allocates 16 bytes for random salt and 8 bytes for page size */
1528
#define HDR_SZ 24

src/pager.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5353,3 +5353,19 @@ i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
53535353
}
53545354

53555355
#endif /* SQLITE_OMIT_DISKIO */
5356+
5357+
/* BEGIN CRYPTO */
5358+
#if defined(SQLITE_HAS_CODEC)
5359+
5360+
int sqlite3pager_get_codec(Pager *pPager, void **ctx) {
5361+
*ctx = pPager->pCodecArg;
5362+
}
5363+
5364+
void sqlite3pager_set_codec(Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), void *pCodecArg){
5365+
pPager->xCodec = xCodec;
5366+
pPager->pCodecArg = pCodecArg;
5367+
}
5368+
5369+
#endif
5370+
/* END CRYPTO */
5371+

0 commit comments

Comments
 (0)