separate out openssl implementation to separate source file
This commit is contained in:
parent
d85cc20dc8
commit
1bc791708a
|
@ -38,12 +38,12 @@
|
|||
#include "btreeInt.h"
|
||||
#include "crypto.h"
|
||||
|
||||
const char* codec_get_cipher_version() {
|
||||
static const char* codec_get_cipher_version() {
|
||||
return CIPHER_VERSION;
|
||||
}
|
||||
|
||||
/* Generate code to return a string value */
|
||||
void codec_vdbe_return_static_string(Parse *pParse, const char *zLabel, const char *value){
|
||||
static void codec_vdbe_return_static_string(Parse *pParse, const char *zLabel, const char *value){
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
sqlite3VdbeSetNumCols(v, 1);
|
||||
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
|
||||
|
@ -69,7 +69,7 @@ static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ct
|
|||
return rc;
|
||||
}
|
||||
|
||||
int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
|
||||
static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) {
|
||||
struct Db *pDb = &db->aDb[nDb];
|
||||
CODEC_TRACE(("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db, nDb, (char *)zKey, nKey, for_ctx));
|
||||
if(pDb->pBt) {
|
||||
|
|
12
src/crypto.h
12
src/crypto.h
|
@ -82,6 +82,15 @@
|
|||
#define HMAC_SALT_MASK 0x3a
|
||||
#endif
|
||||
|
||||
#ifndef CIPHER_MAX_IV_SZ
|
||||
#define CIPHER_MAX_IV_SZ 16
|
||||
#endif
|
||||
|
||||
#ifndef CIPHER_MAX_KEY_SZ
|
||||
#define CIPHER_MAX_KEY_SZ 64
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CODEC_DEBUG
|
||||
#define CODEC_TRACE(X) {printf X;fflush(stdout);}
|
||||
#else
|
||||
|
@ -138,6 +147,9 @@ static void cipher_hex2bin(const char *hex, int sz, unsigned char *out){
|
|||
|
||||
typedef struct codec_ctx codec_ctx;
|
||||
|
||||
void sqlcipher_free(void *ptr, int sz);
|
||||
void* sqlcipher_malloc(int sz);
|
||||
|
||||
/* utility functions */
|
||||
void* sqlcipher_memset(void *v, unsigned char value, int len);
|
||||
int sqlcipher_ismemset(const void *v, unsigned char value, int len);
|
||||
|
|
|
@ -33,9 +33,6 @@
|
|||
/* BEGIN CRYPTO */
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include "sqliteInt.h"
|
||||
#include "btreeInt.h"
|
||||
#include "crypto.h"
|
||||
|
@ -47,14 +44,13 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#include "crypto_openssl.c"
|
||||
|
||||
/* the default implementation of SQLCipher uses a cipher_ctx
|
||||
to keep track of read / write state separately. The following
|
||||
struct and associated functions are defined here */
|
||||
typedef struct {
|
||||
int derive_key;
|
||||
EVP_CIPHER *evp_cipher;
|
||||
EVP_CIPHER_CTX ectx;
|
||||
HMAC_CTX hctx;
|
||||
int kdf_iter;
|
||||
int fast_kdf_iter;
|
||||
int key_sz;
|
||||
|
@ -67,6 +63,7 @@ typedef struct {
|
|||
unsigned char *key;
|
||||
unsigned char *hmac_key;
|
||||
char *pass;
|
||||
void *lib_ctx;
|
||||
} cipher_ctx;
|
||||
|
||||
void sqlcipher_cipher_ctx_free(cipher_ctx **);
|
||||
|
@ -82,9 +79,6 @@ 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 unsigned int openssl_external_init = 0;
|
||||
static unsigned int openssl_init_count = 0;
|
||||
|
||||
struct codec_ctx {
|
||||
int kdf_salt_sz;
|
||||
int page_sz;
|
||||
|
@ -96,50 +90,6 @@ struct codec_ctx {
|
|||
cipher_ctx *write_ctx;
|
||||
};
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
void sqlcipher_activate() {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
|
||||
/* we'll initialize openssl and increment the internal init counter
|
||||
but only if it hasn't been initalized outside of SQLCipher by this program
|
||||
e.g. on startup */
|
||||
if(openssl_init_count == 0 && EVP_get_cipherbyname(CIPHER) != NULL) {
|
||||
openssl_external_init = 1;
|
||||
}
|
||||
|
||||
if(openssl_external_init == 0) {
|
||||
if(openssl_init_count == 0) {
|
||||
OpenSSL_add_all_algorithms();
|
||||
}
|
||||
openssl_init_count++;
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
}
|
||||
|
||||
/* 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() {
|
||||
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
|
||||
when something else in the program might be using it. */
|
||||
if(openssl_external_init == 0) {
|
||||
openssl_init_count--;
|
||||
/* if the counter reaches zero after it's decremented release EVP memory
|
||||
Note: this code will only be reached if OpensSSL_add_all_algorithms()
|
||||
is called by SQLCipher internally. */
|
||||
if(openssl_init_count == 0) {
|
||||
EVP_cleanup();
|
||||
}
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
}
|
||||
|
||||
/* constant time memset using volitile to avoid having the memset
|
||||
optimized out by the compiler.
|
||||
|
@ -185,11 +135,6 @@ int sqlcipher_memcmp(const void *v0, const void *v1, int len) {
|
|||
return (result != 0);
|
||||
}
|
||||
|
||||
/* generate a defined number of pseudorandom bytes */
|
||||
int sqlcipher_random (void *buffer, int length) {
|
||||
return RAND_bytes((unsigned char *)buffer, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free and wipe memory. Uses SQLites internal sqlite3_free so that memory
|
||||
* can be countend and memory leak detection works in the test suite.
|
||||
|
@ -243,13 +188,15 @@ void* sqlcipher_malloc(int sz) {
|
|||
* returns SQLITE_NOMEM if an error occured allocating memory
|
||||
*/
|
||||
int sqlcipher_cipher_ctx_init(cipher_ctx **iCtx) {
|
||||
int rc;
|
||||
cipher_ctx *ctx;
|
||||
*iCtx = (cipher_ctx *) sqlcipher_malloc(sizeof(cipher_ctx));
|
||||
ctx = *iCtx;
|
||||
if(ctx == NULL) return SQLITE_NOMEM;
|
||||
|
||||
ctx->key = (unsigned char *) sqlcipher_malloc(EVP_MAX_KEY_LENGTH);
|
||||
ctx->hmac_key = (unsigned char *) sqlcipher_malloc(EVP_MAX_KEY_LENGTH);
|
||||
if((rc = sqlcipher_ctx_init(&ctx->lib_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;
|
||||
if(ctx->hmac_key == NULL) return SQLITE_NOMEM;
|
||||
|
||||
|
@ -265,6 +212,7 @@ 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);
|
||||
sqlcipher_free(ctx->key, ctx->key_sz);
|
||||
sqlcipher_free(ctx->hmac_key, ctx->key_sz);
|
||||
sqlcipher_free(ctx->pass, ctx->pass_sz);
|
||||
|
@ -281,14 +229,14 @@ int sqlcipher_cipher_ctx_cmp(cipher_ctx *c1, cipher_ctx *c2) {
|
|||
CODEC_TRACE(("sqlcipher_cipher_ctx_cmp: entered c1=%p c2=%p\n", c1, c2));
|
||||
|
||||
if(
|
||||
c1->evp_cipher == c2->evp_cipher
|
||||
&& c1->iv_sz == c2->iv_sz
|
||||
c1->iv_sz == c2->iv_sz
|
||||
&& c1->kdf_iter == c2->kdf_iter
|
||||
&& c1->fast_kdf_iter == c2->fast_kdf_iter
|
||||
&& c1->key_sz == c2->key_sz
|
||||
&& 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->pass == c2->pass
|
||||
|| !sqlcipher_memcmp((const unsigned char*)c1->pass,
|
||||
|
@ -310,16 +258,20 @@ 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;
|
||||
|
||||
CODEC_TRACE(("sqlcipher_cipher_ctx_copy: entered target=%p, source=%p\n", target, source));
|
||||
sqlcipher_free(target->pass, target->pass_sz);
|
||||
memcpy(target, source, sizeof(cipher_ctx));
|
||||
|
||||
target->key = key; //restore pointer to previously allocated key data
|
||||
memcpy(target->key, source->key, EVP_MAX_KEY_LENGTH);
|
||||
memcpy(target->key, source->key, CIPHER_MAX_KEY_SZ);
|
||||
|
||||
target->hmac_key = hmac_key; //restore pointer to previously allocated hmac key data
|
||||
memcpy(target->hmac_key, source->hmac_key, EVP_MAX_KEY_LENGTH);
|
||||
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->pass = sqlcipher_malloc(source->pass_sz);
|
||||
if(target->pass == NULL) return SQLITE_NOMEM;
|
||||
|
@ -366,11 +318,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;
|
||||
|
||||
c_ctx->evp_cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name);
|
||||
c_ctx->key_sz = EVP_CIPHER_key_length(c_ctx->evp_cipher);
|
||||
c_ctx->iv_sz = EVP_CIPHER_iv_length(c_ctx->evp_cipher);
|
||||
c_ctx->block_sz = EVP_CIPHER_block_size(c_ctx->evp_cipher);
|
||||
c_ctx->hmac_sz = EVP_MD_size(EVP_sha1());
|
||||
sqlcipher_set_cipher(c_ctx->lib_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->derive_key = 1;
|
||||
|
||||
if(for_ctx == 2)
|
||||
|
@ -382,8 +335,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;
|
||||
EVP_CIPHER *evp_cipher = c_ctx->evp_cipher;
|
||||
return EVP_CIPHER_name(evp_cipher);
|
||||
return sqlcipher_get_cipher(c_ctx->lib_ctx);
|
||||
}
|
||||
|
||||
int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx) {
|
||||
|
@ -444,7 +396,7 @@ unsigned char sqlcipher_get_hmac_salt_mask() {
|
|||
|
||||
/* set the codec flag for whether this individual database should be using hmac */
|
||||
int sqlcipher_codec_ctx_set_use_hmac(codec_ctx *ctx, int use) {
|
||||
int reserve = EVP_MAX_IV_LENGTH; /* base reserve size will be IV only */
|
||||
int reserve = CIPHER_MAX_IV_SZ; /* base reserve size will be IV only */
|
||||
|
||||
if(use) reserve += ctx->read_ctx->hmac_sz; /* if reserve will include hmac, update that size */
|
||||
|
||||
|
@ -626,16 +578,14 @@ int sqlcipher_page_hmac(cipher_ctx *ctx, Pgno pgno, unsigned char *in, int in_sz
|
|||
memcpy(pgno_raw, &pgno, sizeof(pgno));
|
||||
}
|
||||
|
||||
HMAC_CTX_init(&ctx->hctx);
|
||||
HMAC_Init_ex(&ctx->hctx, ctx->hmac_key, ctx->key_sz, EVP_sha1(), NULL);
|
||||
|
||||
/* 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 */
|
||||
HMAC_Update(&ctx->hctx, in, in_sz);
|
||||
HMAC_Update(&ctx->hctx, (const unsigned char*) pgno_raw, sizeof(pgno));
|
||||
HMAC_Final(&ctx->hctx, out, NULL);
|
||||
HMAC_CTX_cleanup(&ctx->hctx);
|
||||
sqlcipher_hmac(
|
||||
ctx->hmac_key, ctx->key_sz,
|
||||
in, in_sz,
|
||||
(unsigned char*) &pgno_raw, sizeof(pgno),
|
||||
out);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
@ -708,16 +658,7 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
|
|||
}
|
||||
}
|
||||
|
||||
EVP_CipherInit(&c_ctx->ectx, c_ctx->evp_cipher, NULL, NULL, mode);
|
||||
EVP_CIPHER_CTX_set_padding(&c_ctx->ectx, 0);
|
||||
EVP_CipherInit(&c_ctx->ectx, NULL, c_ctx->key, iv_out, mode);
|
||||
EVP_CipherUpdate(&c_ctx->ectx, out, &tmp_csz, in, size);
|
||||
csz = tmp_csz;
|
||||
out += tmp_csz;
|
||||
EVP_CipherFinal(&c_ctx->ectx, out, &tmp_csz);
|
||||
csz += tmp_csz;
|
||||
EVP_CIPHER_CTX_cleanup(&c_ctx->ectx);
|
||||
assert(size == csz);
|
||||
sqlcipher_cipher(c_ctx->lib_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);
|
||||
|
@ -755,7 +696,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));
|
||||
PKCS5_PBKDF2_HMAC_SHA1( c_ctx->pass, c_ctx->pass_sz,
|
||||
sqlcipher_kdf( 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);
|
||||
|
||||
|
@ -779,7 +720,9 @@ int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
|
|||
|
||||
CODEC_TRACE(("codec_key_derive: deriving hmac key from encryption key using PBKDF2 with %d iterations\n",
|
||||
c_ctx->fast_kdf_iter));
|
||||
PKCS5_PBKDF2_HMAC_SHA1( (const char*)c_ctx->key, c_ctx->key_sz,
|
||||
|
||||
|
||||
sqlcipher_kdf( (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);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
#include <openssl/rand.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
typedef struct {
|
||||
EVP_CIPHER *evp_cipher;
|
||||
unsigned char * buffer;
|
||||
} openssl_ctx;
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
void sqlcipher_activate(void *ctx) {
|
||||
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
|
||||
/* we'll initialize openssl and increment the internal init counter
|
||||
but only if it hasn't been initalized outside of SQLCipher by this program
|
||||
e.g. on startup */
|
||||
if(openssl_init_count == 0 && EVP_get_cipherbyname(CIPHER) != NULL) {
|
||||
openssl_external_init = 1;
|
||||
}
|
||||
|
||||
if(openssl_external_init == 0) {
|
||||
if(openssl_init_count == 0) {
|
||||
OpenSSL_add_all_algorithms();
|
||||
}
|
||||
openssl_init_count++;
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
}
|
||||
|
||||
/* 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() {
|
||||
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
|
||||
when something else in the program might be using it. */
|
||||
if(openssl_external_init == 0) {
|
||||
openssl_init_count--;
|
||||
/* if the counter reaches zero after it's decremented release EVP memory
|
||||
Note: this code will only be reached if OpensSSL_add_all_algorithms()
|
||||
is called by SQLCipher internally. */
|
||||
if(openssl_init_count == 0) {
|
||||
EVP_cleanup();
|
||||
}
|
||||
}
|
||||
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
|
||||
}
|
||||
|
||||
/* generate a defined number of pseudorandom bytes */
|
||||
int sqlcipher_random (void *buffer, int length) {
|
||||
return RAND_bytes((unsigned char *)buffer, length);
|
||||
}
|
||||
|
||||
int sqlcipher_hmac(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);
|
||||
HMAC_Update(&hctx, in, in_sz);
|
||||
HMAC_Update(&hctx, in2, in2_sz);
|
||||
HMAC_Final(&hctx, out, NULL);
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_kdf(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) {
|
||||
EVP_CIPHER_CTX ectx;
|
||||
int tmp_csz, csz;
|
||||
|
||||
EVP_CipherInit(&ectx, ((openssl_ctx *)ctx)->evp_cipher, NULL, NULL, mode);
|
||||
EVP_CIPHER_CTX_set_padding(&ectx, 0); // no padding
|
||||
EVP_CipherInit(&ectx, NULL, key, iv, mode);
|
||||
EVP_CipherUpdate(&ectx, out, &tmp_csz, in, in_sz);
|
||||
csz = tmp_csz;
|
||||
out += tmp_csz;
|
||||
EVP_CipherFinal(&ectx, out, &tmp_csz);
|
||||
csz += tmp_csz;
|
||||
EVP_CIPHER_CTX_cleanup(&ectx);
|
||||
assert(in_sz == csz);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_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) {
|
||||
return EVP_CIPHER_name(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_key_sz(void *ctx) {
|
||||
return EVP_CIPHER_key_length(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_iv_sz(void *ctx) {
|
||||
return EVP_CIPHER_iv_length(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_block_sz(void *ctx) {
|
||||
return EVP_CIPHER_block_size(((openssl_ctx *)ctx)->evp_cipher);
|
||||
}
|
||||
|
||||
int sqlcipher_get_hmac_sz(void *ctx) {
|
||||
return EVP_MD_size(EVP_sha1());
|
||||
}
|
||||
|
||||
int sqlcipher_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) {
|
||||
return ((openssl_ctx *)c1)->evp_cipher == ((openssl_ctx *)c2)->evp_cipher;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_init(void **ctx) {
|
||||
*ctx = sqlcipher_malloc(sizeof(openssl_ctx));
|
||||
if(*ctx == NULL) return SQLITE_NOMEM;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int sqlcipher_ctx_free(void **ctx) {
|
||||
sqlcipher_free(*ctx, sizeof(openssl_ctx));
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue