@@ -56,10 +56,12 @@ typedef struct {
5656 int pass_sz ;
5757 int reserve_sz ;
5858 int hmac_sz ;
59+ int keyspec_sz ;
5960 unsigned int flags ;
6061 unsigned char * key ;
6162 unsigned char * hmac_key ;
6263 char * pass ;
64+ char * keyspec ;
6365 sqlcipher_provider * provider ;
6466 void * provider_ctx ;
6567} cipher_ctx ;
@@ -260,6 +262,7 @@ static void sqlcipher_cipher_ctx_free(cipher_ctx **iCtx) {
260262 sqlcipher_free (ctx -> key , ctx -> key_sz );
261263 sqlcipher_free (ctx -> hmac_key , ctx -> key_sz );
262264 sqlcipher_free (ctx -> pass , ctx -> pass_sz );
265+ sqlcipher_free (ctx -> keyspec , ctx -> keyspec_sz );
263266 sqlcipher_free (ctx , sizeof (cipher_ctx ));
264267}
265268
@@ -307,8 +310,9 @@ static int sqlcipher_cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
307310
308311 CODEC_TRACE (("sqlcipher_cipher_ctx_copy: entered target=%p, source=%p\n" , target , source ));
309312 sqlcipher_free (target -> pass , target -> pass_sz );
313+ sqlcipher_free (target -> keyspec , target -> keyspec_sz );
310314 memcpy (target , source , sizeof (cipher_ctx ));
311-
315+
312316 target -> key = key ; //restore pointer to previously allocated key data
313317 memcpy (target -> key , source -> key , CIPHER_MAX_KEY_SZ );
314318
@@ -321,31 +325,67 @@ static int sqlcipher_cipher_ctx_copy(cipher_ctx *target, cipher_ctx *source) {
321325 target -> provider_ctx = provider_ctx ; // restore pointer to previouly allocated provider context;
322326 target -> provider -> ctx_copy (target -> provider_ctx , source -> provider_ctx );
323327
324- target -> pass = sqlcipher_malloc (source -> pass_sz );
325- if (target -> pass == NULL ) return SQLITE_NOMEM ;
326- memcpy (target -> pass , source -> pass , source -> pass_sz );
327-
328+ if (source -> pass && source -> pass_sz ) {
329+ target -> pass = sqlcipher_malloc (source -> pass_sz );
330+ if (target -> pass == NULL ) return SQLITE_NOMEM ;
331+ memcpy (target -> pass , source -> pass , source -> pass_sz );
332+ }
333+ if (source -> keyspec && source -> keyspec_sz ) {
334+ target -> keyspec = sqlcipher_malloc (source -> keyspec_sz );
335+ if (target -> keyspec == NULL ) return SQLITE_NOMEM ;
336+ memcpy (target -> keyspec , source -> keyspec , source -> keyspec_sz );
337+ }
328338 return SQLITE_OK ;
329339}
330340
341+ /**
342+ * Set the keyspec for the cipher_ctx
343+ *
344+ * returns SQLITE_OK if assignment was successfull
345+ * returns SQLITE_NOMEM if an error occured allocating memory
346+ */
347+ static int sqlcipher_cipher_ctx_set_keyspec (cipher_ctx * ctx , const unsigned char * key , int key_sz , const unsigned char * salt , int salt_sz ) {
348+
349+ /* free, zero existing pointers and size */
350+ sqlcipher_free (ctx -> keyspec , ctx -> keyspec_sz );
351+ ctx -> keyspec = NULL ;
352+ ctx -> keyspec_sz = 0 ;
353+
354+ /* establic a hex-formated key specification, containing the raw encryption key and
355+ the salt used to generate it */
356+ ctx -> keyspec_sz = ((key_sz + salt_sz ) * 2 ) + 3 ;
357+ ctx -> keyspec = sqlcipher_malloc (ctx -> keyspec_sz );
358+ if (ctx -> keyspec == NULL ) return SQLITE_NOMEM ;
359+
360+ ctx -> keyspec [0 ] = 'x' ;
361+ ctx -> keyspec [1 ] = '\'' ;
362+ ctx -> keyspec [ctx -> keyspec_sz - 1 ] = '\'' ;
363+ cipher_bin2hex (key , key_sz , ctx -> keyspec + 2 );
364+ cipher_bin2hex (salt , salt_sz , ctx -> keyspec + (key_sz * 2 ) + 2 );
365+
366+ return SQLITE_OK ;
367+ }
331368
332369/**
333- * Set the raw password / key data for a cipher context
370+ * Set the passphrase for the cipher_ctx
334371 *
335372 * returns SQLITE_OK if assignment was successfull
336373 * returns SQLITE_NOMEM if an error occured allocating memory
337- * returns SQLITE_ERROR if the key couldn't be set because the pass was null or size was zero
338374 */
339375static int sqlcipher_cipher_ctx_set_pass (cipher_ctx * ctx , const void * zKey , int nKey ) {
376+
377+ /* free, zero existing pointers and size */
340378 sqlcipher_free (ctx -> pass , ctx -> pass_sz );
341- ctx -> pass_sz = nKey ;
342- if (zKey && nKey ) {
379+ ctx -> pass = NULL ;
380+ ctx -> pass_sz = 0 ;
381+
382+ if (zKey && nKey ) { /* if new password is provided, copy it */
383+ ctx -> pass_sz = nKey ;
343384 ctx -> pass = sqlcipher_malloc (nKey );
344385 if (ctx -> pass == NULL ) return SQLITE_NOMEM ;
345386 memcpy (ctx -> pass , zKey , nKey );
346- return SQLITE_OK ;
347- }
348- return SQLITE_ERROR ;
387+ }
388+ return SQLITE_OK ;
349389}
350390
351391int sqlcipher_codec_ctx_set_pass (codec_ctx * ctx , const void * zKey , int nKey , int for_ctx ) {
@@ -508,9 +548,9 @@ void* sqlcipher_codec_ctx_get_kdf_salt(codec_ctx *ctx) {
508548 return ctx -> kdf_salt ;
509549}
510550
511- void sqlcipher_codec_get_pass (codec_ctx * ctx , void * * zKey , int * nKey ) {
512- * zKey = ctx -> read_ctx -> pass ;
513- * nKey = ctx -> read_ctx -> pass_sz ;
551+ void sqlcipher_codec_get_keyspec (codec_ctx * ctx , void * * zKey , int * nKey ) {
552+ * zKey = ctx -> read_ctx -> keyspec ;
553+ * nKey = ctx -> read_ctx -> keyspec_sz ;
514554}
515555
516556int sqlcipher_codec_ctx_set_pagesize (codec_ctx * ctx , int size ) {
@@ -721,35 +761,47 @@ int sqlcipher_page_cipher(codec_ctx *ctx, int for_ctx, Pgno pgno, int mode, int
721761 * Derive an encryption key for a cipher contex key based on the raw password.
722762 *
723763 * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
724- * the key space (i.e 64 hex chars for a 256 bit key) then the key data will be used directly.
764+ * the key (i.e 64 hex chars for a 256 bit key) then the key data will be used directly.
765+
766+ * Else, if the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
767+ * the key and the salt (i.e 92 hex chars for a 256 bit key and 16 byte salt) then it will be unpacked
768+ * as the key followed by the salt.
725769 *
726770 * Otherwise, a key data will be derived using PBKDF2
727771 *
728772 * returns SQLITE_OK if initialization was successful
729773 * returns SQLITE_ERROR if the key could't be derived (for instance if pass is NULL or pass_sz is 0)
730774 */
731775static int sqlcipher_cipher_ctx_key_derive (codec_ctx * ctx , cipher_ctx * c_ctx ) {
732- CODEC_TRACE (("codec_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
776+ int rc ;
777+ CODEC_TRACE (("cipher_ctx_key_derive: entered c_ctx->pass=%s, c_ctx->pass_sz=%d \
733778 ctx->kdf_salt=%p ctx->kdf_salt_sz=%d c_ctx->kdf_iter=%d \
734779 ctx->hmac_kdf_salt=%p, c_ctx->fast_kdf_iter=%d c_ctx->key_sz=%d\n" ,
735780 c_ctx -> pass , c_ctx -> pass_sz , ctx -> kdf_salt , ctx -> kdf_salt_sz , c_ctx -> kdf_iter ,
736781 ctx -> hmac_kdf_salt , c_ctx -> fast_kdf_iter , c_ctx -> key_sz ));
737782
738783
739784 if (c_ctx -> pass && c_ctx -> pass_sz ) { // if pass is not null
740- if (c_ctx -> pass_sz == ((c_ctx -> key_sz * 2 ) + 3 ) && sqlite3StrNICmp (c_ctx -> pass ,"x'" , 2 ) == 0 ) {
785+ if (c_ctx -> pass_sz == ((c_ctx -> key_sz * 2 ) + 3 ) && sqlite3StrNICmp (c_ctx -> pass ,"x'" , 2 ) == 0 ) {
741786 int n = c_ctx -> pass_sz - 3 ; /* adjust for leading x' and tailing ' */
742787 const char * z = c_ctx -> pass + 2 ; /* adjust lead offset of x' */
743- CODEC_TRACE (("codec_key_derive : using raw key from hex\n" ));
788+ CODEC_TRACE (("cipher_ctx_key_derive : using raw key from hex\n" ));
744789 cipher_hex2bin (z , n , c_ctx -> key );
790+ } else if (c_ctx -> pass_sz == (((c_ctx -> key_sz + ctx -> kdf_salt_sz ) * 2 ) + 3 ) && sqlite3StrNICmp (c_ctx -> pass ,"x'" , 2 ) == 0 ) {
791+ const char * z = c_ctx -> pass + 2 ; /* adjust lead offset of x' */
792+ CODEC_TRACE (("cipher_ctx_key_derive: using raw key from hex\n" ));
793+ cipher_hex2bin (z , (c_ctx -> key_sz * 2 ), c_ctx -> key );
794+ cipher_hex2bin (z + (c_ctx -> key_sz * 2 ), (ctx -> kdf_salt_sz * 2 ), ctx -> kdf_salt );
745795 } else {
746- CODEC_TRACE (("codec_key_derive : deriving key using full PBKDF2 with %d iterations\n" , c_ctx -> kdf_iter ));
796+ CODEC_TRACE (("cipher_ctx_key_derive : deriving key using full PBKDF2 with %d iterations\n" , c_ctx -> kdf_iter ));
747797 c_ctx -> provider -> kdf (c_ctx -> provider_ctx , (const char * ) c_ctx -> pass , c_ctx -> pass_sz ,
748798 ctx -> kdf_salt , ctx -> kdf_salt_sz , c_ctx -> kdf_iter ,
749799 c_ctx -> key_sz , c_ctx -> key );
750-
751800 }
752801
802+ /* set the context "keyspec" containing the hex-formatted key and salt to be used when attaching databases */
803+ if ((rc = sqlcipher_cipher_ctx_set_keyspec (c_ctx , c_ctx -> key , c_ctx -> key_sz , ctx -> kdf_salt , ctx -> kdf_salt_sz )) != SQLITE_OK ) return rc ;
804+
753805 /* if this context is setup to use hmac checks, generate a seperate and different
754806 key for HMAC. In this case, we use the output of the previous KDF as the input to
755807 this KDF run. This ensures a distinct but predictable HMAC key. */
@@ -766,7 +818,7 @@ static int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
766818 ctx -> hmac_kdf_salt [i ] ^= hmac_salt_mask ;
767819 }
768820
769- CODEC_TRACE (("codec_key_derive : deriving hmac key from encryption key using PBKDF2 with %d iterations\n" ,
821+ CODEC_TRACE (("cipher_ctx_key_derive : deriving hmac key from encryption key using PBKDF2 with %d iterations\n" ,
770822 c_ctx -> fast_kdf_iter ));
771823
772824
@@ -789,12 +841,17 @@ int sqlcipher_codec_key_derive(codec_ctx *ctx) {
789841
790842 if (ctx -> write_ctx -> derive_key ) {
791843 if (sqlcipher_cipher_ctx_cmp (ctx -> write_ctx , ctx -> read_ctx ) == 0 ) {
792- // the relevant parameters are the same, just copy read key
844+ /* the relevant parameters are the same, just copy read key */
793845 if (sqlcipher_cipher_ctx_copy (ctx -> write_ctx , ctx -> read_ctx ) != SQLITE_OK ) return SQLITE_ERROR ;
794846 } else {
795847 if (sqlcipher_cipher_ctx_key_derive (ctx , ctx -> write_ctx ) != SQLITE_OK ) return SQLITE_ERROR ;
796848 }
797849 }
850+
851+ /* TODO: wipe and free passphrase after key derivation */
852+ sqlcipher_cipher_ctx_set_pass (ctx -> read_ctx , NULL , 0 );
853+ sqlcipher_cipher_ctx_set_pass (ctx -> write_ctx , NULL , 0 );
854+
798855 return SQLITE_OK ;
799856}
800857
0 commit comments