4444#endif
4545#endif
4646
47- static unsigned int default_flags = DEFAULT_CIPHER_FLAGS ;
48- static unsigned char hmac_salt_mask = HMAC_SALT_MASK ;
49- static int default_kdf_iter = PBKDF2_ITER ;
50- static int default_page_size = 4096 ;
51- static int default_plaintext_header_sz = 0 ;
52- static int default_hmac_algorithm = SQLCIPHER_HMAC_SHA512 ;
53- static int default_kdf_algorithm = SQLCIPHER_PBKDF2_HMAC_SHA512 ;
54- static unsigned int sqlcipher_activate_count = 0 ;
47+ static volatile unsigned int default_flags = DEFAULT_CIPHER_FLAGS ;
48+ static volatile unsigned char hmac_salt_mask = HMAC_SALT_MASK ;
49+ static volatile int default_kdf_iter = PBKDF2_ITER ;
50+ static volatile int default_page_size = 4096 ;
51+ static volatile int default_plaintext_header_sz = 0 ;
52+ static volatile int default_hmac_algorithm = SQLCIPHER_HMAC_SHA512 ;
53+ static volatile int default_kdf_algorithm = SQLCIPHER_PBKDF2_HMAC_SHA512 ;
54+ static volatile int mem_security_on = 1 ;
55+ static volatile int mem_security_activated = 0 ;
56+ static volatile unsigned int sqlcipher_activate_count = 0 ;
57+ static volatile sqlite3_mem_methods default_mem_methods ;
5558static sqlite3_mutex * sqlcipher_provider_mutex = NULL ;
5659static sqlcipher_provider * default_provider = NULL ;
5760
@@ -96,24 +99,33 @@ struct codec_ctx {
9699 void * provider_ctx ;
97100};
98101
99- static sqlite3_mem_methods default_mem_methods ;
100-
101102static int sqlcipher_mem_init (void * pAppData ) {
102103 return default_mem_methods .xInit (pAppData );
103104}
104105static void sqlcipher_mem_shutdown (void * pAppData ) {
105106 default_mem_methods .xShutdown (pAppData );
106107}
107108static void * sqlcipher_mem_malloc (int n ) {
108- return default_mem_methods .xMalloc (n );
109+ void * ptr = default_mem_methods .xMalloc (n );
110+ if (mem_security_on ) {
111+ CODEC_TRACE ("sqlcipher_mem_malloc: calling sqlcipher_mlock(%p,%d)\n" , ptr , sz );
112+ sqlcipher_mlock (ptr , n );
113+ if (!mem_security_activated ) mem_security_activated = 1 ;
114+ }
115+ return ptr ;
109116}
110117static int sqlcipher_mem_size (void * p ) {
111118 return default_mem_methods .xSize (p );
112119}
113120static void sqlcipher_mem_free (void * p ) {
114- int sz = sqlcipher_mem_size (p );
115- CODEC_TRACE ("sqlcipher_mem_free: calling sqlcipher_memset(%p,0,%d)\n" , p , sz );
116- sqlcipher_memset (p , 0 , sz );
121+ int sz ;
122+ if (mem_security_on ) {
123+ sz = sqlcipher_mem_size (p );
124+ CODEC_TRACE ("sqlcipher_mem_free: calling sqlcipher_memset(%p,0,%d) and sqlcipher_munlock(%p, %d) \n" , p , sz , p , sz );
125+ sqlcipher_memset (p , 0 , sz );
126+ sqlcipher_munlock (p , sz );
127+ if (!mem_security_activated ) mem_security_activated = 1 ;
128+ }
117129 default_mem_methods .xFree (p );
118130}
119131static void * sqlcipher_mem_realloc (void * p , int n ) {
@@ -288,45 +300,71 @@ int sqlcipher_memcmp(const void *v0, const void *v1, int len) {
288300 return (result != 0 );
289301}
290302
291- /**
292- * Free and wipe memory. Uses SQLites internal sqlite3_free so that memory
293- * can be countend and memory leak detection works in the test suite.
294- * If ptr is not null memory will be freed.
295- * If sz is greater than zero, the memory will be overwritten with zero before it is freed
296- * If sz is > 0, and not compiled with OMIT_MEMLOCK, system will attempt to unlock the
297- * memory segment so it can be paged
298- */
299- void sqlcipher_free (void * ptr , int sz ) {
300- if (ptr ) {
301- if (sz > 0 ) {
303+ void sqlcipher_mlock (void * ptr , int sz ) {
302304#ifndef OMIT_MEMLOCK
303- int rc ;
305+ int rc ;
304306#if defined(__unix__ ) || defined(__APPLE__ )
305- unsigned long pagesize = sysconf (_SC_PAGESIZE );
306- unsigned long offset = (unsigned long ) ptr % pagesize ;
307+ unsigned long pagesize = sysconf (_SC_PAGESIZE );
308+ unsigned long offset = (unsigned long ) ptr % pagesize ;
309+
310+ if (ptr == NULL || sz == 0 ) return ;
311+
312+ CODEC_TRACE ("sqlcipher_mem_lock: calling mlock(%p,%lu); _SC_PAGESIZE=%lu\n" , ptr - offset , sz + offset , pagesize );
313+ rc = mlock (ptr - offset , sz + offset );
314+ if (rc != 0 ) {
315+ CODEC_TRACE ("sqlcipher_mem_lock: mlock(%p,%lu) returned %d errno=%d\n" , ptr - offset , sz + offset , rc , errno );
316+ }
317+ #elif defined(_WIN32 )
318+ #if !(defined(WINAPI_FAMILY ) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == WINAPI_FAMILY_APP ))
319+ CODEC_TRACE ("sqlcipher_mem_lock: calling VirtualLock(%p,%d)\n" , ptr , sz );
320+ rc = VirtualLock (ptr , sz );
321+ if (rc == 0 ) {
322+ CODEC_TRACE ("sqlcipher_mem_lock: VirtualLock(%p,%d) returned %d LastError=%d\n" , ptr , sz , rc , GetLastError ());
323+ }
307324#endif
308325#endif
309- CODEC_TRACE ("sqlcipher_free: calling sqlcipher_memset(%p,0,%d)\n" , ptr , sz );
310- sqlcipher_memset (ptr , 0 , sz );
326+ #endif
327+ }
328+
329+ void sqlcipher_munlock (void * ptr , int sz ) {
311330#ifndef OMIT_MEMLOCK
331+ int rc ;
312332#if defined(__unix__ ) || defined(__APPLE__ )
313- CODEC_TRACE ("sqlcipher_free: calling munlock(%p,%lu)\n" , ptr - offset , sz + offset );
314- rc = munlock (ptr - offset , sz + offset );
315- if (rc != 0 ) {
316- CODEC_TRACE ("sqlcipher_free: munlock(%p,%lu) returned %d errno=%d\n" , ptr - offset , sz + offset , rc , errno );
317- }
333+ unsigned long pagesize = sysconf (_SC_PAGESIZE );
334+ unsigned long offset = (unsigned long ) ptr % pagesize ;
335+
336+ if (ptr == NULL || sz == 0 ) return ;
337+
338+ CODEC_TRACE ("sqlcipher_mem_unlock: calling munlock(%p,%lu)\n" , ptr - offset , sz + offset );
339+ rc = munlock (ptr - offset , sz + offset );
340+ if (rc != 0 ) {
341+ CODEC_TRACE ("sqlcipher_mem_unlock: munlock(%p,%lu) returned %d errno=%d\n" , ptr - offset , sz + offset , rc , errno );
342+ }
318343#elif defined(_WIN32 )
319344#if !(defined(WINAPI_FAMILY ) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == WINAPI_FAMILY_APP ))
320- rc = VirtualUnlock (ptr , sz );
321- if (!rc ) {
322- CODEC_TRACE ("sqlcipher_free: VirtualUnlock(%p,%d) returned %d LastError=%d\n" , ptr , sz , rc , GetLastError ());
323- }
345+ CODEC_TRACE ("sqlcipher_mem_lock: calling VirtualUnlock(%p,%d)\n" , ptr , sz );
346+ rc = VirtualUnlock (ptr , sz );
347+ if (!rc ) {
348+ CODEC_TRACE ("sqlcipher_mem_unlock: VirtualUnlock(%p,%d) returned %d LastError=%d\n" , ptr , sz , rc , GetLastError ());
349+ }
324350#endif
325351#endif
326352#endif
327- }
328- sqlite3_free (ptr );
329- }
353+ }
354+
355+ /**
356+ * Free and wipe memory. Uses SQLites internal sqlite3_free so that memory
357+ * can be countend and memory leak detection works in the test suite.
358+ * If ptr is not null memory will be freed.
359+ * If sz is greater than zero, the memory will be overwritten with zero before it is freed
360+ * If sz is > 0, and not compiled with OMIT_MEMLOCK, system will attempt to unlock the
361+ * memory segment so it can be paged
362+ */
363+ void sqlcipher_free (void * ptr , int sz ) {
364+ CODEC_TRACE ("sqlcipher_free: calling sqlcipher_memset(%p,0,%d)\n" , ptr , sz );
365+ sqlcipher_memset (ptr , 0 , sz );
366+ sqlcipher_munlock (ptr , sz );
367+ sqlite3_free (ptr );
330368}
331369
332370/**
@@ -340,31 +378,10 @@ void* sqlcipher_malloc(int sz) {
340378 ptr = sqlite3Malloc (sz );
341379 CODEC_TRACE ("sqlcipher_malloc: calling sqlcipher_memset(%p,0,%d)\n" , ptr , sz );
342380 sqlcipher_memset (ptr , 0 , sz );
343- #ifndef OMIT_MEMLOCK
344- if (ptr ) {
345- int rc ;
346- #if defined(__unix__ ) || defined(__APPLE__ )
347- unsigned long pagesize = sysconf (_SC_PAGESIZE );
348- unsigned long offset = (unsigned long ) ptr % pagesize ;
349- CODEC_TRACE ("sqlcipher_malloc: calling mlock(%p,%lu); _SC_PAGESIZE=%lu\n" , ptr - offset , sz + offset , pagesize );
350- rc = mlock (ptr - offset , sz + offset );
351- if (rc != 0 ) {
352- CODEC_TRACE ("sqlcipher_malloc: mlock(%p,%lu) returned %d errno=%d\n" , ptr - offset , sz + offset , rc , errno );
353- }
354- #elif defined(_WIN32 )
355- #if !(defined(WINAPI_FAMILY ) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == WINAPI_FAMILY_APP ))
356- rc = VirtualLock (ptr , sz );
357- if (rc == 0 ) {
358- CODEC_TRACE ("sqlcipher_malloc: VirtualLock(%p,%d) returned %d LastError=%d\n" , ptr , sz , rc , GetLastError ());
359- }
360- #endif
361- #endif
362- }
363- #endif
381+ sqlcipher_mlock (ptr , sz );
364382 return ptr ;
365383}
366384
367-
368385/**
369386 * Initialize new cipher_ctx struct. This function will allocate memory
370387 * for the cipher context and for the key
@@ -800,6 +817,16 @@ int sqlcipher_get_default_pagesize() {
800817 return default_page_size ;
801818}
802819
820+ void sqlcipher_set_mem_security (int on ) {
821+ mem_security_on = on ;
822+ mem_security_activated = 0 ;
823+ }
824+
825+ int sqlcipher_get_mem_security () {
826+ return mem_security_on && mem_security_activated ;
827+ }
828+
829+
803830int sqlcipher_codec_ctx_init (codec_ctx * * iCtx , Db * pDb , Pager * pPager , sqlite3_file * fd , const void * zKey , int nKey ) {
804831 int rc ;
805832 codec_ctx * ctx ;
0 commit comments