@@ -756,6 +756,23 @@ void* sqlcipher_codec_ctx_get_data(codec_ctx *ctx) {
756756 return ctx -> buffer ;
757757}
758758
759+ static int sqlcipher_codec_ctx_init_kdf_salt (codec_ctx * ctx ) {
760+ sqlite3_file * fd = sqlite3PagerFile (ctx -> pBt -> pBt -> pPager );
761+
762+ if (!ctx -> need_kdf_salt ) {
763+ return SQLITE_OK ; /* don't reload salt when not needed */
764+ }
765+
766+ /* read salt from header, if present, otherwise generate a new random salt */
767+ CODEC_TRACE ("sqlcipher_codec_ctx_init_kdf_salt: obtaining salt\n" );
768+ if (fd == NULL || fd -> pMethods == 0 || sqlite3OsRead (fd , ctx -> kdf_salt , ctx -> kdf_salt_sz , 0 ) != SQLITE_OK ) {
769+ CODEC_TRACE ("sqlcipher_codec_ctx_init_kdf_salt: unable to read salt from file header, generating random\n" );
770+ if (ctx -> provider -> random (ctx -> provider_ctx , ctx -> kdf_salt , ctx -> kdf_salt_sz ) != SQLITE_OK ) return SQLITE_ERROR ;
771+ }
772+ ctx -> need_kdf_salt = 0 ;
773+ return SQLITE_OK ;
774+ }
775+
759776int sqlcipher_codec_ctx_set_kdf_salt (codec_ctx * ctx , unsigned char * salt , int size ) {
760777 if (size >= ctx -> kdf_salt_sz ) {
761778 memcpy (ctx -> kdf_salt , salt , ctx -> kdf_salt_sz );
@@ -765,8 +782,13 @@ int sqlcipher_codec_ctx_set_kdf_salt(codec_ctx *ctx, unsigned char *salt, int si
765782 return SQLITE_ERROR ;
766783}
767784
768- void * sqlcipher_codec_ctx_get_kdf_salt (codec_ctx * ctx ) {
769- return ctx -> kdf_salt ;
785+ int sqlcipher_codec_ctx_get_kdf_salt (codec_ctx * ctx , void * * salt ) {
786+ int rc = SQLITE_OK ;
787+ if (ctx -> need_kdf_salt ) {
788+ rc = sqlcipher_codec_ctx_init_kdf_salt (ctx );
789+ }
790+ * salt = ctx -> kdf_salt ;
791+ return rc ;
770792}
771793
772794void sqlcipher_codec_get_keyspec (codec_ctx * ctx , void * * zKey , int * nKey ) {
@@ -1090,17 +1112,13 @@ static int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) {
10901112 ctx -> hmac_kdf_salt , c_ctx -> fast_kdf_iter , ctx -> key_sz );
10911113
10921114
1093- if (c_ctx -> pass && c_ctx -> pass_sz ) { /* if pass is not null */
1115+ if (c_ctx -> pass && c_ctx -> pass_sz ) { /* if key material is present on the context for derivation */
1116+
1117+ /* if necessary, initialize the salt from the header or random source */
10941118 if (ctx -> need_kdf_salt ) {
1095- sqlite3_file * fd = sqlite3PagerFile (ctx -> pBt -> pBt -> pPager );
1096- /* read salt from header, if present, otherwise generate a new random salt */
1097- CODEC_TRACE ("sqlcipher_cipher_ctx_key_derive: obtaining salt\n" );
1098- if (fd == NULL || fd -> pMethods == 0 || sqlite3OsRead (fd , ctx -> kdf_salt , ctx -> kdf_salt_sz , 0 ) != SQLITE_OK ) {
1099- CODEC_TRACE ("sqlcipher_cipher_ctx_key_derive: unable to read salt from file header, generating random\n" );
1100- if (ctx -> provider -> random (ctx -> provider_ctx , ctx -> kdf_salt , ctx -> kdf_salt_sz ) != SQLITE_OK ) return SQLITE_ERROR ;
1101- }
1102- ctx -> need_kdf_salt = 0 ;
1119+ if ((rc = sqlcipher_codec_ctx_init_kdf_salt (ctx )) != SQLITE_OK ) return rc ;
11031120 }
1121+
11041122 if (c_ctx -> pass_sz == ((ctx -> key_sz * 2 ) + 3 ) && sqlite3StrNICmp ((const char * )c_ctx -> pass ,"x'" , 2 ) == 0 && cipher_isHex (c_ctx -> pass + 2 , ctx -> key_sz * 2 )) {
11051123 int n = c_ctx -> pass_sz - 3 ; /* adjust for leading x' and tailing ' */
11061124 const unsigned char * z = c_ctx -> pass + 2 ; /* adjust lead offset of x' */
0 commit comments