• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 243b21cbaa3d360fbdfb91ea3e18398125129167 Mon Sep 17 00:00:00 2001
2From: MartinChoo <214582617@qq.com>
3Date: Wed, 23 Jul 2025 17:38:02 +0800
4Subject: [PATCH 01/12] History features of sqlite
5
6---
7 src/sqlite3.c | 2451 ++++++++++++++++++++++++++++++++++++++++++++++++-
8 1 file changed, 2438 insertions(+), 13 deletions(-)
9
10diff --git a/src/sqlite3.c b/src/sqlite3.c
11index 730b247..b132937 100644
12--- a/src/sqlite3.c
13+++ b/src/sqlite3.c
14@@ -2915,6 +2915,11 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
15 */
16 SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
17
18+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
19+#define SQLITE_DBCONFIG_SET_SHAREDBLOCK  2004
20+#define SQLITE_DBCONFIG_USE_SHAREDBLOCK  2005
21+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
22+
23 /*
24 ** CAPI3REF: Set the Last Insert Rowid value.
25 ** METHOD: sqlite3
26@@ -3274,6 +3279,16 @@ SQLITE_API int sqlite3_get_table(
27 );
28 SQLITE_API void sqlite3_free_table(char **result);
29
30+// export the symbols
31+#ifdef SQLITE_EXPORT_SYMBOLS
32+#if defined(__GNUC__)
33+#  define EXPORT_SYMBOLS  __attribute__ ((visibility ("default")))
34+#elif defined(_MSC_VER)
35+#  define EXPORT_SYMBOLS  __declspec(dllexport)
36+#else
37+#  define EXPORT_SYMBOLS
38+#endif
39+#endif
40 /*
41 ** CAPI3REF: Formatted String Printing Functions
42 **
43@@ -5312,6 +5327,10 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
44 */
45 SQLITE_API int sqlite3_step(sqlite3_stmt*);
46
47+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
48+SQLITE_API int sqlite3_set_droptable_handle(sqlite3*, void (*xFunc)(sqlite3*,const char*,const char*));
49+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
50+
51 /*
52 ** CAPI3REF: Number of columns in a result set
53 ** METHOD: sqlite3_stmt
54@@ -6712,6 +6731,44 @@ SQLITE_API int sqlite3_collation_needed16(
55   void(*)(void*,sqlite3*,int eTextRep,const void*)
56 );
57
58+#ifdef SQLITE_HAS_CODEC
59+/*
60+** Specify the key for an encrypted database.  This routine should be
61+** called right after sqlite3_open().
62+**
63+** The code to implement this API is not available in the public release
64+** of SQLite.
65+*/
66+SQLITE_API int sqlite3_key(
67+  sqlite3 *db,                   /* Database to be rekeyed */
68+  const void *pKey, int nKey     /* The key */
69+);
70+SQLITE_API int sqlite3_key_v2(
71+  sqlite3 *db,                   /* Database to be rekeyed */
72+  const char *zDbName,           /* Name of the database */
73+  const void *pKey, int nKey     /* The key */
74+);
75+
76+/*
77+** Change the key on an open database.  If the current database is not
78+** encrypted, this routine will encrypt it.  If pNew==0 or nNew==0, the
79+** database is decrypted.
80+**
81+** The code to implement this API is not available in the public release
82+** of SQLite.
83+*/
84+SQLITE_API int sqlite3_rekey(
85+  sqlite3 *db,                   /* Database to be rekeyed */
86+  const void *pKey, int nKey     /* The new key */
87+);
88+SQLITE_API int sqlite3_rekey_v2(
89+  sqlite3 *db,                   /* Database to be rekeyed */
90+  const char *zDbName,           /* Name of the database */
91+  const void *pKey, int nKey     /* The new key */
92+);
93+
94+#endif /* SQLITE_HAS_CODEC */
95+
96 #ifdef SQLITE_ENABLE_CEROD
97 /*
98 ** Specify the activation key for a CEROD database.  Unless
99@@ -10149,6 +10206,27 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
100 */
101 SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
102
103+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
104+typedef struct Sqlite3SharedBlockMethods Sqlite3SharedBlockMethods;
105+struct Sqlite3SharedBlockMethods {
106+  int iVersion;
107+  void* pContext;
108+  int countAllRows;
109+  int startPos;
110+  int requiredPos;
111+  int (*xAddRow)(void* pCtx, int addedRows);
112+  int (*xReset)(void* pCtx, int startPos);
113+  int (*xFinish)(void* pCtx, int addedRows, int totalRows);
114+  int (*xPutString)(void *pCtx, int addedRows, int column, const char* text, int len);
115+  int (*xPutLong)(void *pCtx, int addedRows, int column, sqlite3_int64 value);
116+  int (*xPutDouble)(void *pCtx, int addedRows, int column, double value);
117+  int (*xPutBlob)(void *pCtx, int addedRows, int column, const void* blob, int len);
118+  int (*xPutNull)(void *pCtx, int addedRows, int column);
119+  int (*xPutOther)(void *pCtx, int addedRows, int column);
120+  /* Additional methods may be added in future releases */
121+};
122+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
123+
124 /*
125 ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
126 **
127@@ -15771,6 +15849,9 @@ SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
128 /* Functions used to configure a Pager object. */
129 SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
130 SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int);
131+#ifdef SQLITE_HAS_CODEC
132+SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*, Pager*);
133+#endif /* SQLITE_HAS_CODEC */
134 SQLITE_PRIVATE Pgno sqlite3PagerMaxPageCount(Pager*, Pgno);
135 SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
136 SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int);
137@@ -15867,6 +15948,10 @@ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
138
139 SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
140
141+#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
142+SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
143+#endif /* defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) */
144+
145 /* Functions to support testing and debugging. */
146 #if !defined(NDEBUG) || defined(SQLITE_TEST)
147 SQLITE_PRIVATE   Pgno sqlite3PagerPagenumber(DbPage*);
148@@ -17497,6 +17582,21 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
149 */
150 #define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2)
151
152+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
153+typedef void (*sqlite3_xDropTableHandle)(sqlite3*, const char*, const char*);
154+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
155+
156+#if defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED)
157+typedef struct CodecParameter {
158+  int kdfIter;
159+  int pageSize;
160+  u8 cipher;
161+  u8 hmacAlgo;
162+  u8 kdfAlgo;
163+  u8 reserved;
164+} CodecParameter;
165+#endif /* defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED) */
166+
167 /*
168 ** Each database connection is an instance of the following structure.
169 */
170@@ -17641,6 +17741,15 @@ struct sqlite3 {
171 #ifdef SQLITE_USER_AUTHENTICATION
172   sqlite3_userauth auth;        /* User authentication information */
173 #endif
174+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
175+  unsigned int isDropTable;
176+  char *mDropTableName;
177+  char *mDropSchemaName;
178+  sqlite3_xDropTableHandle xDropTableHandle;        /* User drop table callback */
179+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
180+#if defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED)
181+  CodecParameter codecParm;
182+#endif /* defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED) */
183 };
184
185 /*
186@@ -20733,7 +20842,14 @@ SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u32,Select*);
187 SQLITE_PRIVATE void sqlite3AddReturning(Parse*,ExprList*);
188 SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*,
189                     sqlite3_vfs**,char**,char **);
190-#define sqlite3CodecQueryParameters(A,B,C) 0
191+#ifdef SQLITE_HAS_CODEC
192+SQLITE_PRIVATE   int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*);
193+#else
194+# define sqlite3CodecQueryParameters(A,B,C) 0
195+#endif /* SQLITE_HAS_CODEC */
196+#if defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED)
197+SQLITE_PRIVATE void sqlite3CodecResetParameters(CodecParameter *p);
198+#endif /* defined(SQLITE_HAS_CODEC) && defined(SQLITE_CODEC_ATTACH_CHANGED) */
199 SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
200
201 #ifdef SQLITE_UNTESTABLE
202@@ -22095,6 +22211,9 @@ static const char * const sqlite3azCompileOpt[] = {
203 #ifdef SQLITE_FTS5_NO_WITHOUT_ROWID
204   "FTS5_NO_WITHOUT_ROWID",
205 #endif
206+#if SQLITE_HAS_CODEC
207+  "HAS_CODEC",
208+#endif
209 #if HAVE_ISNAN || SQLITE_HAVE_ISNAN
210   "HAVE_ISNAN",
211 #endif
212@@ -22103,6 +22222,9 @@ static const char * const sqlite3azCompileOpt[] = {
213   "HOMEGROWN_RECURSIVE_MUTEX=" CTIMEOPT_VAL(SQLITE_HOMEGROWN_RECURSIVE_MUTEX),
214 # endif
215 #endif
216+#if SQLITE_SHARED_BLOCK_OPTIMIZATION
217+ "SHARED_BLOCK_OPTIMIZATION",
218+#endif
219 #ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
220   "IGNORE_AFP_LOCK_ERRORS",
221 #endif
222@@ -22678,9 +22800,16 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
223 ** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
224 ** disabled. The default value may be changed by compiling with the
225 ** SQLITE_USE_URI symbol defined.
226+**
227+** URI filenames are enabled by default if SQLITE_HAS_CODEC is
228+** enabled.
229 */
230 #ifndef SQLITE_USE_URI
231-# define SQLITE_USE_URI 0
232+# ifdef SQLITE_HAS_CODEC
233+#  define SQLITE_USE_URI 1
234+# else
235+#  define SQLITE_USE_URI 0
236+# endif /* SQLITE_HAS_CODEC */
237 #endif
238
239 /* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
240@@ -23449,6 +23578,13 @@ struct Vdbe {
241   int nScan;              /* Entries in aScan[] */
242   ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
243 #endif
244+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
245+  Sqlite3SharedBlockMethods *pSharedBlock;
246+  int totalRows;
247+  int blockFull;
248+  int startPos;
249+  int addedRows;
250+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
251 };
252
253 /*
254@@ -35960,7 +36096,7 @@ SQLITE_PRIVATE u8 sqlite3HexToInt(int h){
255   return (u8)(h & 0xf);
256 }
257
258-#if !defined(SQLITE_OMIT_BLOB_LITERAL)
259+#if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC)
260 /*
261 ** Convert a BLOB literal of the form "x'hhhhhh'" into its binary
262 ** value.  Return a pointer to its binary value.  Space to hold the
263@@ -35981,7 +36117,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){
264   }
265   return zBlob;
266 }
267-#endif /* !SQLITE_OMIT_BLOB_LITERAL */
268+#endif /* !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) */
269
270 /*
271 ** Log an error that is an API call on a connection pointer that should
272@@ -56898,6 +57034,20 @@ int sqlite3PagerTrace=1;  /* True to enable tracing */
273 */
274 #define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
275
276+#ifdef SQLITE_HAS_CODEC
277+/*
278+** A macro used for invoking the codec if there is one
279+*/
280+# define CODEC1(P,D,N,X,E) \
281+    if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
282+# define CODEC2(P,D,N,X,E,O) \
283+    if( P->xCodec==0 ){ O=(char*)D; }else \
284+    if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
285+#else
286+# define CODEC1(P,D,N,X,E)   /* NO-OP */
287+# define CODEC2(P,D,N,X,E,O) O=(char*)D
288+#endif /* SQLITE_HAS_CODEC */
289+
290 /*
291 ** The maximum allowed sector size. 64KiB. If the xSectorsize() method
292 ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
293@@ -57186,6 +57336,12 @@ struct Pager {
294 #endif
295   void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
296   int (*xGet)(Pager*,Pgno,DbPage**,int); /* Routine to fetch a patch */
297+#ifdef SQLITE_HAS_CODEC
298+  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
299+  void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
300+  void (*xCodecFree)(void*);             /* Destructor for the codec */
301+  void *pCodec;               /* First argument to xCodec... methods */
302+#endif /* SQLITE_HAS_CODEC */
303   char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
304   PCache *pPCache;            /* Pointer to page cache object */
305 #ifndef SQLITE_OMIT_WAL
306@@ -57307,6 +57463,9 @@ static const unsigned char aJournalMagic[] = {
307 SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
308   if( pPager->fd->pMethods==0 ) return 0;
309   if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
310+#ifdef SQLITE_HAS_CODEC
311+  if( pPager->xCodec!=0 ) return 0;
312+#endif /* SQLITE_HAS_CODEC */
313 #ifndef SQLITE_OMIT_WAL
314   if( pPager->pWal ){
315     u32 iRead = 0;
316@@ -57540,7 +57699,11 @@ static void setGetterMethod(Pager *pPager){
317   if( pPager->errCode ){
318     pPager->xGet = getPageError;
319 #if SQLITE_MAX_MMAP_SIZE>0
320-  }else if( USEFETCH(pPager) ){
321+  }else if( USEFETCH(pPager)
322+#ifdef SQLITE_HAS_CODEC
323+   && pPager->xCodec==0
324+#endif /* SQLITE_HAS_CODEC */
325+  ){
326     pPager->xGet = getPageMMap;
327 #endif /* SQLITE_MAX_MMAP_SIZE>0 */
328   }else{
329@@ -58732,6 +58895,32 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){
330   return cksum;
331 }
332
333+#ifdef SQLITE_HAS_CODEC
334+/*
335+** Report the current page size and number of reserved bytes back
336+** to the codec.
337+*/
338+static void pagerReportSize(Pager *pPager){
339+  if( pPager->xCodecSizeChng ){
340+    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
341+                           (int)pPager->nReserve);
342+  }
343+}
344+/*
345+** Make sure the number of reserved bits is the same in the destination
346+** pager as it is in the source.  This comes up when a VACUUM changes the
347+** number of reserved bits to the "optimal" amount.
348+*/
349+SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){
350+  if( pDest->nReserve!=pSrc->nReserve ){
351+    pDest->nReserve = pSrc->nReserve;
352+    pagerReportSize(pDest);
353+  }
354+}
355+#else
356+# define pagerReportSize(X)     /* No-op if we do not support a codec */
357+#endif
358+
359 /*
360 ** Read a single page from either the journal file (if isMainJrnl==1) or
361 ** from the sub-journal (if isMainJrnl==0) and playback that page.
362@@ -58783,6 +58972,11 @@ static int pager_playback_one_page(
363   char *aData;                  /* Temporary storage for the page */
364   sqlite3_file *jfd;            /* The file descriptor for the journal file */
365   int isSynced;                 /* True if journal page is synced */
366+#ifdef SQLITE_HAS_CODEC
367+  /* The jrnlEnc flag is true if Journal pages should be passed through
368+  ** the codec.  It is false for pure in-memory journals. */
369+  const int jrnlEnc = (isMainJrnl || pPager->subjInMemory==0);
370+#endif /* SQLITE_HAS_CODEC */
371
372   assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
373   assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
374@@ -58912,12 +59106,30 @@ static int pager_playback_one_page(
375     ** is if the data was just read from an in-memory sub-journal. In that
376     ** case it must be encrypted here before it is copied into the database
377     ** file.  */
378+#ifdef SQLITE_HAS_CODEC
379+    if( !jrnlEnc ){
380+      CODEC2(pPager, aData, pgno, 7, rc=pPager->errCode, aData);
381+      if (rc == SQLITE_OK) {
382+        rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
383+        CODEC1(pPager, aData, pgno, 3, rc=pPager->errCode);
384+      }
385+    }else
386+#endif /* SQLITE_HAS_CODEC */
387     rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
388
389     if( pgno>pPager->dbFileSize ){
390       pPager->dbFileSize = pgno;
391     }
392     if( pPager->pBackup ){
393+#ifdef SQLITE_HAS_CODEC
394+      if( jrnlEnc ){
395+        CODEC1(pPager, aData, pgno, 3, rc=pPager->errCode);
396+        if (rc == SQLITE_OK) {
397+          sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
398+          CODEC2(pPager, aData, pgno, 7, rc=pPager->errCode, aData);
399+        }
400+      }else
401+#endif /* SQLITE_HAS_CODEC */
402       sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
403     }
404   }else if( !isMainJrnl && pPg==0 ){
405@@ -58968,6 +59180,10 @@ static int pager_playback_one_page(
406     if( pgno==1 ){
407       memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
408     }
409+#if SQLITE_HAS_CODEC
410+    /* Decode the page just read from disk */
411+    if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=pPager->errCode); }
412+#endif /* SQLITE_HAS_CODEC */
413     sqlite3PcacheRelease(pPg);
414   }
415   return rc;
416@@ -59511,7 +59727,7 @@ static int readDbPage(PgHdr *pPg){
417   assert( isOpen(pPager->fd) );
418
419   if( pagerUseWal(pPager) ){
420-    rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
421+    rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);  // find in wal-index
422     if( rc ) return rc;
423   }
424   if( iFrame ){
425@@ -59546,6 +59762,8 @@ static int readDbPage(PgHdr *pPg){
426       memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
427     }
428   }
429+  CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = pPager->errCode);
430+
431   PAGER_INCR(sqlite3_pager_readdb_count);
432   PAGER_INCR(pPager->nRead);
433   IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno));
434@@ -60691,6 +60909,10 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
435   sqlite3OsClose(pPager->fd);
436   sqlite3PageFree(pTmp);
437   sqlite3PcacheClose(pPager->pPCache);
438+#ifdef SQLITE_HAS_CODEC
439+  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
440+#endif /* SQLITE_HAS_CODEC */
441+
442   assert( !pPager->aSavepoint && !pPager->pInJournal );
443   assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
444
445@@ -60941,7 +61163,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
446       assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
447       if( pList->pgno==1 ) pager_write_changecounter(pList);
448
449-      pData = pList->pData;
450+      CODEC2(pPager, pList->pData, pgno, 6, return pPager->errCode, pData);
451
452       /* Write out the page data. */
453       rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
454@@ -61030,6 +61252,11 @@ static int subjournalPage(PgHdr *pPg){
455       void *pData = pPg->pData;
456       i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
457       char *pData2;
458+#if SQLITE_HAS_CODEC
459+      if( !pPager->subjInMemory ){
460+        CODEC2(pPager, pData, pPg->pgno, 7, return pPager->errCode, pData2);
461+      }else
462+#endif /* SQLITE_HAS_CODEC */
463       pData2 = pData;
464       PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
465       rc = write32bits(pPager->sjfd, offset, pPg->pgno);
466@@ -62122,6 +62349,9 @@ static int getPageMMap(
467   );
468
469   assert( USEFETCH(pPager) );
470+#ifdef SQLITE_HAS_CODEC
471+  assert( pPager->xCodec==0 );
472+#endif /* SQLITE_HAS_CODEC */
473
474   /* Optimization note:  Adding the "pgno<=1" term before "pgno==0" here
475   ** allows the compiler optimizer to reuse the results of the "pgno>1"
476@@ -62466,7 +62696,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
477   assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) );
478
479   assert( pPager->journalHdr<=pPager->journalOff );
480-  pData2 = pPg->pData;
481+  CODEC2(pPager, pPg->pData, pPg->pgno, 7, return pPager->errCode, pData2);
482   cksum = pager_cksum(pPager, (u8*)pData2);
483
484   /* Even if an IO or diskfull error occurs while journalling the
485@@ -62831,7 +63061,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
486       if( DIRECT_MODE ){
487         const void *zBuf;
488         assert( pPager->dbFileSize>0 );
489-        zBuf = pPgHdr->pData;
490+        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=pPager->errCode, zBuf);
491         if( rc==SQLITE_OK ){
492           rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
493           pPager->aStat[PAGER_STAT_WRITE]++;
494@@ -63594,6 +63824,48 @@ SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
495   return pPager->zJournal;
496 }
497
498+#ifdef SQLITE_HAS_CODEC
499+/*
500+** Set or retrieve the codec for this pager
501+*/
502+SQLITE_PRIVATE void sqlite3PagerSetCodec(
503+  Pager *pPager,
504+  void *(*xCodec)(void*,void*,Pgno,int),
505+  void (*xCodecSizeChng)(void*,int,int),
506+  void (*xCodecFree)(void*),
507+  void *pCodec
508+){
509+  if( pPager->xCodecFree ){
510+    pPager->xCodecFree(pPager->pCodec);
511+  }else{
512+    pager_reset(pPager);
513+  }
514+  pPager->xCodec = pPager->memDb ? 0 : xCodec;
515+  pPager->xCodecSizeChng = xCodecSizeChng;
516+  pPager->xCodecFree = xCodecFree;
517+  pPager->pCodec = pCodec;
518+  setGetterMethod(pPager);
519+  pagerReportSize(pPager);
520+}
521+SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
522+  return pPager->pCodec;
523+}
524+
525+/*
526+** This function is called by the wal module when writing page content
527+** into the log file.
528+**
529+** This function returns a pointer to a buffer containing the encrypted
530+** page content. If a malloc fails, this function may return NULL.
531+*/
532+SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
533+  void *aData = 0;
534+  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
535+  return aData;
536+}
537+
538+#endif /* SQLITE_HAS_CODEC */
539+
540 #ifndef SQLITE_OMIT_AUTOVACUUM
541 /*
542 ** Move the page pPg to location pgno in the file.
543@@ -68144,7 +68416,11 @@ static int walWriteOneFrame(
544   int rc;                         /* Result code from subfunctions */
545   void *pData;                    /* Data actually written */
546   u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
547+#ifdef SQLITE_HAS_CODEC
548+  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;
549+#else
550   pData = pPage->pData;
551+#endif /* SQLITE_HAS_CODEC */
552   walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
553   rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
554   if( rc ) return rc;
555@@ -68329,7 +68605,11 @@ static int walFrames(
556         if( pWal->iReCksum==0 || iWrite<pWal->iReCksum ){
557           pWal->iReCksum = iWrite;
558         }
559+#ifdef SQLITE_HAS_CODEC
560+        if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
561+#else
562         pData = p->pData;
563+#endif /* SQLITE_HAS_CODEC */
564         rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff);
565         if( rc ) return rc;
566         p->flags &= ~PGHDR_WAL_APPEND;
567@@ -81473,6 +81753,13 @@ static int backupOnePage(
568   int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
569   const int nCopy = MIN(nSrcPgsz, nDestPgsz);
570   const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
571+#ifdef SQLITE_HAS_CODEC
572+  /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is
573+  ** guaranteed that the shared-mutex is held by this thread, handle
574+  ** p->pSrc may not actually be the owner.  */
575+  int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
576+  int nDestReserve = sqlite3BtreeGetRequestedReserve(p->pDest);
577+#endif /* SQLITE_HAS_CODEC */
578   int rc = SQLITE_OK;
579   i64 iOff;
580
581@@ -81483,6 +81770,26 @@ static int backupOnePage(
582   assert( zSrcData );
583   assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 );
584
585+#ifdef SQLITE_HAS_CODEC
586+  /* Backup is not possible if the page size of the destination is changing
587+  ** and a codec is in use.
588+  */
589+  if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){
590+    rc = SQLITE_READONLY;
591+  }
592+
593+  /* Backup is not possible if the number of bytes of reserve space differ
594+  ** between source and destination.  If there is a difference, try to
595+  ** fix the destination to agree with the source.  If that is not possible,
596+  ** then the backup cannot proceed.
597+  */
598+  if( nSrcReserve!=nDestReserve ){
599+    u32 newPgsz = nSrcPgsz;
600+    rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve);
601+    if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY;
602+  }
603+#endif /* SQLITE_HAS_CODEC */
604+
605   /* This loop runs once for each destination page spanned by the source
606   ** page. For each iteration, variable iOff is set to the byte offset
607   ** of the destination page.
608@@ -81981,6 +82288,10 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
609   b.pDest = pTo;
610   b.iNext = 1;
611
612+#ifdef SQLITE_HAS_CODEC
613+  sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom));
614+#endif /* SQLITE_HAS_CODEC */
615+
616   /* 0x7FFFFFFF is the hard limit for the number of pages in a database
617   ** file. By passing this as the number of pages to copy to
618   ** sqlite3_backup_step(), we can guarantee that the copy finishes
619@@ -90447,6 +90758,15 @@ end_of_step:
620   return (rc&db->errMask);
621 }
622
623+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
624+SQLITE_API int sqlite3_set_droptable_handle(sqlite3 *db, void (*xFunc)(sqlite3*, const char*, const char*)){
625+  sqlite3_mutex_enter(db->mutex);
626+  db->xDropTableHandle = xFunc;
627+  sqlite3_mutex_leave(db->mutex);
628+  return 0;
629+}
630+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
631+
632 /*
633 ** This is the top-level implementation of sqlite3_step().  Call
634 ** sqlite3Step() to do most of the work.  If a schema error occurs,
635@@ -90466,6 +90786,13 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
636   while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
637          && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
638     int savedPc = v->pc;
639+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
640+    Sqlite3SharedBlockMethods *pSharedBlock = v->pSharedBlock;
641+    int totalRows = v->totalRows;
642+    int blockFull = v->blockFull;
643+    int startPos = v->startPos;
644+    int addedRows = v->addedRows;
645+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
646     rc = sqlite3Reprepare(v);
647     if( rc!=SQLITE_OK ){
648       /* This case occurs after failing to recompile an sql statement.
649@@ -90487,6 +90814,15 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
650       }
651       break;
652     }
653+
654+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
655+    v->pSharedBlock = pSharedBlock;
656+    v->totalRows = totalRows;
657+    v->blockFull = blockFull;
658+    v->startPos = startPos;
659+    v->addedRows = addedRows;
660+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
661+
662     sqlite3_reset(pStmt);
663     if( savedPc>=0 ){
664       /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and
665@@ -90497,6 +90833,20 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
666     }
667     assert( v->expired==0 );
668   }
669+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
670+  if( rc==SQLITE_DONE && db->xDropTableHandle!=NULL && db->isDropTable==1 ){
671+    db->isDropTable = 0;
672+    db->xDropTableHandle(db, db->mDropTableName, db->mDropSchemaName);
673+  }
674+  if( db->mDropTableName!=NULL ){
675+    sqlite3_free(db->mDropTableName);
676+    db->mDropTableName = NULL;
677+  }
678+  if( db->mDropSchemaName!=NULL ){
679+    sqlite3_free(db->mDropSchemaName);
680+    db->mDropSchemaName = NULL;
681+  }
682+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
683   sqlite3_mutex_leave(db->mutex);
684   return rc;
685 }
686@@ -92944,6 +93294,61 @@ static int checkSavepointCount(sqlite3 *db){
687 }
688 #endif
689
690+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
691+static int copySharedBlockRow(
692+  Vdbe *p,                    /* The VDBE */
693+  Op *pOp,                    /* Current operation */
694+  Mem *pMem,
695+  void *pCtx
696+){
697+  int i = 0;
698+
699+  int rc = p->pSharedBlock->xAddRow(pCtx, p->addedRows);
700+  if( rc!=SQLITE_OK ){
701+    return rc;
702+  }
703+
704+  for(i=0; i<pOp->p2; i++){
705+    switch (sqlite3_value_type(&pMem[i])) {
706+      case SQLITE_INTEGER:{
707+        rc = p->pSharedBlock->xPutLong(pCtx, p->addedRows, i, (sqlite3_int64)pMem[i].u.i);
708+        break;
709+      }
710+      case SQLITE_FLOAT: {
711+        rc = p->pSharedBlock->xPutDouble(pCtx, p->addedRows, i, pMem[i].u.r);
712+        break;
713+      }
714+      case SQLITE_TEXT: {
715+        Deephemeralize(&pMem[i]);
716+        sqlite3VdbeMemNulTerminate(&pMem[i]);
717+        sqlite3VdbeChangeEncoding(&pMem[i],SQLITE_UTF8);
718+        rc = p->pSharedBlock->xPutString(pCtx, p->addedRows, i, pMem[i].z, pMem[i].n+1);
719+        break;
720+      }
721+      case SQLITE_BLOB: {
722+        rc = p->pSharedBlock->xPutBlob(pCtx, p->addedRows, i, pMem[i].z, pMem[i].n);
723+        break;
724+      }
725+      case SQLITE_NULL: {
726+        rc = p->pSharedBlock->xPutNull(pCtx, p->addedRows, i);
727+        break;
728+      }
729+      default:
730+        rc = p->pSharedBlock->xPutOther(pCtx, p->addedRows, i);
731+        break;
732+    }
733+    if( rc!=SQLITE_OK ){
734+        return rc;
735+    }
736+  }
737+
738+  return rc;
739+no_mem:
740+  rc = SQLITE_NOMEM;
741+  return rc;
742+}
743+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
744+
745 /*
746 ** Return the register of pOp->p2 after first preparing it to be
747 ** overwritten with an integer value.
748@@ -93542,6 +93947,12 @@ case OP_Halt: {
749   VdbeFrame *pFrame;
750   int pcx;
751
752+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
753+  if( p->pSharedBlock!=NULL ){
754+    p->pSharedBlock->xFinish(p->pSharedBlock->pContext, p->addedRows, p->totalRows);
755+  }
756+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
757+
758 #ifdef SQLITE_DEBUG
759   if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
760 #endif
761@@ -93991,6 +94402,43 @@ case OP_ResultRow: {
762   assert( pOp->p1>0 || CORRUPT_DB );
763   assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );
764
765+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
766+  if( p->pSharedBlock!=NULL ){
767+    void *pCtx = p->pSharedBlock->pContext;
768+    p->totalRows++;
769+    if( p->totalRows<=p->startPos || p->blockFull ){
770+      break;
771+    }
772+    Mem *pMem = &aMem[pOp->p1];
773+    rc = copySharedBlockRow(p, pOp, pMem, pCtx);
774+    if( rc==SQLITE_FULL && p->addedRows && (p->startPos + p->addedRows) <= p->pSharedBlock->requiredPos ){
775+      p->startPos += p->addedRows;
776+      p->addedRows = 0;
777+      p->pSharedBlock->xReset(pCtx,p->startPos);
778+      p->blockFull = 0;
779+      rc = copySharedBlockRow(p, pOp, pMem, pCtx);
780+    }
781+
782+    if( rc==SQLITE_OK ){
783+      p->addedRows++;
784+    }else if( rc==SQLITE_FULL ){
785+      p->blockFull = 1;
786+    }else{
787+      //SQLITE_NOMEM
788+      goto no_mem;
789+    }
790+
791+    if( p->blockFull && p->pSharedBlock->countAllRows==0 ){
792+      p->pSharedBlock->xFinish(pCtx, p->addedRows, p->totalRows);
793+      rc = SQLITE_DONE;
794+      goto vdbe_return;
795+    }else if( p->blockFull && p->pSharedBlock->countAllRows==1 ){
796+      rc = SQLITE_OK;
797+    }
798+    break;
799+  }
800+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
801+
802   p->cacheCtr = (p->cacheCtr + 2)|1;
803   p->pResultRow = &aMem[pOp->p1];
804 #ifdef SQLITE_DEBUG
805@@ -94793,6 +95241,17 @@ case OP_Compare: {
806 ** This opcode must immediately follow an OP_Compare opcode.
807 */
808 case OP_Jump: {             /* jump */
809+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
810+  if( pOp->p5&0x80 ){
811+    if( p->pSharedBlock!=NULL ){
812+      if( p->totalRows < p->startPos || p->blockFull ){
813+        p->totalRows++;
814+        pOp = &aOp[pOp->p2 - 1];
815+      }
816+    }
817+    break;
818+  }
819+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
820   assert( pOp>aOp && pOp[-1].opcode==OP_Compare );
821   assert( iCompareIsInit );
822   if( iCompare<0 ){
823@@ -99867,6 +100326,20 @@ case OP_IfNotZero: {        /* jump, in1 */
824 ** and jump to P2 if the new value is exactly zero.
825 */
826 case OP_DecrJumpZero: {      /* jump, in1 */
827+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
828+  if( pOp->p5&0x80 ){
829+    if( p->pSharedBlock!=NULL ){
830+      if( p->totalRows < p->startPos || p->blockFull ){
831+         pIn1 = &aMem[pOp->p1];
832+         assert( pIn1->flags&MEM_Int );
833+         if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--;
834+         VdbeBranchTaken(pIn1->u.i==-1, 2);
835+         if( pIn1->u.i==-1 ) goto jump_to_p2;
836+      }
837+    }
838+    break;
839+  }
840+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
841   pIn1 = &aMem[pOp->p1];
842   assert( pIn1->flags&MEM_Int );
843   if( pIn1->u.i>SMALLEST_INT64 ) pIn1->u.i--;
844@@ -119592,6 +120065,40 @@ static void attachFunc(
845   if( rc==SQLITE_OK && pNew->zDbSName==0 ){
846     rc = SQLITE_NOMEM_BKPT;
847   }
848+#ifdef SQLITE_HAS_CODEC
849+  if( rc==SQLITE_OK ){
850+    extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
851+    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
852+    int nKey;
853+    char *zKey;
854+    int t = sqlite3_value_type(argv[2]);
855+    switch( t ){
856+      case SQLITE_INTEGER:
857+      case SQLITE_FLOAT:
858+        zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
859+        rc = SQLITE_ERROR;
860+        break;
861+
862+      case SQLITE_TEXT:
863+      case SQLITE_BLOB:
864+        nKey = sqlite3_value_bytes(argv[2]);
865+        zKey = (char *)sqlite3_value_blob(argv[2]);
866+        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
867+        break;
868+
869+      case SQLITE_NULL:
870+        /* No key specified.  Use the key from URI filename, or if none,
871+        ** use the key from the main database. */
872+        if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){
873+          sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
874+          if( nKey || sqlite3BtreeGetRequestedReserve(db->aDb[0].pBt)>0 ){
875+            rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
876+          }
877+        }
878+        break;
879+    }
880+  }
881+#endif /* SQLITE_HAS_CODEC */
882   sqlite3_free_filename( zPath );
883
884   /* If the file was opened successfully, read the schema for the new database.
885@@ -121163,8 +121670,24 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char
886   testcase( zTabName[0]==0 );  /* Zero-length table names are allowed */
887   pDb = &db->aDb[iDb];
888   p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0);
889+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
890+  u8 tableType = p->eTabType;
891+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
892   sqlite3DeleteTable(db, p);
893   db->mDbFlags |= DBFLAG_SchemaChange;
894+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
895+  if( tableType!=TABTYP_VIEW ){
896+    db->isDropTable = 1;
897+    db->mDropTableName = sqlite3_malloc(strlen(zTabName) + 1);
898+    if( db->mDropTableName!=NULL ){
899+      memcpy(db->mDropTableName, zTabName, strlen(zTabName) + 1);
900+    }
901+    db->mDropSchemaName = sqlite3_malloc(strlen(db->aDb[iDb].zDbSName) + 1);
902+    if( db->mDropSchemaName!=NULL ){
903+      memcpy(db->mDropSchemaName, db->aDb[iDb].zDbSName, strlen(db->aDb[iDb].zDbSName) + 1);
904+    }
905+  }
906+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
907 }
908
909 /*
910@@ -129771,10 +130294,16 @@ static void groupConcatValue(sqlite3_context *context){
911 */
912 SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){
913   int rc = sqlite3_overload_function(db, "MATCH", 2);
914+#ifdef SQLITE_HAS_CODEC
915+  extern void sqlite3CodecExportData(sqlite3_context *, int, sqlite3_value **);
916+#endif /* SQLITE_HAS_CODEC */
917   assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
918   if( rc==SQLITE_NOMEM ){
919     sqlite3OomFault(db);
920   }
921+#ifdef SQLITE_HAS_CODEC
922+  sqlite3CreateFunc(db, "export_database", 1, SQLITE_TEXT, 0, sqlite3CodecExportData, 0, 0, 0, 0, 0);
923+#endif /* SQLITE_HAS_CODEC */
924 }
925
926 /*
927@@ -135492,6 +136021,10 @@ struct sqlite3_api_routines {
928   /* Version 3.44.0 and later */
929   void *(*get_clientdata)(sqlite3*,const char*);
930   int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
931+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
932+  /* handle after drop table done */
933+  int (*set_droptable_handle)(sqlite3*,void(*)(sqlite3*,const char*,const char*));
934+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
935 };
936
937 /*
938@@ -135825,6 +136358,10 @@ typedef int (*sqlite3_loadext_entry)(
939 /* Version 3.44.0 and later */
940 #define sqlite3_get_clientdata         sqlite3_api->get_clientdata
941 #define sqlite3_set_clientdata         sqlite3_api->set_clientdata
942+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
943+/* handle after drop table done */
944+#define sqlite3_set_droptable_handle   sqlite3_api->set_droptable_handle
945+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
946 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
947
948 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
949@@ -135848,7 +136385,7 @@ typedef int (*sqlite3_loadext_entry)(
950 /************** Continuing where we left off in loadext.c ********************/
951 /* #include "sqliteInt.h" */
952
953-#ifndef SQLITE_OMIT_LOAD_EXTENSION
954+#if !defined(SQLITE_OMIT_LOAD_EXTENSION) || defined(SQLITE_EXPORT_SYMBOLS)
955 /*
956 ** Some API routines are omitted when various features are
957 ** excluded from a build of SQLite.  Substitute a NULL pointer
958@@ -135862,7 +136399,9 @@ typedef int (*sqlite3_loadext_entry)(
959 # define sqlite3_column_origin_name     0
960 # define sqlite3_column_origin_name16   0
961 #endif
962+#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) || defined(SQLITE_EXPORT_SYMBOLS) */
963
964+#ifndef SQLITE_OMIT_LOAD_EXTENSION
965 #ifdef SQLITE_OMIT_AUTHORIZATION
966 # define sqlite3_set_authorizer         0
967 #endif
968@@ -135943,6 +136482,7 @@ typedef int (*sqlite3_loadext_entry)(
969 #if defined(SQLITE_OMIT_TRACE)
970 # define sqlite3_trace_v2      0
971 #endif
972+#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
973
974 /*
975 ** The following structure contains pointers to all SQLite API routines.
976@@ -135959,6 +136499,7 @@ typedef int (*sqlite3_loadext_entry)(
977 ** also check to make sure that the pointer to the function is
978 ** not NULL before calling it.
979 */
980+#if !defined(SQLITE_OMIT_LOAD_EXTENSION) || defined(SQLITE_EXPORT_SYMBOLS)
981 static const sqlite3_api_routines sqlite3Apis = {
982   sqlite3_aggregate_context,
983 #ifndef SQLITE_OMIT_DEPRECATED
984@@ -136228,7 +136769,11 @@ static const sqlite3_api_routines sqlite3Apis = {
985   sqlite3_bind_blob64,
986   sqlite3_bind_text64,
987   sqlite3_cancel_auto_extension,
988+#ifndef SQLITE_OMIT_LOAD_EXTENSION
989   sqlite3_load_extension,
990+#else
991+  0,
992+#endif /* !SQLITE_OMIT_LOAD_EXTENSION */
993   sqlite3_malloc64,
994   sqlite3_msize,
995   sqlite3_realloc64,
996@@ -136346,7 +136891,10 @@ static const sqlite3_api_routines sqlite3Apis = {
997   sqlite3_stmt_explain,
998   /* Version 3.44.0 and later */
999   sqlite3_get_clientdata,
1000-  sqlite3_set_clientdata
1001+  sqlite3_set_clientdata,
1002+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
1003+  sqlite3_set_droptable_handle
1004+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
1005 };
1006
1007 /* True if x is the directory separator character
1008@@ -136357,6 +136905,9 @@ static const sqlite3_api_routines sqlite3Apis = {
1009 # define DirSep(X)  ((X)=='/')
1010 #endif
1011
1012+#endif /* !defined(SQLITE_OMIT_LOAD_EXTENSION) || defined(SQLITE_EXPORT_SYMBOLS) */
1013+
1014+#ifndef SQLITE_OMIT_LOAD_EXTENSION
1015 /*
1016 ** Attempt to load an SQLite extension library contained in the file
1017 ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
1018@@ -136836,6 +137387,9 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
1019 #define PragTyp_WAL_CHECKPOINT                43
1020 #define PragTyp_LOCK_STATUS                   44
1021 #define PragTyp_STATS                         45
1022+#ifdef SQLITE_HAS_CODEC
1023+#define PragTyp_KEY                          255
1024+#endif /* SQLITE_HAS_CODEC */
1025
1026 /* Property flags associated with various pragma. */
1027 #define PragFlg_NeedSchema 0x01 /* Force schema load before running */
1028@@ -137126,6 +137680,18 @@ static const PragmaName aPragmaName[] = {
1029   /* ePragFlg:  */ PragFlg_Result0,
1030   /* ColNames:  */ 0, 0,
1031   /* iArg:      */ 0 },
1032+#if defined(SQLITE_HAS_CODEC)
1033+ {/* zName:     */ "hexkey",
1034+  /* ePragTyp:  */ PragTyp_KEY,
1035+  /* ePragFlg:  */ 0,
1036+  /* ColNames:  */ 0, 0,
1037+  /* iArg:      */ 2 },
1038+ {/* zName:     */ "hexrekey",
1039+  /* ePragTyp:  */ PragTyp_KEY,
1040+  /* ePragFlg:  */ 0,
1041+  /* ColNames:  */ 0, 0,
1042+  /* iArg:      */ 3 },
1043+#endif
1044 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
1045 #if !defined(SQLITE_OMIT_CHECK)
1046  {/* zName:     */ "ignore_check_constraints",
1047@@ -137178,6 +137744,13 @@ static const PragmaName aPragmaName[] = {
1048   /* ColNames:  */ 0, 0,
1049   /* iArg:      */ 0 },
1050 #endif
1051+#if defined(SQLITE_HAS_CODEC)
1052+ {/* zName:     */ "key",
1053+  /* ePragTyp:  */ PragTyp_KEY,
1054+  /* ePragFlg:  */ 0,
1055+  /* ColNames:  */ 0, 0,
1056+  /* iArg:      */ 0 },
1057+#endif
1058 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
1059  {/* zName:     */ "legacy_alter_table",
1060   /* ePragTyp:  */ PragTyp_FLAG,
1061@@ -137285,6 +137858,15 @@ static const PragmaName aPragmaName[] = {
1062   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
1063   /* ColNames:  */ 0, 0,
1064   /* iArg:      */ SQLITE_RecTriggers },
1065+#endif
1066+#if defined(SQLITE_HAS_CODEC)
1067+ {/* zName:     */ "rekey",
1068+  /* ePragTyp:  */ PragTyp_KEY,
1069+  /* ePragFlg:  */ 0,
1070+  /* ColNames:  */ 0, 0,
1071+  /* iArg:      */ 1 },
1072+#endif
1073+#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
1074  {/* zName:     */ "reverse_unordered_selects",
1075   /* ePragTyp:  */ PragTyp_FLAG,
1076   /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
1077@@ -137373,6 +137955,18 @@ static const PragmaName aPragmaName[] = {
1078   /* ePragFlg:  */ PragFlg_NoColumns1,
1079   /* ColNames:  */ 0, 0,
1080   /* iArg:      */ 0 },
1081+#endif
1082+#if defined(SQLITE_HAS_CODEC)
1083+ {/* zName:     */ "textkey",
1084+  /* ePragTyp:  */ PragTyp_KEY,
1085+  /* ePragFlg:  */ 0,
1086+  /* ColNames:  */ 0, 0,
1087+  /* iArg:      */ 4 },
1088+ {/* zName:     */ "textrekey",
1089+  /* ePragTyp:  */ PragTyp_KEY,
1090+  /* ePragFlg:  */ 0,
1091+  /* ColNames:  */ 0, 0,
1092+  /* iArg:      */ 5 },
1093 #endif
1094  {/* zName:     */ "threads",
1095   /* ePragTyp:  */ PragTyp_THREADS,
1096@@ -137814,6 +138408,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
1097   Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
1098   const PragmaName *pPragma;   /* The pragma */
1099
1100+#ifdef SQLITE_HAS_CODEC
1101+  extern int sqlite3CodecPragma(sqlite3*, int, Parse *, const char *, const char *);
1102+#endif /* SQLITE_HAS_CODEC */
1103+
1104   if( v==0 ) return;
1105   sqlite3VdbeRunOnlyOnce(v);
1106   pParse->nMem = 2;
1107@@ -137883,6 +138481,14 @@ SQLITE_PRIVATE void sqlite3Pragma(
1108     goto pragma_out;
1109   }
1110
1111+#ifdef SQLITE_HAS_CODEC
1112+  if(sqlite3CodecPragma(db, iDb, pParse, zLeft, zRight)) {
1113+    /* sqlite3CodecPragma executes internal */
1114+    goto pragma_out;
1115+  }
1116+#endif
1117+  /* END CODEC */
1118+
1119   /* Locate the pragma in the lookup table */
1120   pPragma = pragmaLocate(zLeft);
1121   if( pPragma==0 ){
1122@@ -140023,6 +140629,48 @@ SQLITE_PRIVATE void sqlite3Pragma(
1123   }
1124 #endif
1125
1126+#ifdef SQLITE_HAS_CODEC
1127+  /* Pragma        iArg
1128+  ** ----------   ------
1129+  **  key           0
1130+  **  rekey         1
1131+  **  hexkey        2
1132+  **  hexrekey      3
1133+  **  textkey       4
1134+  **  textrekey     5
1135+  */
1136+  case PragTyp_KEY: {
1137+    if( zRight ){
1138+      char zBuf[40];
1139+      const char *zKey = zRight;
1140+      int n;
1141+      if( pPragma->iArg==2 || pPragma->iArg==3 ){
1142+        u8 iByte;
1143+        int i;
1144+        for(i=0, iByte=0; i<(int)(sizeof(zBuf)*2) && sqlite3Isxdigit(zRight[i]); i++){
1145+          iByte = (iByte<<4) + sqlite3HexToInt(zRight[i]);
1146+          if( (i&1)!=0 ) zBuf[i/2] = iByte;
1147+        }
1148+        zKey = zBuf;
1149+        n = i/2;
1150+      }else{
1151+        n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1;
1152+      }
1153+      if( (pPragma->iArg & 1)==0 ){
1154+        rc = sqlite3_key_v2(db, zDb, zKey, n);
1155+      }else{
1156+        rc = sqlite3_rekey_v2(db, zDb, zKey, n);
1157+      }
1158+      if( rc==SQLITE_OK && n!=0 ){
1159+        sqlite3VdbeSetNumCols(v, 1);
1160+        sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC);
1161+        returnSingleText(v, "ok");
1162+      }
1163+    }
1164+    break;
1165+  }
1166+#endif /* SQLITE_HAS_CODEC */
1167+
1168 #if defined(SQLITE_ENABLE_CEROD)
1169   case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){
1170     if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){
1171@@ -142579,9 +143227,25 @@ static void selectInnerLoop(
1172   assert( p->pEList!=0 );
1173   hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
1174   if( pSort && pSort->pOrderBy==0 ) pSort = 0;
1175+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
1176+  if( hasDistinct && (pDistinct->eTnctType==WHERE_DISTINCT_UNIQUE) ){
1177+    hasDistinct = WHERE_DISTINCT_NOOP;
1178+    sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct);
1179+  }
1180+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
1181   if( pSort==0 && !hasDistinct ){
1182     assert( iContinue!=0 );
1183     codeOffset(v, p->iOffset, iContinue);
1184+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
1185+    if( eDest==SRT_Output ){
1186+      if( p->iLimit ){
1187+        sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak);
1188+        sqlite3VdbeChangeP5(v, 128);
1189+      }
1190+      sqlite3VdbeAddOp2(v, OP_Jump, 0, iContinue);
1191+      sqlite3VdbeChangeP5(v, 128);
1192+    }
1193+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
1194   }
1195
1196   /* Pull the requested columns.
1197@@ -142710,6 +143374,16 @@ static void selectInnerLoop(
1198     fixDistinctOpenEph(pParse, eType, iTab, pDistinct->addrTnct);
1199     if( pSort==0 ){
1200       codeOffset(v, p->iOffset, iContinue);
1201+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
1202+      if( eDest==SRT_Output ){
1203+        if( p->iLimit ){
1204+          sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak);
1205+          sqlite3VdbeChangeP5(v, 128);
1206+        }
1207+        sqlite3VdbeAddOp2(v, OP_Jump, 0, iContinue);
1208+        sqlite3VdbeChangeP5(v, 128);
1209+      }
1210+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
1211     }
1212   }
1213
1214@@ -143173,11 +143847,23 @@ static void generateSortTail(
1215     addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
1216     VdbeCoverage(v);
1217     assert( p->iLimit==0 && p->iOffset==0 );
1218+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
1219+    if( eDest==SRT_Output ){
1220+      sqlite3VdbeAddOp2(v, OP_Jump, 0, addrContinue);
1221+      sqlite3VdbeChangeP5(v, 128);
1222+    }
1223+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
1224     sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
1225     bSeq = 0;
1226   }else{
1227     addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
1228     codeOffset(v, p->iOffset, addrContinue);
1229+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
1230+    if( eDest==SRT_Output ){
1231+      sqlite3VdbeAddOp2(v, OP_Jump, 0, addrContinue);
1232+      sqlite3VdbeChangeP5(v, 128);
1233+    }
1234+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
1235     iSortTab = iTab;
1236     bSeq = 1;
1237     if( p->iOffset>0 ){
1238@@ -153658,6 +154344,17 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(
1239   }
1240   nRes = sqlite3BtreeGetRequestedReserve(pMain);
1241
1242+#ifdef SQLITE_HAS_CODEC
1243+  /* A VACUUM cannot change the pagesize of an encrypted database. */
1244+  if( db->nextPagesize ){
1245+    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
1246+    int nKey;
1247+    char *zKey;
1248+    sqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey);
1249+    if( nKey ) db->nextPagesize = 0;
1250+  }
1251+#endif /* SQLITE_HAS_CODEC */
1252+
1253   sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
1254   sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
1255   sqlite3BtreeSetPagerFlags(pTemp, pgflags|PAGER_CACHESPILL);
1256@@ -177753,6 +178450,7 @@ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
1257 /************** End of rtree.h ***********************************************/
1258 /************** Continuing where we left off in main.c ***********************/
1259 #endif
1260+#include "sqlite3tokenizer.h"
1261 #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS)
1262 /************** Include sqliteicu.h in the middle of main.c ******************/
1263 /************** Begin file sqliteicu.h ***************************************/
1264@@ -178752,6 +179450,29 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
1265       rc = setupLookaside(db, pBuf, sz, cnt);
1266       break;
1267     }
1268+#ifdef SQLITE_SHARED_BLOCK_OPTIMIZATION
1269+    case SQLITE_DBCONFIG_SET_SHAREDBLOCK: {
1270+      Vdbe *pVdbe = (Vdbe *)va_arg(ap, sqlite3_stmt*);
1271+      Sqlite3SharedBlockMethods *pSharedBlock = va_arg(ap, Sqlite3SharedBlockMethods*);
1272+      if( pVdbe==NULL ){
1273+        rc = SQLITE_MISUSE;
1274+        break;
1275+      }
1276+      pVdbe->pSharedBlock = pSharedBlock;
1277+      if( pSharedBlock!=NULL ){
1278+        pVdbe->startPos = pSharedBlock->startPos;
1279+      }
1280+      pVdbe->totalRows = 0;
1281+      pVdbe->blockFull = 0;
1282+      pVdbe->addedRows = 0;
1283+      rc = SQLITE_OK;
1284+      break;
1285+    }
1286+    case SQLITE_DBCONFIG_USE_SHAREDBLOCK: {
1287+      rc = SQLITE_OK;
1288+      break;
1289+    }
1290+#endif /* SQLITE_SHARED_BLOCK_OPTIMIZATION */
1291     default: {
1292       static const struct {
1293         int op;      /* The opcode */
1294@@ -181006,7 +181727,41 @@ static const char *uriParameter(const char *zFilename, const char *zParam){
1295   return 0;
1296 }
1297
1298-
1299+#ifdef SQLITE_HAS_CODEC
1300+/*
1301+** Process URI filename query parameters relevant to the SQLite Encryption
1302+** Extension.  Return true if any of the relevant query parameters are
1303+** seen and return false if not.
1304+*/
1305+SQLITE_PRIVATE int sqlite3CodecQueryParameters(
1306+  sqlite3 *db,           /* Database connection */
1307+  const char *zDb,       /* Which schema is being created/attached */
1308+  const char *zUri       /* URI filename */
1309+){
1310+  const char *zKey;
1311+  if( zUri==0 ){
1312+    return 0;
1313+  }else if( (zKey = uriParameter(zUri, "hexkey"))!=0 && zKey[0] ){
1314+    u8 iByte;
1315+    int i;
1316+    char zDecoded[40];
1317+    for(i=0, iByte=0; i<(int)(sizeof(zDecoded)*2) && sqlite3Isxdigit(zKey[i]); i++){
1318+      iByte = (iByte<<4) + sqlite3HexToInt(zKey[i]);
1319+      if( (i&1)!=0 ) zDecoded[i/2] = iByte;
1320+    }
1321+    sqlite3_key_v2(db, zDb, zDecoded, i/2);
1322+    return 1;
1323+  }else if( (zKey = uriParameter(zUri, "key"))!=0 ){
1324+    sqlite3_key_v2(db, zDb, zKey, sqlite3Strlen30(zKey));
1325+    return 1;
1326+  }else if( (zKey = uriParameter(zUri, "textkey"))!=0 ){
1327+    sqlite3_key_v2(db, zDb, zKey, -1);
1328+    return 1;
1329+  }else{
1330+    return 0;
1331+  }
1332+}
1333+#endif /* SQLITE_HAS_CODEC */
1334
1335 /*
1336 ** This routine does the work of opening a database on behalf of
1337@@ -181354,6 +182109,12 @@ opendb_out:
1338   }else if( rc!=SQLITE_OK ){
1339     db->eOpenState = SQLITE_STATE_SICK;
1340   }
1341+#ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK
1342+  db->isDropTable = 0;
1343+  db->mDropTableName = NULL;
1344+  db->mDropSchemaName = NULL;
1345+  db->xDropTableHandle = NULL;
1346+#endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */
1347   *ppDb = db;
1348 #ifdef SQLITE_ENABLE_SQLLOG
1349   if( sqlite3GlobalConfig.xSqllog ){
1350@@ -181362,6 +182123,14 @@ opendb_out:
1351     sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
1352   }
1353 #endif
1354+#ifdef SQLITE_HAS_CODEC
1355+  if( rc==SQLITE_OK ) {
1356+#ifdef SQLITE_CODEC_ATTACH_CHANGED
1357+    sqlite3CodecResetParameters(&db->codecParm);
1358+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
1359+    sqlite3CodecQueryParameters(db, 0, zOpen);
1360+  }
1361+#endif /* SQLITE_HAS_CODEC */
1362   sqlite3_free_filename(zOpen);
1363   return rc;
1364 }
1365@@ -234858,7 +235627,7 @@ static void sqlite3Fts5ParseSetDistance(
1366               );
1367           return;
1368         }
1369-        nNear = nNear * 10 + (p->p[i] - '0');
1370+        if( nNear<214748363 ) nNear = nNear * 10 + (p->p[i] - '0');
1371       }
1372     }else{
1373       nNear = FTS5_DEFAULT_NEARDIST;
1374@@ -252924,3 +253693,1659 @@ SQLITE_API int sqlite3_stmt_init(
1375 /* Return the source-id for this library */
1376 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
1377 /************************** End of sqlite3.c ******************************/
1378+
1379+#ifdef SQLITE_HAS_CODEC
1380+/************** Begin file hw_codec_openssl.h *******************************/
1381+#ifndef EXPOSE_INTERNAL_FUNC
1382+#define CODEC_STATIC static
1383+#else
1384+#define CODEC_STATIC
1385+#endif
1386+
1387+#define DEFAULT_CIPHER "aes-256-gcm"
1388+
1389+typedef struct{
1390+  unsigned char *buffer;
1391+  int bufferSize;
1392+}Buffer;
1393+/************** End file hw_codec_openssl.h *********************************/
1394+/************** Begin file hw_codec.h ***************************************/
1395+#define DEFAULT_PAGE_SIZE 1024
1396+#define DEFAULT_ITER 10000
1397+#define FILE_HEADER_SIZE 16
1398+#define SALT_SIZE FILE_HEADER_SIZE
1399+#define HMAC_SALT_MASK 0x3a
1400+#define HMAC_ITER 2
1401+#define MAX_HMAC_SIZE 64
1402+#define MAX_INIT_VECTOR_SIZE 16
1403+#define MIN_BLOCK_SIZE 16
1404+
1405+#define CODEC_OPERATION_ENCRYPT 1
1406+#define CODEC_OPERATION_DECRYPT 0
1407+
1408+#define KEY_CONTEXT_HEAD_SIZE (sizeof(CodecConstant) + 3 * sizeof(int))
1409+
1410+typedef struct{
1411+  void *cipher;
1412+  int keySize;
1413+  int keyInfoSize;
1414+  int cipherPageSize;
1415+  int initVectorSize;
1416+  int hmacSize;
1417+  int reserveSize;
1418+  int hmacAlgo;
1419+  int kdfAlgo;
1420+  int rekeyHmacAlgo;
1421+}CodecConstant;
1422+
1423+typedef struct{
1424+  CodecConstant codecConst;
1425+  int deriveFlag;
1426+  int iter;
1427+  int passwordSize;
1428+  unsigned char *password;
1429+  unsigned char *key;
1430+  unsigned char *hmacKey;
1431+  unsigned char *keyInfo;
1432+}KeyContext;
1433+
1434+typedef struct{
1435+  Btree *pBt;
1436+  int savePassword;
1437+  unsigned char salt[SALT_SIZE];
1438+  unsigned char hmacSalt[SALT_SIZE];
1439+  unsigned char *buffer;
1440+  KeyContext *readCtx;
1441+  KeyContext *writeCtx;
1442+}CodecContext;
1443+
1444+/************** End file hw_codec.h *****************************************/
1445+/************** Begin file hw_codec_openssl.c *******************************/
1446+#include <openssl/rand.h>
1447+#include <openssl/evp.h>
1448+#include <openssl/hmac.h>
1449+#include <openssl/crypto.h>
1450+
1451+unsigned int openssl_init_count = 0;
1452+unsigned int openssl_external_init_flag = 0;
1453+sqlite3_mutex *openssl_random_mutex = NULL;
1454+
1455+CODEC_STATIC void opensslActive(){
1456+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1457+
1458+  if(openssl_init_count == 0){
1459+    if(EVP_get_cipherbyname(DEFAULT_CIPHER) == NULL){
1460+      OpenSSL_add_all_algorithms();
1461+    }else{
1462+      openssl_external_init_flag = 1;
1463+    }
1464+  }
1465+
1466+  if(openssl_random_mutex == NULL){
1467+    openssl_random_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
1468+  }
1469+  openssl_init_count++;
1470+
1471+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1472+  return;
1473+}
1474+
1475+CODEC_STATIC void opensslDeactive(){
1476+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1477+
1478+  openssl_init_count--;
1479+  if(openssl_init_count == 0){
1480+    if(openssl_external_init_flag){
1481+      openssl_external_init_flag = 0;
1482+    }else{
1483+      EVP_cleanup();
1484+    }
1485+  }
1486+
1487+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1488+  return;
1489+}
1490+
1491+CODEC_STATIC int opensslGetRandom(Buffer *buffer){
1492+  sqlite3_mutex_enter(openssl_random_mutex);
1493+  int rc = RAND_bytes(buffer->buffer, buffer->bufferSize);
1494+  sqlite3_mutex_leave(openssl_random_mutex);
1495+  if(rc != 1){
1496+    return SQLITE_ERROR;
1497+  }
1498+  return SQLITE_OK;
1499+}
1500+
1501+CODEC_STATIC void *opensslGetCipher(const char *cipherName){
1502+  return (void *)EVP_get_cipherbyname(cipherName);
1503+}
1504+
1505+CODEC_STATIC int opensslFreeCipher(void *cipher){
1506+  return SQLITE_OK;
1507+}
1508+
1509+CODEC_STATIC const char *opensslGetCipherName(void *cipher){
1510+  return EVP_CIPHER_name((EVP_CIPHER *)cipher);
1511+}
1512+
1513+CODEC_STATIC int opensslGetKeySize(void *cipher){
1514+  return EVP_CIPHER_key_length((EVP_CIPHER *)cipher);
1515+}
1516+
1517+CODEC_STATIC int opensslGetInitVectorSize(void *cipher){
1518+  return EVP_CIPHER_iv_length((EVP_CIPHER *)cipher);
1519+}
1520+
1521+#define CIPHER_HMAC_ALGORITHM_SHA1 1
1522+#define CIPHER_HMAC_ALGORITHM_SHA256 2
1523+#define CIPHER_HMAC_ALGORITHM_SHA512 3
1524+
1525+#define DEFAULT_HMAC_ALGORITHM CIPHER_HMAC_ALGORITHM_SHA1
1526+
1527+#define CIPHER_HMAC_ALGORITHM_NAME_SHA1 "SHA1"
1528+#define CIPHER_HMAC_ALGORITHM_NAME_SHA256 "SHA256"
1529+#define CIPHER_HMAC_ALGORITHM_NAME_SHA512 "SHA512"
1530+
1531+#define CIPHER_KDF_ALGORITHM_SHA1 1
1532+#define CIPHER_KDF_ALGORITHM_SHA256 2
1533+#define CIPHER_KDF_ALGORITHM_SHA512 3
1534+
1535+#define DEFAULT_KDF_ALGORITHM CIPHER_KDF_ALGORITHM_SHA1
1536+
1537+#define CIPHER_KDF_ALGORITHM_NAME_SHA1 "KDF_SHA1"
1538+#define CIPHER_KDF_ALGORITHM_NAME_SHA256 "KDF_SHA256"
1539+#define CIPHER_KDF_ALGORITHM_NAME_SHA512 "KDF_SHA512"
1540+
1541+
1542+CODEC_STATIC int opensslGetHmacSize(KeyContext *keyCtx){
1543+  if( keyCtx==NULL ){
1544+    return 0;
1545+  }
1546+  if( keyCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA1 ){
1547+    return EVP_MD_size(EVP_sha1());
1548+  }else if( keyCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){
1549+    return EVP_MD_size(EVP_sha256());
1550+  }else if( keyCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){
1551+    return EVP_MD_size(EVP_sha512());
1552+  }
1553+  return 0;
1554+}
1555+
1556+CODEC_STATIC int opensslGetBlockSize(void *cipher){
1557+  return EVP_CIPHER_block_size((EVP_CIPHER *)cipher);
1558+}
1559+
1560+CODEC_STATIC void *opensslGetCtx(void *cipher, int mode, unsigned char *key, unsigned char *initVector){
1561+  EVP_CIPHER_CTX *tmpCtx = EVP_CIPHER_CTX_new();
1562+  if(tmpCtx == NULL){
1563+    return (void *)tmpCtx;
1564+  }
1565+  EVP_CipherInit_ex(tmpCtx, (EVP_CIPHER *)cipher, NULL, NULL, NULL, mode);
1566+  EVP_CIPHER_CTX_set_padding(tmpCtx, 0);
1567+  EVP_CipherInit_ex(tmpCtx, NULL, NULL, key, initVector, mode);
1568+  return (void *)tmpCtx;
1569+}
1570+
1571+CODEC_STATIC int opensslCipher(void *iCtx, Buffer *input, unsigned char *output){
1572+  int outputLength = 0;
1573+  int cipherLength;
1574+  EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX *)iCtx;
1575+  EVP_CipherUpdate(ctx, output, &cipherLength, input->buffer, input->bufferSize);
1576+  outputLength += cipherLength;
1577+  output += cipherLength;
1578+  EVP_CipherFinal_ex(ctx, output, &cipherLength);
1579+  outputLength += cipherLength;
1580+  if(outputLength != input->bufferSize){
1581+    return SQLITE_ERROR;
1582+  }
1583+  return SQLITE_OK;
1584+}
1585+
1586+CODEC_STATIC void opensslFreeCtx(void *ctx){
1587+  EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *)ctx);
1588+}
1589+
1590+CODEC_STATIC int opensslHmac(Buffer *key, Buffer *input1, Buffer *input2, Buffer *output, int hmacAlgo){
1591+  HMAC_CTX *ctx = HMAC_CTX_new();
1592+  if(ctx == NULL){
1593+    return SQLITE_ERROR;
1594+  }
1595+  if( hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA1 ){
1596+    HMAC_Init_ex(ctx, key->buffer, key->bufferSize, EVP_sha1(), NULL);
1597+  }else if( hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){
1598+    HMAC_Init_ex(ctx, key->buffer, key->bufferSize, EVP_sha256(), NULL);
1599+  }else if( hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){
1600+    HMAC_Init_ex(ctx, key->buffer, key->bufferSize, EVP_sha512(), NULL);
1601+  }
1602+  HMAC_Update(ctx, input1->buffer, input1->bufferSize);
1603+  HMAC_Update(ctx, input2->buffer, input2->bufferSize);
1604+  HMAC_Final(ctx, output->buffer, (unsigned int *)(&output->bufferSize));
1605+
1606+  HMAC_CTX_free(ctx);
1607+  return SQLITE_OK;
1608+}
1609+
1610+CODEC_STATIC void opensslKdf(Buffer *password, Buffer *salt, int workfactor, Buffer *key, int kdfAlgo){
1611+  if( kdfAlgo==CIPHER_KDF_ALGORITHM_SHA1 ){
1612+    PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize,
1613+      workfactor, EVP_sha1(), key->bufferSize, key->buffer);
1614+  }else if( kdfAlgo==CIPHER_KDF_ALGORITHM_SHA256 ){
1615+    PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize,
1616+      workfactor, EVP_sha256(), key->bufferSize, key->buffer);
1617+  }else if( kdfAlgo==CIPHER_KDF_ALGORITHM_SHA512 ){
1618+    PKCS5_PBKDF2_HMAC((const char *)(password->buffer), password->bufferSize, salt->buffer, salt->bufferSize,
1619+      workfactor, EVP_sha512(), key->bufferSize, key->buffer);
1620+  }
1621+}
1622+
1623+/************** End file hw_codec_openssl.c *********************************/
1624+/************** Begin file hw_codec.c ***************************************/
1625+
1626+#include "securec.h"
1627+
1628+typedef enum{
1629+  OPERATE_CONTEXT_READ = 0,
1630+  OPERATE_CONTEXT_WRITE,
1631+  OPERATE_CONTEXT_BOTH
1632+}OperateContext;
1633+
1634+CODEC_STATIC int sqlite3CodecIsHex(const unsigned char *buffer, int bufferSize){
1635+  int i;
1636+  for(i = 0; i < bufferSize; i++){
1637+    if((buffer[i] < '0' || buffer[i] > '9') &&
1638+      (buffer[i] < 'a' || buffer[i] > 'f') &&
1639+      (buffer[i] < 'A' || buffer[i] > 'F')){
1640+      return 0;
1641+    }
1642+  }
1643+  return 1;
1644+}
1645+
1646+CODEC_STATIC int sqlite3CodecHex2int(char input){
1647+  if(input >= '0' && input <= '9'){
1648+    return (int)(input - '0');
1649+  }else if(input >= 'a' && input <= 'f'){
1650+    return (int)(input - 'a') + 10;
1651+  }else if(input >= 'A' && input <= 'F'){
1652+    return (int)(input - 'A') + 10;
1653+  }else{
1654+    return 0;
1655+  }
1656+}
1657+
1658+CODEC_STATIC void sqlite3CodecHex2Bin(unsigned char *inputBuffer, int inputBuffersize, unsigned char *outputBuffer){
1659+  int i;
1660+  for(i = 0; i < inputBuffersize - 1; i += 2){
1661+    outputBuffer[i / 2] = sqlite3CodecHex2int(inputBuffer[i]) << 4 | sqlite3CodecHex2int(inputBuffer[i + 1]);
1662+  }
1663+  return;
1664+}
1665+
1666+CODEC_STATIC void sqlite3CodecBin2Hex(unsigned char *inputBuffer, int inputBuffersize, unsigned char *outputBuffer){
1667+  char *buffer = NULL;
1668+  int i;
1669+  for(i = 0; i < inputBuffersize; i++){
1670+    buffer = (char *)(outputBuffer + i * 2);
1671+    sqlite3_snprintf(3, buffer, "%02x ", inputBuffer[i]);
1672+  }
1673+  return;
1674+}
1675+
1676+CODEC_STATIC int sqlite3CodecIfMemset(unsigned char *input, unsigned char val, int len){
1677+  int i;
1678+  for(i = 0; i < len; i++){
1679+    if(input[i] != val){
1680+      return 0;
1681+    }
1682+  }
1683+  return 1;
1684+}
1685+
1686+CODEC_STATIC int sqlite3CodecIsKeyInfoFormat(const unsigned char *input, int inputSize){
1687+  return (input[0] == 'x') && (input[1] == '\'') && (input[inputSize - 1] == '\'') && (sqlite3CodecIsHex(input + 2, inputSize - 3)) ? 1 : 0;
1688+}
1689+
1690+CODEC_STATIC void sqlite3CodecSetError(CodecContext *ctx, int error){
1691+  if(ctx->pBt){
1692+    ctx->pBt->pBt->pPager->errCode = error;
1693+    ctx->pBt->pBt->db->errCode = error;
1694+  }
1695+  return;
1696+}
1697+
1698+CODEC_STATIC void sqlite3CodecClearDeriveKey(KeyContext *keyCtx){
1699+  if(keyCtx->key != NULL){
1700+    (void)memset_s(keyCtx->key, keyCtx->codecConst.keySize, 0, keyCtx->codecConst.keySize);
1701+    sqlite3_free(keyCtx->key);
1702+    keyCtx->key = NULL;
1703+  }
1704+  if(keyCtx->hmacKey != NULL){
1705+    (void)memset_s(keyCtx->hmacKey, keyCtx->codecConst.keySize, 0, keyCtx->codecConst.keySize);
1706+    sqlite3_free(keyCtx->hmacKey);
1707+    keyCtx->hmacKey = NULL;
1708+  }
1709+  if(keyCtx->keyInfo != NULL){
1710+    (void)memset_s(keyCtx->keyInfo, keyCtx->codecConst.keyInfoSize, 0, keyCtx->codecConst.keyInfoSize);
1711+    sqlite3_free(keyCtx->keyInfo);
1712+    keyCtx->keyInfo = NULL;
1713+  }
1714+  keyCtx->deriveFlag = 0;
1715+}
1716+
1717+CODEC_STATIC void sqlite3CodecClearPassword(KeyContext *keyCtx){
1718+  if(keyCtx->password != NULL){
1719+    (void)memset_s(keyCtx->password, keyCtx->passwordSize, 0, keyCtx->passwordSize);
1720+    sqlite3_free(keyCtx->password);
1721+    keyCtx->password = NULL;
1722+  }
1723+  keyCtx->passwordSize = 0;
1724+}
1725+
1726+CODEC_STATIC void sqlite3CodecInitDeriveKeyMemory(KeyContext *keyCtx){
1727+  keyCtx->key = (unsigned char *)sqlite3Malloc(keyCtx->codecConst.keySize);
1728+  keyCtx->hmacKey = (unsigned char *)sqlite3Malloc(keyCtx->codecConst.keySize);
1729+  keyCtx->keyInfo = (unsigned char *)sqlite3Malloc(keyCtx->codecConst.keyInfoSize);
1730+  return;
1731+}
1732+
1733+CODEC_STATIC int sqlite3CodecKeyCtxCmp(KeyContext *first, KeyContext *second){
1734+  if(memcmp((unsigned char *)first, (unsigned char *)second, sizeof(CodecConstant))){
1735+    return 0;
1736+  }
1737+  if(first->iter != second->iter){
1738+    return 0;
1739+  }
1740+  if(first->passwordSize != second->passwordSize){
1741+    return 0;
1742+  }
1743+  if((first->password != second->password) && memcmp(first->password, second->password, first->passwordSize)){
1744+    return 0;
1745+  }
1746+  return 1;
1747+}
1748+
1749+// This function will free all resources of key context, except it self.
1750+CODEC_STATIC void sqlite3CodecFreeKeyContext(KeyContext *keyCtx){
1751+  sqlite3CodecClearDeriveKey(keyCtx);
1752+  sqlite3CodecClearPassword(keyCtx);
1753+  (void)opensslFreeCipher(keyCtx->codecConst.cipher);
1754+  (void)memset_s(keyCtx, sizeof(KeyContext), 0, KEY_CONTEXT_HEAD_SIZE);
1755+}
1756+
1757+// You should clear key derive result of output before you call this function
1758+CODEC_STATIC int sqlite3CodecCopyDeriveKey(KeyContext *input, KeyContext *output){
1759+  errno_t rc = EOK;
1760+  if(input->key != NULL && input->codecConst.keySize > 0){
1761+    output->key = (unsigned char *)sqlite3Malloc(output->codecConst.keySize);
1762+    if(output->key == NULL){
1763+      sqlite3CodecFreeKeyContext(output);
1764+      return SQLITE_NOMEM;
1765+    }
1766+    rc = memcpy_s(output->key, output->codecConst.keySize, input->key, input->codecConst.keySize);
1767+    if(rc != EOK){
1768+      sqlite3CodecFreeKeyContext(output);
1769+      return SQLITE_ERROR;
1770+    }
1771+  }
1772+  if(input->hmacKey != NULL && input->codecConst.keySize > 0){
1773+    output->hmacKey = (unsigned char *)sqlite3Malloc(output->codecConst.keySize);
1774+    if(output->hmacKey == NULL){
1775+      sqlite3CodecFreeKeyContext(output);
1776+      return SQLITE_NOMEM;
1777+    }
1778+    rc = memcpy_s(output->hmacKey, output->codecConst.keySize, input->hmacKey, input->codecConst.keySize);
1779+    if(rc != EOK){
1780+      sqlite3CodecFreeKeyContext(output);
1781+      return SQLITE_ERROR;
1782+    }
1783+  }
1784+  if(input->keyInfo != NULL && input->codecConst.keyInfoSize > 0){
1785+    output->keyInfo = (unsigned char *)sqlite3Malloc(output->codecConst.keyInfoSize);
1786+    if(output->keyInfo == NULL){
1787+      sqlite3CodecFreeKeyContext(output);
1788+      return SQLITE_NOMEM;
1789+    }
1790+    rc = memcpy_s(output->keyInfo, output->codecConst.keyInfoSize, input->keyInfo, input->codecConst.keyInfoSize);
1791+    if(rc != EOK){
1792+      sqlite3CodecFreeKeyContext(output);
1793+      return SQLITE_ERROR;
1794+    }
1795+  }
1796+  return SQLITE_OK;
1797+}
1798+
1799+// You should set all key infos including salt before you call this function
1800+CODEC_STATIC int sqlite3CodecDeriveKey(CodecContext *ctx, OperateContext whichKey){
1801+  KeyContext *keyCtx = NULL;
1802+  KeyContext *secondKeyCtx = NULL;
1803+  switch(whichKey){
1804+    case OPERATE_CONTEXT_READ:
1805+      keyCtx = ctx->readCtx;
1806+      secondKeyCtx = ctx->writeCtx;
1807+      break;
1808+    case OPERATE_CONTEXT_WRITE:
1809+      keyCtx = ctx->writeCtx;
1810+      secondKeyCtx = ctx->readCtx;
1811+      break;
1812+    default:
1813+      return SQLITE_ERROR;
1814+  }
1815+  if(keyCtx->password == NULL || keyCtx->passwordSize <= 0){
1816+    return SQLITE_ERROR;
1817+  }
1818+  if(keyCtx->deriveFlag){
1819+    return SQLITE_OK;
1820+  }
1821+  errno_t memcpyRc = EOK;
1822+  unsigned char salt[SALT_SIZE];
1823+  if (ctx->pBt != NULL && sqlite3OsRead(ctx->pBt->pBt->pPager->fd, salt, SALT_SIZE, 0) == SQLITE_OK) {
1824+    assert(SALT_SIZE == FILE_HEADER_SIZE);
1825+    if (memcmp(SQLITE_FILE_HEADER, salt, SALT_SIZE) != 0 && memcmp(ctx->salt, salt, SALT_SIZE) != 0) {
1826+      memcpyRc = memcpy_s(ctx->salt, FILE_HEADER_SIZE, salt, SALT_SIZE);
1827+      if(memcpyRc != EOK){
1828+        return SQLITE_ERROR;
1829+      }
1830+    }
1831+  }
1832+  sqlite3CodecInitDeriveKeyMemory(keyCtx);
1833+  if(keyCtx->key == NULL || keyCtx->hmacKey == NULL || keyCtx->keyInfo == NULL){
1834+    sqlite3CodecClearDeriveKey(keyCtx);
1835+    return SQLITE_NOMEM;
1836+  }
1837+  if((keyCtx->passwordSize == keyCtx->codecConst.keyInfoSize) &&
1838+    (sqlite3CodecIsKeyInfoFormat(keyCtx->password, keyCtx->passwordSize))){
1839+    sqlite3CodecHex2Bin(keyCtx->password + 2, keyCtx->codecConst.keySize * 2, keyCtx->key);
1840+    sqlite3CodecHex2Bin(keyCtx->password + 2 + keyCtx->codecConst.keySize * 2, SALT_SIZE * 2, ctx->salt);
1841+    memcpyRc = memcpy_s(keyCtx->keyInfo, keyCtx->codecConst.keyInfoSize, keyCtx->password, keyCtx->passwordSize);
1842+    if(memcpyRc != EOK){
1843+      return SQLITE_ERROR;
1844+    }
1845+  }else if((keyCtx->passwordSize == keyCtx->codecConst.keyInfoSize - SALT_SIZE * 2) &&
1846+    (sqlite3CodecIsKeyInfoFormat(keyCtx->password, keyCtx->passwordSize))){
1847+    sqlite3CodecHex2Bin(keyCtx->password + 2, keyCtx->codecConst.keySize * 2, keyCtx->key);
1848+    memcpyRc = memcpy_s(keyCtx->keyInfo, keyCtx->codecConst.keyInfoSize, keyCtx->password, keyCtx->passwordSize);
1849+    if(memcpyRc != EOK){
1850+      return SQLITE_ERROR;
1851+    }
1852+    sqlite3CodecBin2Hex(ctx->salt, SALT_SIZE, keyCtx->keyInfo + 2 + keyCtx->codecConst.keySize * 2);
1853+    keyCtx->keyInfo[keyCtx->codecConst.keyInfoSize - 1] = '\'';
1854+  }else{
1855+    Buffer password;
1856+    Buffer salt;
1857+    Buffer key;
1858+    password.buffer = keyCtx->password;
1859+    password.bufferSize = keyCtx->passwordSize;
1860+    salt.buffer = ctx->salt;
1861+    salt.bufferSize = SALT_SIZE;
1862+    key.buffer = keyCtx->key;
1863+    key.bufferSize = keyCtx->codecConst.keySize;
1864+    opensslKdf(&password, &salt, keyCtx->iter, &key, keyCtx->codecConst.kdfAlgo);
1865+    keyCtx->keyInfo[0] = 'x';
1866+    keyCtx->keyInfo[1] = '\'';
1867+    sqlite3CodecBin2Hex(keyCtx->key, keyCtx->codecConst.keySize, keyCtx->keyInfo + 2);
1868+    sqlite3CodecBin2Hex(ctx->salt, SALT_SIZE, keyCtx->keyInfo + 2 + keyCtx->codecConst.keySize * 2);
1869+    keyCtx->keyInfo[keyCtx->codecConst.keyInfoSize - 1] = '\'';
1870+  }
1871+  int i;
1872+  for(i = 0; i < SALT_SIZE; i++){
1873+    ctx->hmacSalt[i] = ctx->salt[i] ^ HMAC_SALT_MASK;
1874+  }
1875+  Buffer hmacPassword;
1876+  Buffer hmacSalt;
1877+  Buffer hmacKey;
1878+  hmacPassword.buffer = keyCtx->key;
1879+  hmacPassword.bufferSize = keyCtx->codecConst.keySize;
1880+  hmacSalt.buffer = ctx->hmacSalt;
1881+  hmacSalt.bufferSize = SALT_SIZE;
1882+  hmacKey.buffer = keyCtx->hmacKey;
1883+  hmacKey.bufferSize = keyCtx->codecConst.keySize;
1884+  opensslKdf(&hmacPassword, &hmacSalt, HMAC_ITER, &hmacKey, keyCtx->codecConst.kdfAlgo);
1885+  keyCtx->deriveFlag = 1;
1886+  if(sqlite3CodecKeyCtxCmp(keyCtx, secondKeyCtx)){
1887+    sqlite3CodecClearDeriveKey(secondKeyCtx);
1888+    int rc = sqlite3CodecCopyDeriveKey(keyCtx, secondKeyCtx);
1889+    if(rc == SQLITE_OK){
1890+      secondKeyCtx->deriveFlag = 1;
1891+      // clear password
1892+      if(!(ctx->savePassword)){
1893+        sqlite3CodecClearPassword(secondKeyCtx);
1894+      }
1895+    }
1896+  }
1897+  // clear password
1898+  if(!(ctx->savePassword)){
1899+    sqlite3CodecClearPassword(keyCtx);
1900+  }
1901+  return SQLITE_OK;
1902+}
1903+
1904+// This function may clear key derive infos
1905+CODEC_STATIC int sqlite3CodecSetCodecConstant(KeyContext *keyCtx, const char *cipherName){
1906+  if(keyCtx->codecConst.cipher){
1907+    if(sqlite3StrICmp(cipherName, opensslGetCipherName(keyCtx->codecConst.cipher)) == 0){
1908+      return SQLITE_OK;
1909+    }
1910+  }
1911+  sqlite3CodecClearDeriveKey(keyCtx);
1912+  void *cipher = opensslGetCipher(cipherName);
1913+  if(cipher != NULL){
1914+    keyCtx->codecConst.cipher = cipher;
1915+  } else {
1916+    return SQLITE_ERROR;
1917+  }
1918+  keyCtx->codecConst.keySize = opensslGetKeySize(keyCtx->codecConst.cipher);
1919+  keyCtx->codecConst.keyInfoSize = (keyCtx->codecConst.keySize + SALT_SIZE) * 2 + 3;
1920+  keyCtx->codecConst.initVectorSize = opensslGetInitVectorSize(keyCtx->codecConst.cipher);
1921+  return SQLITE_OK;
1922+}
1923+
1924+// You should clear key derive infos before you call this function
1925+CODEC_STATIC int sqlite3CodecSetIter(KeyContext *keyCtx, int iter){
1926+  keyCtx->iter = iter;
1927+  return SQLITE_OK;
1928+}
1929+
1930+#ifdef SQLITE_CODEC_ATTACH_CHANGED
1931+#define CIPHER_ID_AES_256_CBC 0
1932+#define CIPHER_ID_AES_256_GCM 1
1933+
1934+#define CIPHER_TOTAL_NUM 2
1935+
1936+#define CIPHER_NAME_AES_256_CBC "aes-256-cbc"
1937+#define CIPHER_NAME_AES_256_GCM "aes-256-gcm"
1938+
1939+struct CodecCipherNameId {
1940+  int cipherId;
1941+  const char *cipherName;
1942+};
1943+
1944+static const struct CodecCipherNameId g_cipherNameIdMap[CIPHER_TOTAL_NUM] = {
1945+  { CIPHER_ID_AES_256_CBC, CIPHER_NAME_AES_256_CBC },
1946+  { CIPHER_ID_AES_256_GCM, CIPHER_NAME_AES_256_GCM }
1947+};
1948+
1949+SQLITE_PRIVATE void sqlite3CodecResetParameters(CodecParameter *p)
1950+{
1951+  p->kdfIter = DEFAULT_ITER;
1952+  p->pageSize = DEFAULT_PAGE_SIZE;
1953+  p->cipher = CIPHER_ID_AES_256_GCM;
1954+  p->hmacAlgo = DEFAULT_HMAC_ALGORITHM;
1955+  p->kdfAlgo = DEFAULT_KDF_ALGORITHM;
1956+}
1957+
1958+CODEC_STATIC void sqlite3CodecSetDefaultAttachCipher(CodecParameter *parm, const char *cipherName){
1959+  int i;
1960+  for( i=0; i<CIPHER_TOTAL_NUM; i++ ){
1961+    if( sqlite3StrICmp(cipherName, g_cipherNameIdMap[i].cipherName)==0 ){
1962+      sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1963+      parm->cipher = g_cipherNameIdMap[i].cipherId;
1964+      sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1965+      return;
1966+    }
1967+  }
1968+  sqlite3_log(SQLITE_WARNING, "invalid attach cipher algorithm");
1969+}
1970+
1971+CODEC_STATIC const char *sqlite3CodecGetDefaultAttachCipher(CodecParameter *parm){
1972+  const char *attachedCipher = CIPHER_NAME_AES_256_GCM;
1973+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1974+  if( (parm->cipher>=0) && (parm->cipher<CIPHER_TOTAL_NUM) ){
1975+    attachedCipher = g_cipherNameIdMap[parm->cipher].cipherName;
1976+  }
1977+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1978+  return attachedCipher;
1979+}
1980+
1981+CODEC_STATIC void sqlite3CodecSetDefaultAttachKdfIter(CodecParameter *parm, int iter){
1982+  if( iter<=0 ){
1983+    return;
1984+  }
1985+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1986+  parm->kdfIter = iter;
1987+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1988+}
1989+
1990+CODEC_STATIC int sqlite3CodecGetDefaultAttachKdfIter(CodecParameter *parm){
1991+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1992+  int iterNum = parm->kdfIter;
1993+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1994+  return iterNum;
1995+}
1996+
1997+CODEC_STATIC void sqlite3CodecSetDefaultAttachHmacAlgo(CodecParameter *parm, int hmacAlgo){
1998+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
1999+  parm->hmacAlgo = hmacAlgo;
2000+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2001+}
2002+
2003+CODEC_STATIC int sqlite3CodecGetDefaultAttachHmacAlgo(CodecParameter *parm){
2004+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2005+  int hmacAlgo = parm->hmacAlgo;
2006+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2007+  return hmacAlgo;
2008+}
2009+
2010+CODEC_STATIC void sqlite3CodecSetDefaultAttachKdfAlgo(CodecParameter *parm, int kdfAlgo){
2011+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2012+  parm->kdfAlgo = kdfAlgo;
2013+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2014+}
2015+
2016+CODEC_STATIC int sqlite3CodecGetDefaultAttachKdfAlgo(CodecParameter *parm){
2017+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2018+  int kdfAlgo = parm->kdfAlgo;
2019+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2020+  return kdfAlgo;
2021+}
2022+
2023+CODEC_STATIC void sqlite3CodecSetDefaultAttachPageSize(CodecParameter *parm, int pageSize){
2024+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2025+  parm->pageSize = pageSize;
2026+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2027+}
2028+
2029+CODEC_STATIC int sqlite3CodecGetDefaultAttachPageSize(CodecParameter *parm){
2030+  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2031+  int pageSize = parm->pageSize;
2032+  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
2033+  return pageSize;
2034+}
2035+
2036+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
2037+
2038+// You should clear key derive infos and password infos before you call this function
2039+CODEC_STATIC int sqlite3CodecSetPassword(KeyContext *keyCtx, const void *zKey, int nKey){
2040+  keyCtx->passwordSize = nKey;
2041+  keyCtx->password = (unsigned char *)sqlite3Malloc(keyCtx->passwordSize);
2042+  if(keyCtx->password == NULL){
2043+    return SQLITE_NOMEM;
2044+  }
2045+  errno_t rc = memcpy_s(keyCtx->password, keyCtx->passwordSize, zKey, nKey);
2046+  if(rc != EOK){
2047+    sqlite3CodecClearPassword(keyCtx);
2048+    return SQLITE_ERROR;
2049+  }
2050+  return SQLITE_OK;
2051+}
2052+
2053+// You should clear key derive infos and password infos before you call this function
2054+CODEC_STATIC int sqlite3CodecSetHmacAlgorithm(KeyContext *keyCtx, int hmacAlgo){
2055+  keyCtx->codecConst.hmacAlgo = hmacAlgo;
2056+  keyCtx->codecConst.hmacSize = opensslGetHmacSize(keyCtx);
2057+  int cipherBlockSize = opensslGetBlockSize(keyCtx->codecConst.cipher);
2058+  int blockSize = cipherBlockSize;
2059+  while(blockSize < MIN_BLOCK_SIZE){
2060+    blockSize += cipherBlockSize;
2061+  }
2062+  int reserveSize = MAX_INIT_VECTOR_SIZE + keyCtx->codecConst.hmacSize;
2063+  if(reserveSize % blockSize == 0){
2064+    keyCtx->codecConst.reserveSize = reserveSize;
2065+  }else{
2066+    keyCtx->codecConst.reserveSize = (reserveSize / blockSize + 1) * blockSize;
2067+  }
2068+  return SQLITE_OK;
2069+}
2070+
2071+CODEC_STATIC int sqlite3CodecSetKdfAlgorithm(KeyContext *keyCtx, int kdfAlgo){
2072+  keyCtx->codecConst.kdfAlgo = kdfAlgo;
2073+  return SQLITE_OK;
2074+}
2075+
2076+CODEC_STATIC int sqlite3CodecSetCipherPageSize(CodecContext *ctx, int size){
2077+  if(!((size != 0) && ((size & (size - 1)) == 0)) || size < 512 || size > 65536) {
2078+    sqlite3_log(SQLITE_ERROR, "codec: cipher_page_size not a power of 2 and between 512 and 65536 inclusive(%d).", size);
2079+    return SQLITE_ERROR;
2080+  }
2081+  int cipherPageSize = ctx->readCtx->codecConst.cipherPageSize;
2082+  (void)memset_s(ctx->buffer, cipherPageSize, 0, cipherPageSize);
2083+  sqlite3_free(ctx->buffer);
2084+  ctx->readCtx->codecConst.cipherPageSize = size;
2085+  ctx->writeCtx->codecConst.cipherPageSize = size;
2086+
2087+  ctx->buffer = (unsigned char *)sqlite3Malloc(size);
2088+  if (ctx->buffer == NULL) {
2089+    sqlite3_log(SQLITE_NOMEM, "codec: alloc mem failed when set cipher page size(%d).", size);
2090+    return SQLITE_NOMEM;
2091+  }
2092+  return SQLITE_OK;
2093+}
2094+
2095+// You should clear output before you call this function
2096+CODEC_STATIC int sqlite3CodecCopyKeyContext(KeyContext *input, KeyContext *output){
2097+  errno_t rc = memcpy_s(output, sizeof(KeyContext), input, KEY_CONTEXT_HEAD_SIZE);
2098+  if(rc != EOK){
2099+    return SQLITE_ERROR;
2100+  }
2101+  if(input->password != NULL && input->passwordSize > 0){
2102+    output->password = (unsigned char *)sqlite3Malloc(output->passwordSize);
2103+    if(output->password == NULL){
2104+      sqlite3CodecFreeKeyContext(output);
2105+      return SQLITE_NOMEM;
2106+    }
2107+    rc = memcpy_s(output->password, output->passwordSize, input->password, input->passwordSize);
2108+    if(rc != EOK){
2109+      sqlite3CodecFreeKeyContext(output);
2110+      return SQLITE_ERROR;
2111+    }
2112+  }
2113+  return sqlite3CodecCopyDeriveKey(input, output);
2114+}
2115+
2116+// You should clear key context before you call this function
2117+#ifdef SQLITE_CODEC_ATTACH_CHANGED
2118+CODEC_STATIC int sqlite3CodecInitKeyContext(CodecContext *ctx, Btree *p, const void *zKey, int nKey, int attachFlag){
2119+#else
2120+CODEC_STATIC int sqlite3CodecInitKeyContext(CodecContext *ctx, Btree *p, const void *zKey, int nKey){
2121+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
2122+  int rc = SQLITE_OK;
2123+  KeyContext *keyCtx = ctx->readCtx;
2124+#ifdef SQLITE_CODEC_ATTACH_CHANGED
2125+  if( attachFlag!=0 ){
2126+    CodecParameter *parm = &p->db->codecParm;
2127+    int hmacAlgo = sqlite3CodecGetDefaultAttachHmacAlgo(parm);
2128+    rc = sqlite3CodecSetCodecConstant(keyCtx, sqlite3CodecGetDefaultAttachCipher(parm));
2129+    rc += sqlite3CodecSetIter(keyCtx, sqlite3CodecGetDefaultAttachKdfIter(parm));
2130+    if( hmacAlgo!=0 ){
2131+      rc += sqlite3CodecSetHmacAlgorithm(keyCtx, hmacAlgo);
2132+    }
2133+    int attachKdfAlgo = sqlite3CodecGetDefaultAttachKdfAlgo(parm);
2134+    if( attachKdfAlgo!=0 ){
2135+      rc += sqlite3CodecSetKdfAlgorithm(keyCtx, attachKdfAlgo);
2136+    }
2137+    int cipherPageSize = sqlite3CodecGetDefaultAttachPageSize(parm);
2138+    if( cipherPageSize!=0 ){
2139+      rc += sqlite3CodecSetCipherPageSize(ctx, cipherPageSize);
2140+      if ( rc != SQLITE_OK ) {
2141+        sqlite3CodecFreeKeyContext(keyCtx);
2142+        return SQLITE_ERROR;
2143+      }
2144+      rc += sqlite3BtreeSetPageSize(p, cipherPageSize, keyCtx->codecConst.reserveSize, 0);
2145+    }
2146+  }else{
2147+    rc = sqlite3CodecSetCodecConstant(keyCtx, DEFAULT_CIPHER);
2148+    rc += sqlite3CodecSetIter(keyCtx, DEFAULT_ITER);
2149+    rc += sqlite3CodecSetHmacAlgorithm(keyCtx, DEFAULT_HMAC_ALGORITHM);
2150+    rc += sqlite3CodecSetKdfAlgorithm(keyCtx, DEFAULT_KDF_ALGORITHM);
2151+  }
2152+#else
2153+  rc = sqlite3CodecSetCodecConstant(keyCtx, DEFAULT_CIPHER);
2154+  rc += sqlite3CodecSetIter(keyCtx, DEFAULT_ITER);
2155+  rc += sqlite3CodecSetHmacAlgorithm(keyCtx, DEFAULT_HMAC_ALGORITHM);
2156+  rc += sqlite3CodecSetKdfAlgorithm(keyCtx, DEFAULT_KDF_ALGORITHM);
2157+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
2158+  keyCtx->codecConst.rekeyHmacAlgo = DEFAULT_HMAC_ALGORITHM;
2159+  rc += sqlite3CodecSetPassword(keyCtx, zKey, nKey);
2160+  if(rc != SQLITE_OK){
2161+    sqlite3CodecFreeKeyContext(keyCtx);
2162+    return SQLITE_ERROR;
2163+  }
2164+  return SQLITE_OK;
2165+}
2166+
2167+// This function will free all resources of codec context, except it self.
2168+CODEC_STATIC void sqlite3CodecFreeContext(CodecContext *ctx){
2169+  if(ctx->buffer){
2170+    int cipherPageSize = ctx->readCtx->codecConst.cipherPageSize;
2171+    (void)memset_s(ctx->buffer, cipherPageSize, 0, cipherPageSize);
2172+    sqlite3_free(ctx->buffer);
2173+    ctx->buffer = NULL;
2174+  }
2175+  if(ctx->readCtx){
2176+    sqlite3CodecFreeKeyContext(ctx->readCtx);
2177+    sqlite3_free(ctx->readCtx);
2178+    ctx->readCtx = NULL;
2179+  }
2180+  if(ctx->writeCtx){
2181+    sqlite3CodecFreeKeyContext(ctx->writeCtx);
2182+    sqlite3_free(ctx->writeCtx);
2183+    ctx->writeCtx = NULL;
2184+  }
2185+  (void)memset_s(ctx, sizeof(CodecContext), 0, sizeof(CodecContext));
2186+  return;
2187+}
2188+#ifdef SQLITE_CODEC_ATTACH_CHANGED
2189+CODEC_STATIC int sqlite3CodecInitContext(CodecContext *ctx, Btree *p, const void *zKey, int nKey, int nDb){
2190+  int attachFlag = (nDb > 1) ? 1 : 0;
2191+  int defaultPageSz = attachFlag ? p->db->codecParm.pageSize : DEFAULT_PAGE_SIZE;
2192+#else
2193+CODEC_STATIC int sqlite3CodecInitContext(CodecContext *ctx, Btree *p, const void *zKey, int nKey){
2194+  int defaultPageSz = DEFAULT_PAGE_SIZE;
2195+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
2196+  sqlite3_file *fd = p->pBt->pPager->fd;
2197+  ctx->pBt = p;
2198+  ctx->savePassword = 0;
2199+  ctx->buffer = (unsigned char *)sqlite3Malloc(defaultPageSz);
2200+  ctx->readCtx = (KeyContext *)sqlite3Malloc(sizeof(KeyContext));
2201+  ctx->writeCtx = (KeyContext *)sqlite3Malloc(sizeof(KeyContext));
2202+  if(ctx->buffer == NULL || ctx->readCtx == NULL || ctx->writeCtx == NULL){
2203+    sqlite3CodecFreeContext(ctx);
2204+    return SQLITE_NOMEM;
2205+  }
2206+  errno_t memsetRc = memset_s(ctx->buffer, defaultPageSz, 0, defaultPageSz);
2207+  memsetRc += memset_s(ctx->readCtx, sizeof(KeyContext), 0, sizeof(KeyContext));
2208+  memsetRc += memset_s(ctx->writeCtx, sizeof(KeyContext), 0, sizeof(KeyContext));
2209+  if(memsetRc != EOK){
2210+    sqlite3CodecFreeContext(ctx);
2211+    return SQLITE_ERROR;
2212+  }
2213+  ctx->readCtx->codecConst.cipherPageSize = defaultPageSz;
2214+  ctx->writeCtx->codecConst.cipherPageSize = defaultPageSz;
2215+#ifdef SQLITE_CODEC_ATTACH_CHANGED
2216+  int rc = sqlite3CodecInitKeyContext(ctx, p, zKey, nKey, attachFlag);
2217+#else
2218+  int rc = sqlite3CodecInitKeyContext(ctx, p, zKey, nKey);
2219+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
2220+  if(rc != SQLITE_OK){
2221+    sqlite3CodecFreeContext(ctx);
2222+    return SQLITE_ERROR;
2223+  }
2224+  rc = sqlite3CodecCopyKeyContext(ctx->readCtx, ctx->writeCtx);
2225+  if(rc != SQLITE_OK){
2226+    sqlite3CodecFreeContext(ctx);
2227+    return SQLITE_ERROR;
2228+  }
2229+  if(fd == NULL || !(isOpen(fd)) || sqlite3OsRead(fd, ctx->salt, SALT_SIZE, 0) != SQLITE_OK){
2230+    Buffer salt;
2231+    salt.buffer = ctx->salt;
2232+    salt.bufferSize = SALT_SIZE;
2233+    rc = opensslGetRandom(&salt);
2234+    if(rc != SQLITE_OK){
2235+      sqlite3CodecFreeContext(ctx);
2236+      return rc;
2237+    }
2238+  }
2239+  return SQLITE_OK;
2240+}
2241+
2242+CODEC_STATIC int sqlite3CodecGetDbIndex(sqlite3 *db, const char *zDb){
2243+  int nDbIndex;
2244+  if(zDb == NULL){
2245+    return 0;
2246+  }
2247+  for(nDbIndex = 0; nDbIndex < db->nDb; nDbIndex++){
2248+    const char *zDbSName = db->aDb[nDbIndex].zDbSName;
2249+    if(strcmp(zDbSName, zDb) == 0){
2250+      return nDbIndex;
2251+    }
2252+  }
2253+  return 0;
2254+}
2255+
2256+CODEC_STATIC void sqlite3CodecTransPgno(Pgno input, unsigned char *output){
2257+#ifdef CIPHER_BIG_ENDAIN
2258+  sqlite3Put4byte(output, input);
2259+#else
2260+  output[0] = (u8)input;
2261+  output[1] = (u8)(input>>8);
2262+  output[2] = (u8)(input>>16);
2263+  output[3] = (u8)(input>>24);
2264+#endif
2265+}
2266+
2267+CODEC_STATIC int sqlite3CodecHmac(KeyContext *ctx, Pgno pgno, int bufferSize, unsigned char *input, unsigned char *output){
2268+  Buffer key;
2269+  key.buffer = ctx->hmacKey;
2270+  key.bufferSize = ctx->codecConst.keySize;
2271+  Buffer input1;
2272+  input1.buffer = input;
2273+  input1.bufferSize = bufferSize;
2274+  Buffer input2;
2275+  unsigned char pgnoBuffer[sizeof(Pgno)];
2276+  sqlite3CodecTransPgno(pgno, pgnoBuffer);
2277+  input2.buffer = pgnoBuffer;
2278+  input2.bufferSize = sizeof(Pgno);
2279+  Buffer outputBuffer;
2280+  outputBuffer.buffer = output;
2281+  outputBuffer.bufferSize = 0;
2282+  int rc = opensslHmac(&key, &input1, &input2, &outputBuffer, ctx->codecConst.hmacAlgo);
2283+  if(rc != SQLITE_OK || outputBuffer.bufferSize != ctx->codecConst.hmacSize){
2284+    return SQLITE_ERROR;
2285+  }
2286+  return SQLITE_OK;
2287+}
2288+
2289+CODEC_STATIC int sqlite3CodecCheckHmac(KeyContext *ctx, Pgno pgno, int bufferSize, unsigned char *input, unsigned char *expectResult){
2290+  if (ctx->codecConst.hmacSize <= 0) {
2291+    return 1;
2292+  }
2293+  int rc = SQLITE_OK;
2294+  if (ctx->codecConst.hmacSize <= MAX_HMAC_SIZE) {
2295+    unsigned char buffer[MAX_HMAC_SIZE];
2296+    rc = sqlite3CodecHmac(ctx, pgno, bufferSize, input, buffer);
2297+    if(rc != SQLITE_OK){
2298+      return 1;
2299+    }
2300+    return memcmp(buffer, expectResult, ctx->codecConst.hmacSize);
2301+  } else {
2302+    unsigned char *output = (unsigned char *)malloc(ctx->codecConst.hmacSize);
2303+    if (output == NULL) {
2304+      return 1;
2305+    }
2306+    rc = sqlite3CodecHmac(ctx, pgno, bufferSize, input, output);
2307+    if(rc != SQLITE_OK){
2308+      free(output);
2309+      return 1;
2310+    }
2311+    rc = memcmp(output, expectResult, ctx->codecConst.hmacSize);
2312+    free(output);
2313+    return rc;
2314+  }
2315+}
2316+
2317+CODEC_STATIC int sqlite3CodecEncryptData(CodecContext *ctx, OperateContext whichKey, Pgno pgno, int bufferSize, unsigned char *input, unsigned char *output){
2318+  KeyContext *keyCtx = NULL;
2319+  switch(whichKey){
2320+    case OPERATE_CONTEXT_READ:
2321+      keyCtx = ctx->readCtx;
2322+      break;
2323+    case OPERATE_CONTEXT_WRITE:
2324+      keyCtx = ctx->writeCtx;
2325+      break;
2326+    default:
2327+      return SQLITE_ERROR;
2328+  }
2329+  int rc = SQLITE_OK;
2330+  if(!(keyCtx->deriveFlag)){
2331+    rc = sqlite3CodecDeriveKey(ctx, whichKey);
2332+    if(rc != SQLITE_OK){
2333+      return rc;
2334+    }
2335+  }
2336+  if(keyCtx->codecConst.keySize == 0){
2337+    return SQLITE_ERROR;
2338+  }
2339+  Buffer inputBuffer;
2340+  inputBuffer.buffer = input;
2341+  inputBuffer.bufferSize = bufferSize - keyCtx->codecConst.reserveSize;
2342+  Buffer initVector;
2343+  initVector.buffer = output + inputBuffer.bufferSize;
2344+  initVector.bufferSize = keyCtx->codecConst.initVectorSize;
2345+  rc = opensslGetRandom(&initVector);
2346+  if(rc != SQLITE_OK){
2347+    return rc;
2348+  }
2349+  void *cipherCtx = opensslGetCtx(keyCtx->codecConst.cipher, CODEC_OPERATION_ENCRYPT, keyCtx->key, initVector.buffer);
2350+  if(cipherCtx == NULL){
2351+    return SQLITE_ERROR;
2352+  }
2353+  rc = opensslCipher(cipherCtx, &inputBuffer, output);
2354+  opensslFreeCtx(cipherCtx);
2355+  if(rc != SQLITE_OK){
2356+    return rc;
2357+  }
2358+  rc = sqlite3CodecHmac(keyCtx, pgno, inputBuffer.bufferSize + keyCtx->codecConst.initVectorSize, output, output + inputBuffer.bufferSize + keyCtx->codecConst.initVectorSize);
2359+  if(rc != SQLITE_OK){
2360+    return rc;
2361+  }
2362+  return SQLITE_OK;
2363+}
2364+
2365+CODEC_STATIC int sqlite3CodecDecryptData(CodecContext *ctx, OperateContext whichKey, Pgno pgno, int bufferSize, unsigned char *input, unsigned char *output){
2366+  KeyContext *keyCtx = NULL;
2367+  switch(whichKey){
2368+    case OPERATE_CONTEXT_READ:
2369+      keyCtx = ctx->readCtx;
2370+      break;
2371+    case OPERATE_CONTEXT_WRITE:
2372+      keyCtx = ctx->writeCtx;
2373+      break;
2374+    default:
2375+      return SQLITE_ERROR;
2376+  }
2377+  int rc = SQLITE_OK;
2378+  if(!(keyCtx->deriveFlag)){
2379+    rc = sqlite3CodecDeriveKey(ctx, whichKey);
2380+    if(rc != SQLITE_OK){
2381+      return rc;
2382+    }
2383+  }
2384+  if(keyCtx->codecConst.keySize == 0){
2385+    return SQLITE_ERROR;
2386+  }
2387+  if(sqlite3CodecIfMemset(input, 0, bufferSize)){
2388+    errno_t memsetRc = memset_s(output, bufferSize, 0, bufferSize);
2389+    if(memsetRc != EOK){
2390+      return SQLITE_ERROR;
2391+    }
2392+    return SQLITE_OK;
2393+  }else{
2394+    Buffer inputBuffer;
2395+    inputBuffer.buffer = input;
2396+    inputBuffer.bufferSize = bufferSize - keyCtx->codecConst.reserveSize;
2397+    if(sqlite3CodecCheckHmac(keyCtx, pgno, inputBuffer.bufferSize + keyCtx->codecConst.initVectorSize, input, input + inputBuffer.bufferSize + keyCtx->codecConst.initVectorSize)){
2398+      sqlite3_log(SQLITE_ERROR, "codec: check hmac error at page %d, hmac %d, kdf %d, pageSize %d, iter %d.",
2399+        pgno, keyCtx->codecConst.hmacAlgo, keyCtx->codecConst.kdfAlgo, keyCtx->codecConst.cipherPageSize, keyCtx->iter);
2400+      return pgno == 1 ? SQLITE_NOTADB : SQLITE_CORRUPT;
2401+    }
2402+    unsigned char *initVector = input + inputBuffer.bufferSize;
2403+    void *cipherCtx = opensslGetCtx(keyCtx->codecConst.cipher, CODEC_OPERATION_DECRYPT, keyCtx->key, initVector);
2404+    if(cipherCtx == NULL){
2405+      return SQLITE_ERROR;
2406+    }
2407+    rc = opensslCipher(cipherCtx, &inputBuffer, output);
2408+    opensslFreeCtx(cipherCtx);
2409+    if(rc != SQLITE_OK){
2410+      return rc;
2411+    }
2412+  }
2413+  return SQLITE_OK;
2414+}
2415+
2416+void* sqlite3Codec(void *ctx, void *data, Pgno pgno, int mode){
2417+  CodecContext *pCtx = (CodecContext *)ctx;
2418+  unsigned char *pData = (unsigned char *)data;
2419+  int offset = 0;
2420+  int rc = SQLITE_OK;
2421+  errno_t memcpyRc = EOK;
2422+  if(ctx == NULL || data == NULL){
2423+    return NULL;
2424+  }
2425+  if(pgno == 1){
2426+    offset = FILE_HEADER_SIZE;
2427+  }
2428+  int cipherPageSize = pCtx->readCtx->codecConst.cipherPageSize;
2429+  switch(mode){
2430+    case 0:
2431+    case 2:
2432+    case 3:
2433+      if(pgno == 1){
2434+        memcpyRc = memcpy_s(pCtx->buffer, cipherPageSize, SQLITE_FILE_HEADER, FILE_HEADER_SIZE);
2435+        if(memcpyRc != EOK){
2436+          sqlite3CodecSetError(pCtx, SQLITE_ERROR);
2437+          return NULL;
2438+        }
2439+      }
2440+      rc = sqlite3CodecDecryptData(pCtx, OPERATE_CONTEXT_READ, pgno, cipherPageSize - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset);
2441+      if(rc != SQLITE_OK){
2442+        sqlite3CodecSetError(pCtx, rc);
2443+        return NULL;
2444+      }
2445+      (void)memcpy_s(pData, cipherPageSize, pCtx->buffer, cipherPageSize);
2446+      return pData;
2447+      break;
2448+    case 6:
2449+      if(pgno == 1){
2450+        memcpyRc = memcpy_s(pCtx->buffer, cipherPageSize, pCtx->salt, FILE_HEADER_SIZE);
2451+        if(memcpyRc != EOK){
2452+          sqlite3CodecSetError(pCtx, SQLITE_ERROR);
2453+          return NULL;
2454+        }
2455+      }
2456+      rc = sqlite3CodecEncryptData(pCtx, OPERATE_CONTEXT_WRITE, pgno, cipherPageSize - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset);
2457+      if(rc != SQLITE_OK){
2458+        sqlite3CodecSetError(pCtx, rc);
2459+        return NULL;
2460+      }
2461+      return pCtx->buffer;
2462+      break;
2463+    case 7:
2464+      if(pgno == 1){
2465+        memcpyRc = memcpy_s(pCtx->buffer, cipherPageSize, pCtx->salt, FILE_HEADER_SIZE);
2466+        if(memcpyRc != EOK){
2467+          sqlite3CodecSetError(pCtx, SQLITE_ERROR);
2468+          return NULL;
2469+        }
2470+      }
2471+      rc = sqlite3CodecEncryptData(pCtx, OPERATE_CONTEXT_READ, pgno, cipherPageSize - offset, (unsigned char *)(pData + offset), pCtx->buffer + offset);
2472+      if(rc != SQLITE_OK){
2473+        sqlite3CodecSetError(pCtx, rc);
2474+        return NULL;
2475+      }
2476+      return pCtx->buffer;
2477+      break;
2478+    default:
2479+      return NULL;
2480+      break;
2481+  }
2482+}
2483+
2484+void sqlite3CodecDetach(void *ctx){
2485+  if(ctx != NULL){
2486+    sqlite3CodecFreeContext((CodecContext *)ctx);
2487+    sqlite3_free(ctx);
2488+    opensslDeactive();
2489+  }
2490+  return;
2491+}
2492+
2493+int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){
2494+  if(db == NULL){
2495+    return SQLITE_ERROR;
2496+  }
2497+  Btree *p = db->aDb[nDb].pBt;
2498+  if(p == NULL || pKey == NULL || nKey <= 0){
2499+    return SQLITE_OK;
2500+  }
2501+  opensslActive();
2502+  CodecContext *ctx = (CodecContext *)sqlite3Malloc(sizeof(CodecContext));
2503+  if(ctx == NULL){
2504+    return SQLITE_NOMEM;
2505+  }
2506+  errno_t memsetRc = memset_s(ctx, sizeof(CodecContext), 0, sizeof(CodecContext));
2507+  if(memsetRc != EOK){
2508+    sqlite3_free(ctx);
2509+    return SQLITE_ERROR;
2510+  }
2511+  sqlite3_mutex_enter(db->mutex);
2512+#ifdef SQLITE_CODEC_ATTACH_CHANGED
2513+  int rc = sqlite3CodecInitContext(ctx, p, pKey, nKey, nDb);
2514+#else
2515+  int rc = sqlite3CodecInitContext(ctx, p, pKey, nKey);
2516+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
2517+  if(rc != SQLITE_OK){
2518+    sqlite3_free(ctx);
2519+    return rc;
2520+  }
2521+  sqlite3PagerSetCodec(sqlite3BtreePager(p), sqlite3Codec, NULL, sqlite3CodecDetach, (void *)ctx);
2522+
2523+  db->nextPagesize = ctx->readCtx->codecConst.cipherPageSize;
2524+  p->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
2525+  sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0);
2526+  sqlite3BtreeSecureDelete(p, 1);
2527+  if(isOpen(p->pBt->pPager->fd)){
2528+    sqlite3BtreeSetAutoVacuum(p, SQLITE_DEFAULT_AUTOVACUUM);
2529+  }
2530+
2531+  sqlite3_mutex_leave(db->mutex);
2532+
2533+  return SQLITE_OK;
2534+}
2535+
2536+void sqlite3CodecGetKey(sqlite3* db, int nDb, void **pKey, int *nKey)
2537+{
2538+  Btree *p = db->aDb[nDb].pBt;
2539+  if(p == NULL){
2540+    return;
2541+  }
2542+  CodecContext *ctx = (CodecContext *)(p->pBt->pPager->pCodec);
2543+  if(ctx){
2544+    if(ctx->savePassword){
2545+      *pKey = ctx->readCtx->password;
2546+      *nKey = ctx->readCtx->passwordSize;
2547+    }else{
2548+      *pKey = ctx->readCtx->keyInfo;
2549+      *nKey = ctx->readCtx->codecConst.keyInfoSize;
2550+    }
2551+  }else{
2552+    *pKey = NULL;
2553+    *nKey = 0;
2554+  }
2555+  return;
2556+}
2557+
2558+int sqlite3_key(sqlite3 *db, const void *pKey, int nKey){
2559+  return sqlite3_key_v2(db, "main", pKey, nKey);
2560+}
2561+
2562+int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey){
2563+  if(db == NULL || pKey == NULL || nKey <= 0){
2564+    return SQLITE_ERROR;
2565+  }
2566+  int iDb = sqlite3CodecGetDbIndex(db, zDb);
2567+  return sqlite3CodecAttach(db, iDb, pKey, nKey);
2568+}
2569+
2570+int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey){
2571+  return sqlite3_rekey_v2(db, "main", pKey, nKey);
2572+}
2573+
2574+int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey){
2575+  if(db == NULL || pKey == NULL || nKey == 0){
2576+    return SQLITE_ERROR;
2577+  }
2578+  int iDb = sqlite3CodecGetDbIndex(db, zDb);
2579+  Btree *p = db->aDb[iDb].pBt;
2580+  if(p == NULL){
2581+    return SQLITE_OK;
2582+  }
2583+  int pageCount;
2584+  Pgno pgno;
2585+  PgHdr *page = NULL;
2586+  Pager *pPager = p->pBt->pPager;
2587+  CodecContext *ctx = (CodecContext *)(p->pBt->pPager->pCodec);
2588+  if(ctx == NULL){
2589+    return SQLITE_OK;
2590+  }
2591+  sqlite3CodecClearDeriveKey(ctx->writeCtx);
2592+  sqlite3CodecClearPassword(ctx->writeCtx);
2593+  int rc = sqlite3CodecSetPassword(ctx->writeCtx, pKey, nKey);
2594+  if(rc != SQLITE_OK){
2595+    return rc;
2596+  }
2597+  sqlite3_mutex_enter(db->mutex);
2598+  (void)sqlite3BtreeBeginTrans(p, 1, 0);
2599+  sqlite3PagerPagecount(pPager, &pageCount);
2600+  // support hmac algo changed by using rekey operation
2601+  int oldHmacAlgo = ctx->writeCtx->codecConst.hmacAlgo;
2602+  if( ctx->writeCtx->codecConst.rekeyHmacAlgo!=ctx->writeCtx->codecConst.hmacAlgo ){
2603+    sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, ctx->writeCtx->codecConst.rekeyHmacAlgo);
2604+    sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, ctx->writeCtx->codecConst.rekeyHmacAlgo);
2605+  }
2606+
2607+  for(pgno = 1; pgno <= (unsigned int)pageCount; pgno++){
2608+    if(PAGER_SJ_PGNO(pPager) != pgno){
2609+      rc = sqlite3PagerGet(pPager, pgno, &page, 0);
2610+      if(rc == SQLITE_OK){
2611+        rc = sqlite3PagerWrite(page);
2612+        if(rc == SQLITE_OK){
2613+          sqlite3PagerUnref(page);
2614+        }else{
2615+          sqlite3_log(SQLITE_WARNING, "sqlite3_rekey_v2: error when writing page %d: errno = %d.", pgno, rc);
2616+        }
2617+      }else{
2618+        sqlite3_log(SQLITE_WARNING, "sqlite3_rekey_v2: error when reading page %d: errno = %d.", pgno, rc);
2619+      }
2620+    }
2621+  }
2622+  if(rc == SQLITE_OK){
2623+    (void)sqlite3BtreeCommit(p);
2624+    sqlite3CodecFreeKeyContext(ctx->readCtx);
2625+    (void)sqlite3CodecCopyKeyContext(ctx->writeCtx, ctx->readCtx);
2626+  }else{
2627+    if( ctx->writeCtx->codecConst.rekeyHmacAlgo!=oldHmacAlgo ){
2628+      sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, oldHmacAlgo);
2629+      sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, oldHmacAlgo);
2630+    }
2631+    (void)sqlite3BtreeRollback(p, SQLITE_ABORT_ROLLBACK, 0);
2632+  }
2633+  sqlite3_mutex_leave(db->mutex);
2634+
2635+  return rc;
2636+}
2637+
2638+void sqlite3_activate_see(const char* zPassPhrase){
2639+  return;
2640+}
2641+
2642+CODEC_STATIC void sqlite3CodecReturnPragmaResult(Parse *parse, const char *label, const char *value){
2643+  Vdbe *v = sqlite3GetVdbe(parse);
2644+  sqlite3VdbeSetNumCols(v, 1);
2645+  sqlite3VdbeSetColName(v, 0, COLNAME_NAME, label, SQLITE_STATIC);
2646+  sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, 0);
2647+  sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
2648+  return;
2649+}
2650+
2651+// Each configuration setting operation should be done before read/write DB file or there might be some error.
2652+int sqlite3CodecPragma(sqlite3 *db, int iDb, Parse *parse, const char *zLeft, const char *zRight){
2653+  Btree *p = db->aDb[iDb].pBt;
2654+  if(p == NULL){
2655+    return 0;
2656+  }
2657+  CodecContext *ctx = (CodecContext *)(p->pBt->pPager->pCodec);
2658+#ifdef SQLITE_CODEC_ATTACH_CHANGED
2659+  CodecParameter *parm = &db->codecParm;
2660+  if(sqlite3StrICmp(zLeft, "cipher_default_attach_cipher") == 0 && zRight != NULL){
2661+    (void)sqlite3CodecSetDefaultAttachCipher(parm, zRight);
2662+    return 1;
2663+  }else if(sqlite3StrICmp(zLeft, "cipher_default_attach_kdf_iter") == 0 && zRight != NULL){
2664+    (void)sqlite3CodecSetDefaultAttachKdfIter(parm, atoi(zRight));
2665+    return 1;
2666+  }else if( sqlite3StrICmp(zLeft, "cipher_default_attach_hmac_algo")==0 && zRight!=NULL ){
2667+    /*
2668+    ** Make sure to set the Kdf algorithm after setting the Hmac algorithm, or it will not take effect.
2669+    ** This behavior is to ensure backward compatible.
2670+    */
2671+    if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA1)==0 ){
2672+      sqlite3CodecSetDefaultAttachHmacAlgo(parm, CIPHER_HMAC_ALGORITHM_SHA1);
2673+      sqlite3CodecSetDefaultAttachKdfAlgo(parm, CIPHER_KDF_ALGORITHM_SHA1);
2674+    }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA256)==0 ){
2675+      sqlite3CodecSetDefaultAttachHmacAlgo(parm, CIPHER_HMAC_ALGORITHM_SHA256);
2676+      sqlite3CodecSetDefaultAttachKdfAlgo(parm, CIPHER_KDF_ALGORITHM_SHA256);
2677+    }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA512)==0 ){
2678+      sqlite3CodecSetDefaultAttachHmacAlgo(parm, CIPHER_HMAC_ALGORITHM_SHA512);
2679+      sqlite3CodecSetDefaultAttachKdfAlgo(parm, CIPHER_KDF_ALGORITHM_SHA512);
2680+    }else{
2681+      return 0;
2682+    }
2683+    return 1;
2684+  }else if( sqlite3StrICmp(zLeft, "cipher_default_attach_kdf_algo")==0 && zRight!=NULL ){
2685+    if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA1)==0 ){
2686+      sqlite3CodecSetDefaultAttachKdfAlgo(parm, CIPHER_KDF_ALGORITHM_SHA1);
2687+    }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA256)==0 ){
2688+      sqlite3CodecSetDefaultAttachKdfAlgo(parm, CIPHER_KDF_ALGORITHM_SHA256);
2689+    }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA512)==0 ){
2690+      sqlite3CodecSetDefaultAttachKdfAlgo(parm, CIPHER_KDF_ALGORITHM_SHA512);
2691+    }else{
2692+      return 0;
2693+    }
2694+    return 1;
2695+  }else if( sqlite3StrICmp(zLeft, "cipher_default_attach_page_size")==0 && zRight!=NULL ){
2696+    (void)sqlite3CodecSetDefaultAttachPageSize(parm, atoi(zRight));
2697+    return 1;
2698+  }
2699+#endif /* SQLITE_CODEC_ATTACH_CHANGED */
2700+  if(ctx == NULL){
2701+    return 0;
2702+  }
2703+  if(sqlite3StrICmp(zLeft, "codec_cipher") == 0){
2704+    if(zRight){
2705+      sqlite3_mutex_enter(db->mutex);
2706+      (void)sqlite3CodecSetCodecConstant(ctx->readCtx, zRight);
2707+      (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, ctx->readCtx->codecConst.hmacAlgo);
2708+      (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, ctx->readCtx->codecConst.hmacAlgo);
2709+      sqlite3CodecFreeKeyContext(ctx->writeCtx);
2710+      (void)sqlite3CodecCopyKeyContext(ctx->readCtx, ctx->writeCtx);
2711+      sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0);
2712+      sqlite3_mutex_leave(db->mutex);
2713+    }else{
2714+      sqlite3CodecReturnPragmaResult(parse, "codec_cipher", opensslGetCipherName(ctx->writeCtx->codecConst.cipher));
2715+    }
2716+  }else if(sqlite3StrICmp(zLeft, "codec_kdf_iter") == 0){
2717+    if(zRight){
2718+      (void)sqlite3CodecSetIter(ctx->readCtx, atoi(zRight));
2719+      (void)sqlite3CodecSetIter(ctx->writeCtx, atoi(zRight));
2720+    }else{
2721+      char *iter = sqlite3_mprintf("%d", ctx->writeCtx->iter);
2722+      if(iter != NULL){
2723+        sqlite3CodecReturnPragmaResult(parse, "codec_kdf_iter", iter);
2724+        sqlite3_free(iter);
2725+      }
2726+    }
2727+  }else if( sqlite3StrICmp(zLeft, "codec_hmac_algo")==0 ){
2728+    /*
2729+    ** Make sure to set the Kdf algorithm after setting the Hmac algorithm, or it will not take effect.
2730+    ** This behavior is to ensure backward compatible.
2731+    */
2732+    if(zRight){
2733+      sqlite3_mutex_enter(db->mutex);
2734+      if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA1)==0 ){
2735+        (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, CIPHER_HMAC_ALGORITHM_SHA1);
2736+        (void)sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, CIPHER_HMAC_ALGORITHM_SHA1);
2737+        (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA1);
2738+        (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA1);
2739+      }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA256)==0 ){
2740+        (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, CIPHER_HMAC_ALGORITHM_SHA256);
2741+        (void)sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, CIPHER_HMAC_ALGORITHM_SHA256);
2742+        (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA256);
2743+        (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA256);
2744+      }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA512)==0 ){
2745+        (void)sqlite3CodecSetHmacAlgorithm(ctx->readCtx, CIPHER_HMAC_ALGORITHM_SHA512);
2746+        (void)sqlite3CodecSetHmacAlgorithm(ctx->writeCtx, CIPHER_HMAC_ALGORITHM_SHA512);
2747+        (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA512);
2748+        (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA512);
2749+      }else{
2750+        sqlite3_mutex_leave(db->mutex);
2751+        return 0;
2752+      }
2753+      sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0);
2754+      sqlite3_mutex_leave(db->mutex);
2755+    }else{
2756+      if( ctx->writeCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA1 ){
2757+        sqlite3CodecReturnPragmaResult(parse, "codec_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA1);
2758+      }else if( ctx->writeCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){
2759+        sqlite3CodecReturnPragmaResult(parse, "codec_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA256);
2760+      }else if( ctx->writeCtx->codecConst.hmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){
2761+        sqlite3CodecReturnPragmaResult(parse, "codec_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA512);
2762+      }
2763+    }
2764+  }else if( sqlite3StrICmp(zLeft, "codec_kdf_algo")==0 ){
2765+    if(zRight){
2766+      sqlite3_mutex_enter(db->mutex);
2767+      if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA1)==0 ){
2768+        (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA1);
2769+        (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA1);
2770+      }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA256)==0 ){
2771+        (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA256);
2772+        (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA256);
2773+      }else if( sqlite3_stricmp(zRight, CIPHER_KDF_ALGORITHM_NAME_SHA512)==0 ){
2774+        (void)sqlite3CodecSetKdfAlgorithm(ctx->readCtx, CIPHER_KDF_ALGORITHM_SHA512);
2775+        (void)sqlite3CodecSetKdfAlgorithm(ctx->writeCtx, CIPHER_KDF_ALGORITHM_SHA512);
2776+      }else{
2777+        sqlite3_mutex_leave(db->mutex);
2778+        return 0;
2779+      }
2780+      sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0);
2781+      sqlite3_mutex_leave(db->mutex);
2782+    }else{
2783+      if( ctx->writeCtx->codecConst.kdfAlgo==CIPHER_KDF_ALGORITHM_SHA1 ){
2784+        sqlite3CodecReturnPragmaResult(parse, "codec_kdf_algo", CIPHER_KDF_ALGORITHM_NAME_SHA1);
2785+      }else if( ctx->writeCtx->codecConst.kdfAlgo==CIPHER_KDF_ALGORITHM_SHA256 ){
2786+        sqlite3CodecReturnPragmaResult(parse, "codec_kdf_algo", CIPHER_KDF_ALGORITHM_NAME_SHA256);
2787+      }else if( ctx->writeCtx->codecConst.kdfAlgo==CIPHER_KDF_ALGORITHM_SHA512 ){
2788+        sqlite3CodecReturnPragmaResult(parse, "codec_kdf_algo", CIPHER_KDF_ALGORITHM_NAME_SHA512);
2789+      }
2790+    }
2791+  }else if( sqlite3StrICmp(zLeft, "codec_page_size")==0 ){
2792+    if(zRight){
2793+      sqlite3_mutex_enter(db->mutex);
2794+      int rc = sqlite3CodecSetCipherPageSize(ctx, atoi(zRight));
2795+      if (rc != SQLITE_OK){
2796+        sqlite3_mutex_leave(db->mutex);
2797+        return 0;
2798+      }
2799+      sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0);
2800+      sqlite3_mutex_leave(db->mutex);
2801+    } else {
2802+      char *pageSize = sqlite3_mprintf("%d", ctx->readCtx->codecConst.cipherPageSize);
2803+      if (pageSize != NULL) {
2804+        sqlite3CodecReturnPragmaResult(parse, "codec_page_size", pageSize);
2805+        sqlite3_free(pageSize);
2806+      }
2807+    }
2808+  }else if(sqlite3StrICmp(zLeft, "codec_rekey_hmac_algo") == 0){
2809+    if(zRight){
2810+      sqlite3_mutex_enter(db->mutex);
2811+      if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA1)==0 ){
2812+        ctx->writeCtx->codecConst.rekeyHmacAlgo = CIPHER_HMAC_ALGORITHM_SHA1;
2813+      }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA256)==0 ){
2814+        ctx->writeCtx->codecConst.rekeyHmacAlgo = CIPHER_HMAC_ALGORITHM_SHA256;
2815+      }else if( sqlite3_stricmp(zRight, CIPHER_HMAC_ALGORITHM_NAME_SHA512)==0 ){
2816+        ctx->writeCtx->codecConst.rekeyHmacAlgo = CIPHER_HMAC_ALGORITHM_SHA512;
2817+      }else{
2818+        sqlite3_mutex_leave(db->mutex);
2819+        return 0;
2820+      }
2821+      sqlite3_mutex_leave(db->mutex);
2822+    }else{
2823+      if( ctx->writeCtx->codecConst.rekeyHmacAlgo==CIPHER_HMAC_ALGORITHM_SHA1 ){
2824+        sqlite3CodecReturnPragmaResult(parse, "codec_rekey_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA1);
2825+      }else if( ctx->writeCtx->codecConst.rekeyHmacAlgo==CIPHER_HMAC_ALGORITHM_SHA256 ){
2826+        sqlite3CodecReturnPragmaResult(parse, "codec_rekey_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA256);
2827+      }else if( ctx->writeCtx->codecConst.rekeyHmacAlgo==CIPHER_HMAC_ALGORITHM_SHA512 ){
2828+        sqlite3CodecReturnPragmaResult(parse, "codec_rekey_hmac_algo", CIPHER_HMAC_ALGORITHM_NAME_SHA512);
2829+      }
2830+    }
2831+  }else{
2832+    return 0;
2833+  }
2834+  return 1;
2835+}
2836+
2837+CODEC_STATIC int sqlite3CodecExportMetadata(sqlite3 *db, const char *dbName, const char *metaName){
2838+  char *sql = sqlite3_mprintf("PRAGMA %s;", metaName);
2839+  if(sql == NULL){
2840+    return SQLITE_NOMEM;
2841+  }
2842+  sqlite3_stmt *statement = NULL;
2843+  int rc = sqlite3_prepare_v2(db, sql, -1, &statement, NULL);
2844+  sqlite3_free(sql);
2845+  if(rc != SQLITE_OK){
2846+    return rc;
2847+  }
2848+  rc = sqlite3_step(statement);
2849+  if(rc != SQLITE_ROW){
2850+    sqlite3_finalize(statement);
2851+    return rc;
2852+  }
2853+  int metadata = sqlite3_column_int(statement, 0);
2854+  sqlite3_finalize(statement);
2855+
2856+  sql = sqlite3_mprintf("PRAGMA %s.%s=%d;", dbName, metaName, metadata);
2857+  if(sql == NULL){
2858+    return SQLITE_NOMEM;
2859+  }
2860+  rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
2861+  sqlite3_free(sql);
2862+  return rc;
2863+}
2864+
2865+CODEC_STATIC int sqlite3CodecBatchExportSql(sqlite3 *db, const char *sql, char **errMsg){
2866+  sqlite3_stmt *statement = NULL;
2867+  int rc = sqlite3_prepare_v2(db, sql, -1, &statement, NULL);
2868+  if(rc != SQLITE_OK){
2869+    return rc;
2870+  }
2871+  while(sqlite3_step(statement) == SQLITE_ROW){
2872+    rc = sqlite3_exec(db, (char*)sqlite3_column_text(statement, 0), NULL, NULL, errMsg);
2873+    if(rc != SQLITE_OK){
2874+      sqlite3_finalize(statement);
2875+      return rc;
2876+    }
2877+  }
2878+  sqlite3_finalize(statement);
2879+  return rc;
2880+}
2881+
2882+void sqlite3CodecExportData(sqlite3_context *context, int argc, sqlite3_value **argv){
2883+  sqlite3 *db = sqlite3_context_db_handle(context);
2884+  const char *dbName = (const char*) sqlite3_value_text(argv[0]);
2885+
2886+  int rc = SQLITE_OK;
2887+  char *sql = NULL;
2888+  char *errMsg = NULL;
2889+
2890+  u64 flagsBackup = db->flags;
2891+  u32 mDbFlagsBackup = db->mDbFlags;
2892+  int nChangeBackup = db->nChange;
2893+  int nTotalChangeBackup = db->nTotalChange;
2894+  int (*xTraceBackup)(u32,void*,void*,void*) = db->trace.xV2;
2895+
2896+  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
2897+  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
2898+  db->mDbFlags |= DBFLAG_PreferBuiltin;
2899+  db->trace.xV2 = 0;
2900+
2901+  rc = sqlite3CodecExportMetadata(db, dbName, "schema_version");
2902+  if(rc != SQLITE_OK){
2903+    goto export_finish;
2904+  }
2905+  rc = sqlite3CodecExportMetadata(db, dbName, "user_version");
2906+  if(rc != SQLITE_OK){
2907+    goto export_finish;
2908+  }
2909+  rc = sqlite3CodecExportMetadata(db, dbName, "application_id");
2910+  if(rc != SQLITE_OK){
2911+    goto export_finish;
2912+  }
2913+  sql = sqlite3_mprintf("SELECT 'CREATE TABLE %s.' || substr(sql,14) FROM sqlite_master WHERE type='table' AND name!='sqlite_sequence' AND rootpage>0;", dbName);
2914+  if(sql == NULL){
2915+    rc = SQLITE_NOMEM;
2916+    goto export_finish;
2917+  }
2918+  rc = sqlite3CodecBatchExportSql(db, sql, &errMsg);
2919+  sqlite3_free(sql);
2920+  if(rc != SQLITE_OK){
2921+    goto export_finish;
2922+  }
2923+  sql = sqlite3_mprintf("SELECT 'CREATE INDEX %s.' || substr(sql,14) FROM sqlite_master WHERE sql LIKE 'CREATE INDEX %%';", dbName);
2924+  if(sql == NULL){
2925+    rc = SQLITE_NOMEM;
2926+    goto export_finish;
2927+  }
2928+  rc = sqlite3CodecBatchExportSql(db, sql, &errMsg);
2929+  sqlite3_free(sql);
2930+  if(rc != SQLITE_OK){
2931+    goto export_finish;
2932+  }
2933+  sql = sqlite3_mprintf("SELECT 'CREATE UNIQUE INDEX %s.' || substr(sql,21) FROM sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%';", dbName);
2934+  if(sql == NULL){
2935+    rc = SQLITE_NOMEM;
2936+    goto export_finish;
2937+  }
2938+  rc = sqlite3CodecBatchExportSql(db, sql, &errMsg);
2939+  sqlite3_free(sql);
2940+  if(rc != SQLITE_OK){
2941+    goto export_finish;
2942+  }
2943+  sql = sqlite3_mprintf("SELECT 'INSERT INTO %s.' || quote(name) || ' SELECT * FROM main.' || quote(name) || ';' FROM main.sqlite_master WHERE type = 'table' AND name!='sqlite_sequence' AND rootpage>0;", dbName);
2944+  if(sql == NULL){
2945+    rc = SQLITE_NOMEM;
2946+    goto export_finish;
2947+  }
2948+  rc = sqlite3CodecBatchExportSql(db, sql, &errMsg);
2949+  sqlite3_free(sql);
2950+  if(rc != SQLITE_OK){
2951+    goto export_finish;
2952+  }
2953+  sql = sqlite3_mprintf("SELECT 'DELETE FROM %s.' || quote(name) || ';' FROM %s.sqlite_master WHERE name='sqlite_sequence';", dbName, dbName);
2954+  if(sql == NULL){
2955+    rc = SQLITE_NOMEM;
2956+    goto export_finish;
2957+  }
2958+  rc = sqlite3CodecBatchExportSql(db, sql, &errMsg);
2959+  sqlite3_free(sql);
2960+  if(rc != SQLITE_OK){
2961+    goto export_finish;
2962+  }
2963+  sql = sqlite3_mprintf("SELECT 'INSERT INTO %s.' || quote(name) || ' SELECT * FROM main.' || quote(name) || ';' FROM %s.sqlite_master WHERE name=='sqlite_sequence';", dbName, dbName);
2964+  if(sql == NULL){
2965+    rc = SQLITE_NOMEM;
2966+    goto export_finish;
2967+  }
2968+  rc = sqlite3CodecBatchExportSql(db, sql, &errMsg);
2969+  sqlite3_free(sql);
2970+  if(rc != SQLITE_OK){
2971+    goto export_finish;
2972+  }
2973+  sql = sqlite3_mprintf("INSERT INTO %s.sqlite_master SELECT type, name, tbl_name, rootpage, sql FROM main.sqlite_master WHERE type='view' OR type='trigger' OR (type='table' AND rootpage=0);", dbName, dbName);
2974+  if(sql == NULL){
2975+    rc = SQLITE_NOMEM;
2976+    goto export_finish;
2977+  }
2978+  rc = sqlite3_exec(db, sql, NULL, NULL, &errMsg);
2979+  sqlite3_free(sql);
2980+  if(rc != SQLITE_OK){
2981+    goto export_finish;
2982+  }
2983+export_finish:
2984+  db->flags = flagsBackup;
2985+  db->mDbFlags = mDbFlagsBackup;
2986+  db->nChange = nChangeBackup;
2987+  db->nTotalChange = nTotalChangeBackup;
2988+  db->trace.xV2 = xTraceBackup;
2989+  if(rc != SQLITE_OK){
2990+    if(errMsg != NULL) {
2991+      sqlite3_result_error(context, errMsg, -1);
2992+      sqlite3DbFree(db, errMsg);
2993+    } else {
2994+      sqlite3_result_error(context, sqlite3ErrStr(rc), -1);
2995+    }
2996+  }
2997+  return;
2998+}
2999+/************** End file hw_codec.c *****************************************/
3000+#endif
3001+
3002+// export the symbols
3003+#ifdef SQLITE_EXPORT_SYMBOLS
3004+struct sqlite3_api_routines_extra {
3005+  int (*initialize)();
3006+  int (*config)(int,...);
3007+  int (*key)(sqlite3*,const void*,int);
3008+  int (*key_v2)(sqlite3*,const char*,const void*,int);
3009+  int (*rekey)(sqlite3*,const void*,int);
3010+  int (*rekey_v2)(sqlite3*,const char*,const void*,int);
3011+};
3012+
3013+typedef struct sqlite3_api_routines_extra sqlite3_api_routines_extra;
3014+static const sqlite3_api_routines_extra sqlite3ExtraApis = {
3015+  sqlite3_initialize,
3016+  sqlite3_config,
3017+#ifdef SQLITE_HAS_CODEC
3018+  sqlite3_key,
3019+  sqlite3_key_v2,
3020+  sqlite3_rekey,
3021+  sqlite3_rekey_v2
3022+#else
3023+  0,
3024+  0,
3025+  0,
3026+  0
3027+#endif /* SQLITE_HAS_CODEC */
3028+};
3029+
3030+EXPORT_SYMBOLS const sqlite3_api_routines *sqlite3_export_symbols = &sqlite3Apis;
3031+EXPORT_SYMBOLS const sqlite3_api_routines_extra *sqlite3_export_extra_symbols = &sqlite3ExtraApis;
3032+/************** End export the symbols *****************************************/
3033+#endif /* SQLITE_EXPORT_SYMBOLS */
3034--
30352.47.0.windows.2
3036
3037