switch digest to sha256 (requires sha256 support in openssl); allow setting a passphrase instead of raw blob key; update readme

This commit is contained in:
Stephen Lombardo 2008-07-30 13:15:55 -04:00
parent 11dd40da8d
commit a45a181cee
6 changed files with 101 additions and 167 deletions

View File

@ -17,6 +17,7 @@
#
TOP = @srcdir@
# C Compiler and options for use in building executables that
# will run on the platform that is doing the build.
#
@ -122,6 +123,13 @@ USE_GCOV = @USE_GCOV@
LTCOMPILE_EXTRAS += $(GCOV_CFLAGS$(USE_GCOV))
LTLINK_EXTRAS += $(GCOV_LDFLAGS$(USE_GCOV))
# BEGIN CRYPTO
CRYPTOLIBOBJ = \
crypto.lo
CRYPTOSRC = \
$(TOP)/src/crypto.c
# END CRYPTO
# The directory into which to store package information for
@ -160,7 +168,7 @@ OBJS0 = alter.lo analyze.lo attach.lo auth.lo bitvec.lo btmutex.lo \
select.lo status.lo table.lo tokenize.lo trigger.lo update.lo \
util.lo vacuum.lo \
vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbefifo.lo vdbemem.lo \
where.lo utf.lo legacy.lo vtab.lo
where.lo utf.lo legacy.lo vtab.lo $(CRYPTOLIBOBJ)
# Object files for the amalgamation.
#
@ -175,6 +183,7 @@ LIBOBJ = $(OBJS$(USE_AMALGAMATION))
# All of the source code files.
#
SRC = \
$(CRYPTOSRC) \
$(TOP)/src/alter.c \
$(TOP)/src/analyze.c \
$(TOP)/src/attach.c \
@ -464,6 +473,11 @@ lemon$(BEXE): $(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
sqlite3.lo: sqlite3.c
$(LTCOMPILE) -c sqlite3.c
# BEGIN CRYPTO
crypto.lo: $(TOP)/src/crypto.c $(HDR)
$(LTCOMPILE) -c $(TOP)/src/crypto.c
# END CRYPTO
# Rules to build individual files
#
alter.lo: $(TOP)/src/alter.c $(HDR)

17
README
View File

@ -1,3 +1,20 @@
== SQLite Cipher Introduction ==
SQLite Cipher is an SQLite extension that provides transparent 256 bit AES encryption of database files.
Pages are encrypted before being written to disk and are decrypted when read back.
Encryption is provided by the OpenSSL crypto library.
Static linking (replace /opt/local/lib with the path to libcrypto.a)
./configure --disable-amalgamation CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="/opt/local/lib/libcrypto.a"
make
Dynamic linking
./configure --disable-amalgamation CFLAGS="-DSQLITE_HAS_CODEC -lcrypto"
make
== End Introduction ==
This directory contains source code to
SQLite: An Embeddable SQL Database Engine

View File

@ -1,150 +0,0 @@
EXPORTS
sqlite3_aggregate_context
sqlite3_aggregate_count
sqlite3_auto_extension
sqlite3_bind_blob
sqlite3_bind_double
sqlite3_bind_int
sqlite3_bind_int64
sqlite3_bind_null
sqlite3_bind_parameter_count
sqlite3_bind_parameter_index
sqlite3_bind_parameter_name
sqlite3_bind_text
sqlite3_bind_text16
sqlite3_bind_value
sqlite3_bind_zeroblob
sqlite3_blob_bytes
sqlite3_blob_close
sqlite3_blob_open
sqlite3_blob_read
sqlite3_blob_write
sqlite3_busy_handler
sqlite3_busy_timeout
sqlite3_changes
sqlite3_clear_bindings
sqlite3_close
sqlite3_collation_needed
sqlite3_collation_needed16
sqlite3_column_blob
sqlite3_column_bytes
sqlite3_column_bytes16
sqlite3_column_count
sqlite3_column_decltype
sqlite3_column_decltype16
sqlite3_column_double
sqlite3_column_int
sqlite3_column_int64
sqlite3_column_name
sqlite3_column_name16
sqlite3_column_text
sqlite3_column_text16
sqlite3_column_type
sqlite3_column_value
sqlite3_commit_hook
sqlite3_complete
sqlite3_complete16
sqlite3_create_collation
sqlite3_create_collation16
sqlite3_create_collation_v2
sqlite3_create_function
sqlite3_create_function16
sqlite3_create_module
sqlite3_create_module_v2
sqlite3_data_count
sqlite3_db_handle
sqlite3_declare_vtab
sqlite3_enable_load_extension
sqlite3_enable_shared_cache
sqlite3_errcode
sqlite3_errmsg
sqlite3_errmsg16
sqlite3_exec
sqlite3_expired
sqlite3_extended_result_codes
sqlite3_file_control
sqlite3_finalize
sqlite3_free
sqlite3_free_table
sqlite3_get_autocommit
sqlite3_get_auxdata
sqlite3_get_table
sqlite3_global_recover
sqlite3_interrupt
sqlite3_last_insert_rowid
sqlite3_libversion
sqlite3_libversion_number
sqlite3_load_extension
sqlite3_malloc
sqlite3_memory_alarm
sqlite3_memory_highwater
sqlite3_memory_used
sqlite3_mprintf
sqlite3_mutex_alloc
sqlite3_mutex_enter
sqlite3_mutex_free
sqlite3_mutex_leave
sqlite3_mutex_try
sqlite3_open
sqlite3_open16
sqlite3_open_v2
sqlite3_overload_function
sqlite3_prepare
sqlite3_prepare16
sqlite3_prepare16_v2
sqlite3_prepare_v2
sqlite3_profile
sqlite3_progress_handler
sqlite3_randomness
sqlite3_realloc
sqlite3_release_memory
sqlite3_reset
sqlite3_reset_auto_extension
sqlite3_result_blob
sqlite3_result_double
sqlite3_result_error
sqlite3_result_error16
sqlite3_result_error_code
sqlite3_result_error_nomem
sqlite3_result_error_toobig
sqlite3_result_int
sqlite3_result_int64
sqlite3_result_null
sqlite3_result_text
sqlite3_result_text16
sqlite3_result_text16be
sqlite3_result_text16le
sqlite3_result_value
sqlite3_result_zeroblob
sqlite3_rollback_hook
sqlite3_set_authorizer
sqlite3_set_auxdata
sqlite3_sleep
sqlite3_snprintf
sqlite3_soft_heap_limit
sqlite3_sql
sqlite3_step
sqlite3_test_control
sqlite3_thread_cleanup
sqlite3_threadsafe
sqlite3_total_changes
sqlite3_trace
sqlite3_transfer_bindings
sqlite3_update_hook
sqlite3_user_data
sqlite3_value_blob
sqlite3_value_bytes
sqlite3_value_bytes16
sqlite3_value_double
sqlite3_value_int
sqlite3_value_int64
sqlite3_value_numeric_type
sqlite3_value_text
sqlite3_value_text16
sqlite3_value_text16be
sqlite3_value_text16le
sqlite3_value_type
sqlite3_vfs_find
sqlite3_vfs_register
sqlite3_vfs_unregister
sqlite3_vmprintf

View File

@ -1,10 +1,11 @@
/* BEGIN CRYPTO */
#if defined(SQLITE_HAS_CODEC)
#include "sqliteInt.h"
#include "btreeInt.h"
#include <assert.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "sqliteInt.h"
#include "btreeInt.h"
#include "crypto.h"
typedef struct {
@ -16,7 +17,7 @@ typedef struct {
void *buffer;
} codec_ctx;
static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLen) {
static int codec_page_hash(Pgno pgno, void *in, int inLen, void *out, int *outLen) {
EVP_MD_CTX mdctx;
unsigned int md_sz;
unsigned char md_value[EVP_MAX_MD_SIZE];
@ -24,10 +25,9 @@ static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLe
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, DIGEST, NULL);
if(ctx->rand)
EVP_DigestUpdate(&mdctx, ctx->rand, 16);
EVP_DigestUpdate(&mdctx, in, inLen); /* add random "salt" data to hash*/
EVP_DigestUpdate(&mdctx, &pgno, sizeof(pgno));
EVP_DigestUpdate(&mdctx, in, inLen);
EVP_DigestFinal_ex(&mdctx, md_value, &md_sz);
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
*outLen = md_sz;
}
static int codec_passphrase_hash(void *in, int inLen, void *out, int *outLen) {
EVP_MD_CTX mdctx;
unsigned int md_sz;
unsigned char md_value[EVP_MAX_MD_SIZE];
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, DIGEST, NULL);
EVP_DigestUpdate(&mdctx, in, inLen);
EVP_DigestFinal_ex(&mdctx, md_value, &md_sz);
memcpy(out, md_value, md_sz);
EVP_MD_CTX_cleanup(&mdctx);
memset(md_value, 0, md_sz);
*outLen = md_sz;
}
/*
* ctx - codec context
* pgno - page number in database
@ -45,12 +60,16 @@ static int codec_hash(codec_ctx *ctx, void *out, int *outLen, void *in, int inLe
* in - pointer to input bytes
* out - pouter to output bytes
*/
static int codec_cipher(codec_ctx *ctx, int pgno, int mode, int size, void *in, void *out) {
static int codec_cipher(codec_ctx *ctx, Pgno pgno, int mode, int size, void *in, void *out) {
EVP_CIPHER_CTX ectx;
unsigned char iv[EVP_MAX_MD_SIZE];
int iv_sz, tmp_csz, csz;
codec_hash(ctx, iv, &iv_sz, &pgno, sizeof(pgno));
/* the initilization vector is created from the hash of the
16 byte database random salt and the page number. This will
ensure that each page in the database has a unique initialization
vector */
codec_page_hash(pgno, ctx->rand, 16, iv, &iv_sz);
EVP_CipherInit(&ectx, CIPHER, NULL, NULL, mode);
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,
assert(size == csz);
}
void sqlite3_activate_see(const char* in) {
/* do nothing, security enhancements are always active */
}
/*
* sqlite3Codec can be called in multiple modes.
* encrypt mode - expected to return a pointer to the
@ -152,12 +166,22 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) {
operations to avoid overhead of multiple memory allocations*/
ctx->buffer = sqlite3_malloc(sqlite3BtreeGetPageSize(ctx->pBt));
/* if key string starts with x' then this is a blob literal key*/
ctx->key_sz = EVP_CIPHER_key_length(CIPHER);
/* if key string starts with x' then assume this is a blob literal key*/
if(sqlite3StrNICmp(zKey,"x'", 2) == 0) {
int n = nKey - 3; /* adjust for leading x' and tailing ' */
const char *z = zKey + 2; /* adjust lead offset of x' */
ctx->key_sz = EVP_CIPHER_key_length(CIPHER);
assert((n/2) == ctx->key_sz); /* keylength after hex decode should equal cipher key length */
ctx->key = sqlite3HexToBlob(db, z, n);
/* otherwise the key is provided as a string so hash it to get key data */
} else {
int key_sz;
ctx->key = sqlite3_malloc(ctx->key_sz);
codec_passphrase_hash(zKey, nKey, ctx->key, &key_sz);
assert(key_sz == ctx->key_sz);
}
sqlite3pager_set_codec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, (void *) ctx);

View File

@ -1,15 +1,28 @@
/*
** SQLite Security Enh
** crypto.h developed by Stephen Lombardo (Zetetic LLC)
** sjlombardo at zetetic dot net
** http://zetetic.net
**
** July 30, 2008
**
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
**
*/
/* BEGIN CRYPTO */
#ifndef CRYPTO_H
#define CRYPTO_H
#define CIPHER EVP_aes_256_cfb()
#define DIGEST EVP_sha1()
#define DIGEST EVP_sha256()
/* HDR_SIZE allocates 16 bytes for random salt and 8 bytes for page size */
#define HDR_SZ 24

View File

@ -5353,3 +5353,19 @@ i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
}
#endif /* SQLITE_OMIT_DISKIO */
/* BEGIN CRYPTO */
#if defined(SQLITE_HAS_CODEC)
int sqlite3pager_get_codec(Pager *pPager, void **ctx) {
*ctx = pPager->pCodecArg;
}
void sqlite3pager_set_codec(Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), void *pCodecArg){
pPager->xCodec = xCodec;
pPager->pCodecArg = pCodecArg;
}
#endif
/* END CRYPTO */