System.Data.SQLite
Hex Artifact Content
Not logged in

Artifact 992ffe54e47e8057e32869af130b0b8471603c8e:


0000: 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f  #ifndef SQLITE_O
0010: 4d 49 54 5f 44 49 53 4b 49 4f 0a 23 69 66 64 65  MIT_DISKIO.#ifde
0020: 66 20 53 51 4c 49 54 45 5f 48 41 53 5f 43 4f 44  f SQLITE_HAS_COD
0030: 45 43 0a 0a 2f 2f 23 69 66 64 65 66 20 53 51 4c  EC..//#ifdef SQL
0040: 49 54 45 5f 44 45 42 55 47 0a 2f 2f 23 69 6e 63  ITE_DEBUG.//#inc
0050: 6c 75 64 65 20 22 73 70 6c 69 74 73 6f 75 72 63  lude "splitsourc
0060: 65 5c 70 61 67 65 72 2e 63 22 0a 2f 2f 23 65 6e  e\pager.c".//#en
0070: 64 69 66 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 77  dif..#include <w
0080: 69 6e 64 6f 77 73 2e 68 3e 0a 23 69 6e 63 6c 75  indows.h>.#inclu
0090: 64 65 20 3c 77 69 6e 63 72 79 70 74 2e 68 3e 0a  de <wincrypt.h>.
00a0: 0a 2f 2f 20 45 78 74 72 61 20 70 61 64 64 69 6e  .// Extra paddin
00b0: 67 20 62 65 66 6f 72 65 20 61 6e 64 20 61 66 74  g before and aft
00c0: 65 72 20 74 68 65 20 63 72 79 70 74 6f 67 72 61  er the cryptogra
00d0: 70 68 69 63 20 62 75 66 66 65 72 0a 23 64 65 66  phic buffer.#def
00e0: 69 6e 65 20 43 52 59 50 54 5f 4f 46 46 53 45 54  ine CRYPT_OFFSET
00f0: 20 38 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75   8..typedef stru
0100: 63 74 20 5f 43 52 59 50 54 42 4c 4f 43 4b 0a 7b  ct _CRYPTBLOCK.{
0110: 0a 20 20 50 61 67 65 72 20 20 20 20 2a 70 50 61  .  Pager    *pPa
0120: 67 65 72 3b 20 20 20 20 20 20 20 2f 2f 20 50 61  ger;       // Pa
0130: 67 65 72 20 74 68 69 73 20 63 72 79 70 74 62 6c  ger this cryptbl
0140: 6f 63 6b 20 62 65 6c 6f 6e 67 73 20 74 6f 0a 20  ock belongs to. 
0150: 20 48 43 52 59 50 54 4b 45 59 20 68 52 65 61 64   HCRYPTKEY hRead
0160: 4b 65 79 3b 20 20 20 20 20 2f 2f 20 4b 65 79 20  Key;     // Key 
0170: 75 73 65 64 20 74 6f 20 72 65 61 64 20 66 72 6f  used to read fro
0180: 6d 20 74 68 65 20 64 61 74 61 62 61 73 65 20 61  m the database a
0190: 6e 64 20 77 72 69 74 65 20 74 6f 20 74 68 65 20  nd write to the 
01a0: 6a 6f 75 72 6e 61 6c 0a 20 20 48 43 52 59 50 54  journal.  HCRYPT
01b0: 4b 45 59 20 68 57 72 69 74 65 4b 65 79 3b 20 20  KEY hWriteKey;  
01c0: 20 20 2f 2f 20 4b 65 79 20 75 73 65 64 20 74 6f    // Key used to
01d0: 20 77 72 69 74 65 20 74 6f 20 74 68 65 20 64 61   write to the da
01e0: 74 61 62 61 73 65 0a 20 20 44 57 4f 52 44 20 20  tabase.  DWORD  
01f0: 20 20 20 64 77 50 61 67 65 53 69 7a 65 3b 20 20     dwPageSize;  
0200: 20 2f 2f 20 53 69 7a 65 20 6f 66 20 70 61 67 65   // Size of page
0210: 73 0a 20 20 4c 50 56 4f 49 44 20 20 20 20 70 76  s.  LPVOID    pv
0220: 43 72 79 70 74 3b 20 20 20 20 20 20 2f 2f 20 41  Crypt;      // A
0230: 20 62 75 66 66 65 72 20 66 6f 72 20 65 6e 63 72   buffer for encr
0240: 79 70 74 69 6e 67 2f 64 65 63 72 79 70 74 69 6e  ypting/decryptin
0250: 67 20 28 69 66 20 6e 65 63 65 73 73 61 72 79 29  g (if necessary)
0260: 0a 20 20 44 57 4f 52 44 20 20 20 20 20 64 77 43  .  DWORD     dwC
0270: 72 79 70 74 53 69 7a 65 3b 20 20 2f 2f 20 45 71  ryptSize;  // Eq
0280: 75 61 6c 20 74 6f 20 6f 72 20 67 72 65 61 74 65  ual to or greate
0290: 72 20 74 68 61 6e 20 64 77 50 61 67 65 53 69 7a  r than dwPageSiz
02a0: 65 2e 20 20 49 66 20 6c 61 72 67 65 72 2c 20 70  e.  If larger, p
02b0: 76 43 72 79 70 74 20 69 73 20 76 61 6c 69 64 20  vCrypt is valid 
02c0: 61 6e 64 20 74 68 69 73 20 69 73 20 69 74 73 20  and this is its 
02d0: 73 69 7a 65 0a 7d 20 43 52 59 50 54 42 4c 4f 43  size.} CRYPTBLOC
02e0: 4b 2c 20 2a 4c 50 43 52 59 50 54 42 4c 4f 43 4b  K, *LPCRYPTBLOCK
02f0: 3b 0a 0a 48 43 52 59 50 54 50 52 4f 56 20 67 5f  ;..HCRYPTPROV g_
0300: 68 50 72 6f 76 69 64 65 72 20 3d 20 30 3b 20 2f  hProvider = 0; /
0310: 2f 20 47 6c 6f 62 61 6c 20 69 6e 73 74 61 6e 63  / Global instanc
0320: 65 20 6f 66 20 74 68 65 20 63 72 79 70 74 6f 67  e of the cryptog
0330: 72 61 70 68 69 63 20 70 72 6f 76 69 64 65 72 0a  raphic provider.
0340: 0a 23 64 65 66 69 6e 65 20 53 51 4c 49 54 45 43  .#define SQLITEC
0350: 52 59 50 54 45 52 52 4f 52 5f 50 52 4f 56 49 44  RYPTERROR_PROVID
0360: 45 52 20 22 43 72 79 70 74 6f 67 72 61 70 68 69  ER "Cryptographi
0370: 63 20 70 72 6f 76 69 64 65 72 20 6e 6f 74 20 61  c provider not a
0380: 76 61 69 6c 61 62 6c 65 22 0a 0a 2f 2f 20 4e 65  vailable"..// Ne
0390: 65 64 65 64 20 66 6f 72 20 72 65 2d 6b 65 79 69  eded for re-keyi
03a0: 6e 67 0a 73 74 61 74 69 63 20 76 6f 69 64 20 2a  ng.static void *
03b0: 20 73 71 6c 69 74 65 33 70 61 67 65 72 5f 67 65   sqlite3pager_ge
03c0: 74 5f 63 6f 64 65 63 61 72 67 28 50 61 67 65 72  t_codecarg(Pager
03d0: 20 2a 70 50 61 67 65 72 29 0a 7b 0a 20 20 72 65   *pPager).{.  re
03e0: 74 75 72 6e 20 28 70 50 61 67 65 72 2d 3e 78 43  turn (pPager->xC
03f0: 6f 64 65 63 29 20 3f 20 70 50 61 67 65 72 2d 3e  odec) ? pPager->
0400: 70 43 6f 64 65 63 3a 20 4e 55 4c 4c 3b 0a 7d 0a  pCodec: NULL;.}.
0410: 0a 76 6f 69 64 20 73 71 6c 69 74 65 33 5f 61 63  .void sqlite3_ac
0420: 74 69 76 61 74 65 5f 73 65 65 28 63 6f 6e 73 74  tivate_see(const
0430: 20 63 68 61 72 20 2a 69 6e 66 6f 29 0a 7b 0a 7d   char *info).{.}
0440: 0a 0a 2f 2f 20 43 72 65 61 74 65 20 61 20 63 72  ..// Create a cr
0450: 79 70 74 6f 67 72 61 70 68 69 63 20 63 6f 6e 74  yptographic cont
0460: 65 78 74 2e 20 20 55 73 65 20 74 68 65 20 65 6e  ext.  Use the en
0470: 68 61 6e 63 65 64 20 70 72 6f 76 69 64 65 72 20  hanced provider 
0480: 62 65 63 61 75 73 65 20 69 74 20 69 73 20 61 76  because it is av
0490: 61 69 6c 61 62 6c 65 20 6f 6e 0a 2f 2f 20 6d 6f  ailable on.// mo
04a0: 73 74 20 70 6c 61 74 66 6f 72 6d 73 0a 73 74 61  st platforms.sta
04b0: 74 69 63 20 42 4f 4f 4c 20 49 6e 69 74 69 61 6c  tic BOOL Initial
04c0: 69 7a 65 50 72 6f 76 69 64 65 72 28 29 0a 7b 0a  izeProvider().{.
04d0: 20 20 69 66 20 28 67 5f 68 50 72 6f 76 69 64 65    if (g_hProvide
04e0: 72 29 20 72 65 74 75 72 6e 20 54 52 55 45 3b 0a  r) return TRUE;.
04f0: 0a 20 20 69 66 20 28 21 43 72 79 70 74 41 63 71  .  if (!CryptAcq
0500: 75 69 72 65 43 6f 6e 74 65 78 74 28 26 67 5f 68  uireContext(&g_h
0510: 50 72 6f 76 69 64 65 72 2c 20 4e 55 4c 4c 2c 20  Provider, NULL, 
0520: 4d 53 5f 45 4e 48 41 4e 43 45 44 5f 50 52 4f 56  MS_ENHANCED_PROV
0530: 2c 20 50 52 4f 56 5f 52 53 41 5f 46 55 4c 4c 2c  , PROV_RSA_FULL,
0540: 20 43 52 59 50 54 5f 56 45 52 49 46 59 43 4f 4e   CRYPT_VERIFYCON
0550: 54 45 58 54 29 29 0a 20 20 7b 0a 20 20 20 20 72  TEXT)).  {.    r
0560: 65 74 75 72 6e 20 46 41 4c 53 45 3b 0a 20 20 7d  eturn FALSE;.  }
0570: 0a 20 20 72 65 74 75 72 6e 20 54 52 55 45 3b 0a  .  return TRUE;.
0580: 7d 0a 0a 2f 2f 20 43 72 65 61 74 65 20 6f 72 20  }..// Create or 
0590: 75 70 64 61 74 65 20 61 20 63 72 79 70 74 6f 67  update a cryptog
05a0: 72 61 70 68 69 63 20 63 6f 6e 74 65 78 74 20 66  raphic context f
05b0: 6f 72 20 61 20 70 61 67 65 72 2e 0a 2f 2f 20 54  or a pager..// T
05c0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 77 69 6c  his function wil
05d0: 6c 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20  l automatically 
05e0: 64 65 74 65 72 6d 69 6e 65 20 69 66 20 74 68 65  determine if the
05f0: 20 65 6e 63 72 79 70 74 69 6f 6e 20 61 6c 67 6f   encryption algo
0600: 72 69 74 68 6d 20 72 65 71 75 69 72 65 73 0a 2f  rithm requires./
0610: 2f 20 65 78 74 72 61 20 70 61 64 64 69 6e 67 2c  / extra padding,
0620: 20 61 6e 64 20 69 66 20 69 74 20 64 6f 65 73 2c   and if it does,
0630: 20 77 69 6c 6c 20 63 72 65 61 74 65 20 61 20 74   will create a t
0640: 65 6d 70 20 62 75 66 66 65 72 20 62 69 67 20 65  emp buffer big e
0650: 6e 6f 75 67 68 20 74 6f 20 70 72 6f 76 69 64 65  nough to provide
0660: 0a 2f 2f 20 73 70 61 63 65 20 74 6f 20 68 6f 6c  .// space to hol
0670: 64 20 69 74 2e 0a 73 74 61 74 69 63 20 4c 50 43  d it..static LPC
0680: 52 59 50 54 42 4c 4f 43 4b 20 43 72 65 61 74 65  RYPTBLOCK Create
0690: 43 72 79 70 74 42 6c 6f 63 6b 28 48 43 52 59 50  CryptBlock(HCRYP
06a0: 54 4b 45 59 20 68 4b 65 79 2c 20 50 61 67 65 72  TKEY hKey, Pager
06b0: 20 2a 70 61 67 65 72 2c 20 69 6e 74 20 70 61 67   *pager, int pag
06c0: 65 53 69 7a 65 2c 20 4c 50 43 52 59 50 54 42 4c  eSize, LPCRYPTBL
06d0: 4f 43 4b 20 70 45 78 69 73 74 69 6e 67 29 0a 7b  OCK pExisting).{
06e0: 0a 20 20 4c 50 43 52 59 50 54 42 4c 4f 43 4b 20  .  LPCRYPTBLOCK 
06f0: 70 42 6c 6f 63 6b 3b 0a 0a 20 20 69 66 20 28 21  pBlock;..  if (!
0700: 70 45 78 69 73 74 69 6e 67 29 20 2f 2f 20 43 72  pExisting) // Cr
0710: 65 61 74 69 6e 67 20 61 20 6e 65 77 20 63 72 79  eating a new cry
0720: 70 74 62 6c 6f 63 6b 0a 20 20 7b 0a 20 20 20 20  ptblock.  {.    
0730: 70 42 6c 6f 63 6b 20 3d 20 73 71 6c 69 74 65 33  pBlock = sqlite3
0740: 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 43  _malloc(sizeof(C
0750: 52 59 50 54 42 4c 4f 43 4b 29 29 3b 0a 20 20 20  RYPTBLOCK));.   
0760: 20 69 66 20 28 21 70 42 6c 6f 63 6b 29 20 72 65   if (!pBlock) re
0770: 74 75 72 6e 20 4e 55 4c 4c 3b 0a 0a 20 20 20 20  turn NULL;..    
0780: 5a 65 72 6f 4d 65 6d 6f 72 79 28 70 42 6c 6f 63  ZeroMemory(pBloc
0790: 6b 2c 20 73 69 7a 65 6f 66 28 43 52 59 50 54 42  k, sizeof(CRYPTB
07a0: 4c 4f 43 4b 29 29 3b 0a 20 20 20 20 70 42 6c 6f  LOCK));.    pBlo
07b0: 63 6b 2d 3e 68 52 65 61 64 4b 65 79 20 3d 20 68  ck->hReadKey = h
07c0: 4b 65 79 3b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d  Key;.    pBlock-
07d0: 3e 68 57 72 69 74 65 4b 65 79 20 3d 20 68 4b 65  >hWriteKey = hKe
07e0: 79 3b 0a 20 20 7d 0a 20 20 65 6c 73 65 20 2f 2f  y;.  }.  else //
07f0: 20 55 70 64 61 74 69 6e 67 20 61 6e 20 65 78 69   Updating an exi
0800: 73 74 69 6e 67 20 63 72 79 70 74 62 6c 6f 63 6b  sting cryptblock
0810: 0a 20 20 7b 0a 20 20 20 20 70 42 6c 6f 63 6b 20  .  {.    pBlock 
0820: 3d 20 70 45 78 69 73 74 69 6e 67 3b 0a 20 20 7d  = pExisting;.  }
0830: 0a 0a 20 20 69 66 20 28 70 61 67 65 53 69 7a 65  ..  if (pageSize
0840: 20 3d 3d 20 2d 31 29 0a 20 20 20 20 70 61 67 65   == -1).    page
0850: 53 69 7a 65 20 3d 20 70 61 67 65 72 2d 3e 70 61  Size = pager->pa
0860: 67 65 53 69 7a 65 3b 0a 0a 20 20 70 42 6c 6f 63  geSize;..  pBloc
0870: 6b 2d 3e 70 50 61 67 65 72 20 3d 20 70 61 67 65  k->pPager = page
0880: 72 3b 0a 20 20 70 42 6c 6f 63 6b 2d 3e 64 77 50  r;.  pBlock->dwP
0890: 61 67 65 53 69 7a 65 20 3d 20 28 44 57 4f 52 44  ageSize = (DWORD
08a0: 29 70 61 67 65 53 69 7a 65 3b 0a 20 20 70 42 6c  )pageSize;.  pBl
08b0: 6f 63 6b 2d 3e 64 77 43 72 79 70 74 53 69 7a 65  ock->dwCryptSize
08c0: 20 3d 20 70 42 6c 6f 63 6b 2d 3e 64 77 50 61 67   = pBlock->dwPag
08d0: 65 53 69 7a 65 3b 0a 0a 20 20 2f 2f 20 45 78 69  eSize;..  // Exi
08e0: 73 74 69 6e 67 20 63 72 79 70 74 62 6c 6f 63 6b  sting cryptblock
08f0: 73 20 6d 61 79 20 68 61 76 65 20 61 20 62 75 66  s may have a buf
0900: 66 65 72 2c 20 69 66 20 73 6f 2c 20 64 65 6c 65  fer, if so, dele
0910: 74 65 20 69 74 0a 20 20 69 66 20 28 70 42 6c 6f  te it.  if (pBlo
0920: 63 6b 2d 3e 70 76 43 72 79 70 74 29 0a 20 20 7b  ck->pvCrypt).  {
0930: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
0940: 65 28 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70  e(pBlock->pvCryp
0950: 74 29 3b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e  t);.    pBlock->
0960: 70 76 43 72 79 70 74 20 3d 20 4e 55 4c 4c 3b 0a  pvCrypt = NULL;.
0970: 20 20 7d 0a 0a 20 20 2f 2f 20 46 69 67 75 72 65    }..  // Figure
0980: 20 6f 75 74 20 68 6f 77 20 62 69 67 20 74 6f 20   out how big to 
0990: 6d 61 6b 65 20 6f 75 72 20 73 70 61 72 65 20 63  make our spare c
09a0: 72 79 70 74 20 62 6c 6f 63 6b 0a 20 20 43 72 79  rypt block.  Cry
09b0: 70 74 45 6e 63 72 79 70 74 28 68 4b 65 79 2c 20  ptEncrypt(hKey, 
09c0: 30 2c 20 54 52 55 45 2c 20 30 2c 20 4e 55 4c 4c  0, TRUE, 0, NULL
09d0: 2c 20 26 70 42 6c 6f 63 6b 2d 3e 64 77 43 72 79  , &pBlock->dwCry
09e0: 70 74 53 69 7a 65 2c 20 70 42 6c 6f 63 6b 2d 3e  ptSize, pBlock->
09f0: 64 77 43 72 79 70 74 53 69 7a 65 20 2a 20 32 29  dwCryptSize * 2)
0a00: 3b 0a 20 20 70 42 6c 6f 63 6b 2d 3e 70 76 43 72  ;.  pBlock->pvCr
0a10: 79 70 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61  ypt = sqlite3_ma
0a20: 6c 6c 6f 63 28 70 42 6c 6f 63 6b 2d 3e 64 77 43  lloc(pBlock->dwC
0a30: 72 79 70 74 53 69 7a 65 20 2b 20 28 43 52 59 50  ryptSize + (CRYP
0a40: 54 5f 4f 46 46 53 45 54 20 2a 20 32 29 29 3b 0a  T_OFFSET * 2));.
0a50: 20 20 69 66 20 28 21 70 42 6c 6f 63 6b 2d 3e 70    if (!pBlock->p
0a60: 76 43 72 79 70 74 29 0a 20 20 7b 0a 20 20 20 20  vCrypt).  {.    
0a70: 2f 2f 20 57 65 20 63 72 65 61 74 65 64 20 61 20  // We created a 
0a80: 6e 65 77 20 62 6c 6f 63 6b 20 69 6e 20 68 65 72  new block in her
0a90: 65 2c 20 73 6f 20 66 72 65 65 20 69 74 2e 20 20  e, so free it.  
0aa0: 4f 74 68 65 72 77 69 73 65 20 6c 65 61 76 65 20  Otherwise leave 
0ab0: 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 69 6e 74  the original int
0ac0: 61 63 74 0a 20 20 20 20 69 66 20 28 70 42 6c 6f  act.    if (pBlo
0ad0: 63 6b 20 21 3d 20 70 45 78 69 73 74 69 6e 67 29  ck != pExisting)
0ae0: 20 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f   .      sqlite3_
0af0: 66 72 65 65 28 70 42 6c 6f 63 6b 29 3b 0a 0a 20  free(pBlock);.. 
0b00: 20 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 3b 0a     return NULL;.
0b10: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 70 42    }..  return pB
0b20: 6c 6f 63 6b 3b 0a 7d 0a 0a 2f 2f 20 44 65 73 74  lock;.}..// Dest
0b30: 72 6f 79 20 61 20 63 72 79 70 74 6f 67 72 61 70  roy a cryptograp
0b40: 68 69 63 20 63 6f 6e 74 65 78 74 20 61 6e 64 20  hic context and 
0b50: 61 6e 79 20 62 75 66 66 65 72 73 20 61 6e 64 20  any buffers and 
0b60: 6b 65 79 73 20 61 6c 6c 6f 63 61 74 65 64 20 74  keys allocated t
0b70: 68 65 72 65 69 6e 0a 73 74 61 74 69 63 20 76 6f  herein.static vo
0b80: 69 64 20 73 71 6c 69 74 65 33 43 6f 64 65 63 46  id sqlite3CodecF
0b90: 72 65 65 28 4c 50 56 4f 49 44 20 70 76 29 0a 7b  ree(LPVOID pv).{
0ba0: 0a 20 20 4c 50 43 52 59 50 54 42 4c 4f 43 4b 20  .  LPCRYPTBLOCK 
0bb0: 70 42 6c 6f 63 6b 20 3d 20 28 4c 50 43 52 59 50  pBlock = (LPCRYP
0bc0: 54 42 4c 4f 43 4b 29 70 76 3b 0a 20 20 2f 2f 20  TBLOCK)pv;.  // 
0bd0: 44 65 73 74 72 6f 79 20 74 68 65 20 72 65 61 64  Destroy the read
0be0: 20 6b 65 79 20 69 66 20 74 68 65 72 65 20 69 73   key if there is
0bf0: 20 6f 6e 65 0a 20 20 69 66 20 28 70 42 6c 6f 63   one.  if (pBloc
0c00: 6b 2d 3e 68 52 65 61 64 4b 65 79 29 0a 20 20 7b  k->hReadKey).  {
0c10: 0a 20 20 20 20 43 72 79 70 74 44 65 73 74 72 6f  .    CryptDestro
0c20: 79 4b 65 79 28 70 42 6c 6f 63 6b 2d 3e 68 52 65  yKey(pBlock->hRe
0c30: 61 64 4b 65 79 29 3b 0a 20 20 7d 0a 0a 20 20 2f  adKey);.  }..  /
0c40: 2f 20 49 66 20 74 68 65 72 65 27 73 20 61 20 77  / If there's a w
0c50: 72 69 74 65 6b 65 79 20 61 6e 64 20 69 74 73 20  ritekey and its 
0c60: 6e 6f 74 20 65 71 75 61 6c 20 74 6f 20 74 68 65  not equal to the
0c70: 20 72 65 61 64 6b 65 79 2c 20 64 65 73 74 72 6f   readkey, destro
0c80: 79 20 69 74 0a 20 20 69 66 20 28 70 42 6c 6f 63  y it.  if (pBloc
0c90: 6b 2d 3e 68 57 72 69 74 65 4b 65 79 20 26 26 20  k->hWriteKey && 
0ca0: 70 42 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65  pBlock->hWriteKe
0cb0: 79 20 21 3d 20 70 42 6c 6f 63 6b 2d 3e 68 52 65  y != pBlock->hRe
0cc0: 61 64 4b 65 79 29 0a 20 20 7b 0a 20 20 20 20 43  adKey).  {.    C
0cd0: 72 79 70 74 44 65 73 74 72 6f 79 4b 65 79 28 70  ryptDestroyKey(p
0ce0: 42 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65 79  Block->hWriteKey
0cf0: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2f 20 49 66 20  );.  }..  // If 
0d00: 74 68 65 72 65 27 73 20 65 78 74 72 61 20 62 75  there's extra bu
0d10: 66 66 65 72 20 73 70 61 63 65 20 61 6c 6c 6f 63  ffer space alloc
0d20: 61 74 65 64 2c 20 66 72 65 65 20 69 74 20 61 73  ated, free it as
0d30: 20 77 65 6c 6c 0a 20 20 69 66 20 28 70 42 6c 6f   well.  if (pBlo
0d40: 63 6b 2d 3e 70 76 43 72 79 70 74 29 0a 20 20 7b  ck->pvCrypt).  {
0d50: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
0d60: 65 28 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70  e(pBlock->pvCryp
0d70: 74 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2f 20 41 6c  t);.  }..  // Al
0d80: 6c 20 64 6f 6e 65 20 77 69 74 68 20 74 68 69 73  l done with this
0d90: 20 63 72 79 70 74 62 6c 6f 63 6b 0a 20 20 73 71   cryptblock.  sq
0da0: 6c 69 74 65 33 5f 66 72 65 65 28 70 42 6c 6f 63  lite3_free(pBloc
0db0: 6b 29 3b 0a 7d 0a 0a 76 6f 69 64 20 73 71 6c 69  k);.}..void sqli
0dc0: 74 65 33 43 6f 64 65 63 53 69 7a 65 43 68 61 6e  te3CodecSizeChan
0dd0: 67 65 28 76 6f 69 64 20 2a 70 41 72 67 2c 20 69  ge(void *pArg, i
0de0: 6e 74 20 70 61 67 65 53 69 7a 65 2c 20 69 6e 74  nt pageSize, int
0df0: 20 72 65 73 65 72 76 65 64 53 69 7a 65 29 0a 7b   reservedSize).{
0e00: 0a 20 20 4c 50 43 52 59 50 54 42 4c 4f 43 4b 20  .  LPCRYPTBLOCK 
0e10: 70 42 6c 6f 63 6b 20 3d 20 28 4c 50 43 52 59 50  pBlock = (LPCRYP
0e20: 54 42 4c 4f 43 4b 29 70 41 72 67 3b 0a 0a 20 20  TBLOCK)pArg;..  
0e30: 69 66 20 28 70 42 6c 6f 63 6b 2d 3e 64 77 50 61  if (pBlock->dwPa
0e40: 67 65 53 69 7a 65 20 21 3d 20 70 61 67 65 53 69  geSize != pageSi
0e50: 7a 65 29 0a 20 20 7b 0a 20 20 20 20 43 72 65 61  ze).  {.    Crea
0e60: 74 65 43 72 79 70 74 42 6c 6f 63 6b 28 70 42 6c  teCryptBlock(pBl
0e70: 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79 2c 20 70  ock->hReadKey, p
0e80: 42 6c 6f 63 6b 2d 3e 70 50 61 67 65 72 2c 20 70  Block->pPager, p
0e90: 61 67 65 53 69 7a 65 2c 20 70 42 6c 6f 63 6b 29  ageSize, pBlock)
0ea0: 3b 0a 20 20 20 20 2f 2f 20 49 66 20 74 68 69 73  ;.    // If this
0eb0: 20 66 61 69 6c 73 2c 20 70 76 43 72 79 70 74 20   fails, pvCrypt 
0ec0: 77 69 6c 6c 20 62 65 20 4e 55 4c 4c 2c 20 61 6e  will be NULL, an
0ed0: 64 20 74 68 65 20 6e 65 78 74 20 74 69 6d 65 20  d the next time 
0ee0: 73 71 6c 69 74 65 33 43 6f 64 65 63 28 29 20 69  sqlite3Codec() i
0ef0: 73 20 63 61 6c 6c 65 64 2c 20 69 74 20 77 69 6c  s called, it wil
0f00: 6c 20 72 65 73 75 6c 74 20 69 6e 20 61 6e 20 65  l result in an e
0f10: 72 72 6f 72 0a 20 20 7d 0a 7d 0a 0a 2f 2f 20 45  rror.  }.}..// E
0f20: 6e 63 72 79 70 74 2f 44 65 63 72 79 70 74 20 66  ncrypt/Decrypt f
0f30: 75 6e 63 74 69 6f 6e 61 6c 69 74 79 2c 20 63 61  unctionality, ca
0f40: 6c 6c 65 64 20 62 79 20 70 61 67 65 72 2e 63 0a  lled by pager.c.
0f50: 76 6f 69 64 20 2a 20 73 71 6c 69 74 65 33 43 6f  void * sqlite3Co
0f60: 64 65 63 28 76 6f 69 64 20 2a 70 41 72 67 2c 20  dec(void *pArg, 
0f70: 76 6f 69 64 20 2a 64 61 74 61 2c 20 50 67 6e 6f  void *data, Pgno
0f80: 20 6e 50 61 67 65 4e 75 6d 2c 20 69 6e 74 20 6e   nPageNum, int n
0f90: 4d 6f 64 65 29 0a 7b 0a 20 20 4c 50 43 52 59 50  Mode).{.  LPCRYP
0fa0: 54 42 4c 4f 43 4b 20 70 42 6c 6f 63 6b 20 3d 20  TBLOCK pBlock = 
0fb0: 28 4c 50 43 52 59 50 54 42 4c 4f 43 4b 29 70 41  (LPCRYPTBLOCK)pA
0fc0: 72 67 3b 0a 20 20 44 57 4f 52 44 20 64 77 50 61  rg;.  DWORD dwPa
0fd0: 67 65 53 69 7a 65 3b 0a 20 20 4c 50 56 4f 49 44  geSize;.  LPVOID
0fe0: 20 70 76 54 65 6d 70 3b 0a 0a 20 20 69 66 20 28   pvTemp;..  if (
0ff0: 21 70 42 6c 6f 63 6b 29 20 72 65 74 75 72 6e 20  !pBlock) return 
1000: 64 61 74 61 3b 0a 20 20 69 66 20 28 70 42 6c 6f  data;.  if (pBlo
1010: 63 6b 2d 3e 70 76 43 72 79 70 74 20 3d 3d 20 4e  ck->pvCrypt == N
1020: 55 4c 4c 29 20 72 65 74 75 72 6e 20 4e 55 4c 4c  ULL) return NULL
1030: 3b 20 2f 2f 20 54 68 69 73 20 6f 6e 6c 79 20 68  ; // This only h
1040: 61 70 70 65 6e 73 20 69 66 20 43 72 65 61 74 65  appens if Create
1050: 43 72 79 70 74 42 6c 6f 63 6b 28 29 20 66 61 69  CryptBlock() fai
1060: 6c 65 64 20 74 6f 20 6d 61 6b 65 20 73 63 72 61  led to make scra
1070: 74 63 68 20 73 70 61 63 65 0a 0a 20 20 73 77 69  tch space..  swi
1080: 74 63 68 28 6e 4d 6f 64 65 29 0a 20 20 7b 0a 20  tch(nMode).  {. 
1090: 20 63 61 73 65 20 30 3a 20 2f 2f 20 55 6e 64 6f   case 0: // Undo
10a0: 20 61 20 22 63 61 73 65 20 37 22 20 6a 6f 75 72   a "case 7" jour
10b0: 6e 61 6c 20 66 69 6c 65 20 65 6e 63 72 79 70 74  nal file encrypt
10c0: 69 6f 6e 0a 20 20 63 61 73 65 20 32 3a 20 2f 2f  ion.  case 2: //
10d0: 20 52 65 6c 6f 61 64 20 61 20 70 61 67 65 0a 20   Reload a page. 
10e0: 20 63 61 73 65 20 33 3a 20 2f 2f 20 4c 6f 61 64   case 3: // Load
10f0: 20 61 20 70 61 67 65 0a 20 20 20 20 69 66 20 28   a page.    if (
1100: 21 70 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b 65  !pBlock->hReadKe
1110: 79 29 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 2f  y) break;..    /
1120: 2a 20 42 6c 6f 63 6b 20 63 69 70 68 65 72 73 20  * Block ciphers 
1130: 6f 66 74 65 6e 20 6e 65 65 64 20 74 6f 20 77 72  often need to wr
1140: 69 74 65 20 65 78 74 72 61 20 70 61 64 64 69 6e  ite extra paddin
1150: 67 20 62 65 79 6f 6e 64 20 74 68 65 20 0a 20 20  g beyond the .  
1160: 20 20 64 61 74 61 20 62 6c 6f 63 6b 2e 20 20 57    data block.  W
1170: 65 20 64 6f 6e 27 74 20 68 61 76 65 20 74 68 61  e don't have tha
1180: 74 20 6c 75 78 75 72 79 20 66 6f 72 20 61 20 67  t luxury for a g
1190: 69 76 65 6e 20 70 61 67 65 20 6f 66 20 64 61 74  iven page of dat
11a0: 61 20 73 6f 0a 20 20 20 20 77 65 20 6d 75 73 74  a so.    we must
11b0: 20 63 6f 70 79 20 74 68 65 20 70 61 67 65 20 64   copy the page d
11c0: 61 74 61 20 74 6f 20 61 20 62 75 66 66 65 72 20  ata to a buffer 
11d0: 74 68 61 74 20 49 53 20 6c 61 72 67 65 20 65 6e  that IS large en
11e0: 6f 75 67 68 20 74 6f 20 68 6f 6c 64 0a 20 20 20  ough to hold.   
11f0: 20 74 68 65 20 70 61 64 64 69 6e 67 2e 20 20 57   the padding.  W
1200: 65 20 74 68 65 6e 20 65 6e 63 72 79 70 74 20 74  e then encrypt t
1210: 68 65 20 62 6c 6f 63 6b 20 61 6e 64 20 77 72 69  he block and wri
1220: 74 65 20 74 68 65 20 62 75 66 66 65 72 20 62 61  te the buffer ba
1230: 63 6b 20 74 6f 0a 20 20 20 20 74 68 65 20 70 61  ck to.    the pa
1240: 67 65 20 77 69 74 68 6f 75 74 20 74 68 65 20 75  ge without the u
1250: 6e 6e 65 63 65 73 73 61 72 79 20 70 61 64 64 69  nnecessary paddi
1260: 6e 67 2e 0a 20 20 20 20 57 65 20 6f 6e 6c 79 20  ng..    We only 
1270: 75 73 65 20 74 68 65 20 73 70 65 63 69 61 6c 20  use the special 
1280: 62 6c 6f 63 6b 20 6f 66 20 6d 65 6d 6f 72 79 20  block of memory 
1290: 69 66 20 69 74 73 20 61 62 73 6f 6c 75 74 65 6c  if its absolutel
12a0: 79 20 6e 65 63 65 73 73 61 72 79 2e 20 2a 2f 0a  y necessary. */.
12b0: 20 20 20 20 69 66 20 28 70 42 6c 6f 63 6b 2d 3e      if (pBlock->
12c0: 64 77 43 72 79 70 74 53 69 7a 65 20 21 3d 20 70  dwCryptSize != p
12d0: 42 6c 6f 63 6b 2d 3e 64 77 50 61 67 65 53 69 7a  Block->dwPageSiz
12e0: 65 29 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 43  e).    {.      C
12f0: 6f 70 79 4d 65 6d 6f 72 79 28 28 28 4c 50 42 59  opyMemory(((LPBY
1300: 54 45 29 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79  TE)pBlock->pvCry
1310: 70 74 29 20 2b 20 43 52 59 50 54 5f 4f 46 46 53  pt) + CRYPT_OFFS
1320: 45 54 2c 20 64 61 74 61 2c 20 70 42 6c 6f 63 6b  ET, data, pBlock
1330: 2d 3e 64 77 50 61 67 65 53 69 7a 65 29 3b 0a 20  ->dwPageSize);. 
1340: 20 20 20 20 20 70 76 54 65 6d 70 20 3d 20 64 61       pvTemp = da
1350: 74 61 3b 0a 20 20 20 20 20 20 64 61 74 61 20 3d  ta;.      data =
1360: 20 28 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b   ((LPBYTE)pBlock
1370: 2d 3e 70 76 43 72 79 70 74 29 20 2b 20 43 52 59  ->pvCrypt) + CRY
1380: 50 54 5f 4f 46 46 53 45 54 3b 0a 20 20 20 20 7d  PT_OFFSET;.    }
1390: 0a 0a 20 20 20 20 64 77 50 61 67 65 53 69 7a 65  ..    dwPageSize
13a0: 20 3d 20 70 42 6c 6f 63 6b 2d 3e 64 77 43 72 79   = pBlock->dwCry
13b0: 70 74 53 69 7a 65 3b 0a 20 20 20 20 43 72 79 70  ptSize;.    Cryp
13c0: 74 44 65 63 72 79 70 74 28 70 42 6c 6f 63 6b 2d  tDecrypt(pBlock-
13d0: 3e 68 52 65 61 64 4b 65 79 2c 20 30 2c 20 54 52  >hReadKey, 0, TR
13e0: 55 45 2c 20 30 2c 20 28 4c 50 42 59 54 45 29 64  UE, 0, (LPBYTE)d
13f0: 61 74 61 2c 20 26 64 77 50 61 67 65 53 69 7a 65  ata, &dwPageSize
1400: 29 3b 0a 0a 20 20 20 20 2f 2f 20 49 66 20 74 68  );..    // If th
1410: 65 20 65 6e 63 72 79 70 74 69 6f 6e 20 61 6c 67  e encryption alg
1420: 6f 72 69 74 68 6d 20 72 65 71 75 69 72 65 64 20  orithm required 
1430: 65 78 74 72 61 20 70 61 64 64 69 6e 67 20 61 6e  extra padding an
1440: 64 20 77 65 20 77 65 72 65 20 66 6f 72 63 65 64  d we were forced
1450: 20 74 6f 20 65 6e 63 72 79 70 74 20 6f 72 0a 20   to encrypt or. 
1460: 20 20 20 2f 2f 20 64 65 63 72 79 70 74 20 61 20     // decrypt a 
1470: 63 6f 70 79 20 6f 66 20 74 68 65 20 70 61 67 65  copy of the page
1480: 20 64 61 74 61 20 74 6f 20 61 20 74 65 6d 70 20   data to a temp 
1490: 62 75 66 66 65 72 2c 20 74 68 65 6e 20 77 72 69  buffer, then wri
14a0: 74 65 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  te the contents 
14b0: 6f 66 20 74 68 65 20 74 65 6d 70 0a 20 20 20 20  of the temp.    
14c0: 2f 2f 20 62 75 66 66 65 72 20 62 61 63 6b 20 74  // buffer back t
14d0: 6f 20 74 68 65 20 70 61 67 65 20 64 61 74 61 20  o the page data 
14e0: 6d 69 6e 75 73 20 61 6e 79 20 70 61 64 64 69 6e  minus any paddin
14f0: 67 20 61 70 70 6c 69 65 64 2e 0a 20 20 20 20 69  g applied..    i
1500: 66 20 28 70 42 6c 6f 63 6b 2d 3e 64 77 43 72 79  f (pBlock->dwCry
1510: 70 74 53 69 7a 65 20 21 3d 20 70 42 6c 6f 63 6b  ptSize != pBlock
1520: 2d 3e 64 77 50 61 67 65 53 69 7a 65 29 0a 20 20  ->dwPageSize).  
1530: 20 20 7b 0a 20 20 20 20 20 20 43 6f 70 79 4d 65    {.      CopyMe
1540: 6d 6f 72 79 28 70 76 54 65 6d 70 2c 20 64 61 74  mory(pvTemp, dat
1550: 61 2c 20 70 42 6c 6f 63 6b 2d 3e 64 77 50 61 67  a, pBlock->dwPag
1560: 65 53 69 7a 65 29 3b 0a 20 20 20 20 20 20 64 61  eSize);.      da
1570: 74 61 20 3d 20 70 76 54 65 6d 70 3b 0a 20 20 20  ta = pvTemp;.   
1580: 20 7d 0a 20 20 20 20 62 72 65 61 6b 3b 0a 20 20   }.    break;.  
1590: 63 61 73 65 20 36 3a 20 2f 2f 20 45 6e 63 72 79  case 6: // Encry
15a0: 70 74 20 61 20 70 61 67 65 20 66 6f 72 20 74 68  pt a page for th
15b0: 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 20  e main database 
15c0: 66 69 6c 65 0a 20 20 20 20 69 66 20 28 21 70 42  file.    if (!pB
15d0: 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65 79 29  lock->hWriteKey)
15e0: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 43 6f 70   break;..    Cop
15f0: 79 4d 65 6d 6f 72 79 28 28 28 4c 50 42 59 54 45  yMemory(((LPBYTE
1600: 29 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70 74  )pBlock->pvCrypt
1610: 29 20 2b 20 43 52 59 50 54 5f 4f 46 46 53 45 54  ) + CRYPT_OFFSET
1620: 2c 20 64 61 74 61 2c 20 70 42 6c 6f 63 6b 2d 3e  , data, pBlock->
1630: 64 77 50 61 67 65 53 69 7a 65 29 3b 0a 20 20 20  dwPageSize);.   
1640: 20 64 61 74 61 20 3d 20 28 28 4c 50 42 59 54 45   data = ((LPBYTE
1650: 29 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70 74  )pBlock->pvCrypt
1660: 29 20 2b 20 43 52 59 50 54 5f 4f 46 46 53 45 54  ) + CRYPT_OFFSET
1670: 3b 0a 0a 20 20 20 20 64 77 50 61 67 65 53 69 7a  ;..    dwPageSiz
1680: 65 20 3d 20 70 42 6c 6f 63 6b 2d 3e 64 77 50 61  e = pBlock->dwPa
1690: 67 65 53 69 7a 65 3b 0a 20 20 20 20 43 72 79 70  geSize;.    Cryp
16a0: 74 45 6e 63 72 79 70 74 28 70 42 6c 6f 63 6b 2d  tEncrypt(pBlock-
16b0: 3e 68 57 72 69 74 65 4b 65 79 2c 20 30 2c 20 54  >hWriteKey, 0, T
16c0: 52 55 45 2c 20 30 2c 20 28 28 4c 50 42 59 54 45  RUE, 0, ((LPBYTE
16d0: 29 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70 74  )pBlock->pvCrypt
16e0: 29 20 2b 20 43 52 59 50 54 5f 4f 46 46 53 45 54  ) + CRYPT_OFFSET
16f0: 2c 20 26 64 77 50 61 67 65 53 69 7a 65 2c 20 70  , &dwPageSize, p
1700: 42 6c 6f 63 6b 2d 3e 64 77 43 72 79 70 74 53 69  Block->dwCryptSi
1710: 7a 65 29 3b 0a 20 20 20 20 62 72 65 61 6b 3b 0a  ze);.    break;.
1720: 20 20 63 61 73 65 20 37 3a 20 2f 2f 20 45 6e 63    case 7: // Enc
1730: 72 79 70 74 20 61 20 70 61 67 65 20 66 6f 72 20  rypt a page for 
1740: 74 68 65 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65  the journal file
1750: 0a 20 20 20 20 2f 2a 20 55 6e 64 65 72 20 6e 6f  .    /* Under no
1760: 72 6d 61 6c 20 63 69 72 63 75 6d 73 74 61 6e 63  rmal circumstanc
1770: 65 73 2c 20 74 68 65 20 72 65 61 64 6b 65 79 20  es, the readkey 
1780: 69 73 20 74 68 65 20 73 61 6d 65 20 61 73 20 74  is the same as t
1790: 68 65 20 77 72 69 74 65 6b 65 79 2e 20 20 48 6f  he writekey.  Ho
17a0: 77 65 76 65 72 2c 0a 20 20 20 20 77 68 65 6e 20  wever,.    when 
17b0: 74 68 65 20 64 61 74 61 62 61 73 65 20 69 73 20  the database is 
17c0: 62 65 69 6e 67 20 72 65 6b 65 79 65 64 2c 20 74  being rekeyed, t
17d0: 68 65 20 72 65 61 64 6b 65 79 20 69 73 20 6e 6f  he readkey is no
17e0: 74 20 74 68 65 20 73 61 6d 65 20 61 73 20 74 68  t the same as th
17f0: 65 20 77 72 69 74 65 6b 65 79 2e 0a 20 20 20 20  e writekey..    
1800: 54 68 65 20 72 6f 6c 6c 62 61 63 6b 20 6a 6f 75  The rollback jou
1810: 72 6e 61 6c 20 6d 75 73 74 20 62 65 20 77 72 69  rnal must be wri
1820: 74 74 65 6e 20 75 73 69 6e 67 20 74 68 65 20 6f  tten using the o
1830: 72 69 67 69 6e 61 6c 20 6b 65 79 20 66 6f 72 20  riginal key for 
1840: 74 68 65 0a 20 20 20 20 64 61 74 61 62 61 73 65  the.    database
1850: 20 66 69 6c 65 20 62 65 63 61 75 73 65 20 69 74   file because it
1860: 20 69 73 2c 20 62 79 20 6e 61 74 75 72 65 2c 20   is, by nature, 
1870: 61 20 72 6f 6c 6c 62 61 63 6b 20 6a 6f 75 72 6e  a rollback journ
1880: 61 6c 2e 0a 20 20 20 20 54 68 65 72 65 66 6f 72  al..    Therefor
1890: 65 2c 20 66 6f 72 20 63 61 73 65 20 37 2c 20 77  e, for case 7, w
18a0: 68 65 6e 20 74 68 65 20 72 6f 6c 6c 62 61 63 6b  hen the rollback
18b0: 20 69 73 20 62 65 69 6e 67 20 77 72 69 74 74 65   is being writte
18c0: 6e 2c 20 61 6c 77 61 79 73 20 65 6e 63 72 79 70  n, always encryp
18d0: 74 20 75 73 69 6e 67 0a 20 20 20 20 74 68 65 20  t using.    the 
18e0: 64 61 74 61 62 61 73 65 27 73 20 72 65 61 64 6b  database's readk
18f0: 65 79 2c 20 77 68 69 63 68 20 69 73 20 67 75 61  ey, which is gua
1900: 72 61 6e 74 65 65 64 20 74 6f 20 62 65 20 74 68  ranteed to be th
1910: 65 20 73 61 6d 65 20 6b 65 79 20 74 68 61 74 20  e same key that 
1920: 77 61 73 20 75 73 65 64 20 74 6f 0a 20 20 20 20  was used to.    
1930: 72 65 61 64 20 74 68 65 20 6f 72 69 67 69 6e 61  read the origina
1940: 6c 20 64 61 74 61 2e 0a 20 20 20 20 2a 2f 0a 20  l data..    */. 
1950: 20 20 20 69 66 20 28 21 70 42 6c 6f 63 6b 2d 3e     if (!pBlock->
1960: 68 52 65 61 64 4b 65 79 29 20 62 72 65 61 6b 3b  hReadKey) break;
1970: 0a 0a 20 20 20 20 43 6f 70 79 4d 65 6d 6f 72 79  ..    CopyMemory
1980: 28 28 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b  (((LPBYTE)pBlock
1990: 2d 3e 70 76 43 72 79 70 74 29 20 2b 20 43 52 59  ->pvCrypt) + CRY
19a0: 50 54 5f 4f 46 46 53 45 54 2c 20 64 61 74 61 2c  PT_OFFSET, data,
19b0: 20 70 42 6c 6f 63 6b 2d 3e 64 77 50 61 67 65 53   pBlock->dwPageS
19c0: 69 7a 65 29 3b 0a 20 20 20 20 64 61 74 61 20 3d  ize);.    data =
19d0: 20 28 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b   ((LPBYTE)pBlock
19e0: 2d 3e 70 76 43 72 79 70 74 29 20 2b 20 43 52 59  ->pvCrypt) + CRY
19f0: 50 54 5f 4f 46 46 53 45 54 3b 0a 0a 20 20 20 20  PT_OFFSET;..    
1a00: 64 77 50 61 67 65 53 69 7a 65 20 3d 20 70 42 6c  dwPageSize = pBl
1a10: 6f 63 6b 2d 3e 64 77 50 61 67 65 53 69 7a 65 3b  ock->dwPageSize;
1a20: 0a 20 20 20 20 43 72 79 70 74 45 6e 63 72 79 70  .    CryptEncryp
1a30: 74 28 70 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b  t(pBlock->hReadK
1a40: 65 79 2c 20 30 2c 20 54 52 55 45 2c 20 30 2c 20  ey, 0, TRUE, 0, 
1a50: 28 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b 2d  ((LPBYTE)pBlock-
1a60: 3e 70 76 43 72 79 70 74 29 20 2b 20 43 52 59 50  >pvCrypt) + CRYP
1a70: 54 5f 4f 46 46 53 45 54 2c 20 26 64 77 50 61 67  T_OFFSET, &dwPag
1a80: 65 53 69 7a 65 2c 20 70 42 6c 6f 63 6b 2d 3e 64  eSize, pBlock->d
1a90: 77 43 72 79 70 74 53 69 7a 65 29 3b 0a 20 20 20  wCryptSize);.   
1aa0: 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 72   break;.  }..  r
1ab0: 65 74 75 72 6e 20 64 61 74 61 3b 0a 7d 0a 0a 2f  eturn data;.}../
1ac0: 2f 20 44 65 72 69 76 65 20 61 6e 20 65 6e 63 72  / Derive an encr
1ad0: 79 70 74 69 6f 6e 20 6b 65 79 20 66 72 6f 6d 20  yption key from 
1ae0: 61 20 75 73 65 72 2d 73 75 70 70 6c 69 65 64 20  a user-supplied 
1af0: 62 75 66 66 65 72 0a 73 74 61 74 69 63 20 48 43  buffer.static HC
1b00: 52 59 50 54 4b 45 59 20 44 65 72 69 76 65 4b 65  RYPTKEY DeriveKe
1b10: 79 28 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70 4b  y(const void *pK
1b20: 65 79 2c 20 69 6e 74 20 6e 4b 65 79 4c 65 6e 29  ey, int nKeyLen)
1b30: 0a 7b 0a 20 20 48 43 52 59 50 54 48 41 53 48 20  .{.  HCRYPTHASH 
1b40: 68 48 61 73 68 20 3d 20 30 3b 0a 20 20 48 43 52  hHash = 0;.  HCR
1b50: 59 50 54 4b 45 59 20 20 68 4b 65 79 3b 0a 0a 20  YPTKEY  hKey;.. 
1b60: 20 69 66 20 28 21 70 4b 65 79 20 7c 7c 20 21 6e   if (!pKey || !n
1b70: 4b 65 79 4c 65 6e 29 20 72 65 74 75 72 6e 20 30  KeyLen) return 0
1b80: 3b 0a 0a 20 20 69 66 20 28 21 49 6e 69 74 69 61  ;..  if (!Initia
1b90: 6c 69 7a 65 50 72 6f 76 69 64 65 72 28 29 29 0a  lizeProvider()).
1ba0: 20 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 4d    {.    return M
1bb0: 41 58 44 57 4f 52 44 3b 0a 20 20 7d 0a 0a 20 20  AXDWORD;.  }..  
1bc0: 69 66 20 28 43 72 79 70 74 43 72 65 61 74 65 48  if (CryptCreateH
1bd0: 61 73 68 28 67 5f 68 50 72 6f 76 69 64 65 72 2c  ash(g_hProvider,
1be0: 20 43 41 4c 47 5f 53 48 41 31 2c 20 30 2c 20 30   CALG_SHA1, 0, 0
1bf0: 2c 20 26 68 48 61 73 68 29 29 0a 20 20 7b 0a 20  , &hHash)).  {. 
1c00: 20 20 20 69 66 20 28 43 72 79 70 74 48 61 73 68     if (CryptHash
1c10: 44 61 74 61 28 68 48 61 73 68 2c 20 28 4c 50 42  Data(hHash, (LPB
1c20: 59 54 45 29 70 4b 65 79 2c 20 6e 4b 65 79 4c 65  YTE)pKey, nKeyLe
1c30: 6e 2c 20 30 29 29 0a 20 20 20 20 7b 0a 20 20 20  n, 0)).    {.   
1c40: 20 20 20 43 72 79 70 74 44 65 72 69 76 65 4b 65     CryptDeriveKe
1c50: 79 28 67 5f 68 50 72 6f 76 69 64 65 72 2c 20 43  y(g_hProvider, C
1c60: 41 4c 47 5f 52 43 34 2c 20 68 48 61 73 68 2c 20  ALG_RC4, hHash, 
1c70: 30 2c 20 26 68 4b 65 79 29 3b 0a 20 20 20 20 7d  0, &hKey);.    }
1c80: 0a 20 20 20 20 43 72 79 70 74 44 65 73 74 72 6f  .    CryptDestro
1c90: 79 48 61 73 68 28 68 48 61 73 68 29 3b 0a 20 20  yHash(hHash);.  
1ca0: 7d 20 20 0a 20 20 72 65 74 75 72 6e 20 68 4b 65  }  .  return hKe
1cb0: 79 3b 0a 7d 0a 0a 2f 2f 20 43 61 6c 6c 65 64 20  y;.}..// Called 
1cc0: 62 79 20 73 71 6c 69 74 65 20 61 6e 64 20 73 71  by sqlite and sq
1cd0: 6c 69 74 65 33 5f 6b 65 79 5f 69 6e 74 65 72 6f  lite3_key_intero
1ce0: 70 20 74 6f 20 61 74 74 61 63 68 20 61 20 6b 65  p to attach a ke
1cf0: 79 20 74 6f 20 61 20 64 61 74 61 62 61 73 65 2e  y to a database.
1d00: 0a 69 6e 74 20 73 71 6c 69 74 65 33 43 6f 64 65  .int sqlite3Code
1d10: 63 41 74 74 61 63 68 28 73 71 6c 69 74 65 33 20  cAttach(sqlite3 
1d20: 2a 64 62 2c 20 69 6e 74 20 6e 44 62 2c 20 63 6f  *db, int nDb, co
1d30: 6e 73 74 20 76 6f 69 64 20 2a 70 4b 65 79 2c 20  nst void *pKey, 
1d40: 69 6e 74 20 6e 4b 65 79 4c 65 6e 29 0a 7b 0a 20  int nKeyLen).{. 
1d50: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
1d60: 5f 45 52 52 4f 52 3b 0a 20 20 48 43 52 59 50 54  _ERROR;.  HCRYPT
1d70: 4b 45 59 20 68 4b 65 79 20 3d 20 30 3b 0a 0a 20  KEY hKey = 0;.. 
1d80: 20 2f 2f 20 4e 6f 20 6b 65 79 20 73 70 65 63 69   // No key speci
1d90: 66 69 65 64 2c 20 63 6f 75 6c 64 20 6d 65 61 6e  fied, could mean
1da0: 20 65 69 74 68 65 72 20 75 73 65 20 74 68 65 20   either use the 
1db0: 6d 61 69 6e 20 64 62 27 73 20 65 6e 63 72 79 70  main db's encryp
1dc0: 74 69 6f 6e 20 6f 72 20 6e 6f 20 65 6e 63 72 79  tion or no encry
1dd0: 70 74 69 6f 6e 0a 20 20 69 66 20 28 21 70 4b 65  ption.  if (!pKe
1de0: 79 20 7c 7c 20 21 6e 4b 65 79 4c 65 6e 29 0a 20  y || !nKeyLen). 
1df0: 20 7b 0a 20 20 20 20 69 66 20 28 21 6e 44 62 29   {.    if (!nDb)
1e00: 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 72 65 74  .    {.      ret
1e10: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 2f  urn SQLITE_OK; /
1e20: 2f 20 4d 61 69 6e 20 64 61 74 61 62 61 73 65 2c  / Main database,
1e30: 20 6e 6f 20 6b 65 79 20 73 70 65 63 69 66 69 65   no key specifie
1e40: 64 20 73 6f 20 6e 6f 74 20 65 6e 63 72 79 70 74  d so not encrypt
1e50: 65 64 0a 20 20 20 20 7d 0a 20 20 20 20 65 6c 73  ed.    }.    els
1e60: 65 20 2f 2f 20 41 74 74 61 63 68 65 64 20 64 61  e // Attached da
1e70: 74 61 62 61 73 65 2c 20 75 73 65 20 74 68 65 20  tabase, use the 
1e80: 6d 61 69 6e 20 64 61 74 61 62 61 73 65 27 73 20  main database's 
1e90: 6b 65 79 0a 20 20 20 20 7b 0a 20 20 20 20 20 20  key.    {.      
1ea0: 2f 2f 20 47 65 74 20 74 68 65 20 65 6e 63 72 79  // Get the encry
1eb0: 70 74 69 6f 6e 20 62 6c 6f 63 6b 20 66 6f 72 20  ption block for 
1ec0: 74 68 65 20 6d 61 69 6e 20 64 61 74 61 62 61 73  the main databas
1ed0: 65 20 61 6e 64 20 61 74 74 65 6d 70 74 20 74 6f  e and attempt to
1ee0: 20 64 75 70 6c 69 63 61 74 65 20 74 68 65 20 6b   duplicate the k
1ef0: 65 79 0a 20 20 20 20 20 20 2f 2f 20 66 6f 72 20  ey.      // for 
1f00: 75 73 65 20 62 79 20 74 68 65 20 61 74 74 61 63  use by the attac
1f10: 68 65 64 20 64 61 74 61 62 61 73 65 0a 20 20 20  hed database.   
1f20: 20 20 20 50 61 67 65 72 20 2a 70 20 3d 20 73 71     Pager *p = sq
1f30: 6c 69 74 65 33 42 74 72 65 65 50 61 67 65 72 28  lite3BtreePager(
1f40: 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 29 3b  db->aDb[0].pBt);
1f50: 0a 20 20 20 20 20 20 4c 50 43 52 59 50 54 42 4c  .      LPCRYPTBL
1f60: 4f 43 4b 20 70 42 6c 6f 63 6b 20 3d 20 28 4c 50  OCK pBlock = (LP
1f70: 43 52 59 50 54 42 4c 4f 43 4b 29 73 71 6c 69 74  CRYPTBLOCK)sqlit
1f80: 65 33 70 61 67 65 72 5f 67 65 74 5f 63 6f 64 65  e3pager_get_code
1f90: 63 61 72 67 28 70 29 3b 0a 0a 20 20 20 20 20 20  carg(p);..      
1fa0: 69 66 20 28 21 70 42 6c 6f 63 6b 29 20 72 65 74  if (!pBlock) ret
1fb0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 2f  urn SQLITE_OK; /
1fc0: 2f 20 4d 61 69 6e 20 64 61 74 61 62 61 73 65 20  / Main database 
1fd0: 69 73 20 6e 6f 74 20 65 6e 63 72 79 70 74 65 64  is not encrypted
1fe0: 20 73 6f 20 6e 65 69 74 68 65 72 20 77 69 6c 6c   so neither will
1ff0: 20 62 65 20 61 6e 79 20 61 74 74 61 63 68 65 64   be any attached
2000: 20 64 61 74 61 62 61 73 65 0a 20 20 20 20 20 20   database.      
2010: 69 66 20 28 21 70 42 6c 6f 63 6b 2d 3e 68 52 65  if (!pBlock->hRe
2020: 61 64 4b 65 79 29 20 72 65 74 75 72 6e 20 53 51  adKey) return SQ
2030: 4c 49 54 45 5f 4f 4b 3b 20 2f 2f 20 4e 6f 74 20  LITE_OK; // Not 
2040: 65 6e 63 72 79 70 74 65 64 0a 0a 20 20 20 20 20  encrypted..     
2050: 20 69 66 20 28 21 43 72 79 70 74 44 75 70 6c 69   if (!CryptDupli
2060: 63 61 74 65 4b 65 79 28 70 42 6c 6f 63 6b 2d 3e  cateKey(pBlock->
2070: 68 52 65 61 64 4b 65 79 2c 20 4e 55 4c 4c 2c 20  hReadKey, NULL, 
2080: 30 2c 20 26 68 4b 65 79 29 29 0a 20 20 20 20 20  0, &hKey)).     
2090: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 20 2f 2f     return rc; //
20a0: 20 55 6e 61 62 6c 65 20 74 6f 20 64 75 70 6c 69   Unable to dupli
20b0: 63 61 74 65 20 74 68 65 20 6b 65 79 0a 20 20 20  cate the key.   
20c0: 20 7d 0a 20 20 7d 0a 20 20 65 6c 73 65 20 2f 2f   }.  }.  else //
20d0: 20 55 73 65 72 2d 73 75 70 70 6c 69 65 64 20 70   User-supplied p
20e0: 61 73 73 70 68 72 61 73 65 2c 20 73 6f 20 63 72  assphrase, so cr
20f0: 65 61 74 65 20 61 20 63 72 79 70 74 6f 67 72 61  eate a cryptogra
2100: 70 68 69 63 20 6b 65 79 20 6f 75 74 20 6f 66 20  phic key out of 
2110: 69 74 0a 20 20 7b 0a 20 20 20 20 68 4b 65 79 20  it.  {.    hKey 
2120: 3d 20 44 65 72 69 76 65 4b 65 79 28 70 4b 65 79  = DeriveKey(pKey
2130: 2c 20 6e 4b 65 79 4c 65 6e 29 3b 0a 20 20 20 20  , nKeyLen);.    
2140: 69 66 20 28 68 4b 65 79 20 3d 3d 20 4d 41 58 44  if (hKey == MAXD
2150: 57 4f 52 44 29 0a 20 20 20 20 7b 0a 20 20 20 20  WORD).    {.    
2160: 20 20 73 71 6c 69 74 65 33 45 72 72 6f 72 28 64    sqlite3Error(d
2170: 62 2c 20 72 63 2c 20 53 51 4c 49 54 45 43 52 59  b, rc, SQLITECRY
2180: 50 54 45 52 52 4f 52 5f 50 52 4f 56 49 44 45 52  PTERROR_PROVIDER
2190: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
21a0: 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  rc;.    }.  }.. 
21b0: 20 2f 2f 20 43 72 65 61 74 65 20 61 20 6e 65 77   // Create a new
21c0: 20 65 6e 63 72 79 70 74 69 6f 6e 20 62 6c 6f 63   encryption bloc
21d0: 6b 20 61 6e 64 20 61 73 73 69 67 6e 20 74 68 65  k and assign the
21e0: 20 63 6f 64 65 63 20 74 6f 20 74 68 65 20 6e 65   codec to the ne
21f0: 77 20 61 74 74 61 63 68 65 64 20 64 61 74 61 62  w attached datab
2200: 61 73 65 0a 20 20 69 66 20 28 68 4b 65 79 29 0a  ase.  if (hKey).
2210: 20 20 7b 0a 20 20 20 20 50 61 67 65 72 20 2a 70    {.    Pager *p
2220: 20 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65 50   = sqlite3BtreeP
2230: 61 67 65 72 28 64 62 2d 3e 61 44 62 5b 6e 44 62  ager(db->aDb[nDb
2240: 5d 2e 70 42 74 29 3b 0a 20 20 20 20 4c 50 43 52  ].pBt);.    LPCR
2250: 59 50 54 42 4c 4f 43 4b 20 70 42 6c 6f 63 6b 20  YPTBLOCK pBlock 
2260: 3d 20 43 72 65 61 74 65 43 72 79 70 74 42 6c 6f  = CreateCryptBlo
2270: 63 6b 28 68 4b 65 79 2c 20 70 2c 20 2d 31 2c 20  ck(hKey, p, -1, 
2280: 4e 55 4c 4c 29 3b 0a 20 20 20 20 69 66 20 28 21  NULL);.    if (!
2290: 70 42 6c 6f 63 6b 29 20 72 65 74 75 72 6e 20 53  pBlock) return S
22a0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20  QLITE_NOMEM;..  
22b0: 20 20 73 71 6c 69 74 65 33 50 61 67 65 72 53 65    sqlite3PagerSe
22c0: 74 43 6f 64 65 63 28 70 2c 20 73 71 6c 69 74 65  tCodec(p, sqlite
22d0: 33 43 6f 64 65 63 2c 20 73 71 6c 69 74 65 33 43  3Codec, sqlite3C
22e0: 6f 64 65 63 53 69 7a 65 43 68 61 6e 67 65 2c 20  odecSizeChange, 
22f0: 73 71 6c 69 74 65 33 43 6f 64 65 63 46 72 65 65  sqlite3CodecFree
2300: 2c 20 70 42 6c 6f 63 6b 29 3b 0a 20 20 20 20 2f  , pBlock);.    /
2310: 2f 64 62 2d 3e 61 44 62 5b 6e 44 62 5d 2e 70 41  /db->aDb[nDb].pA
2320: 75 78 20 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20 20  ux = pBlock;.   
2330: 20 2f 2f 64 62 2d 3e 61 44 62 5b 6e 44 62 5d 2e   //db->aDb[nDb].
2340: 78 46 72 65 65 41 75 78 20 3d 20 44 65 73 74 72  xFreeAux = Destr
2350: 6f 79 43 72 79 70 74 42 6c 6f 63 6b 3b 0a 0a 20  oyCryptBlock;.. 
2360: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f     rc = SQLITE_O
2370: 4b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  K;.  }.  return 
2380: 72 63 3b 0a 7d 0a 0a 2f 2f 20 4f 6e 63 65 20 61  rc;.}..// Once a
2390: 20 70 61 73 73 77 6f 72 64 20 68 61 73 20 62 65   password has be
23a0: 65 6e 20 73 75 70 70 6c 69 65 64 20 61 6e 64 20  en supplied and 
23b0: 61 20 6b 65 79 20 63 72 65 61 74 65 64 2c 20 77  a key created, w
23c0: 65 20 64 6f 6e 27 74 20 6b 65 65 70 20 74 68 65  e don't keep the
23d0: 20 0a 2f 2f 20 6f 72 69 67 69 6e 61 6c 20 70 61   .// original pa
23e0: 73 73 77 6f 72 64 20 66 6f 72 20 73 65 63 75 72  ssword for secur
23f0: 69 74 79 20 70 75 72 70 6f 73 65 73 2e 20 20 54  ity purposes.  T
2400: 68 65 72 65 66 6f 72 65 20 72 65 74 75 72 6e 20  herefore return 
2410: 4e 55 4c 4c 2e 0a 76 6f 69 64 20 73 71 6c 69 74  NULL..void sqlit
2420: 65 33 43 6f 64 65 63 47 65 74 4b 65 79 28 73 71  e3CodecGetKey(sq
2430: 6c 69 74 65 33 20 2a 64 62 2c 20 69 6e 74 20 6e  lite3 *db, int n
2440: 44 62 2c 20 76 6f 69 64 20 2a 2a 70 70 4b 65 79  Db, void **ppKey
2450: 2c 20 69 6e 74 20 2a 70 6e 4b 65 79 4c 65 6e 29  , int *pnKeyLen)
2460: 0a 7b 0a 20 20 42 74 72 65 65 20 2a 70 62 74 20  .{.  Btree *pbt 
2470: 3d 20 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 42 74  = db->aDb[0].pBt
2480: 3b 0a 20 20 50 61 67 65 72 20 2a 70 20 3d 20 73  ;.  Pager *p = s
2490: 71 6c 69 74 65 33 42 74 72 65 65 50 61 67 65 72  qlite3BtreePager
24a0: 28 70 62 74 29 3b 0a 20 20 4c 50 43 52 59 50 54  (pbt);.  LPCRYPT
24b0: 42 4c 4f 43 4b 20 70 42 6c 6f 63 6b 20 3d 20 28  BLOCK pBlock = (
24c0: 4c 50 43 52 59 50 54 42 4c 4f 43 4b 29 73 71 6c  LPCRYPTBLOCK)sql
24d0: 69 74 65 33 70 61 67 65 72 5f 67 65 74 5f 63 6f  ite3pager_get_co
24e0: 64 65 63 61 72 67 28 70 29 3b 0a 0a 20 20 69 66  decarg(p);..  if
24f0: 20 28 70 70 4b 65 79 29 20 2a 70 70 4b 65 79 20   (ppKey) *ppKey 
2500: 3d 20 30 3b 0a 20 20 69 66 20 28 70 6e 4b 65 79  = 0;.  if (pnKey
2510: 4c 65 6e 20 26 26 20 70 42 6c 6f 63 6b 29 20 2a  Len && pBlock) *
2520: 70 6e 4b 65 79 4c 65 6e 20 3d 20 31 3b 0a 7d 0a  pnKeyLen = 1;.}.
2530: 0a 2f 2f 20 57 65 20 64 6f 20 6e 6f 74 20 61 74  .// We do not at
2540: 74 61 63 68 20 74 68 69 73 20 6b 65 79 20 74 6f  tach this key to
2550: 20 74 68 65 20 74 65 6d 70 20 73 74 6f 72 65 2c   the temp store,
2560: 20 6f 6e 6c 79 20 74 68 65 20 6d 61 69 6e 20 64   only the main d
2570: 61 74 61 62 61 73 65 2e 0a 53 51 4c 49 54 45 5f  atabase..SQLITE_
2580: 41 50 49 20 69 6e 74 20 73 71 6c 69 74 65 33 5f  API int sqlite3_
2590: 6b 65 79 28 73 71 6c 69 74 65 33 20 2a 64 62 2c  key(sqlite3 *db,
25a0: 20 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20   const unsigned 
25b0: 63 68 61 72 20 2a 70 4b 65 79 2c 20 69 6e 74 20  char *pKey, int 
25c0: 6e 4b 65 79 53 69 7a 65 29 0a 7b 0a 20 20 72 65  nKeySize).{.  re
25d0: 74 75 72 6e 20 73 71 6c 69 74 65 33 43 6f 64 65  turn sqlite3Code
25e0: 63 41 74 74 61 63 68 28 64 62 2c 20 30 2c 20 70  cAttach(db, 0, p
25f0: 4b 65 79 2c 20 6e 4b 65 79 53 69 7a 65 29 3b 0a  Key, nKeySize);.
2600: 7d 0a 0a 2f 2f 20 43 68 61 6e 67 65 73 20 74 68  }..// Changes th
2610: 65 20 65 6e 63 72 79 70 74 69 6f 6e 20 6b 65 79  e encryption key
2620: 20 66 6f 72 20 61 6e 20 65 78 69 73 74 69 6e 67   for an existing
2630: 20 64 61 74 61 62 61 73 65 2e 0a 53 51 4c 49 54   database..SQLIT
2640: 45 5f 41 50 49 20 69 6e 74 20 73 71 6c 69 74 65  E_API int sqlite
2650: 33 5f 72 65 6b 65 79 28 73 71 6c 69 74 65 33 20  3_rekey(sqlite3 
2660: 2a 64 62 2c 20 63 6f 6e 73 74 20 75 6e 73 69 67  *db, const unsig
2670: 6e 65 64 20 63 68 61 72 20 2a 70 4b 65 79 2c 20  ned char *pKey, 
2680: 69 6e 74 20 6e 4b 65 79 53 69 7a 65 29 0a 7b 0a  int nKeySize).{.
2690: 20 20 42 74 72 65 65 20 2a 70 62 74 20 3d 20 64    Btree *pbt = d
26a0: 62 2d 3e 61 44 62 5b 30 5d 2e 70 42 74 3b 0a 20  b->aDb[0].pBt;. 
26b0: 20 50 61 67 65 72 20 2a 70 20 3d 20 73 71 6c 69   Pager *p = sqli
26c0: 74 65 33 42 74 72 65 65 50 61 67 65 72 28 70 62  te3BtreePager(pb
26d0: 74 29 3b 0a 20 20 4c 50 43 52 59 50 54 42 4c 4f  t);.  LPCRYPTBLO
26e0: 43 4b 20 70 42 6c 6f 63 6b 20 3d 20 28 4c 50 43  CK pBlock = (LPC
26f0: 52 59 50 54 42 4c 4f 43 4b 29 73 71 6c 69 74 65  RYPTBLOCK)sqlite
2700: 33 70 61 67 65 72 5f 67 65 74 5f 63 6f 64 65 63  3pager_get_codec
2710: 61 72 67 28 70 29 3b 0a 20 20 48 43 52 59 50 54  arg(p);.  HCRYPT
2720: 4b 45 59 20 68 4b 65 79 20 3d 20 44 65 72 69 76  KEY hKey = Deriv
2730: 65 4b 65 79 28 70 4b 65 79 2c 20 6e 4b 65 79 53  eKey(pKey, nKeyS
2740: 69 7a 65 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d  ize);.  int rc =
2750: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 0a   SQLITE_ERROR;..
2760: 20 20 69 66 20 28 68 4b 65 79 20 3d 3d 20 4d 41    if (hKey == MA
2770: 58 44 57 4f 52 44 29 0a 20 20 7b 0a 20 20 20 20  XDWORD).  {.    
2780: 73 71 6c 69 74 65 33 45 72 72 6f 72 28 64 62 2c  sqlite3Error(db,
2790: 20 72 63 2c 20 53 51 4c 49 54 45 43 52 59 50 54   rc, SQLITECRYPT
27a0: 45 52 52 4f 52 5f 50 52 4f 56 49 44 45 52 29 3b  ERROR_PROVIDER);
27b0: 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
27c0: 20 20 7d 0a 0a 20 20 69 66 20 28 21 70 42 6c 6f    }..  if (!pBlo
27d0: 63 6b 20 26 26 20 21 68 4b 65 79 29 20 72 65 74  ck && !hKey) ret
27e0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 2f  urn SQLITE_OK; /
27f0: 2f 20 57 61 73 6e 27 74 20 65 6e 63 72 79 70 74  / Wasn't encrypt
2800: 65 64 20 74 6f 20 62 65 67 69 6e 20 77 69 74 68  ed to begin with
2810: 0a 0a 20 20 2f 2f 20 54 6f 20 72 65 6b 65 79 20  ..  // To rekey 
2820: 61 20 64 61 74 61 62 61 73 65 2c 20 77 65 20 63  a database, we c
2830: 68 61 6e 67 65 20 74 68 65 20 77 72 69 74 65 6b  hange the writek
2840: 65 79 20 66 6f 72 20 74 68 65 20 70 61 67 65 72  ey for the pager
2850: 2e 20 20 54 68 65 20 72 65 61 64 6b 65 79 20 72  .  The readkey r
2860: 65 6d 61 69 6e 73 0a 20 20 2f 2f 20 74 68 65 20  emains.  // the 
2870: 73 61 6d 65 0a 20 20 69 66 20 28 21 70 42 6c 6f  same.  if (!pBlo
2880: 63 6b 29 20 2f 2f 20 45 6e 63 72 79 70 74 20 61  ck) // Encrypt a
2890: 6e 20 75 6e 65 6e 63 72 79 70 74 65 64 20 64 61  n unencrypted da
28a0: 74 61 62 61 73 65 0a 20 20 7b 0a 20 20 20 20 70  tabase.  {.    p
28b0: 42 6c 6f 63 6b 20 3d 20 43 72 65 61 74 65 43 72  Block = CreateCr
28c0: 79 70 74 42 6c 6f 63 6b 28 68 4b 65 79 2c 20 70  yptBlock(hKey, p
28d0: 2c 20 2d 31 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20  , -1, NULL);.   
28e0: 20 69 66 20 28 21 70 42 6c 6f 63 6b 29 0a 20 20   if (!pBlock).  
28f0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
2900: 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 20 20 70 42  E_NOMEM;..    pB
2910: 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79 20 3d  lock->hReadKey =
2920: 20 30 3b 20 2f 2f 20 4f 72 69 67 69 6e 61 6c 20   0; // Original 
2930: 64 61 74 61 62 61 73 65 20 69 73 20 6e 6f 74 20  database is not 
2940: 65 6e 63 72 79 70 74 65 64 0a 20 20 20 20 73 71  encrypted.    sq
2950: 6c 69 74 65 33 50 61 67 65 72 53 65 74 43 6f 64  lite3PagerSetCod
2960: 65 63 28 73 71 6c 69 74 65 33 42 74 72 65 65 50  ec(sqlite3BtreeP
2970: 61 67 65 72 28 70 62 74 29 2c 20 73 71 6c 69 74  ager(pbt), sqlit
2980: 65 33 43 6f 64 65 63 2c 20 73 71 6c 69 74 65 33  e3Codec, sqlite3
2990: 43 6f 64 65 63 53 69 7a 65 43 68 61 6e 67 65 2c  CodecSizeChange,
29a0: 20 73 71 6c 69 74 65 33 43 6f 64 65 63 46 72 65   sqlite3CodecFre
29b0: 65 2c 20 70 42 6c 6f 63 6b 29 3b 0a 20 20 20 20  e, pBlock);.    
29c0: 2f 2f 64 62 2d 3e 61 44 62 5b 30 5d 2e 70 41 75  //db->aDb[0].pAu
29d0: 78 20 3d 20 70 42 6c 6f 63 6b 3b 0a 20 20 20 20  x = pBlock;.    
29e0: 2f 2f 64 62 2d 3e 61 44 62 5b 30 5d 2e 78 46 72  //db->aDb[0].xFr
29f0: 65 65 41 75 78 20 3d 20 44 65 73 74 72 6f 79 43  eeAux = DestroyC
2a00: 72 79 70 74 42 6c 6f 63 6b 3b 0a 20 20 7d 0a 20  ryptBlock;.  }. 
2a10: 20 65 6c 73 65 20 2f 2f 20 43 68 61 6e 67 65 20   else // Change 
2a20: 74 68 65 20 77 72 69 74 65 6b 65 79 20 66 6f 72  the writekey for
2a30: 20 61 6e 20 61 6c 72 65 61 64 79 2d 65 6e 63 72   an already-encr
2a40: 79 70 74 65 64 20 64 61 74 61 62 61 73 65 0a 20  ypted database. 
2a50: 20 7b 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 68   {.    pBlock->h
2a60: 57 72 69 74 65 4b 65 79 20 3d 20 68 4b 65 79 3b  WriteKey = hKey;
2a70: 0a 20 20 7d 0a 0a 20 20 2f 2f 20 53 74 61 72 74  .  }..  // Start
2a80: 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 0a 20   a transaction. 
2a90: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 42 74 72   rc = sqlite3Btr
2aa0: 65 65 42 65 67 69 6e 54 72 61 6e 73 28 70 62 74  eeBeginTrans(pbt
2ab0: 2c 20 31 29 3b 0a 0a 20 20 69 66 20 28 21 72 63  , 1);..  if (!rc
2ac0: 29 0a 20 20 7b 0a 20 20 20 20 2f 2f 20 52 65 77  ).  {.    // Rew
2ad0: 72 69 74 65 20 61 6c 6c 20 74 68 65 20 70 61 67  rite all the pag
2ae0: 65 73 20 69 6e 20 74 68 65 20 64 61 74 61 62 61  es in the databa
2af0: 73 65 20 75 73 69 6e 67 20 74 68 65 20 6e 65 77  se using the new
2b00: 20 65 6e 63 72 79 70 74 69 6f 6e 20 6b 65 79 0a   encryption key.
2b10: 20 20 20 20 50 67 6e 6f 20 6e 50 61 67 65 3b 0a      Pgno nPage;.
2b20: 20 20 20 20 50 67 6e 6f 20 6e 53 6b 69 70 20 3d      Pgno nSkip =
2b30: 20 50 41 47 45 52 5f 4d 4a 5f 50 47 4e 4f 28 70   PAGER_MJ_PGNO(p
2b40: 29 3b 0a 20 20 20 20 44 62 50 61 67 65 20 2a 70  );.    DbPage *p
2b50: 50 61 67 65 3b 0a 20 20 20 20 50 67 6e 6f 20 6e  Page;.    Pgno n
2b60: 3b 0a 20 20 20 20 69 6e 74 20 63 6f 75 6e 74 3b  ;.    int count;
2b70: 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 50 61 67  ..    sqlite3Pag
2b80: 65 72 50 61 67 65 63 6f 75 6e 74 28 70 2c 20 26  erPagecount(p, &
2b90: 63 6f 75 6e 74 29 3b 0a 20 20 20 20 6e 50 61 67  count);.    nPag
2ba0: 65 20 3d 20 28 50 67 6e 6f 29 63 6f 75 6e 74 3b  e = (Pgno)count;
2bb0: 0a 0a 20 20 20 20 66 6f 72 28 6e 20 3d 20 31 3b  ..    for(n = 1;
2bc0: 20 6e 20 3c 3d 20 6e 50 61 67 65 3b 20 6e 20 2b   n <= nPage; n +
2bd0: 2b 29 0a 20 20 20 20 7b 0a 20 20 20 20 20 20 69  +).    {.      i
2be0: 66 20 28 6e 20 3d 3d 20 6e 53 6b 69 70 29 20 63  f (n == nSkip) c
2bf0: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 72  ontinue;.      r
2c00: 63 20 3d 20 73 71 6c 69 74 65 33 50 61 67 65 72  c = sqlite3Pager
2c10: 47 65 74 28 70 2c 20 6e 2c 20 26 70 50 61 67 65  Get(p, n, &pPage
2c20: 29 3b 0a 20 20 20 20 20 20 69 66 28 21 72 63 29  );.      if(!rc)
2c30: 0a 20 20 20 20 20 20 7b 0a 20 20 20 20 20 20 20  .      {.       
2c40: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 50 61 67   rc = sqlite3Pag
2c50: 65 72 57 72 69 74 65 28 70 50 61 67 65 29 3b 0a  erWrite(pPage);.
2c60: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 50          sqlite3P
2c70: 61 67 65 72 55 6e 72 65 66 28 70 50 61 67 65 29  agerUnref(pPage)
2c80: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
2c90: 20 20 7d 0a 0a 20 20 2f 2f 20 49 66 20 77 65 20    }..  // If we 
2ca0: 73 75 63 63 65 65 64 65 64 2c 20 74 72 79 20 61  succeeded, try a
2cb0: 6e 64 20 63 6f 6d 6d 69 74 20 74 68 65 20 74 72  nd commit the tr
2cc0: 61 6e 73 61 63 74 69 6f 6e 0a 20 20 69 66 20 28  ansaction.  if (
2cd0: 21 72 63 29 0a 20 20 7b 0a 20 20 20 20 72 63 20  !rc).  {.    rc 
2ce0: 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65 43 6f  = sqlite3BtreeCo
2cf0: 6d 6d 69 74 28 70 62 74 29 3b 0a 20 20 7d 0a 0a  mmit(pbt);.  }..
2d00: 20 20 2f 2f 20 49 66 20 77 65 20 66 61 69 6c 65    // If we faile
2d10: 64 2c 20 72 6f 6c 6c 62 61 63 6b 0a 20 20 69 66  d, rollback.  if
2d20: 20 28 72 63 29 0a 20 20 7b 0a 20 20 20 20 73 71   (rc).  {.    sq
2d30: 6c 69 74 65 33 42 74 72 65 65 52 6f 6c 6c 62 61  lite3BtreeRollba
2d40: 63 6b 28 70 62 74 29 3b 0a 20 20 7d 0a 0a 20 20  ck(pbt);.  }..  
2d50: 2f 2f 20 49 66 20 77 65 20 73 75 63 63 65 65 64  // If we succeed
2d60: 65 64 2c 20 64 65 73 74 72 6f 79 20 61 6e 79 20  ed, destroy any 
2d70: 70 72 65 76 69 6f 75 73 20 72 65 61 64 20 6b 65  previous read ke
2d80: 79 20 74 68 69 73 20 64 61 74 61 62 61 73 65 20  y this database 
2d90: 75 73 65 64 0a 20 20 2f 2f 20 61 6e 64 20 6d 61  used.  // and ma
2da0: 6b 65 20 74 68 65 20 72 65 61 64 6b 65 79 20 65  ke the readkey e
2db0: 71 75 61 6c 20 74 6f 20 74 68 65 20 77 72 69 74  qual to the writ
2dc0: 65 6b 65 79 0a 20 20 69 66 20 28 21 72 63 29 0a  ekey.  if (!rc).
2dd0: 20 20 7b 0a 20 20 20 20 69 66 20 28 70 42 6c 6f    {.    if (pBlo
2de0: 63 6b 2d 3e 68 52 65 61 64 4b 65 79 29 0a 20 20  ck->hReadKey).  
2df0: 20 20 7b 0a 20 20 20 20 20 20 43 72 79 70 74 44    {.      CryptD
2e00: 65 73 74 72 6f 79 4b 65 79 28 70 42 6c 6f 63 6b  estroyKey(pBlock
2e10: 2d 3e 68 52 65 61 64 4b 65 79 29 3b 0a 20 20 20  ->hReadKey);.   
2e20: 20 7d 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 68   }.    pBlock->h
2e30: 52 65 61 64 4b 65 79 20 3d 20 70 42 6c 6f 63 6b  ReadKey = pBlock
2e40: 2d 3e 68 57 72 69 74 65 4b 65 79 3b 0a 20 20 7d  ->hWriteKey;.  }
2e50: 0a 20 20 2f 2f 20 57 65 20 66 61 69 6c 65 64 2e  .  // We failed.
2e60: 20 20 44 65 73 74 72 6f 79 20 74 68 65 20 6e 65    Destroy the ne
2e70: 77 20 77 72 69 74 65 6b 65 79 20 28 69 66 20 74  w writekey (if t
2e80: 68 65 72 65 20 77 61 73 20 6f 6e 65 29 20 61 6e  here was one) an
2e90: 64 20 72 65 76 65 72 74 20 69 74 20 62 61 63 6b  d revert it back
2ea0: 20 74 6f 0a 20 20 2f 2f 20 74 68 65 20 6f 72 69   to.  // the ori
2eb0: 67 69 6e 61 6c 20 72 65 61 64 6b 65 79 0a 20 20  ginal readkey.  
2ec0: 65 6c 73 65 0a 20 20 7b 0a 20 20 20 20 69 66 20  else.  {.    if 
2ed0: 28 70 42 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b  (pBlock->hWriteK
2ee0: 65 79 29 0a 20 20 20 20 7b 0a 20 20 20 20 20 20  ey).    {.      
2ef0: 43 72 79 70 74 44 65 73 74 72 6f 79 4b 65 79 28  CryptDestroyKey(
2f00: 70 42 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65  pBlock->hWriteKe
2f10: 79 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 42  y);.    }.    pB
2f20: 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65 79 20  lock->hWriteKey 
2f30: 3d 20 70 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b  = pBlock->hReadK
2f40: 65 79 3b 0a 20 20 7d 0a 0a 20 20 2f 2f 20 49 66  ey;.  }..  // If
2f50: 20 74 68 65 20 72 65 61 64 6b 65 79 20 61 6e 64   the readkey and
2f60: 20 77 72 69 74 65 6b 65 79 20 61 72 65 20 62 6f   writekey are bo
2f70: 74 68 20 65 6d 70 74 79 2c 20 74 68 65 72 65 27  th empty, there'
2f80: 73 20 6e 6f 20 6e 65 65 64 20 66 6f 72 20 61 20  s no need for a 
2f90: 63 6f 64 65 63 20 6f 6e 20 74 68 69 73 0a 20 20  codec on this.  
2fa0: 2f 2f 20 70 61 67 65 72 20 61 6e 79 6d 6f 72 65  // pager anymore
2fb0: 2e 20 20 44 65 73 74 72 6f 79 20 74 68 65 20 63  .  Destroy the c
2fc0: 72 79 70 74 20 62 6c 6f 63 6b 20 61 6e 64 20 72  rypt block and r
2fd0: 65 6d 6f 76 65 20 74 68 65 20 63 6f 64 65 63 20  emove the codec 
2fe0: 66 72 6f 6d 20 74 68 65 20 70 61 67 65 72 2e 0a  from the pager..
2ff0: 20 20 69 66 20 28 21 70 42 6c 6f 63 6b 2d 3e 68    if (!pBlock->h
3000: 52 65 61 64 4b 65 79 20 26 26 20 21 70 42 6c 6f  ReadKey && !pBlo
3010: 63 6b 2d 3e 68 57 72 69 74 65 4b 65 79 29 0a 20  ck->hWriteKey). 
3020: 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 50 61   {.    sqlite3Pa
3030: 67 65 72 53 65 74 43 6f 64 65 63 28 70 2c 20 4e  gerSetCodec(p, N
3040: 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c  ULL, NULL, NULL,
3050: 20 4e 55 4c 4c 29 3b 0a 20 20 7d 0a 0a 20 20 72   NULL);.  }..  r
3060: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 23 65 6e  eturn rc;.}..#en
3070: 64 69 66 20 2f 2f 20 53 51 4c 49 54 45 5f 48 41  dif // SQLITE_HA
3080: 53 5f 43 4f 44 45 43 0a 0a 23 65 6e 64 69 66 20  S_CODEC..#endif 
3090: 2f 2f 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 44  // SQLITE_OMIT_D
30a0: 49 53 4b 49 4f 0a                                ISKIO.