System.Data.SQLite
Hex Artifact Content
Not logged in

Artifact 9d8c1453443cb3955ba4bf09ef444e07a64fdbd3:


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 20 3d 20 4e 55 4c 4c 3b 0a   pvTemp = NULL;.
0ff0: 0a 20 20 69 66 20 28 21 70 42 6c 6f 63 6b 29 20  .  if (!pBlock) 
1000: 72 65 74 75 72 6e 20 64 61 74 61 3b 0a 20 20 69  return data;.  i
1010: 66 20 28 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79  f (pBlock->pvCry
1020: 70 74 20 3d 3d 20 4e 55 4c 4c 29 20 72 65 74 75  pt == NULL) retu
1030: 72 6e 20 4e 55 4c 4c 3b 20 2f 2f 20 54 68 69 73  rn NULL; // This
1040: 20 6f 6e 6c 79 20 68 61 70 70 65 6e 73 20 69 66   only happens if
1050: 20 43 72 65 61 74 65 43 72 79 70 74 42 6c 6f 63   CreateCryptBloc
1060: 6b 28 29 20 66 61 69 6c 65 64 20 74 6f 20 6d 61  k() failed to ma
1070: 6b 65 20 73 63 72 61 74 63 68 20 73 70 61 63 65  ke scratch space
1080: 0a 0a 20 20 73 77 69 74 63 68 28 6e 4d 6f 64 65  ..  switch(nMode
1090: 29 0a 20 20 7b 0a 20 20 63 61 73 65 20 30 3a 20  ).  {.  case 0: 
10a0: 2f 2f 20 55 6e 64 6f 20 61 20 22 63 61 73 65 20  // Undo a "case 
10b0: 37 22 20 6a 6f 75 72 6e 61 6c 20 66 69 6c 65 20  7" journal file 
10c0: 65 6e 63 72 79 70 74 69 6f 6e 0a 20 20 63 61 73  encryption.  cas
10d0: 65 20 32 3a 20 2f 2f 20 52 65 6c 6f 61 64 20 61  e 2: // Reload a
10e0: 20 70 61 67 65 0a 20 20 63 61 73 65 20 33 3a 20   page.  case 3: 
10f0: 2f 2f 20 4c 6f 61 64 20 61 20 70 61 67 65 0a 20  // Load a page. 
1100: 20 20 20 69 66 20 28 21 70 42 6c 6f 63 6b 2d 3e     if (!pBlock->
1110: 68 52 65 61 64 4b 65 79 29 20 62 72 65 61 6b 3b  hReadKey) break;
1120: 0a 0a 20 20 20 20 2f 2a 20 42 6c 6f 63 6b 20 63  ..    /* Block c
1130: 69 70 68 65 72 73 20 6f 66 74 65 6e 20 6e 65 65  iphers often nee
1140: 64 20 74 6f 20 77 72 69 74 65 20 65 78 74 72 61  d to write extra
1150: 20 70 61 64 64 69 6e 67 20 62 65 79 6f 6e 64 20   padding beyond 
1160: 74 68 65 20 0a 20 20 20 20 64 61 74 61 20 62 6c  the .    data bl
1170: 6f 63 6b 2e 20 20 57 65 20 64 6f 6e 27 74 20 68  ock.  We don't h
1180: 61 76 65 20 74 68 61 74 20 6c 75 78 75 72 79 20  ave that luxury 
1190: 66 6f 72 20 61 20 67 69 76 65 6e 20 70 61 67 65  for a given page
11a0: 20 6f 66 20 64 61 74 61 20 73 6f 0a 20 20 20 20   of data so.    
11b0: 77 65 20 6d 75 73 74 20 63 6f 70 79 20 74 68 65  we must copy the
11c0: 20 70 61 67 65 20 64 61 74 61 20 74 6f 20 61 20   page data to a 
11d0: 62 75 66 66 65 72 20 74 68 61 74 20 49 53 20 6c  buffer that IS l
11e0: 61 72 67 65 20 65 6e 6f 75 67 68 20 74 6f 20 68  arge enough to h
11f0: 6f 6c 64 0a 20 20 20 20 74 68 65 20 70 61 64 64  old.    the padd
1200: 69 6e 67 2e 20 20 57 65 20 74 68 65 6e 20 65 6e  ing.  We then en
1210: 63 72 79 70 74 20 74 68 65 20 62 6c 6f 63 6b 20  crypt the block 
1220: 61 6e 64 20 77 72 69 74 65 20 74 68 65 20 62 75  and write the bu
1230: 66 66 65 72 20 62 61 63 6b 20 74 6f 0a 20 20 20  ffer back to.   
1240: 20 74 68 65 20 70 61 67 65 20 77 69 74 68 6f 75   the page withou
1250: 74 20 74 68 65 20 75 6e 6e 65 63 65 73 73 61 72  t the unnecessar
1260: 79 20 70 61 64 64 69 6e 67 2e 0a 20 20 20 20 57  y padding..    W
1270: 65 20 6f 6e 6c 79 20 75 73 65 20 74 68 65 20 73  e only use the s
1280: 70 65 63 69 61 6c 20 62 6c 6f 63 6b 20 6f 66 20  pecial block of 
1290: 6d 65 6d 6f 72 79 20 69 66 20 69 74 73 20 61 62  memory if its ab
12a0: 73 6f 6c 75 74 65 6c 79 20 6e 65 63 65 73 73 61  solutely necessa
12b0: 72 79 2e 20 2a 2f 0a 20 20 20 20 69 66 20 28 70  ry. */.    if (p
12c0: 42 6c 6f 63 6b 2d 3e 64 77 43 72 79 70 74 53 69  Block->dwCryptSi
12d0: 7a 65 20 21 3d 20 70 42 6c 6f 63 6b 2d 3e 64 77  ze != pBlock->dw
12e0: 50 61 67 65 53 69 7a 65 29 0a 20 20 20 20 7b 0a  PageSize).    {.
12f0: 20 20 20 20 20 20 43 6f 70 79 4d 65 6d 6f 72 79        CopyMemory
1300: 28 28 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b  (((LPBYTE)pBlock
1310: 2d 3e 70 76 43 72 79 70 74 29 20 2b 20 43 52 59  ->pvCrypt) + CRY
1320: 50 54 5f 4f 46 46 53 45 54 2c 20 64 61 74 61 2c  PT_OFFSET, data,
1330: 20 70 42 6c 6f 63 6b 2d 3e 64 77 50 61 67 65 53   pBlock->dwPageS
1340: 69 7a 65 29 3b 0a 20 20 20 20 20 20 70 76 54 65  ize);.      pvTe
1350: 6d 70 20 3d 20 64 61 74 61 3b 0a 20 20 20 20 20  mp = data;.     
1360: 20 64 61 74 61 20 3d 20 28 28 4c 50 42 59 54 45   data = ((LPBYTE
1370: 29 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70 74  )pBlock->pvCrypt
1380: 29 20 2b 20 43 52 59 50 54 5f 4f 46 46 53 45 54  ) + CRYPT_OFFSET
1390: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 64 77 50  ;.    }..    dwP
13a0: 61 67 65 53 69 7a 65 20 3d 20 70 42 6c 6f 63 6b  ageSize = pBlock
13b0: 2d 3e 64 77 43 72 79 70 74 53 69 7a 65 3b 0a 20  ->dwCryptSize;. 
13c0: 20 20 20 43 72 79 70 74 44 65 63 72 79 70 74 28     CryptDecrypt(
13d0: 70 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79  pBlock->hReadKey
13e0: 2c 20 30 2c 20 54 52 55 45 2c 20 30 2c 20 28 4c  , 0, TRUE, 0, (L
13f0: 50 42 59 54 45 29 64 61 74 61 2c 20 26 64 77 50  PBYTE)data, &dwP
1400: 61 67 65 53 69 7a 65 29 3b 0a 0a 20 20 20 20 2f  ageSize);..    /
1410: 2f 20 49 66 20 74 68 65 20 65 6e 63 72 79 70 74  / If the encrypt
1420: 69 6f 6e 20 61 6c 67 6f 72 69 74 68 6d 20 72 65  ion algorithm re
1430: 71 75 69 72 65 64 20 65 78 74 72 61 20 70 61 64  quired extra pad
1440: 64 69 6e 67 20 61 6e 64 20 77 65 20 77 65 72 65  ding and we were
1450: 20 66 6f 72 63 65 64 20 74 6f 20 65 6e 63 72 79   forced to encry
1460: 70 74 20 6f 72 0a 20 20 20 20 2f 2f 20 64 65 63  pt or.    // dec
1470: 72 79 70 74 20 61 20 63 6f 70 79 20 6f 66 20 74  rypt a copy of t
1480: 68 65 20 70 61 67 65 20 64 61 74 61 20 74 6f 20  he page data to 
1490: 61 20 74 65 6d 70 20 62 75 66 66 65 72 2c 20 74  a temp buffer, t
14a0: 68 65 6e 20 77 72 69 74 65 20 74 68 65 20 63 6f  hen write the co
14b0: 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 74 65  ntents of the te
14c0: 6d 70 0a 20 20 20 20 2f 2f 20 62 75 66 66 65 72  mp.    // buffer
14d0: 20 62 61 63 6b 20 74 6f 20 74 68 65 20 70 61 67   back to the pag
14e0: 65 20 64 61 74 61 20 6d 69 6e 75 73 20 61 6e 79  e data minus any
14f0: 20 70 61 64 64 69 6e 67 20 61 70 70 6c 69 65 64   padding applied
1500: 2e 0a 20 20 20 20 69 66 20 28 70 42 6c 6f 63 6b  ..    if (pBlock
1510: 2d 3e 64 77 43 72 79 70 74 53 69 7a 65 20 21 3d  ->dwCryptSize !=
1520: 20 70 42 6c 6f 63 6b 2d 3e 64 77 50 61 67 65 53   pBlock->dwPageS
1530: 69 7a 65 29 0a 20 20 20 20 7b 0a 20 20 20 20 20  ize).    {.     
1540: 20 43 6f 70 79 4d 65 6d 6f 72 79 28 70 76 54 65   CopyMemory(pvTe
1550: 6d 70 2c 20 64 61 74 61 2c 20 70 42 6c 6f 63 6b  mp, data, pBlock
1560: 2d 3e 64 77 50 61 67 65 53 69 7a 65 29 3b 0a 20  ->dwPageSize);. 
1570: 20 20 20 20 20 64 61 74 61 20 3d 20 70 76 54 65       data = pvTe
1580: 6d 70 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62 72  mp;.    }.    br
1590: 65 61 6b 3b 0a 20 20 63 61 73 65 20 36 3a 20 2f  eak;.  case 6: /
15a0: 2f 20 45 6e 63 72 79 70 74 20 61 20 70 61 67 65  / Encrypt a page
15b0: 20 66 6f 72 20 74 68 65 20 6d 61 69 6e 20 64 61   for the main da
15c0: 74 61 62 61 73 65 20 66 69 6c 65 0a 20 20 20 20  tabase file.    
15d0: 69 66 20 28 21 70 42 6c 6f 63 6b 2d 3e 68 57 72  if (!pBlock->hWr
15e0: 69 74 65 4b 65 79 29 20 62 72 65 61 6b 3b 0a 0a  iteKey) break;..
15f0: 20 20 20 20 43 6f 70 79 4d 65 6d 6f 72 79 28 28      CopyMemory((
1600: 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b 2d 3e  (LPBYTE)pBlock->
1610: 70 76 43 72 79 70 74 29 20 2b 20 43 52 59 50 54  pvCrypt) + CRYPT
1620: 5f 4f 46 46 53 45 54 2c 20 64 61 74 61 2c 20 70  _OFFSET, data, p
1630: 42 6c 6f 63 6b 2d 3e 64 77 50 61 67 65 53 69 7a  Block->dwPageSiz
1640: 65 29 3b 0a 20 20 20 20 64 61 74 61 20 3d 20 28  e);.    data = (
1650: 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b 2d 3e  (LPBYTE)pBlock->
1660: 70 76 43 72 79 70 74 29 20 2b 20 43 52 59 50 54  pvCrypt) + CRYPT
1670: 5f 4f 46 46 53 45 54 3b 0a 0a 20 20 20 20 64 77  _OFFSET;..    dw
1680: 50 61 67 65 53 69 7a 65 20 3d 20 70 42 6c 6f 63  PageSize = pBloc
1690: 6b 2d 3e 64 77 50 61 67 65 53 69 7a 65 3b 0a 20  k->dwPageSize;. 
16a0: 20 20 20 43 72 79 70 74 45 6e 63 72 79 70 74 28     CryptEncrypt(
16b0: 70 42 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65  pBlock->hWriteKe
16c0: 79 2c 20 30 2c 20 54 52 55 45 2c 20 30 2c 20 28  y, 0, TRUE, 0, (
16d0: 28 4c 50 42 59 54 45 29 70 42 6c 6f 63 6b 2d 3e  (LPBYTE)pBlock->
16e0: 70 76 43 72 79 70 74 29 20 2b 20 43 52 59 50 54  pvCrypt) + CRYPT
16f0: 5f 4f 46 46 53 45 54 2c 20 26 64 77 50 61 67 65  _OFFSET, &dwPage
1700: 53 69 7a 65 2c 20 70 42 6c 6f 63 6b 2d 3e 64 77  Size, pBlock->dw
1710: 43 72 79 70 74 53 69 7a 65 29 3b 0a 20 20 20 20  CryptSize);.    
1720: 62 72 65 61 6b 3b 0a 20 20 63 61 73 65 20 37 3a  break;.  case 7:
1730: 20 2f 2f 20 45 6e 63 72 79 70 74 20 61 20 70 61   // Encrypt a pa
1740: 67 65 20 66 6f 72 20 74 68 65 20 6a 6f 75 72 6e  ge for the journ
1750: 61 6c 20 66 69 6c 65 0a 20 20 20 20 2f 2a 20 55  al file.    /* U
1760: 6e 64 65 72 20 6e 6f 72 6d 61 6c 20 63 69 72 63  nder normal circ
1770: 75 6d 73 74 61 6e 63 65 73 2c 20 74 68 65 20 72  umstances, the r
1780: 65 61 64 6b 65 79 20 69 73 20 74 68 65 20 73 61  eadkey is the sa
1790: 6d 65 20 61 73 20 74 68 65 20 77 72 69 74 65 6b  me as the writek
17a0: 65 79 2e 20 20 48 6f 77 65 76 65 72 2c 0a 20 20  ey.  However,.  
17b0: 20 20 77 68 65 6e 20 74 68 65 20 64 61 74 61 62    when the datab
17c0: 61 73 65 20 69 73 20 62 65 69 6e 67 20 72 65 6b  ase is being rek
17d0: 65 79 65 64 2c 20 74 68 65 20 72 65 61 64 6b 65  eyed, the readke
17e0: 79 20 69 73 20 6e 6f 74 20 74 68 65 20 73 61 6d  y is not the sam
17f0: 65 20 61 73 20 74 68 65 20 77 72 69 74 65 6b 65  e as the writeke
1800: 79 2e 0a 20 20 20 20 54 68 65 20 72 6f 6c 6c 62  y..    The rollb
1810: 61 63 6b 20 6a 6f 75 72 6e 61 6c 20 6d 75 73 74  ack journal must
1820: 20 62 65 20 77 72 69 74 74 65 6e 20 75 73 69 6e   be written usin
1830: 67 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 6b  g the original k
1840: 65 79 20 66 6f 72 20 74 68 65 0a 20 20 20 20 64  ey for the.    d
1850: 61 74 61 62 61 73 65 20 66 69 6c 65 20 62 65 63  atabase file bec
1860: 61 75 73 65 20 69 74 20 69 73 2c 20 62 79 20 6e  ause it is, by n
1870: 61 74 75 72 65 2c 20 61 20 72 6f 6c 6c 62 61 63  ature, a rollbac
1880: 6b 20 6a 6f 75 72 6e 61 6c 2e 0a 20 20 20 20 54  k journal..    T
1890: 68 65 72 65 66 6f 72 65 2c 20 66 6f 72 20 63 61  herefore, for ca
18a0: 73 65 20 37 2c 20 77 68 65 6e 20 74 68 65 20 72  se 7, when the r
18b0: 6f 6c 6c 62 61 63 6b 20 69 73 20 62 65 69 6e 67  ollback is being
18c0: 20 77 72 69 74 74 65 6e 2c 20 61 6c 77 61 79 73   written, always
18d0: 20 65 6e 63 72 79 70 74 20 75 73 69 6e 67 0a 20   encrypt using. 
18e0: 20 20 20 74 68 65 20 64 61 74 61 62 61 73 65 27     the database'
18f0: 73 20 72 65 61 64 6b 65 79 2c 20 77 68 69 63 68  s readkey, which
1900: 20 69 73 20 67 75 61 72 61 6e 74 65 65 64 20 74   is guaranteed t
1910: 6f 20 62 65 20 74 68 65 20 73 61 6d 65 20 6b 65  o be the same ke
1920: 79 20 74 68 61 74 20 77 61 73 20 75 73 65 64 20  y that was used 
1930: 74 6f 0a 20 20 20 20 72 65 61 64 20 74 68 65 20  to.    read the 
1940: 6f 72 69 67 69 6e 61 6c 20 64 61 74 61 2e 0a 20  original data.. 
1950: 20 20 20 2a 2f 0a 20 20 20 20 69 66 20 28 21 70     */.    if (!p
1960: 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79 29  Block->hReadKey)
1970: 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20 43 6f 70   break;..    Cop
1980: 79 4d 65 6d 6f 72 79 28 28 28 4c 50 42 59 54 45  yMemory(((LPBYTE
1990: 29 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70 74  )pBlock->pvCrypt
19a0: 29 20 2b 20 43 52 59 50 54 5f 4f 46 46 53 45 54  ) + CRYPT_OFFSET
19b0: 2c 20 64 61 74 61 2c 20 70 42 6c 6f 63 6b 2d 3e  , data, pBlock->
19c0: 64 77 50 61 67 65 53 69 7a 65 29 3b 0a 20 20 20  dwPageSize);.   
19d0: 20 64 61 74 61 20 3d 20 28 28 4c 50 42 59 54 45   data = ((LPBYTE
19e0: 29 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70 74  )pBlock->pvCrypt
19f0: 29 20 2b 20 43 52 59 50 54 5f 4f 46 46 53 45 54  ) + CRYPT_OFFSET
1a00: 3b 0a 0a 20 20 20 20 64 77 50 61 67 65 53 69 7a  ;..    dwPageSiz
1a10: 65 20 3d 20 70 42 6c 6f 63 6b 2d 3e 64 77 50 61  e = pBlock->dwPa
1a20: 67 65 53 69 7a 65 3b 0a 20 20 20 20 43 72 79 70  geSize;.    Cryp
1a30: 74 45 6e 63 72 79 70 74 28 70 42 6c 6f 63 6b 2d  tEncrypt(pBlock-
1a40: 3e 68 52 65 61 64 4b 65 79 2c 20 30 2c 20 54 52  >hReadKey, 0, TR
1a50: 55 45 2c 20 30 2c 20 28 28 4c 50 42 59 54 45 29  UE, 0, ((LPBYTE)
1a60: 70 42 6c 6f 63 6b 2d 3e 70 76 43 72 79 70 74 29  pBlock->pvCrypt)
1a70: 20 2b 20 43 52 59 50 54 5f 4f 46 46 53 45 54 2c   + CRYPT_OFFSET,
1a80: 20 26 64 77 50 61 67 65 53 69 7a 65 2c 20 70 42   &dwPageSize, pB
1a90: 6c 6f 63 6b 2d 3e 64 77 43 72 79 70 74 53 69 7a  lock->dwCryptSiz
1aa0: 65 29 3b 0a 20 20 20 20 62 72 65 61 6b 3b 0a 20  e);.    break;. 
1ab0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 64 61 74   }..  return dat
1ac0: 61 3b 0a 7d 0a 0a 2f 2f 20 44 65 72 69 76 65 20  a;.}..// Derive 
1ad0: 61 6e 20 65 6e 63 72 79 70 74 69 6f 6e 20 6b 65  an encryption ke
1ae0: 79 20 66 72 6f 6d 20 61 20 75 73 65 72 2d 73 75  y from a user-su
1af0: 70 70 6c 69 65 64 20 62 75 66 66 65 72 0a 73 74  pplied buffer.st
1b00: 61 74 69 63 20 48 43 52 59 50 54 4b 45 59 20 44  atic HCRYPTKEY D
1b10: 65 72 69 76 65 4b 65 79 28 63 6f 6e 73 74 20 76  eriveKey(const v
1b20: 6f 69 64 20 2a 70 4b 65 79 2c 20 69 6e 74 20 6e  oid *pKey, int n
1b30: 4b 65 79 4c 65 6e 29 0a 7b 0a 20 20 48 43 52 59  KeyLen).{.  HCRY
1b40: 50 54 48 41 53 48 20 68 48 61 73 68 20 3d 20 30  PTHASH hHash = 0
1b50: 3b 0a 20 20 48 43 52 59 50 54 4b 45 59 20 20 68  ;.  HCRYPTKEY  h
1b60: 4b 65 79 3b 0a 0a 20 20 69 66 20 28 21 70 4b 65  Key;..  if (!pKe
1b70: 79 20 7c 7c 20 21 6e 4b 65 79 4c 65 6e 29 20 72  y || !nKeyLen) r
1b80: 65 74 75 72 6e 20 30 3b 0a 0a 20 20 69 66 20 28  eturn 0;..  if (
1b90: 21 49 6e 69 74 69 61 6c 69 7a 65 50 72 6f 76 69  !InitializeProvi
1ba0: 64 65 72 28 29 29 0a 20 20 7b 0a 20 20 20 20 72  der()).  {.    r
1bb0: 65 74 75 72 6e 20 4d 41 58 44 57 4f 52 44 3b 0a  eturn MAXDWORD;.
1bc0: 20 20 7d 0a 0a 20 20 69 66 20 28 43 72 79 70 74    }..  if (Crypt
1bd0: 43 72 65 61 74 65 48 61 73 68 28 67 5f 68 50 72  CreateHash(g_hPr
1be0: 6f 76 69 64 65 72 2c 20 43 41 4c 47 5f 53 48 41  ovider, CALG_SHA
1bf0: 31 2c 20 30 2c 20 30 2c 20 26 68 48 61 73 68 29  1, 0, 0, &hHash)
1c00: 29 0a 20 20 7b 0a 20 20 20 20 69 66 20 28 43 72  ).  {.    if (Cr
1c10: 79 70 74 48 61 73 68 44 61 74 61 28 68 48 61 73  yptHashData(hHas
1c20: 68 2c 20 28 4c 50 42 59 54 45 29 70 4b 65 79 2c  h, (LPBYTE)pKey,
1c30: 20 6e 4b 65 79 4c 65 6e 2c 20 30 29 29 0a 20 20   nKeyLen, 0)).  
1c40: 20 20 7b 0a 20 20 20 20 20 20 43 72 79 70 74 44    {.      CryptD
1c50: 65 72 69 76 65 4b 65 79 28 67 5f 68 50 72 6f 76  eriveKey(g_hProv
1c60: 69 64 65 72 2c 20 43 41 4c 47 5f 52 43 34 2c 20  ider, CALG_RC4, 
1c70: 68 48 61 73 68 2c 20 30 2c 20 26 68 4b 65 79 29  hHash, 0, &hKey)
1c80: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 43 72 79 70  ;.    }.    Cryp
1c90: 74 44 65 73 74 72 6f 79 48 61 73 68 28 68 48 61  tDestroyHash(hHa
1ca0: 73 68 29 3b 0a 20 20 7d 20 20 0a 20 20 72 65 74  sh);.  }  .  ret
1cb0: 75 72 6e 20 68 4b 65 79 3b 0a 7d 0a 0a 2f 2f 20  urn hKey;.}..// 
1cc0: 43 61 6c 6c 65 64 20 62 79 20 73 71 6c 69 74 65  Called by sqlite
1cd0: 20 61 6e 64 20 73 71 6c 69 74 65 33 5f 6b 65 79   and sqlite3_key
1ce0: 5f 69 6e 74 65 72 6f 70 20 74 6f 20 61 74 74 61  _interop to atta
1cf0: 63 68 20 61 20 6b 65 79 20 74 6f 20 61 20 64 61  ch a key to a da
1d00: 74 61 62 61 73 65 2e 0a 69 6e 74 20 73 71 6c 69  tabase..int sqli
1d10: 74 65 33 43 6f 64 65 63 41 74 74 61 63 68 28 73  te3CodecAttach(s
1d20: 71 6c 69 74 65 33 20 2a 64 62 2c 20 69 6e 74 20  qlite3 *db, int 
1d30: 6e 44 62 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20  nDb, const void 
1d40: 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 4c  *pKey, int nKeyL
1d50: 65 6e 29 0a 7b 0a 20 20 69 6e 74 20 72 63 20 3d  en).{.  int rc =
1d60: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
1d70: 20 48 43 52 59 50 54 4b 45 59 20 68 4b 65 79 20   HCRYPTKEY hKey 
1d80: 3d 20 30 3b 0a 0a 20 20 2f 2f 20 4e 6f 20 6b 65  = 0;..  // No ke
1d90: 79 20 73 70 65 63 69 66 69 65 64 2c 20 63 6f 75  y specified, cou
1da0: 6c 64 20 6d 65 61 6e 20 65 69 74 68 65 72 20 75  ld mean either u
1db0: 73 65 20 74 68 65 20 6d 61 69 6e 20 64 62 27 73  se the main db's
1dc0: 20 65 6e 63 72 79 70 74 69 6f 6e 20 6f 72 20 6e   encryption or n
1dd0: 6f 20 65 6e 63 72 79 70 74 69 6f 6e 0a 20 20 69  o encryption.  i
1de0: 66 20 28 21 70 4b 65 79 20 7c 7c 20 21 6e 4b 65  f (!pKey || !nKe
1df0: 79 4c 65 6e 29 0a 20 20 7b 0a 20 20 20 20 69 66  yLen).  {.    if
1e00: 20 28 21 6e 44 62 29 0a 20 20 20 20 7b 0a 20 20   (!nDb).    {.  
1e10: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
1e20: 45 5f 4f 4b 3b 20 2f 2f 20 4d 61 69 6e 20 64 61  E_OK; // Main da
1e30: 74 61 62 61 73 65 2c 20 6e 6f 20 6b 65 79 20 73  tabase, no key s
1e40: 70 65 63 69 66 69 65 64 20 73 6f 20 6e 6f 74 20  pecified so not 
1e50: 65 6e 63 72 79 70 74 65 64 0a 20 20 20 20 7d 0a  encrypted.    }.
1e60: 20 20 20 20 65 6c 73 65 20 2f 2f 20 41 74 74 61      else // Atta
1e70: 63 68 65 64 20 64 61 74 61 62 61 73 65 2c 20 75  ched database, u
1e80: 73 65 20 74 68 65 20 6d 61 69 6e 20 64 61 74 61  se the main data
1e90: 62 61 73 65 27 73 20 6b 65 79 0a 20 20 20 20 7b  base's key.    {
1ea0: 0a 20 20 20 20 20 20 2f 2f 20 47 65 74 20 74 68  .      // Get th
1eb0: 65 20 65 6e 63 72 79 70 74 69 6f 6e 20 62 6c 6f  e encryption blo
1ec0: 63 6b 20 66 6f 72 20 74 68 65 20 6d 61 69 6e 20  ck for the main 
1ed0: 64 61 74 61 62 61 73 65 20 61 6e 64 20 61 74 74  database and att
1ee0: 65 6d 70 74 20 74 6f 20 64 75 70 6c 69 63 61 74  empt to duplicat
1ef0: 65 20 74 68 65 20 6b 65 79 0a 20 20 20 20 20 20  e the key.      
1f00: 2f 2f 20 66 6f 72 20 75 73 65 20 62 79 20 74 68  // for use by th
1f10: 65 20 61 74 74 61 63 68 65 64 20 64 61 74 61 62  e attached datab
1f20: 61 73 65 0a 20 20 20 20 20 20 50 61 67 65 72 20  ase.      Pager 
1f30: 2a 70 20 3d 20 73 71 6c 69 74 65 33 42 74 72 65  *p = sqlite3Btre
1f40: 65 50 61 67 65 72 28 64 62 2d 3e 61 44 62 5b 30  ePager(db->aDb[0
1f50: 5d 2e 70 42 74 29 3b 0a 20 20 20 20 20 20 4c 50  ].pBt);.      LP
1f60: 43 52 59 50 54 42 4c 4f 43 4b 20 70 42 6c 6f 63  CRYPTBLOCK pBloc
1f70: 6b 20 3d 20 28 4c 50 43 52 59 50 54 42 4c 4f 43  k = (LPCRYPTBLOC
1f80: 4b 29 73 71 6c 69 74 65 33 70 61 67 65 72 5f 67  K)sqlite3pager_g
1f90: 65 74 5f 63 6f 64 65 63 61 72 67 28 70 29 3b 0a  et_codecarg(p);.
1fa0: 0a 20 20 20 20 20 20 69 66 20 28 21 70 42 6c 6f  .      if (!pBlo
1fb0: 63 6b 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ck) return SQLIT
1fc0: 45 5f 4f 4b 3b 20 2f 2f 20 4d 61 69 6e 20 64 61  E_OK; // Main da
1fd0: 74 61 62 61 73 65 20 69 73 20 6e 6f 74 20 65 6e  tabase is not en
1fe0: 63 72 79 70 74 65 64 20 73 6f 20 6e 65 69 74 68  crypted so neith
1ff0: 65 72 20 77 69 6c 6c 20 62 65 20 61 6e 79 20 61  er will be any a
2000: 74 74 61 63 68 65 64 20 64 61 74 61 62 61 73 65  ttached database
2010: 0a 20 20 20 20 20 20 69 66 20 28 21 70 42 6c 6f  .      if (!pBlo
2020: 63 6b 2d 3e 68 52 65 61 64 4b 65 79 29 20 72 65  ck->hReadKey) re
2030: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 20  turn SQLITE_OK; 
2040: 2f 2f 20 4e 6f 74 20 65 6e 63 72 79 70 74 65 64  // Not encrypted
2050: 0a 0a 20 20 20 20 20 20 69 66 20 28 21 43 72 79  ..      if (!Cry
2060: 70 74 44 75 70 6c 69 63 61 74 65 4b 65 79 28 70  ptDuplicateKey(p
2070: 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79 2c  Block->hReadKey,
2080: 20 4e 55 4c 4c 2c 20 30 2c 20 26 68 4b 65 79 29   NULL, 0, &hKey)
2090: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ).        return
20a0: 20 72 63 3b 20 2f 2f 20 55 6e 61 62 6c 65 20 74   rc; // Unable t
20b0: 6f 20 64 75 70 6c 69 63 61 74 65 20 74 68 65 20  o duplicate the 
20c0: 6b 65 79 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  key.    }.  }.  
20d0: 65 6c 73 65 20 2f 2f 20 55 73 65 72 2d 73 75 70  else // User-sup
20e0: 70 6c 69 65 64 20 70 61 73 73 70 68 72 61 73 65  plied passphrase
20f0: 2c 20 73 6f 20 63 72 65 61 74 65 20 61 20 63 72  , so create a cr
2100: 79 70 74 6f 67 72 61 70 68 69 63 20 6b 65 79 20  yptographic key 
2110: 6f 75 74 20 6f 66 20 69 74 0a 20 20 7b 0a 20 20  out of it.  {.  
2120: 20 20 68 4b 65 79 20 3d 20 44 65 72 69 76 65 4b    hKey = DeriveK
2130: 65 79 28 70 4b 65 79 2c 20 6e 4b 65 79 4c 65 6e  ey(pKey, nKeyLen
2140: 29 3b 0a 20 20 20 20 69 66 20 28 68 4b 65 79 20  );.    if (hKey 
2150: 3d 3d 20 4d 41 58 44 57 4f 52 44 29 0a 20 20 20  == MAXDWORD).   
2160: 20 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33   {.      sqlite3
2170: 45 72 72 6f 72 28 64 62 2c 20 72 63 2c 20 53 51  Error(db, rc, SQ
2180: 4c 49 54 45 43 52 59 50 54 45 52 52 4f 52 5f 50  LITECRYPTERROR_P
2190: 52 4f 56 49 44 45 52 29 3b 0a 20 20 20 20 20 20  ROVIDER);.      
21a0: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
21b0: 0a 20 20 7d 0a 0a 20 20 2f 2f 20 43 72 65 61 74  .  }..  // Creat
21c0: 65 20 61 20 6e 65 77 20 65 6e 63 72 79 70 74 69  e a new encrypti
21d0: 6f 6e 20 62 6c 6f 63 6b 20 61 6e 64 20 61 73 73  on block and ass
21e0: 69 67 6e 20 74 68 65 20 63 6f 64 65 63 20 74 6f  ign the codec to
21f0: 20 74 68 65 20 6e 65 77 20 61 74 74 61 63 68 65   the new attache
2200: 64 20 64 61 74 61 62 61 73 65 0a 20 20 69 66 20  d database.  if 
2210: 28 68 4b 65 79 29 0a 20 20 7b 0a 20 20 20 20 50  (hKey).  {.    P
2220: 61 67 65 72 20 2a 70 20 3d 20 73 71 6c 69 74 65  ager *p = sqlite
2230: 33 42 74 72 65 65 50 61 67 65 72 28 64 62 2d 3e  3BtreePager(db->
2240: 61 44 62 5b 6e 44 62 5d 2e 70 42 74 29 3b 0a 20  aDb[nDb].pBt);. 
2250: 20 20 20 4c 50 43 52 59 50 54 42 4c 4f 43 4b 20     LPCRYPTBLOCK 
2260: 70 42 6c 6f 63 6b 20 3d 20 43 72 65 61 74 65 43  pBlock = CreateC
2270: 72 79 70 74 42 6c 6f 63 6b 28 68 4b 65 79 2c 20  ryptBlock(hKey, 
2280: 70 2c 20 2d 31 2c 20 4e 55 4c 4c 29 3b 0a 20 20  p, -1, NULL);.  
2290: 20 20 69 66 20 28 21 70 42 6c 6f 63 6b 29 20 72    if (!pBlock) r
22a0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
22b0: 45 4d 3b 0a 0a 20 20 20 20 73 71 6c 69 74 65 33  EM;..    sqlite3
22c0: 50 61 67 65 72 53 65 74 43 6f 64 65 63 28 70 2c  PagerSetCodec(p,
22d0: 20 73 71 6c 69 74 65 33 43 6f 64 65 63 2c 20 73   sqlite3Codec, s
22e0: 71 6c 69 74 65 33 43 6f 64 65 63 53 69 7a 65 43  qlite3CodecSizeC
22f0: 68 61 6e 67 65 2c 20 73 71 6c 69 74 65 33 43 6f  hange, sqlite3Co
2300: 64 65 63 46 72 65 65 2c 20 70 42 6c 6f 63 6b 29  decFree, pBlock)
2310: 3b 0a 20 20 20 20 2f 2f 64 62 2d 3e 61 44 62 5b  ;.    //db->aDb[
2320: 6e 44 62 5d 2e 70 41 75 78 20 3d 20 70 42 6c 6f  nDb].pAux = pBlo
2330: 63 6b 3b 0a 20 20 20 20 2f 2f 64 62 2d 3e 61 44  ck;.    //db->aD
2340: 62 5b 6e 44 62 5d 2e 78 46 72 65 65 41 75 78 20  b[nDb].xFreeAux 
2350: 3d 20 44 65 73 74 72 6f 79 43 72 79 70 74 42 6c  = DestroyCryptBl
2360: 6f 63 6b 3b 0a 0a 20 20 20 20 72 63 20 3d 20 53  ock;..    rc = S
2370: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20 20  QLITE_OK;.  }.  
2380: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2f  return rc;.}..//
2390: 20 4f 6e 63 65 20 61 20 70 61 73 73 77 6f 72 64   Once a password
23a0: 20 68 61 73 20 62 65 65 6e 20 73 75 70 70 6c 69   has been suppli
23b0: 65 64 20 61 6e 64 20 61 20 6b 65 79 20 63 72 65  ed and a key cre
23c0: 61 74 65 64 2c 20 77 65 20 64 6f 6e 27 74 20 6b  ated, we don't k
23d0: 65 65 70 20 74 68 65 20 0a 2f 2f 20 6f 72 69 67  eep the .// orig
23e0: 69 6e 61 6c 20 70 61 73 73 77 6f 72 64 20 66 6f  inal password fo
23f0: 72 20 73 65 63 75 72 69 74 79 20 70 75 72 70 6f  r security purpo
2400: 73 65 73 2e 20 20 54 68 65 72 65 66 6f 72 65 20  ses.  Therefore 
2410: 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 0a 76 6f 69  return NULL..voi
2420: 64 20 73 71 6c 69 74 65 33 43 6f 64 65 63 47 65  d sqlite3CodecGe
2430: 74 4b 65 79 28 73 71 6c 69 74 65 33 20 2a 64 62  tKey(sqlite3 *db
2440: 2c 20 69 6e 74 20 6e 44 62 2c 20 76 6f 69 64 20  , int nDb, void 
2450: 2a 2a 70 70 4b 65 79 2c 20 69 6e 74 20 2a 70 6e  **ppKey, int *pn
2460: 4b 65 79 4c 65 6e 29 0a 7b 0a 20 20 42 74 72 65  KeyLen).{.  Btre
2470: 65 20 2a 70 62 74 20 3d 20 64 62 2d 3e 61 44 62  e *pbt = db->aDb
2480: 5b 30 5d 2e 70 42 74 3b 0a 20 20 50 61 67 65 72  [0].pBt;.  Pager
2490: 20 2a 70 20 3d 20 73 71 6c 69 74 65 33 42 74 72   *p = sqlite3Btr
24a0: 65 65 50 61 67 65 72 28 70 62 74 29 3b 0a 20 20  eePager(pbt);.  
24b0: 4c 50 43 52 59 50 54 42 4c 4f 43 4b 20 70 42 6c  LPCRYPTBLOCK pBl
24c0: 6f 63 6b 20 3d 20 28 4c 50 43 52 59 50 54 42 4c  ock = (LPCRYPTBL
24d0: 4f 43 4b 29 73 71 6c 69 74 65 33 70 61 67 65 72  OCK)sqlite3pager
24e0: 5f 67 65 74 5f 63 6f 64 65 63 61 72 67 28 70 29  _get_codecarg(p)
24f0: 3b 0a 0a 20 20 69 66 20 28 70 70 4b 65 79 29 20  ;..  if (ppKey) 
2500: 2a 70 70 4b 65 79 20 3d 20 30 3b 0a 20 20 69 66  *ppKey = 0;.  if
2510: 20 28 70 6e 4b 65 79 4c 65 6e 20 26 26 20 70 42   (pnKeyLen && pB
2520: 6c 6f 63 6b 29 20 2a 70 6e 4b 65 79 4c 65 6e 20  lock) *pnKeyLen 
2530: 3d 20 31 3b 0a 7d 0a 0a 2f 2f 20 57 65 20 64 6f  = 1;.}..// We do
2540: 20 6e 6f 74 20 61 74 74 61 63 68 20 74 68 69 73   not attach this
2550: 20 6b 65 79 20 74 6f 20 74 68 65 20 74 65 6d 70   key to the temp
2560: 20 73 74 6f 72 65 2c 20 6f 6e 6c 79 20 74 68 65   store, only the
2570: 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65 2e 0a   main database..
2580: 53 51 4c 49 54 45 5f 41 50 49 20 69 6e 74 20 73  SQLITE_API int s
2590: 71 6c 69 74 65 33 5f 6b 65 79 28 73 71 6c 69 74  qlite3_key(sqlit
25a0: 65 33 20 2a 64 62 2c 20 63 6f 6e 73 74 20 75 6e  e3 *db, const un
25b0: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 70 4b 65  signed char *pKe
25c0: 79 2c 20 69 6e 74 20 6e 4b 65 79 53 69 7a 65 29  y, int nKeySize)
25d0: 0a 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  .{.  return sqli
25e0: 74 65 33 43 6f 64 65 63 41 74 74 61 63 68 28 64  te3CodecAttach(d
25f0: 62 2c 20 30 2c 20 70 4b 65 79 2c 20 6e 4b 65 79  b, 0, pKey, nKey
2600: 53 69 7a 65 29 3b 0a 7d 0a 0a 2f 2f 20 43 68 61  Size);.}..// Cha
2610: 6e 67 65 73 20 74 68 65 20 65 6e 63 72 79 70 74  nges the encrypt
2620: 69 6f 6e 20 6b 65 79 20 66 6f 72 20 61 6e 20 65  ion key for an e
2630: 78 69 73 74 69 6e 67 20 64 61 74 61 62 61 73 65  xisting database
2640: 2e 0a 53 51 4c 49 54 45 5f 41 50 49 20 69 6e 74  ..SQLITE_API int
2650: 20 73 71 6c 69 74 65 33 5f 72 65 6b 65 79 28 73   sqlite3_rekey(s
2660: 71 6c 69 74 65 33 20 2a 64 62 2c 20 63 6f 6e 73  qlite3 *db, cons
2670: 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20  t unsigned char 
2680: 2a 70 4b 65 79 2c 20 69 6e 74 20 6e 4b 65 79 53  *pKey, int nKeyS
2690: 69 7a 65 29 0a 7b 0a 20 20 42 74 72 65 65 20 2a  ize).{.  Btree *
26a0: 70 62 74 20 3d 20 64 62 2d 3e 61 44 62 5b 30 5d  pbt = db->aDb[0]
26b0: 2e 70 42 74 3b 0a 20 20 50 61 67 65 72 20 2a 70  .pBt;.  Pager *p
26c0: 20 3d 20 73 71 6c 69 74 65 33 42 74 72 65 65 50   = sqlite3BtreeP
26d0: 61 67 65 72 28 70 62 74 29 3b 0a 20 20 4c 50 43  ager(pbt);.  LPC
26e0: 52 59 50 54 42 4c 4f 43 4b 20 70 42 6c 6f 63 6b  RYPTBLOCK pBlock
26f0: 20 3d 20 28 4c 50 43 52 59 50 54 42 4c 4f 43 4b   = (LPCRYPTBLOCK
2700: 29 73 71 6c 69 74 65 33 70 61 67 65 72 5f 67 65  )sqlite3pager_ge
2710: 74 5f 63 6f 64 65 63 61 72 67 28 70 29 3b 0a 20  t_codecarg(p);. 
2720: 20 48 43 52 59 50 54 4b 45 59 20 68 4b 65 79 20   HCRYPTKEY hKey 
2730: 3d 20 44 65 72 69 76 65 4b 65 79 28 70 4b 65 79  = DeriveKey(pKey
2740: 2c 20 6e 4b 65 79 53 69 7a 65 29 3b 0a 20 20 69  , nKeySize);.  i
2750: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45  nt rc = SQLITE_E
2760: 52 52 4f 52 3b 0a 0a 20 20 69 66 20 28 68 4b 65  RROR;..  if (hKe
2770: 79 20 3d 3d 20 4d 41 58 44 57 4f 52 44 29 0a 20  y == MAXDWORD). 
2780: 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 45 72   {.    sqlite3Er
2790: 72 6f 72 28 64 62 2c 20 72 63 2c 20 53 51 4c 49  ror(db, rc, SQLI
27a0: 54 45 43 52 59 50 54 45 52 52 4f 52 5f 50 52 4f  TECRYPTERROR_PRO
27b0: 56 49 44 45 52 29 3b 0a 20 20 20 20 72 65 74 75  VIDER);.    retu
27c0: 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20 69 66  rn rc;.  }..  if
27d0: 20 28 21 70 42 6c 6f 63 6b 20 26 26 20 21 68 4b   (!pBlock && !hK
27e0: 65 79 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ey) return SQLIT
27f0: 45 5f 4f 4b 3b 20 2f 2f 20 57 61 73 6e 27 74 20  E_OK; // Wasn't 
2800: 65 6e 63 72 79 70 74 65 64 20 74 6f 20 62 65 67  encrypted to beg
2810: 69 6e 20 77 69 74 68 0a 0a 20 20 2f 2f 20 54 6f  in with..  // To
2820: 20 72 65 6b 65 79 20 61 20 64 61 74 61 62 61 73   rekey a databas
2830: 65 2c 20 77 65 20 63 68 61 6e 67 65 20 74 68 65  e, we change the
2840: 20 77 72 69 74 65 6b 65 79 20 66 6f 72 20 74 68   writekey for th
2850: 65 20 70 61 67 65 72 2e 20 20 54 68 65 20 72 65  e pager.  The re
2860: 61 64 6b 65 79 20 72 65 6d 61 69 6e 73 0a 20 20  adkey remains.  
2870: 2f 2f 20 74 68 65 20 73 61 6d 65 0a 20 20 69 66  // the same.  if
2880: 20 28 21 70 42 6c 6f 63 6b 29 20 2f 2f 20 45 6e   (!pBlock) // En
2890: 63 72 79 70 74 20 61 6e 20 75 6e 65 6e 63 72 79  crypt an unencry
28a0: 70 74 65 64 20 64 61 74 61 62 61 73 65 0a 20 20  pted database.  
28b0: 7b 0a 20 20 20 20 70 42 6c 6f 63 6b 20 3d 20 43  {.    pBlock = C
28c0: 72 65 61 74 65 43 72 79 70 74 42 6c 6f 63 6b 28  reateCryptBlock(
28d0: 68 4b 65 79 2c 20 70 2c 20 2d 31 2c 20 4e 55 4c  hKey, p, -1, NUL
28e0: 4c 29 3b 0a 20 20 20 20 69 66 20 28 21 70 42 6c  L);.    if (!pBl
28f0: 6f 63 6b 29 0a 20 20 20 20 20 20 72 65 74 75 72  ock).      retur
2900: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
2910: 0a 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 68 52 65  .    pBlock->hRe
2920: 61 64 4b 65 79 20 3d 20 30 3b 20 2f 2f 20 4f 72  adKey = 0; // Or
2930: 69 67 69 6e 61 6c 20 64 61 74 61 62 61 73 65 20  iginal database 
2940: 69 73 20 6e 6f 74 20 65 6e 63 72 79 70 74 65 64  is not encrypted
2950: 0a 20 20 20 20 73 71 6c 69 74 65 33 50 61 67 65  .    sqlite3Page
2960: 72 53 65 74 43 6f 64 65 63 28 73 71 6c 69 74 65  rSetCodec(sqlite
2970: 33 42 74 72 65 65 50 61 67 65 72 28 70 62 74 29  3BtreePager(pbt)
2980: 2c 20 73 71 6c 69 74 65 33 43 6f 64 65 63 2c 20  , sqlite3Codec, 
2990: 73 71 6c 69 74 65 33 43 6f 64 65 63 53 69 7a 65  sqlite3CodecSize
29a0: 43 68 61 6e 67 65 2c 20 73 71 6c 69 74 65 33 43  Change, sqlite3C
29b0: 6f 64 65 63 46 72 65 65 2c 20 70 42 6c 6f 63 6b  odecFree, pBlock
29c0: 29 3b 0a 20 20 20 20 2f 2f 64 62 2d 3e 61 44 62  );.    //db->aDb
29d0: 5b 30 5d 2e 70 41 75 78 20 3d 20 70 42 6c 6f 63  [0].pAux = pBloc
29e0: 6b 3b 0a 20 20 20 20 2f 2f 64 62 2d 3e 61 44 62  k;.    //db->aDb
29f0: 5b 30 5d 2e 78 46 72 65 65 41 75 78 20 3d 20 44  [0].xFreeAux = D
2a00: 65 73 74 72 6f 79 43 72 79 70 74 42 6c 6f 63 6b  estroyCryptBlock
2a10: 3b 0a 20 20 7d 0a 20 20 65 6c 73 65 20 2f 2f 20  ;.  }.  else // 
2a20: 43 68 61 6e 67 65 20 74 68 65 20 77 72 69 74 65  Change the write
2a30: 6b 65 79 20 66 6f 72 20 61 6e 20 61 6c 72 65 61  key for an alrea
2a40: 64 79 2d 65 6e 63 72 79 70 74 65 64 20 64 61 74  dy-encrypted dat
2a50: 61 62 61 73 65 0a 20 20 7b 0a 20 20 20 20 70 42  abase.  {.    pB
2a60: 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65 79 20  lock->hWriteKey 
2a70: 3d 20 68 4b 65 79 3b 0a 20 20 7d 0a 0a 20 20 73  = hKey;.  }..  s
2a80: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
2a90: 65 72 28 64 62 2d 3e 6d 75 74 65 78 29 3b 0d 0a  er(db->mutex);..
2aa0: 0a 20 20 2f 2f 20 53 74 61 72 74 20 61 20 74 72  .  // Start a tr
2ab0: 61 6e 73 61 63 74 69 6f 6e 0a 20 20 72 63 20 3d  ansaction.  rc =
2ac0: 20 73 71 6c 69 74 65 33 42 74 72 65 65 42 65 67   sqlite3BtreeBeg
2ad0: 69 6e 54 72 61 6e 73 28 70 62 74 2c 20 31 29 3b  inTrans(pbt, 1);
2ae0: 0a 0a 20 20 69 66 20 28 21 72 63 29 0a 20 20 7b  ..  if (!rc).  {
2af0: 0a 20 20 20 20 2f 2f 20 52 65 77 72 69 74 65 20  .    // Rewrite 
2b00: 61 6c 6c 20 74 68 65 20 70 61 67 65 73 20 69 6e  all the pages in
2b10: 20 74 68 65 20 64 61 74 61 62 61 73 65 20 75 73   the database us
2b20: 69 6e 67 20 74 68 65 20 6e 65 77 20 65 6e 63 72  ing the new encr
2b30: 79 70 74 69 6f 6e 20 6b 65 79 0a 20 20 20 20 50  yption key.    P
2b40: 67 6e 6f 20 6e 50 61 67 65 3b 0a 20 20 20 20 50  gno nPage;.    P
2b50: 67 6e 6f 20 6e 53 6b 69 70 20 3d 20 50 41 47 45  gno nSkip = PAGE
2b60: 52 5f 4d 4a 5f 50 47 4e 4f 28 70 29 3b 0a 20 20  R_MJ_PGNO(p);.  
2b70: 20 20 44 62 50 61 67 65 20 2a 70 50 61 67 65 3b    DbPage *pPage;
2b80: 0a 20 20 20 20 50 67 6e 6f 20 6e 3b 0a 20 20 20  .    Pgno n;.   
2b90: 20 69 6e 74 20 63 6f 75 6e 74 3b 0a 0a 20 20 20   int count;..   
2ba0: 20 73 71 6c 69 74 65 33 50 61 67 65 72 50 61 67   sqlite3PagerPag
2bb0: 65 63 6f 75 6e 74 28 70 2c 20 26 63 6f 75 6e 74  ecount(p, &count
2bc0: 29 3b 0a 20 20 20 20 6e 50 61 67 65 20 3d 20 28  );.    nPage = (
2bd0: 50 67 6e 6f 29 63 6f 75 6e 74 3b 0a 0a 20 20 20  Pgno)count;..   
2be0: 20 66 6f 72 28 6e 20 3d 20 31 3b 20 6e 20 3c 3d   for(n = 1; n <=
2bf0: 20 6e 50 61 67 65 3b 20 6e 20 2b 2b 29 0a 20 20   nPage; n ++).  
2c00: 20 20 7b 0a 20 20 20 20 20 20 69 66 20 28 6e 20    {.      if (n 
2c10: 3d 3d 20 6e 53 6b 69 70 29 20 63 6f 6e 74 69 6e  == nSkip) contin
2c20: 75 65 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  ue;.      rc = s
2c30: 71 6c 69 74 65 33 50 61 67 65 72 47 65 74 28 70  qlite3PagerGet(p
2c40: 2c 20 6e 2c 20 26 70 50 61 67 65 29 3b 0a 20 20  , n, &pPage);.  
2c50: 20 20 20 20 69 66 28 21 72 63 29 0a 20 20 20 20      if(!rc).    
2c60: 20 20 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d    {.        rc =
2c70: 20 73 71 6c 69 74 65 33 50 61 67 65 72 57 72 69   sqlite3PagerWri
2c80: 74 65 28 70 50 61 67 65 29 3b 0a 20 20 20 20 20  te(pPage);.     
2c90: 20 20 20 73 71 6c 69 74 65 33 50 61 67 65 72 55     sqlite3PagerU
2ca0: 6e 72 65 66 28 70 50 61 67 65 29 3b 0a 20 20 20  nref(pPage);.   
2cb0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
2cc0: 20 20 2f 2f 20 49 66 20 77 65 20 73 75 63 63 65    // If we succe
2cd0: 65 64 65 64 2c 20 74 72 79 20 61 6e 64 20 63 6f  eded, try and co
2ce0: 6d 6d 69 74 20 74 68 65 20 74 72 61 6e 73 61 63  mmit the transac
2cf0: 74 69 6f 6e 0a 20 20 69 66 20 28 21 72 63 29 0a  tion.  if (!rc).
2d00: 20 20 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c    {.    rc = sql
2d10: 69 74 65 33 42 74 72 65 65 43 6f 6d 6d 69 74 28  ite3BtreeCommit(
2d20: 70 62 74 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2f 20  pbt);.  }..  // 
2d30: 49 66 20 77 65 20 66 61 69 6c 65 64 2c 20 72 6f  If we failed, ro
2d40: 6c 6c 62 61 63 6b 0a 20 20 69 66 20 28 72 63 29  llback.  if (rc)
2d50: 0a 20 20 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  .  {.    sqlite3
2d60: 42 74 72 65 65 52 6f 6c 6c 62 61 63 6b 28 70 62  BtreeRollback(pb
2d70: 74 2c 20 53 51 4c 49 54 45 5f 4f 4b 29 3b 0a 20  t, SQLITE_OK);. 
2d80: 20 7d 0a 0a 20 20 2f 2f 20 49 66 20 77 65 20 73   }..  // If we s
2d90: 75 63 63 65 65 64 65 64 2c 20 64 65 73 74 72 6f  ucceeded, destro
2da0: 79 20 61 6e 79 20 70 72 65 76 69 6f 75 73 20 72  y any previous r
2db0: 65 61 64 20 6b 65 79 20 74 68 69 73 20 64 61 74  ead key this dat
2dc0: 61 62 61 73 65 20 75 73 65 64 0a 20 20 2f 2f 20  abase used.  // 
2dd0: 61 6e 64 20 6d 61 6b 65 20 74 68 65 20 72 65 61  and make the rea
2de0: 64 6b 65 79 20 65 71 75 61 6c 20 74 6f 20 74 68  dkey equal to th
2df0: 65 20 77 72 69 74 65 6b 65 79 0a 20 20 69 66 20  e writekey.  if 
2e00: 28 21 72 63 29 0a 20 20 7b 0a 20 20 20 20 69 66  (!rc).  {.    if
2e10: 20 28 70 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b   (pBlock->hReadK
2e20: 65 79 29 0a 20 20 20 20 7b 0a 20 20 20 20 20 20  ey).    {.      
2e30: 43 72 79 70 74 44 65 73 74 72 6f 79 4b 65 79 28  CryptDestroyKey(
2e40: 70 42 6c 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79  pBlock->hReadKey
2e50: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 42 6c  );.    }.    pBl
2e60: 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79 20 3d 20  ock->hReadKey = 
2e70: 70 42 6c 6f 63 6b 2d 3e 68 57 72 69 74 65 4b 65  pBlock->hWriteKe
2e80: 79 3b 0a 20 20 7d 0a 20 20 2f 2f 20 57 65 20 66  y;.  }.  // We f
2e90: 61 69 6c 65 64 2e 20 20 44 65 73 74 72 6f 79 20  ailed.  Destroy 
2ea0: 74 68 65 20 6e 65 77 20 77 72 69 74 65 6b 65 79  the new writekey
2eb0: 20 28 69 66 20 74 68 65 72 65 20 77 61 73 20 6f   (if there was o
2ec0: 6e 65 29 20 61 6e 64 20 72 65 76 65 72 74 20 69  ne) and revert i
2ed0: 74 20 62 61 63 6b 20 74 6f 0a 20 20 2f 2f 20 74  t back to.  // t
2ee0: 68 65 20 6f 72 69 67 69 6e 61 6c 20 72 65 61 64  he original read
2ef0: 6b 65 79 0a 20 20 65 6c 73 65 0a 20 20 7b 0a 20  key.  else.  {. 
2f00: 20 20 20 69 66 20 28 70 42 6c 6f 63 6b 2d 3e 68     if (pBlock->h
2f10: 57 72 69 74 65 4b 65 79 29 0a 20 20 20 20 7b 0a  WriteKey).    {.
2f20: 20 20 20 20 20 20 43 72 79 70 74 44 65 73 74 72        CryptDestr
2f30: 6f 79 4b 65 79 28 70 42 6c 6f 63 6b 2d 3e 68 57  oyKey(pBlock->hW
2f40: 72 69 74 65 4b 65 79 29 3b 0a 20 20 20 20 7d 0a  riteKey);.    }.
2f50: 20 20 20 20 70 42 6c 6f 63 6b 2d 3e 68 57 72 69      pBlock->hWri
2f60: 74 65 4b 65 79 20 3d 20 70 42 6c 6f 63 6b 2d 3e  teKey = pBlock->
2f70: 68 52 65 61 64 4b 65 79 3b 0a 20 20 7d 0a 0a 20  hReadKey;.  }.. 
2f80: 20 2f 2f 20 49 66 20 74 68 65 20 72 65 61 64 6b   // If the readk
2f90: 65 79 20 61 6e 64 20 77 72 69 74 65 6b 65 79 20  ey and writekey 
2fa0: 61 72 65 20 62 6f 74 68 20 65 6d 70 74 79 2c 20  are both empty, 
2fb0: 74 68 65 72 65 27 73 20 6e 6f 20 6e 65 65 64 20  there's no need 
2fc0: 66 6f 72 20 61 20 63 6f 64 65 63 20 6f 6e 20 74  for a codec on t
2fd0: 68 69 73 0a 20 20 2f 2f 20 70 61 67 65 72 20 61  his.  // pager a
2fe0: 6e 79 6d 6f 72 65 2e 20 20 44 65 73 74 72 6f 79  nymore.  Destroy
2ff0: 20 74 68 65 20 63 72 79 70 74 20 62 6c 6f 63 6b   the crypt block
3000: 20 61 6e 64 20 72 65 6d 6f 76 65 20 74 68 65 20   and remove the 
3010: 63 6f 64 65 63 20 66 72 6f 6d 20 74 68 65 20 70  codec from the p
3020: 61 67 65 72 2e 0a 20 20 69 66 20 28 21 70 42 6c  ager..  if (!pBl
3030: 6f 63 6b 2d 3e 68 52 65 61 64 4b 65 79 20 26 26  ock->hReadKey &&
3040: 20 21 70 42 6c 6f 63 6b 2d 3e 68 57 72 69 74 65   !pBlock->hWrite
3050: 4b 65 79 29 0a 20 20 7b 0a 20 20 20 20 73 71 6c  Key).  {.    sql
3060: 69 74 65 33 50 61 67 65 72 53 65 74 43 6f 64 65  ite3PagerSetCode
3070: 63 28 70 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c  c(p, NULL, NULL,
3080: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 20 20   NULL, NULL);.  
3090: 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  }..  sqlite3_mut
30a0: 65 78 5f 6c 65 61 76 65 28 64 62 2d 3e 6d 75 74  ex_leave(db->mut
30b0: 65 78 29 3b 0d 0a 0a 20 20 72 65 74 75 72 6e 20  ex);...  return 
30c0: 72 63 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2f  rc;.}..#endif //
30d0: 20 53 51 4c 49 54 45 5f 48 41 53 5f 43 4f 44 45   SQLITE_HAS_CODE
30e0: 43 0a 0a 23 65 6e 64 69 66 20 2f 2f 20 53 51 4c  C..#endif // SQL
30f0: 49 54 45 5f 4f 4d 49 54 5f 44 49 53 4b 49 4f 0a  ITE_OMIT_DISKIO.