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
1011typedef 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 );
0 commit comments