mirror of
https://github.com/status-im/sqlcipher.git
synced 2026-08-30 22:11:14 +00:00
providers accessed via function pointers
This commit is contained in:
@@ -140,7 +140,6 @@ CRYPTOLIBOBJ = \
|
||||
CRYPTOSRC = \
|
||||
$(TOP)/src/crypto.h \
|
||||
$(TOP)/src/crypto.c \
|
||||
$(TOP)/src/crypto_impl.h \
|
||||
$(TOP)/src/crypto_impl.c \
|
||||
$(TOP)/src/crypto_libtomcrypt.c \
|
||||
$(TOP)/src/crypto_openssl.c
|
||||
|
||||
@@ -208,6 +208,25 @@ int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag, int for_ctx)
|
||||
|
||||
/* end extensions defined in crypto_impl.c */
|
||||
|
||||
typedef struct {
|
||||
int (*activate)(void *ctx);
|
||||
int (*deactivate)(void *ctx);
|
||||
int (*random)(void *ctx, void *buffer, int length);
|
||||
int (*hmac)(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out);
|
||||
int (*kdf)(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key);
|
||||
int (*cipher)(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out);
|
||||
int (*set_cipher)(void *ctx, const char *cipher_name);
|
||||
const char* (*get_cipher)(void *ctx);
|
||||
int (*get_key_sz)(void *ctx);
|
||||
int (*get_iv_sz)(void *ctx);
|
||||
int (*get_block_sz)(void *ctx);
|
||||
int (*get_hmac_sz)(void *ctx);
|
||||
int (*ctx_copy)(void *target_ctx, void *source_ctx);
|
||||
int (*ctx_cmp)(void *c1, void *c2);
|
||||
int (*ctx_init)(void **ctx);
|
||||
int (*ctx_free)(void **ctx);
|
||||
} sqlcipher_provider;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
/* END CRYPTO */
|
||||
|
||||
+65
-21
@@ -36,7 +36,6 @@
|
||||
#include "sqliteInt.h"
|
||||
#include "btreeInt.h"
|
||||
#include "crypto.h"
|
||||
#include "crypto_impl.h"
|
||||
#ifndef OMIT_MEMLOCK
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
#include <sys/mman.h>
|
||||
@@ -62,7 +61,8 @@ typedef struct {
|
||||
unsigned char *key;
|
||||
unsigned char *hmac_key;
|
||||
char *pass;
|
||||
void *lib_ctx;
|
||||
sqlcipher_provider *provider;
|
||||
void *provider_ctx;
|
||||
} cipher_ctx;
|
||||
|
||||
void sqlcipher_cipher_ctx_free(cipher_ctx **);
|
||||
@@ -78,6 +78,8 @@ int sqlcipher_page_hmac(cipher_ctx *, Pgno, unsigned char *, int, unsigned char
|
||||
static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
|
||||
static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
|
||||
|
||||
static sqlcipher_provider *default_provider = NULL;
|
||||
|
||||
struct codec_ctx {
|
||||
int kdf_salt_sz;
|
||||
int page_sz;
|
||||
@@ -89,6 +91,39 @@ struct codec_ctx {
|
||||
cipher_ctx *write_ctx;
|
||||
};
|
||||
|
||||
static int sqlcipher_register_provider(sqlcipher_provider *p) {
|
||||
if(default_provider != NULL) {
|
||||
sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
|
||||
}
|
||||
default_provider = p;
|
||||
}
|
||||
|
||||
void sqlcipher_activate() {
|
||||
sqlcipher_provider *p;
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
p = sqlcipher_malloc(sizeof(sqlcipher_provider));
|
||||
{
|
||||
#ifdef SQLCIPHER_CRYPTO_OPENSSL
|
||||
extern int sqlcipher_openssl_setup(sqlcipher_provider *p);
|
||||
sqlcipher_openssl_setup(p);
|
||||
#elif SQLCIPHER_CRYPTO_LIBTOMCRYPT
|
||||
extern int sqlcipher_ltc_setup(sqlcipher_provider *p);
|
||||
sqlcipher_ltc_setup(p);
|
||||
#endif
|
||||
}
|
||||
sqlcipher_register_provider(p);
|
||||
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
}
|
||||
|
||||
void sqlcipher_deactivate() {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
if(default_provider != NULL) {
|
||||
sqlcipher_free(default_provider, sizeof(sqlcipher_provider));
|
||||
default_provider = NULL;
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
}
|
||||
|
||||
/* constant time memset using volitile to avoid having the memset
|
||||
optimized out by the compiler.
|
||||
@@ -193,7 +228,11 @@ int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
|
||||
ctx = *iCtx;
|
||||
if(ctx == NULL) return SQLITE_NOMEM;
|
||||
|
||||
if((rc = sqlcipher_ctx_init(&ctx->lib_ctx)) != SQLITE_OK) return rc;
|
||||
ctx->provider = (sqlcipher_provider *) sqlcipher_malloc(sizeof(sqlcipher_provider));
|
||||
if(ctx->provider == NULL) return SQLITE_NOMEM;
|
||||
memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider));
|
||||
|
||||
if((rc = ctx->provider->ctx_init(&ctx->provider_ctx)) != SQLITE_OK) return rc;
|
||||
ctx->key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);
|
||||
ctx->hmac_key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);
|
||||
if(ctx->key == NULL) return SQLITE_NOMEM;
|
||||
@@ -211,7 +250,8 @@ int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
|
||||
void sqlcipher_cipher_ctx_free(cipher_ctx **iCtx) {
|
||||
cipher_ctx *ctx = *iCtx;
|
||||
CODEC_TRACE(("cipher_ctx_free: entered iCtx=%p\n", iCtx));
|
||||
sqlcipher_ctx_free(&ctx->lib_ctx);
|
||||
ctx->provider->ctx_free(&ctx->provider_ctx);
|
||||
sqlcipher_free(ctx->provider, sizeof(sqlcipher_provider));
|
||||
sqlcipher_free(ctx->key, ctx->key_sz);
|
||||
sqlcipher_free(ctx->hmac_key, ctx->key_sz);
|
||||
sqlcipher_free(ctx->pass, ctx->pass_sz);
|
||||
@@ -235,7 +275,7 @@ int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
|
||||
&& c1->pass_sz == c2->pass_sz
|
||||
&& c1->flags == c2->flags
|
||||
&& c1->hmac_sz == c2->hmac_sz
|
||||
&& sqlcipher_ctx_cmp(c1->lib_ctx, c2->lib_ctx)
|
||||
&& c1->provider->ctx_cmp(c1->provider_ctx, c2->provider_ctx)
|
||||
&& (
|
||||
c1->pass == c2->pass
|
||||
|| !sqlcipher_memcmp((const unsigned char*)c1->pass,
|
||||
@@ -257,7 +297,8 @@ int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
|
||||
int sqlcipher_cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
|
||||
void *key = target->key;
|
||||
void *hmac_key = target->hmac_key;
|
||||
void *lib_ctx = target->lib_ctx;
|
||||
void *provider = target->provider;
|
||||
void *provider_ctx = target->provider_ctx;
|
||||
|
||||
CODEC_TRACE(("sqlcipher_cipher_ctx_copy: entered target=%p, source=%p\n", target, source));
|
||||
sqlcipher_free(target->pass, target->pass_sz);
|
||||
@@ -269,8 +310,11 @@ int sqlcipher_cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
|
||||
target->hmac_key = hmac_key; //restore pointer to previously allocated hmac key data
|
||||
memcpy(target->hmac_key, source->hmac_key, CIPHER_MAX_KEY_SZ);
|
||||
|
||||
target->lib_ctx = lib_ctx; // restore pointer to previouly allocated evp;
|
||||
sqlcipher_ctx_copy(target->lib_ctx, source->lib_ctx);
|
||||
target->provider = provider; // restore pointer to previouly allocated provider;
|
||||
memcpy(target->provider, source->provider, sizeof(sqlcipher_provider));
|
||||
|
||||
target->provider_ctx = provider_ctx; // restore pointer to previouly allocated provider context;
|
||||
target->provider->ctx_copy(target->provider_ctx, source->provider_ctx);
|
||||
|
||||
target->pass = sqlcipher_malloc(source->pass_sz);
|
||||
if(target->pass == NULL) return SQLITE_NOMEM;
|
||||
@@ -317,12 +361,12 @@ int sqlcipher_codec_ctx_set_cipher(codec_ctx *ctx, const char *cipher_name, int
|
||||
cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
|
||||
int rc;
|
||||
|
||||
sqlcipher_set_cipher(c_ctx->lib_ctx, cipher_name);
|
||||
c_ctx->provider->set_cipher(c_ctx->provider_ctx, cipher_name);
|
||||
|
||||
c_ctx->key_sz = sqlcipher_get_key_sz(c_ctx->lib_ctx);
|
||||
c_ctx->iv_sz = sqlcipher_get_iv_sz(c_ctx->lib_ctx);
|
||||
c_ctx->block_sz = sqlcipher_get_block_sz(c_ctx->lib_ctx);
|
||||
c_ctx->hmac_sz = sqlcipher_get_hmac_sz(c_ctx->lib_ctx);
|
||||
c_ctx->key_sz = c_ctx->provider->get_key_sz(c_ctx->provider_ctx);
|
||||
c_ctx->iv_sz = c_ctx->provider->get_iv_sz(c_ctx->provider_ctx);
|
||||
c_ctx->block_sz = c_ctx->provider->get_block_sz(c_ctx->provider_ctx);
|
||||
c_ctx->hmac_sz = c_ctx->provider->get_hmac_sz(c_ctx->provider_ctx);
|
||||
c_ctx->derive_key = 1;
|
||||
|
||||
if(for_ctx == 2)
|
||||
@@ -334,7 +378,7 @@ int sqlcipher_codec_ctx_set_cipher(codec_ctx *ctx, const char *cipher_name, int
|
||||
|
||||
const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx) {
|
||||
cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
|
||||
return sqlcipher_get_cipher(c_ctx->lib_ctx);
|
||||
return c_ctx->provider->get_cipher(c_ctx->provider_ctx);
|
||||
}
|
||||
|
||||
int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx) {
|
||||
@@ -519,7 +563,7 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_f
|
||||
|
||||
if(fd == NULL || sqlite3OsRead(fd, ctx->kdf_salt, FILE_HEADER_SZ, 0) != SQLITE_OK) {
|
||||
/* if unable to read the bytes, generate random salt */
|
||||
if(sqlcipher_random(&ctx->read_ctx->lib_ctx, ctx->kdf_salt, FILE_HEADER_SZ) != 1) return SQLITE_ERROR;
|
||||
if(ctx->read_ctx->provider->random(&ctx->read_ctx->provider_ctx, ctx->kdf_salt, FILE_HEADER_SZ) != 1) return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc;
|
||||
@@ -580,8 +624,8 @@ int sqlcipher_page_hmac(cipher_ctx *ctx, Pgno pgno, unsigned char *in, int in_sz
|
||||
/* include the encrypted page data, initialization vector, and page number in HMAC. This will
|
||||
prevent both tampering with the ciphertext, manipulation of the IV, or resequencing otherwise
|
||||
valid pages out of order in a database */
|
||||
sqlcipher_hmac(
|
||||
ctx->lib_ctx, ctx->hmac_key,
|
||||
ctx->provider->hmac(
|
||||
ctx->provider_ctx, ctx->hmac_key,
|
||||
ctx->key_sz, in,
|
||||
in_sz, (unsigned char*) &pgno_raw,
|
||||
sizeof(pgno), out);
|
||||
@@ -624,7 +668,7 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
|
||||
|
||||
if(mode == CIPHER_ENCRYPT) {
|
||||
/* start at front of the reserve block, write random data to the end */
|
||||
if(sqlcipher_random(c_ctx->lib_ctx, iv_out, c_ctx->reserve_sz) != 1) return SQLITE_ERROR;
|
||||
if(c_ctx->provider->random(c_ctx->provider_ctx, iv_out, c_ctx->reserve_sz) != 1) return SQLITE_ERROR;
|
||||
} else { /* CIPHER_DECRYPT */
|
||||
memcpy(iv_out, iv_in, c_ctx->iv_sz); /* copy the iv from the input to output buffer */
|
||||
}
|
||||
@@ -657,7 +701,7 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
|
||||
}
|
||||
}
|
||||
|
||||
sqlcipher_cipher(c_ctx->lib_ctx, mode, c_ctx->key, c_ctx->key_sz, iv_out, in, size, out);
|
||||
c_ctx->provider->cipher(c_ctx->provider_ctx, mode, c_ctx->key, c_ctx->key_sz, iv_out, in, size, out);
|
||||
|
||||
if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_ENCRYPT)) {
|
||||
sqlcipher_page_hmac(c_ctx, pgno, out_start, size + c_ctx->iv_sz, hmac_out);
|
||||
@@ -695,7 +739,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
|
||||
cipher_hex2bin(z, n, c_ctx->key);
|
||||
} else {
|
||||
CODEC_TRACE(("codec_key_derive: deriving key using full PBKDF2 with %d iterations\n", c_ctx->kdf_iter));
|
||||
sqlcipher_kdf(c_ctx->lib_ctx, c_ctx->pass, c_ctx->pass_sz,
|
||||
c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->pass, c_ctx->pass_sz,
|
||||
ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
|
||||
c_ctx->key_sz, c_ctx->key);
|
||||
|
||||
@@ -721,7 +765,7 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
|
||||
c_ctx->fast_kdf_iter));
|
||||
|
||||
|
||||
sqlcipher_kdf(c_ctx->lib_ctx, (const char*)c_ctx->key, c_ctx->key_sz,
|
||||
c_ctx->provider->kdf(c_ctx->provider_ctx, (const char*)c_ctx->key, c_ctx->key_sz,
|
||||
ctx->hmac_kdf_salt, ctx->kdf_salt_sz, c_ctx->fast_kdf_iter,
|
||||
c_ctx->key_sz, c_ctx->hmac_key);
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
** SQLCipher
|
||||
** crypto.h developed by Stephen Lombardo (Zetetic LLC)
|
||||
** sjlombardo at zetetic dot net
|
||||
** http://zetetic.net
|
||||
**
|
||||
** Copyright (c) 2008, ZETETIC LLC
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the ZETETIC LLC nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
|
||||
** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
*/
|
||||
/* BEGIN CRYPTO_IMPL */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
#ifndef CRYPTO_IMPL_H
|
||||
#define CRYPTO_IMPL_H
|
||||
|
||||
void sqlcipher_activate(void *ctx);
|
||||
void sqlcipher_deactivate(void *ctx);
|
||||
int sqlcipher_random (void *ctx, void *buffer, int length);
|
||||
int sqlcipher_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out);
|
||||
int sqlcipher_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key);
|
||||
int sqlcipher_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out);
|
||||
int sqlcipher_set_cipher(void *ctx, const char *cipher_name);
|
||||
const char* sqlcipher_get_cipher(void *ctx);
|
||||
int sqlcipher_get_key_sz(void *ctx);
|
||||
int sqlcipher_get_iv_sz(void *ctx);
|
||||
int sqlcipher_get_block_sz(void *ctx);
|
||||
int sqlcipher_get_hmac_sz(void *ctx);
|
||||
int sqlcipher_ctx_copy(void *target_ctx, void *source_ctx);
|
||||
int sqlcipher_ctx_cmp(void *c1, void *c2);
|
||||
int sqlcipher_ctx_init(void **ctx);
|
||||
int sqlcipher_ctx_free(void **ctx);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
/* END CRYPTO_IMPL */
|
||||
+57
-27
@@ -1,17 +1,24 @@
|
||||
#ifdef SQLCIPHER_CRYPTO_LIBTOMCRYPT
|
||||
#include <tomcrypt.h>
|
||||
|
||||
void sqlcipher_activate(void *ctx) {
|
||||
register_prng(&fortuna_desc);
|
||||
register_cipher(&rijndael_desc);
|
||||
register_hash(&sha256_desc);
|
||||
register_hash(&sha1_desc);
|
||||
static unsigned int ltc_init = 0;
|
||||
|
||||
static int sqlcipher_ltc_activate(void *ctx) {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
if(ltc_init == 0) {
|
||||
register_prng(&fortuna_desc);
|
||||
register_cipher(&rijndael_desc);
|
||||
register_hash(&sha256_desc);
|
||||
register_hash(&sha1_desc);
|
||||
ltc_init = 1;
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
}
|
||||
|
||||
void sqlcipher_deactivate(void *ctx) {
|
||||
static int sqlcipher_ltc_deactivate(void *ctx) {
|
||||
}
|
||||
|
||||
int sqlcipher_random(void *ctx, void *buffer, int length) {
|
||||
static int sqlcipher_ltc_random(void *ctx, void *buffer, int length) {
|
||||
prng_state prng;
|
||||
int random_value;
|
||||
int random_buffer_sz = 256;
|
||||
@@ -27,7 +34,7 @@ int sqlcipher_random(void *ctx, void *buffer, int length) {
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
|
||||
static int sqlcipher_ltc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
|
||||
int rc, hash_idx;
|
||||
hmac_state hmac;
|
||||
unsigned long outlen = key_sz;
|
||||
@@ -40,7 +47,7 @@ int sqlcipher_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
|
||||
static int sqlcipher_ltc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
|
||||
int rc, hash_idx;
|
||||
unsigned long outlen = key_sz;
|
||||
|
||||
@@ -50,11 +57,15 @@ int sqlcipher_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned ch
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
|
||||
static const char* sqlcipher_ltc_get_cipher(void *ctx) {
|
||||
return "rijndael";
|
||||
}
|
||||
|
||||
static int sqlcipher_ltc_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
|
||||
int rc, cipher_idx, hash_idx;
|
||||
symmetric_CBC cbc;
|
||||
|
||||
if((cipher_idx = find_cipher(sqlcipher_get_cipher(ctx))) == -1) return SQLITE_ERROR;
|
||||
if((cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx))) == -1) return SQLITE_ERROR;
|
||||
if((hash_idx = find_hash("sha256")) == -1) return SQLITE_ERROR;
|
||||
if((rc = cbc_start(cipher_idx, iv, key, key_sz, 0, &cbc)) != CRYPT_OK) return SQLITE_ERROR;
|
||||
rc = mode == 1 ? cbc_encrypt(in, out, in_sz, &cbc) : cbc_decrypt(in, out, in_sz, &cbc);
|
||||
@@ -63,47 +74,66 @@ int sqlcipher_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsign
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_set_cipher(void *ctx, const char *cipher_name) {
|
||||
static int sqlcipher_ltc_set_cipher(void *ctx, const char *cipher_name) {
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
const char* sqlcipher_get_cipher(void *ctx) {
|
||||
return "rijndael";
|
||||
}
|
||||
|
||||
int sqlcipher_get_key_sz(void *ctx) {
|
||||
int cipher_idx = find_cipher(sqlcipher_get_cipher(ctx));
|
||||
static int sqlcipher_ltc_get_key_sz(void *ctx) {
|
||||
int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
|
||||
return cipher_descriptor[cipher_idx].max_key_length;
|
||||
}
|
||||
|
||||
int sqlcipher_get_iv_sz(void *ctx) {
|
||||
int cipher_idx = find_cipher(sqlcipher_get_cipher(ctx));
|
||||
static int sqlcipher_ltc_get_iv_sz(void *ctx) {
|
||||
int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
|
||||
return cipher_descriptor[cipher_idx].block_length;
|
||||
}
|
||||
|
||||
int sqlcipher_get_block_sz(void *ctx) {
|
||||
int cipher_idx = find_cipher(sqlcipher_get_cipher(ctx));
|
||||
static int sqlcipher_ltc_get_block_sz(void *ctx) {
|
||||
int cipher_idx = find_cipher(sqlcipher_ltc_get_cipher(ctx));
|
||||
return cipher_descriptor[cipher_idx].block_length;
|
||||
}
|
||||
|
||||
int sqlcipher_get_hmac_sz(void *ctx) {
|
||||
static int sqlcipher_ltc_get_hmac_sz(void *ctx) {
|
||||
int hash_idx = find_hash("sha1");
|
||||
return hash_descriptor[hash_idx].hashsize;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_copy(void *target_ctx, void *source_ctx) {
|
||||
static int sqlcipher_ltc_ctx_copy(void *target_ctx, void *source_ctx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_cmp(void *c1, void *c2) {
|
||||
static int sqlcipher_ltc_ctx_cmp(void *c1, void *c2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_init(void **ctx) {
|
||||
static int sqlcipher_ltc_ctx_init(void **ctx) {
|
||||
sqlcipher_ltc_activate(&ctx);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_free(void **ctx) {
|
||||
static int sqlcipher_ltc_ctx_free(void **ctx) {
|
||||
sqlcipher_ltc_deactivate(&ctx);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_ltc_setup(sqlcipher_provider *p) {
|
||||
p->activate = sqlcipher_ltc_activate;
|
||||
p->deactivate = sqlcipher_ltc_deactivate;
|
||||
p->random = sqlcipher_ltc_random;
|
||||
p->hmac = sqlcipher_ltc_hmac;
|
||||
p->kdf = sqlcipher_ltc_kdf;
|
||||
p->cipher = sqlcipher_ltc_cipher;
|
||||
p->set_cipher = sqlcipher_ltc_set_cipher;
|
||||
p->get_cipher = sqlcipher_ltc_get_cipher;
|
||||
p->get_key_sz = sqlcipher_ltc_get_key_sz;
|
||||
p->get_iv_sz = sqlcipher_ltc_get_iv_sz;
|
||||
p->get_block_sz = sqlcipher_ltc_get_block_sz;
|
||||
p->get_hmac_sz = sqlcipher_ltc_get_hmac_sz;
|
||||
p->ctx_copy = sqlcipher_ltc_ctx_copy;
|
||||
p->ctx_cmp = sqlcipher_ltc_ctx_cmp;
|
||||
p->ctx_init = sqlcipher_ltc_ctx_init;
|
||||
p->ctx_free = sqlcipher_ltc_ctx_free;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
+40
-17
@@ -11,13 +11,14 @@ typedef struct {
|
||||
static unsigned int openssl_external_init = 0;
|
||||
static unsigned int openssl_init_count = 0;
|
||||
|
||||
|
||||
/* activate and initialize sqlcipher. Most importantly, this will automatically
|
||||
intialize OpenSSL's EVP system if it hasn't already be externally. Note that
|
||||
this function may be called multiple times as new codecs are intiialized.
|
||||
Thus it performs some basic counting to ensure that only the last and final
|
||||
sqlcipher_deactivate() will free the EVP structures.
|
||||
sqlcipher_openssl_deactivate() will free the EVP structures.
|
||||
*/
|
||||
void sqlcipher_activate(void *ctx) {
|
||||
static int sqlcipher_openssl_activate(void *ctx) {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
|
||||
/* we'll initialize openssl and increment the internal init counter
|
||||
@@ -39,7 +40,7 @@ void sqlcipher_activate(void *ctx) {
|
||||
/* deactivate SQLCipher, most imporantly decremeting the activation count and
|
||||
freeing the EVP structures on the final deactivation to ensure that
|
||||
OpenSSL memory is cleaned up */
|
||||
void sqlcipher_deactivate(void *ctx) {
|
||||
static int sqlcipher_openssl_deactivate(void *ctx) {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
/* If it is initialized externally, then the init counter should never be greater than zero.
|
||||
This should prevent SQLCipher from "cleaning up" openssl
|
||||
@@ -57,11 +58,11 @@ void sqlcipher_deactivate(void *ctx) {
|
||||
}
|
||||
|
||||
/* generate a defined number of pseudorandom bytes */
|
||||
int sqlcipher_random (void *ctx, void *buffer, int length) {
|
||||
static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) {
|
||||
return RAND_bytes((unsigned char *)buffer, length);
|
||||
}
|
||||
|
||||
int sqlcipher_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
|
||||
static int sqlcipher_openssl_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, unsigned char *in2, int in2_sz, unsigned char *out) {
|
||||
HMAC_CTX hctx;
|
||||
HMAC_CTX_init(&hctx);
|
||||
HMAC_Init_ex(&hctx, hmac_key, key_sz, EVP_sha1(), NULL);
|
||||
@@ -72,12 +73,12 @@ int sqlcipher_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
|
||||
static int sqlcipher_openssl_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int salt_sz, int workfactor, int key_sz, unsigned char *key) {
|
||||
PKCS5_PBKDF2_HMAC_SHA1(pass, pass_sz, salt, salt_sz, workfactor, key_sz, key);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
|
||||
static int sqlcipher_openssl_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsigned char *iv, unsigned char *in, int in_sz, unsigned char *out) {
|
||||
EVP_CIPHER_CTX ectx;
|
||||
int tmp_csz, csz;
|
||||
|
||||
@@ -94,49 +95,71 @@ int sqlcipher_cipher(void *ctx, int mode, unsigned char *key, int key_sz, unsign
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_set_cipher(void *ctx, const char *cipher_name) {
|
||||
static int sqlcipher_openssl_set_cipher(void *ctx, const char *cipher_name) {
|
||||
openssl_ctx *o_ctx = (openssl_ctx *)ctx;
|
||||
o_ctx->evp_cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
const char* sqlcipher_get_cipher(void *ctx) {
|
||||
static const char* sqlcipher_openssl_get_cipher(void *ctx) {
|
||||
return EVP_CIPHER_name(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_key_sz(void *ctx) {
|
||||
static int sqlcipher_openssl_get_key_sz(void *ctx) {
|
||||
return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_iv_sz(void *ctx) {
|
||||
static int sqlcipher_openssl_get_iv_sz(void *ctx) {
|
||||
return EVP_CIPHER_iv_length(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_block_sz(void *ctx) {
|
||||
static int sqlcipher_openssl_get_block_sz(void *ctx) {
|
||||
return EVP_CIPHER_block_size(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_hmac_sz(void *ctx) {
|
||||
static int sqlcipher_openssl_get_hmac_sz(void *ctx) {
|
||||
return EVP_MD_size(EVP_sha1());
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_copy(void *target_ctx, void *source_ctx) {
|
||||
static int sqlcipher_openssl_ctx_copy(void *target_ctx, void *source_ctx) {
|
||||
memcpy(target_ctx, source_ctx, sizeof(openssl_ctx));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_cmp(void *c1, void *c2) {
|
||||
static int sqlcipher_openssl_ctx_cmp(void *c1, void *c2) {
|
||||
return ((openssl_ctx *)c1)->evp_cipher == ((openssl_ctx *)c2)->evp_cipher;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_init(void **ctx) {
|
||||
static int sqlcipher_openssl_ctx_init(void **ctx) {
|
||||
*ctx = sqlcipher_malloc(sizeof(openssl_ctx));
|
||||
if(*ctx == NULL) return SQLITE_NOMEM;
|
||||
sqlcipher_openssl_activate(*ctx);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_free(void **ctx) {
|
||||
static int sqlcipher_openssl_ctx_free(void **ctx) {
|
||||
sqlcipher_free(*ctx, sizeof(openssl_ctx));
|
||||
sqlcipher_openssl_deactivate(*ctx);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_openssl_setup(sqlcipher_provider *p) {
|
||||
p->activate = sqlcipher_openssl_activate;
|
||||
p->deactivate = sqlcipher_openssl_deactivate;
|
||||
p->random = sqlcipher_openssl_random;
|
||||
p->hmac = sqlcipher_openssl_hmac;
|
||||
p->kdf = sqlcipher_openssl_kdf;
|
||||
p->cipher = sqlcipher_openssl_cipher;
|
||||
p->set_cipher = sqlcipher_openssl_set_cipher;
|
||||
p->get_cipher = sqlcipher_openssl_get_cipher;
|
||||
p->get_key_sz = sqlcipher_openssl_get_key_sz;
|
||||
p->get_iv_sz = sqlcipher_openssl_get_iv_sz;
|
||||
p->get_block_sz = sqlcipher_openssl_get_block_sz;
|
||||
p->get_hmac_sz = sqlcipher_openssl_get_hmac_sz;
|
||||
p->ctx_copy = sqlcipher_openssl_ctx_copy;
|
||||
p->ctx_cmp = sqlcipher_openssl_ctx_cmp;
|
||||
p->ctx_init = sqlcipher_openssl_ctx_init;
|
||||
p->ctx_free = sqlcipher_openssl_ctx_free;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -92,7 +92,6 @@ if {$addstatic} {
|
||||
#
|
||||
foreach hdr {
|
||||
crypto.h
|
||||
crypto_impl.h
|
||||
btree.h
|
||||
btreeInt.h
|
||||
fts3.h
|
||||
|
||||
Reference in New Issue
Block a user