rework attach to require explicit key
[sqlcipher.git] / test / crypto.test
blob055b2cd33ccc83e22b89555d0464ebab11e79f3a
1 # SQLCipher
2 # codec.test developed by Stephen Lombardo (Zetetic LLC) 
3 # sjlombardo at zetetic dot net
4 # http://zetetic.net
5
6 # Copyright (c) 2009, ZETETIC LLC
7 # All rights reserved.
8
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are met:
11 #     * Redistributions of source code must retain the above copyright
12 #       notice, this list of conditions and the following disclaimer.
13 #     * Redistributions in binary form must reproduce the above copyright
14 #       notice, this list of conditions and the following disclaimer in the
15 #       documentation and/or other materials provided with the distribution.
16 #     * Neither the name of the ZETETIC LLC nor the
17 #       names of its contributors may be used to endorse or promote products
18 #       derived from this software without specific prior written permission.
19
20 # THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
21 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 # DISCLAIMED. IN NO EVENT SHALL ZETETIC LLC BE LIABLE FOR ANY
24 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 # This file implements regression tests for SQLite library.  The
32 # focus of this script is testing code cipher features.
34 # NOTE: tester.tcl has overridden the definition of sqlite3 to 
35 # automatically pass in a key value. Thus tests in this file
36 # should explicitly close and open db with sqlite_orig in order
37 # to bypass default key assignment.
40 file delete -force test.db
41 file delete -force test2.db
42 file delete -force test3.db
43 file delete -force test4.db
45 set testdir [file dirname $argv0]
46 source $testdir/tester.tcl
48 # If the library is not compiled with has_codec support then
49 # skip all tests in this file.
50 if {![sqlite_orig -has-codec]} {
51   finish_test
52   return
55 proc setup {file key} {
56   sqlite_orig db $file
57   execsql "PRAGMA key=$key;"
58   execsql {
59     CREATE table t1(a,b);
60     INSERT INTO t1 VALUES ('test1', 'test2'); 
61   } db
62   db close
65 # The database is initially empty.
66 # set an hex key create some basic data
67 # create table and insert operations should work
68 # close database, open it again with the same
69 # hex key. verify that the table is readable
70 # and the data just inserted is visible
71 setup test.db "\"x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'\""
72 do_test will-open-with-correct-raw-key {
73   sqlite_orig db test.db
74   execsql {
75     PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
76     SELECT name FROM sqlite_master WHERE type='table';
77     SELECT * from t1;
78   }
79 } {t1 test1 test2}
80 db close
81 file delete -force test.db
83 # set an encryption key (non-hex) and create some basic data
84 # create table and insert operations should work
85 # close database, open it again with the same
86 # key. verify that the table is readable
87 # and the data just inserted is visible
88 setup test.db "'testkey'"
89 do_test will-open-with-correct-derived-key {
91   sqlite_orig db test.db
92   execsql {
93     PRAGMA key = 'testkey';
94     SELECT name FROM sqlite_master WHERE type='table';
95     SELECT * from t1;
96   }
97 } {t1 test1 test2}
98 db close
99 file delete -force test.db
101 # open the database and try to read from it without
102 # providing a passphrase. verify that the 
103 # an error is returned from the library
104 setup test.db "'testkey'"
105 do_test wont-open-without-key {
106   sqlite_orig db test.db
107   catchsql {
108     SELECT name FROM sqlite_master WHERE type='table';
109   }
110 } {1 {file is encrypted or is not a database}}
111 db close
112 file delete -force test.db
114 # open the database and try to set an invalid
115 # passphrase. verify that an error is returned
116 # and that data couldn't be read
117 setup test.db "'testkey'"
118 do_test wont-open-with-invalid-derived-key {
119   sqlite_orig db test.db
120   catchsql {
121     PRAGMA key = 'testkey2';
122     SELECT name FROM sqlite_master WHERE type='table';
123   }
124 } {1 {file is encrypted or is not a database}}
125 db close
126 file delete -force test.db
128 # open the database and try to set an invalid
129 # hex key. verify that an error is returned
130 # and that data couldn't be read
131 setup test.db "'testkey'"
132 do_test wont-open-with-invalid-raw-key {
133   sqlite_orig db test.db
134   catchsql {
135     PRAGMA key = "x'98483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836480'";
136     SELECT name FROM sqlite_master WHERE type='table';
137   }
138 } {1 {file is encrypted or is not a database}}
139 db close
140 file delete -force test.db
142 # test a large number of inserts in a transaction to a memory database 
143 do_test memory-database {
144   sqlite_orig db :memory:
145   execsql {
146     PRAGMA key = 'testkey3';
147     BEGIN;
148     CREATE TABLE t2(a,b);
149   }
150   for {set i 1} {$i<=25000} {incr i} {
151     set r [expr {int(rand()*500000)}]
152     execsql "INSERT INTO t2 VALUES($i,$r);" 
153   }
154   execsql {
155     COMMIT;
156     SELECT count(*) FROM t2;
157     DELETE FROM t2;
158     SELECT count(*) FROM t2;
159   } 
160 } {25000 0}
161 db close
163 # test a large number of inserts in a transaction for multiple pages
164 do_test multi-page-database {
165   sqlite_orig db test.db
166   execsql {
167     PRAGMA key = 'testkey';
168     CREATE TABLE t2(a,b);
169     BEGIN;
170   }
171   for {set i 1} {$i<=25000} {incr i} {
172     set r [expr {int(rand()*500000)}]
173     execsql "INSERT INTO t2 VALUES($i,$r);" 
174   }
175   execsql {
176     COMMIT;
177     SELECT count(*) FROM t2;
178   } 
179 } {25000}
180 db close
181 file delete -force test.db
183 # test a rekey operation as the first op on a database
184 # then test that now the new key opens the database
185 # now close database re-open with new key
186 setup test.db "'testkey'"
187 do_test rekey-as-first-operation {
188   sqlite_orig db test.db
189   execsql {
190     PRAGMA key = 'testkey';
191     PRAGMA rekey = 'testkeynew';
192   }
193   db close
195   sqlite_orig db test.db
196   execsql {
197     PRAGMA key = 'testkeynew';
198     SELECT name FROM sqlite_master WHERE type='table';
199   }
200 } {t1}
201 db close
202 file delete -force test.db
204 # create a new database, insert some data
205 # then rekey it with the same password
206 do_test rekey-same-passkey {
207   sqlite_orig db test.db
209   execsql {
210     PRAGMA key = 'test123';
211     CREATE TABLE t1(a,b);
212     BEGIN;
213   }
215   for {set i 1} {$i<=1000} {incr i} {
216     set r [expr {int(rand()*500000)}]
217     execsql "INSERT INTO t1 VALUES($i,'value $r');"
218   }
220   execsql {
221     COMMIT;
222     SELECT count(*) FROM t1;
223     PRAGMA rekey = 'test123';
224     SELECT count(*) FROM t1;
225   }
226 } {1000 1000}
227 db close
228 file delete -force test.db
230 # create a new database, insert some data
231 # then rekey it. Make sure it is immediately
232 # readable. Then close it and make sure it can be
233 # read back 
234 do_test rekey-and-query-1 {
235   sqlite_orig db test.db
237   execsql {
238     PRAGMA key = 'test123';
239     CREATE TABLE t1(a,b);
240     BEGIN;
241   }
243   for {set i 1} {$i<=1000} {incr i} {
244     set r [expr {int(rand()*500000)}]
245     execsql "INSERT INTO t1 VALUES($i,'value $r');"
246   }
248   execsql {
249     COMMIT;
250     SELECT count(*) FROM t1;
251     PRAGMA rekey = 'test321';
252     SELECT count(*) FROM t1;
253   }
254 } {1000 1000}
256 db close
258 do_test rekey-and-query-2 {
259   sqlite_orig db test.db
260   execsql {
261     PRAGMA key = 'test321';
262     SELECT count(*) FROM t1;
263   }
264 } {1000}
265 db close
266 file delete -force test.db
268 # create a new database, insert some data
269 # delete about 50% of the data
270 # write some new data
271 # delete another 50%
272 # then rekey it. Make sure it is immediately
273 # readable. Then close it and make sure it can be
274 # read back. This test will ensure that Secure Delete
275 # is enabled and all pages are being written and are not
276 # being optimized out by sqlite3PagerDontWrite
277 do_test rekey-delete-and-query-1 {
278   sqlite_orig db test.db
280   execsql {
281     PRAGMA key = 'test123';
282     CREATE TABLE t1(a,b);
283     CREATE INDEX ta_a ON t1(a);
284     BEGIN;
285   }
287   for {set i 1} {$i<1000} {incr i} {
288     set r [expr {int(rand()*32767)}]
289     set r1 [expr {int(rand()*32767)}]
290     execsql "INSERT INTO t1 VALUES($r,$r1);"
291   }
292   set r [expr {int(rand()*32767)}]
293   set r1 [expr {int(rand()*32767)}]
294   execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
296   set r [expr {int(rand()*32767)}]
298   execsql "DELETE FROM t1 WHERE a < $r;"
300   execsql {
301     COMMIT;
302     SELECT (count(*) > 0) FROM t1;
303   }
304 } {1}
305 db close
307 do_test rekey-delete-and-query-2 {
308   sqlite_orig db test.db
309   execsql {
310     PRAGMA key = 'test123';
311     PRAGMA rekey = 'test321';
312     SELECT count(*) > 1 FROM t1;
313     PRAGMA integrity_check;
314   }
315 } {1 ok}
316 db close
318 do_test rekey-delete-and-query-3 {
319   sqlite_orig db test.db
320   execsql {
321     PRAGMA key = 'test321';
322     SELECT count(*) > 1 FROM t1;
323   }
324 } {1}
325 db close
326 file delete -force test.db
329 # same as previous test, but use WAL
330 do_test rekey-delete-and-query-wal-1 {
331   sqlite_orig db test.db
333   execsql {
334     PRAGMA key = 'test123';
335     PRAGMA journal_mode = WAL;
336     CREATE TABLE t1(a,b);
337     CREATE INDEX ta_a ON t1(a);
338     BEGIN;
339   }
341   for {set i 1} {$i<1000} {incr i} {
342     set r [expr {int(rand()*32767)}]
343     set r1 [expr {int(rand()*32767)}]
344     execsql "INSERT INTO t1 VALUES($r,$r1);"
345   }
346   set r [expr {int(rand()*32767)}]
347   set r1 [expr {int(rand()*32767)}]
348   execsql "UPDATE t1 SET b = $r WHERE a < $r1;"
350   set r [expr {int(rand()*32767)}]
352   execsql "DELETE FROM t1 WHERE a < $r;"
354   execsql {
355     COMMIT;
356     SELECT (count(*) > 0) FROM t1;
357   }
358 } {1}
359 db close
361 do_test rekey-delete-and-query-wal-2 {
362   sqlite_orig db test.db
363   execsql {
364     PRAGMA key = 'test123';
365     PRAGMA journal_mode = WAL;
366     PRAGMA rekey = 'test321';
367     SELECT count(*) > 1 FROM t1;
368     PRAGMA integrity_check;
369   }
370 } {wal 1 ok}
371 db close
373 do_test rekey-delete-and-query-wal-3 {
374   sqlite_orig db test.db
375   execsql {
376     PRAGMA key = 'test321';
377     PRAGMA journal_mode = WAL;
378     SELECT count(*) > 1 FROM t1;
379   }
380 } {wal 1}
381 db close
382 file delete -force test.db
384 # attach an encrypted database
385 # without specifying key, verify it fails
386 setup test.db "'testkey'"
387 do_test attach-database-with-default-key {
388   sqlite_orig db2 test2.db
390   execsql {
391     PRAGMA key = 'testkey';
392     CREATE TABLE t2(a,b);
393     INSERT INTO t2 VALUES ('test1', 'test2'); 
394   } db2
396   catchsql {
397     ATTACH 'test.db' AS db;
398   } db2
400 } {1 {unable to open database: test.db}}
401 db2 close
402 file delete -force test.db
403 file delete -force test2.db
405 # attach an encrypted database
406 # where both database have the same
407 # key explicitly
408 setup test.db "'testkey'"
409 do_test attach-database-with-same-key {
410   sqlite_orig db2 test2.db
412   execsql {
413     PRAGMA key = 'testkey';
414     CREATE TABLE t2(a,b);
415     INSERT INTO t2 VALUES ('test1', 'test2'); 
416   } db2
418   execsql {
419     SELECT count(*) FROM t2;
420     ATTACH 'test.db' AS db KEY 'testkey';
421     SELECT count(*) FROM db.t1;
422   } db2
424 } {1 1}
425 db2 close
426 file delete -force test.db
427 file delete -force test2.db
429 # attach an encrypted database
430 # where databases have different keys
431 setup test.db "'testkey'"
432 do_test attach-database-with-different-keys {
433   sqlite_orig db2 test2.db
435   execsql {
436     PRAGMA key = 'testkey2';
437     CREATE TABLE t2(a,b);
438     INSERT INTO t2 VALUES ('test1', 'test2'); 
439   } db2
440   
441   execsql {
442     ATTACH 'test.db' AS db KEY 'testkey';
443     SELECT count(*) FROM db.t1;
444     SELECT count(*) FROM t2;
445   } db2
447 } {1 1}
448 db2 close
449 file delete -force test.db
450 file delete -force test2.db
452 # test locking across multiple handles
453 setup test.db "'testkey'"
454 do_test locking-across-multiple-handles-start {
455   sqlite_orig db test.db
457   execsql {
458     PRAGMA key = 'testkey';
459     BEGIN EXCLUSIVE;
460     INSERT INTO t1 VALUES(1,2);
461   } 
462   
463   sqlite_orig dba test.db
464   catchsql {
465     PRAGMA key = 'testkey';
466       SELECT count(*) FROM t1;
467   } dba
469  } {1 {database is locked}} 
471 do_test locking-accross-multiple-handles-finish {
472  execsql {
473     COMMIT;
474   }
476   execsql {
477     SELECT count(*) FROM t1;
478   } dba
479 } {2}
480 db close
481 dba close
482 file delete -force test.db
484 # alter schema
485 setup test.db "'testkey'"
486 do_test alter-schema {
487   sqlite_orig db test.db
488   execsql {
489     PRAGMA key = 'testkey';
490     ALTER TABLE t1 ADD COLUMN c;
491     INSERT INTO t1 VALUES (1,2,3);
492     INSERT INTO t1 VALUES (1,2,4);
493     CREATE TABLE t1a (a);
494     INSERT INTO t1a VALUES ('teststring');
495   }
496   db close
498   sqlite_orig db test.db
499   execsql {
500     PRAGMA key = 'testkey';
501     SELECT count(*) FROM t1 WHERE a IS NOT NULL;
502     SELECT count(*) FROM t1 WHERE c IS NOT NULL;
503     SELECT * FROM t1a;
504   } 
506 } {3 2 teststring}
507 db close
508 file delete -force test.db
510 # test alterations of KDF iterations and ciphers
511 # rekey then add
512 setup test.db "'testkey'"
513 do_test non-standard-kdf-and-ciphers {
514   sqlite_orig db test.db
515   execsql {
516     PRAGMA key = 'testkey';
517     PRAGMA rekey_kdf_iter = 1000;
518     PRAGMA rekey_cipher = 'aes-256-cfb';
519     PRAGMA rekey = 'testkey2';
520     INSERT INTO t1 VALUES (1,2);
521   } 
522   db close
524   sqlite_orig db test.db
525   execsql {
526     PRAGMA key = 'testkey2';
527     PRAGMA kdf_iter = 1000;
528     PRAGMA cipher = 'aes-256-cfb';
529     SELECT count(*) FROM t1;
530   } 
532 } {2}
533 db close
534 file delete -force test.db
536 # test alterations of CIPHER from CBC Mode requiring
537 # IV to ECB mode that does not
538 setup test.db "'testkey'"
539 do_test rekey-from-cbc-to-ecb-no-iv {
540   sqlite_orig db test.db
541   execsql {
542     PRAGMA key = 'testkey';
543     BEGIN;
544   }
546   for {set i 1} {$i<=1000} {incr i} {
547     set r [expr {int(rand()*500000)}]
548     execsql "INSERT INTO t1 VALUES($i,$r);" 
549   }
550   
551   execsql {
552     COMMIT;
553     PRAGMA rekey_kdf_iter = 1000;
554     PRAGMA rekey_cipher = 'aes-128-ecb';
555     PRAGMA rekey = 'testkey';
556   } 
557   db close
559   sqlite_orig db test.db
560   execsql {
561     PRAGMA key = 'testkey';
562     PRAGMA kdf_iter = 1000;
563     PRAGMA cipher = 'aes-128-ecb';
564     SELECT count(*) FROM t1;
565   } 
567 } {1001}
568 db close
569 file delete -force test.db
571 # test alterations of CIPHER from ECB Mode (no IV) to CBC Mode
572 do_test rekey-from-ecb-to-cbc-with-iv {
573   sqlite_orig db test.db
574   execsql {
575     PRAGMA key = 'testkey';
576     PRAGMA cipher = 'aes-256-ecb';
577     CREATE table t1(a,b);
578     BEGIN;
579   }
581   for {set i 1} {$i<=1000} {incr i} {
582     set r [expr {int(rand()*500000)}]
583     execsql "INSERT INTO t1 VALUES($i,$r);" 
584   }
585   
586   execsql {
587     COMMIT;
588     PRAGMA rekey_cipher = 'aes-256-cbc';
589     PRAGMA rekey = 'testkey';
590   } 
591   db close
593   sqlite_orig db test.db
594   execsql {
595     PRAGMA key = 'testkey';
596     SELECT count(*) FROM t1;
597   } 
599 } {1000}
600 db close
601 file delete -force test.db
603 # create an unencrypted database, attach a new encrypted volume
604 # copy data between, verify the encypted database is good afterwards
605 do_test unencrypted-attach {
606   sqlite_orig db test.db
608   execsql {
609     CREATE TABLE t1(a,b);
610     BEGIN;
611   } 
613   for {set i 1} {$i<=1000} {incr i} {
614     set r [expr {int(rand()*500000)}]
615     execsql "INSERT INTO t1 VALUES($i,$r);" 
616   }
617   
618   execsql {
619     COMMIT;
620     ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey';
621     CREATE TABLE db2.t1(a,b);
622     INSERT INTO db2.t1 SELECT * FROM t1;
623     DETACH DATABASE db2;
624   }
625   
626   sqlite_orig db2 test2.db
627   execsql {
628     PRAGMA  key='testkey';
629     SELECT count(*) FROM t1;
630   } db2 
631 } {1000}
632 db2 close
633 file delete -force test.db
634 file delete -force test2.db
636 # create an unencrypted database, attach a new encrypted volume
637 # using a raw key copy data between, verify the encypted 
638 # database is good afterwards 
639 do_test unencryped-attach-raw-key {
640   sqlite_orig db test.db
642   execsql {
643     CREATE TABLE t1(a,b);
644     BEGIN;
645   } 
647   for {set i 1} {$i<=1000} {incr i} {
648     set r [expr {int(rand()*500000)}]
649     execsql "INSERT INTO t1 VALUES($i,$r);" 
650   }
651   
652   execsql {
653     COMMIT;
654     ATTACH DATABASE 'test2.db' AS db2 KEY "x'10483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
655     CREATE TABLE db2.t1(a,b);
656     INSERT INTO db2.t1 SELECT * FROM t1;
657     DETACH DATABASE db2;
658   }
659   
660   sqlite_orig db2 test2.db
661   execsql {
662     PRAGMA key="x'10483C6EB40B6C31A448C22A66DED3B5E5E8D5119CAC8327B655C8B5C4836481'";
663     SELECT count(*) FROM t1;
664   } db2 
665 } {1000}
666 db2 close
667 file delete -force test.db
668 file delete -force test2.db
670 # create an encrypted database, attach an unencrypted volume
671 # copy data between, verify the unencypted database is good afterwards
672 do_test encryped-attach-unencrypted {
673   sqlite_orig db test.db
675   execsql {
676     CREATE TABLE t1(a,b);
677   } 
679   sqlite_orig db2 test2.db
680   execsql {
681     PRAGMA  key='testkey';
682     CREATE TABLE t1(a,b);
683     BEGIN;
684   }  db2
686   for {set i 1} {$i<=1000} {incr i} {
687     set r [expr {int(rand()*500000)}]
688     execsql "INSERT INTO t1 VALUES($i,$r);" db2 
689   }
690   
691   execsql {
692     COMMIT;
693     ATTACH DATABASE 'test.db' AS test KEY '';
694     INSERT INTO test.t1 SELECT * FROM t1;
695     DETACH DATABASE test;
696   } db2
698   execsql {
699     SELECT count(*) FROM t1;
700   } 
701 } {1000}
702 db close
703 db2 close
704 file delete -force test.db
705 file delete -force test2.db
707 # create an unencrypted database, attach an unencrypted volume
708 # copy data between, verify the unencypted database is good afterwards
709 do_test unencryped-attach-unencrypted {
710   sqlite_orig db test.db
712   execsql {
713     CREATE TABLE t1(a,b);
714   } 
716   sqlite_orig db2 test2.db
717   execsql {
718     CREATE TABLE t1(a,b);
719     BEGIN;
720   }  db2
722   for {set i 1} {$i<=1000} {incr i} {
723     set r [expr {int(rand()*500000)}]
724     execsql "INSERT INTO t1 VALUES($i,$r);" db2 
725   }
726   
727   execsql {
728     COMMIT;
729     ATTACH DATABASE 'test.db' AS test;
730     INSERT INTO test.t1 SELECT * FROM t1;
731     DETACH DATABASE test;
732   } db2
734   execsql {
735     SELECT count(*) FROM t1;
736   } 
737 } {1000}
738 db close
739 db2 close
740 file delete -force test.db
741 file delete -force test2.db
743 # 1. create a database with a custom page size, 
744 # 2. create table and insert operations should work
745 # 3. close database, open it again with the same
746 #    key and page size
747 # 4. verify that the table is readable
748 #    and the data just inserted is visible
749 do_test custom-pagesize {
750   sqlite_orig db test.db
752   execsql {
753     PRAGMA key = 'testkey';
754     PRAGMA cipher_page_size = 4096;
755     CREATE table t1(a,b);
756     BEGIN;
757   }
759   for {set i 1} {$i<=1000} {incr i} {
760     set r [expr {int(rand()*500000)}]
761     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
762   }
764   execsql {
765     COMMIT;
766   } 
768   db close
769   sqlite_orig db test.db
771   execsql {
772     PRAGMA key = 'testkey';
773     PRAGMA cipher_page_size = 4096;
774     SELECT count(*) FROM t1;
775   }
777 } {1000}
778 db close
780 # open the database with the default page size
781 ## and verfiy that it is not readable 
782 do_test custom-pagesize-must-match {
783   sqlite_orig db test.db
784   catchsql {
785     PRAGMA key = 'testkey';
786     SELECT name FROM sqlite_master WHERE type='table';
787   }
788 } {1 {file is encrypted or is not a database}}
789 db close
790 file delete -force test.db
792 # 1. create a database and insert a bunch of data, close the database
793 # 2. seek to the middle of a database page and write some junk
794 # 3. Open the database and verify that the database is no longer readable
795 do_test hmac-tamper-resistence {
796   sqlite_orig db test.db
798   execsql {
799     PRAGMA key = 'testkey';
800     CREATE table t1(a,b);
801     BEGIN;
802   }
804   for {set i 1} {$i<=1000} {incr i} {
805     set r [expr {int(rand()*500000)}]
806     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
807   }
809   execsql {
810     COMMIT;
811   } 
813   db close
815   # write some junk into the hmac segment, leaving
816   # the page data valid but with an invalid signature
817   hexio_write test.db 1000 0000
819   sqlite_orig db test.db
821   catchsql {
822     PRAGMA key = 'testkey';
823     SELECT count(*) FROM t1;
824   }
826 } {1 {file is encrypted or is not a database}}
827 db close
828 file delete -force test.db
830 # 1. create a database and insert a bunch of data, close the database
831 # 2. seek to the middle of a database page and write some junk
832 # 3. Open the database and verify that the database is still readable
833 do_test nohmac-not-tamper-resistent {
834   sqlite_orig db test.db
836   execsql {
837     PRAGMA key = 'testkey';
838     PRAGMA cipher_use_hmac = OFF;
839     PRAGMA cipher_page_size = 1024;
840     CREATE table t1(a,b);
841     BEGIN;
842   }
844   for {set i 1} {$i<=1000} {incr i} {
845     set r [expr {int(rand()*500000)}]
846     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
847   }
849   execsql {
850     COMMIT;
851   } 
853   db close
855   # write some junk into the middle of the page
856   hexio_write test.db 2560 00
858   sqlite_orig db test.db
860   execsql {
861     PRAGMA key = 'testkey';
862     PRAGMA cipher_use_hmac = OFF;
863     PRAGMA cipher_page_size = 1024;
864     SELECT count(*) FROM t1;
865   }
867 } {1000}
868 db close
869 file delete -force test.db
871 # open a 1.1.8 database using the new code, HMAC disabled
872 do_test open-1.1.8-database {
873   sqlite_orig db sqlcipher-1.1.8-testkey.db
874   execsql {
875     PRAGMA key = 'testkey';
876     PRAGMA cipher_use_hmac = OFF;
877     SELECT count(*) FROM t1;
878     SELECT * FROM t1;
879   } 
880 } {4 1 1 one one 1 2 one two}
881 db close
884 # open a 1.1.8 database without hmac, then copy the data
885 do_test attach-and-copy-1.1.8 {
886   sqlite_orig db sqlcipher-1.1.8-testkey.db
888   execsql {
889     PRAGMA key = 'testkey';
890     PRAGMA cipher_use_hmac = OFF;
891     ATTACH DATABASE 'test.db' AS db2 KEY 'testkey-hmac'; 
892     CREATE TABLE db2.t1(a,b);
893     INSERT INTO db2.t1 SELECT * FROM main.t1;
894     DETACH DATABASE db2;
895   }
896   db close
898   sqlite_orig db test.db
899   execsql {
900     PRAGMA key = 'testkey-hmac';
901     SELECT count(*) FROM t1;
902     SELECT * FROM t1;
903   }
904 } {4 1 1 one one 1 2 one two}
905 db close
906 file delete -force test.db
908 # open a standard database, then attach a new 
909 # database with completely different options. 
910 # copy data between them, and verify that the
911 # new database can be opened with the proper data
912 do_test attached-database-pragmas {
913   sqlite_orig db test.db
915   execsql {
916     PRAGMA key = 'testkey';
917     CREATE TABLE t1(a,b);
918     BEGIN;
919   }
921   for {set i 1} {$i<=1000} {incr i} {
922     set r [expr {int(rand()*500000)}]
923     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
924   } 
926   execsql {
927     COMMIT;
928     ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2'; 
929     PRAGMA db2.cipher_page_size = 4096;
930     PRAGMA db2.cipher = 'aes-128-cbc';
931     PRAGMA db2.kdf_iter = 1000;
932     PRAGMA db2.cipher_use_hmac = OFF;
933     CREATE TABLE db2.t1(a,b);
934     INSERT INTO db2.t1 SELECT * FROM main.t1;
935     DETACH DATABASE db2;
936   }
937   db close
939   sqlite_orig db test2.db
940   execsql {
941     PRAGMA key = 'testkey2';
942     PRAGMA cipher_page_size = 4096;
943     PRAGMA cipher = 'aes-128-cbc';
944     PRAGMA kdf_iter = 1000;
945     PRAGMA cipher_use_hmac = OFF;
946     SELECT count(*) FROM t1;
947   }
948 } {1000}
949 db close
950 file delete -force test.db
951 file delete -force test2.db
953 # use the sqlcipher_export function
954 # on a non-existent database. Verify 
955 # the error gets through.
956 do_test export-error {
957   sqlite_orig db test.db
959   catchsql {
960     PRAGMA key = 'testkey';
961     CREATE TABLE t1(a,b);
962     SELECT sqlcipher_export('nodb');
963   } 
964 } {1 {unknown database nodb}}
965 db close
966 file delete -force test.db
968 # use the sqlcipher_export function
969 # to copy a complicated database. 
970 # tests autoincrement fields,
971 # indexes, views, and triggers,
972 # tables and virtual tables
973 do_test export-database {
974   sqlite_orig db test.db
976   execsql {
977     PRAGMA key = 'testkey';
978     CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b, c);
979     CREATE UNIQUE INDEX b_idx ON t1(b);
980     CREATE INDEX c_idx ON t1(c);
982     CREATE TABLE t2(b,c);
983     CREATE TRIGGER t2_after_insert AFTER INSERT ON t2
984     BEGIN 
985       INSERT INTO t1(b,c) VALUES (new.b, new.c);
986     END;
988     CREATE VIEW v1 AS
989       SELECT c FROM t1;
991     CREATE VIRTUAL TABLE fts USING fts3(a,b); 
993     BEGIN;
994     -- start with one known value
995     INSERT INTO t2 VALUES(1000000,'value 1000000');
996   }
998   for {set i 1} {$i<=999} {incr i} {
999     set r [expr {int(rand()*500000)}]
1000     execsql "INSERT INTO t2 VALUES($i,'value $r');" 
1001   } 
1003   execsql {
1004     INSERT INTO fts SELECT b,c FROM t1;
1005     COMMIT;
1007     ATTACH DATABASE 'test2.db' AS db2 KEY 'testkey2'; 
1008     PRAGMA db2.cipher_page_size = 4096;
1010     SELECT sqlcipher_export('db2');
1012     DETACH DATABASE db2;
1013   }
1014   db close
1016   sqlite_orig db test2.db
1017   execsql {
1018     PRAGMA key = 'testkey2';
1019     PRAGMA cipher_page_size = 4096;
1020     SELECT count(*) FROM t1;
1021     SELECT count(*) FROM v1;
1022     SELECT count(*) FROM sqlite_sequence;
1023     SELECT seq FROM sqlite_sequence WHERE name = 't1';
1024     INSERT INTO t2 VALUES(10001, 'value 938383');
1025     SELECT count(*) FROM t1; -- verify the trigger worked
1026     SELECT seq FROM sqlite_sequence WHERE name = 't1'; -- verify that autoincrement worked
1027     SELECT a FROM fts WHERE b MATCH '1000000';  
1028   }
1029 } {1000 1000 1 1000 1001 1001 1000000}
1030 db close
1031 file delete -force test.db
1032 file delete -force test2.db
1034 # 1. create a database with WAL journal mode
1035 # 2. create table and insert operations should work
1036 # 3. close database, open it again
1037 # 4. verify that the table is present, readable, and that
1038 #    the journal mode is WAL
1039 do_test journal-mode-wal {
1040   sqlite_orig db test.db
1042   execsql {
1043     PRAGMA key = 'testkey';
1044     PRAGMA journal_mode = WAL;
1045     CREATE table t1(a,b);
1046     BEGIN;
1047   }
1049   for {set i 1} {$i<=1000} {incr i} {
1050     set r [expr {int(rand()*500000)}]
1051     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
1052   }
1054   execsql {
1055     COMMIT;
1056   } 
1058   db close
1059   sqlite_orig db test.db
1061   execsql {
1062     PRAGMA key = 'testkey';
1063     SELECT count(*) FROM t1;
1064     PRAGMA journal_mode;
1065   }
1067 } {1000 wal}
1068 db close
1069 file delete -force test.db
1071 # Test rekey as first operation on an empty database. should be a no-op
1072 do_test rekey-as-first-op {
1073   sqlite_orig db test.db
1075   execsql {
1076     PRAGMA rekey = 'testkey';
1077     CREATE table t1(a,b);
1078     BEGIN;
1079   }
1081   for {set i 1} {$i<=100} {incr i} {
1082     set r [expr {int(rand()*500000)}]
1083     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
1084   }
1086   execsql {
1087     COMMIT;
1088   } 
1090   db close
1091   sqlite_orig db test.db
1093   execsql {
1094     PRAGMA rekey = 'testkey';
1095     SELECT count(*) FROM t1;
1096   }
1098 } {100}
1099 db close
1100 file delete -force test.db
1102 # Test rekey as first operation follwed by key
1103 do_test rekey-then-key-as-first-ops {
1104   sqlite_orig db test.db
1106   execsql {
1107     PRAGMA rekey = '1234';
1108     PRAGMA key = 'testkey';
1109     CREATE table t1(a,b);
1110     BEGIN;
1111   }
1113   for {set i 1} {$i<=100} {incr i} {
1114     set r [expr {int(rand()*500000)}]
1115     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
1116   }
1118   execsql {
1119     COMMIT;
1120   } 
1122   db close
1123   sqlite_orig db test.db
1125   execsql {
1126     PRAGMA rekey = '4321';
1127     PRAGMA key = 'testkey';
1128     SELECT count(*) FROM t1;
1129   }
1131 } {100}
1132 db close
1133 file delete -force test.db
1135 setup test.db "'testkey'"
1136 do_test multiple-key-calls-safe-1 {
1137   sqlite_orig db test.db
1138   execsql {
1139     PRAGMA key = 'testkey';
1140     PRAGMA cache_size = 0; 
1141     SELECT name FROM sqlite_master WHERE type='table';
1142   }
1143 } {t1} 
1145 do_test multiple-key-calls-safe-2 {
1146   catchsql {
1147     PRAGMA key = 'wrong key'; 
1148     SELECT name FROM sqlite_master WHERE type='table';
1149   }
1150 } {1 {file is encrypted or is not a database}}
1152 do_test multiple-key-calls-safe-3 {
1153   execsql {
1154     PRAGMA key = 'testkey'; 
1155     SELECT name FROM sqlite_master WHERE type='table';
1156   }
1157 } {t1} 
1159 db close
1160 file delete -force test.db
1162 # 1. create a database with a custom hmac kdf iteration count, 
1163 # 2. create table and insert operations should work
1164 # 3. close database, open it again with the same
1165 #    key and  hmac kdf iteration count
1166 # 4. verify that the table is readable
1167 #    and the data just inserted is visible
1168 do_test custom-hmac-kdf-iter {
1169   sqlite_orig db test.db
1171   execsql {
1172     PRAGMA key = 'testkey';
1173     PRAGMA fast_kdf_iter = 10;
1174     CREATE table t1(a,b);
1175     BEGIN;
1176   }
1178   for {set i 1} {$i<=1000} {incr i} {
1179     set r [expr {int(rand()*500000)}]
1180     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
1181   }
1183   execsql {
1184     COMMIT;
1185   } 
1187   db close
1188   sqlite_orig db test.db
1190   execsql {
1191     PRAGMA key = 'testkey';
1192     PRAGMA fast_kdf_iter = 10;
1193     SELECT count(*) FROM t1;
1194   }
1196 } {1000}
1197 db close
1199 # open the database with the default hmac
1200 # kdf iteration count
1201 # to verify that it is not readable 
1202 do_test custom-hmac-kdf-iter-must-match {
1203   sqlite_orig db test.db
1204   catchsql {
1205     PRAGMA key = 'testkey';
1206     SELECT name FROM sqlite_master WHERE type='table';
1207   }
1208 } {1 {file is encrypted or is not a database}}
1209 db close
1210 file delete -force test.db
1212 # open the database and turn on auto_vacuum
1213 # then insert a bunch of data, delete it 
1214 # and verify that the file has become smaller
1215 # but can still be opened with the proper
1216 # key
1217 do_test auto-vacuum {
1218   sqlite_orig db test.db
1219   set rc {}
1221   execsql {
1222     PRAGMA key = 'testkey';
1223     PRAGMA auto_vacuum=FULL;
1224     CREATE table t1(a,b);
1225     BEGIN;
1226   }
1228   for {set i 1} {$i<=10000} {incr i} {
1229     set r [expr {int(rand()*500000)}]
1230     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
1231   }
1233   lappend rc [execsql {
1234     COMMIT;
1235     SELECT count(*) FROM t1;
1236   }]
1238   # grab current size of file
1239   set sz [file size test.db]
1240   
1241   # delete some records, and verify
1242   # autovacuum removes them
1243   execsql {
1244     DELETE FROM t1 WHERE rowid > 5000;
1245   } 
1247   db close
1249   # grab new file size, post
1250   # autovacuum
1251   set sz2 [file size test.db]
1253   # verify that the new size is 
1254   # smaller than the old size
1255   if {$sz > $sz2} { lappend rc true }
1257   sqlite_orig db test.db
1259   lappend rc [execsql {
1260     PRAGMA key = 'testkey';
1261     SELECT count(*) FROM t1;
1262   }]
1264 } {10000 true 5000}
1265 db close
1266 file delete -force test.db
1268 # open the database then insert a bunch of data.
1269 # then delete it and run a manual vacuum
1270 # verify that the file has become smaller
1271 # but can still be opened with the proper
1272 # key
1273 do_test vacuum {
1274   sqlite_orig db test.db
1275   set rc {}
1277   execsql {
1278     PRAGMA key = 'testkey';
1279     CREATE table t1(a,b);
1280     BEGIN;
1281   }
1283   for {set i 1} {$i<=10000} {incr i} {
1284     set r [expr {int(rand()*500000)}]
1285     execsql "INSERT INTO t1 VALUES($i,'value $r');" 
1286   }
1288   lappend rc [execsql {
1289     COMMIT;
1290     SELECT count(*) FROM t1;
1291   }]
1293   # grab current size of file
1294   set sz [file size test.db]
1296   execsql {
1297     DELETE FROM t1 WHERE rowid > 5000;
1298     VACUUM;
1299   } 
1300   db close
1302   # grab new file size, post
1303   # autovacuum
1304   set sz2 [file size test.db]
1306   # verify that the new size is 
1307   # smaller than the old size
1308   if {$sz > $sz2} { lappend rc true }
1310   sqlite_orig db test.db
1311   lappend rc [execsql {
1312     PRAGMA key = 'testkey';
1313     SELECT count(*) FROM t1;
1314   }]
1316 } {10000 true 5000}
1317 db close
1318 file delete -force test.db
1320 # test kdf_iter and other pragmas 
1321 # before a key is set. Verify that they
1322 # are no-ops
1323 do_test cipher-options-before-keys {
1324   sqlite_orig db test.db
1326   execsql {
1327     PRAGMA kdf_iter = 1000;
1328     PRAGMA cipher_page_size = 4096;
1329     PRAGMA cipher = 'aes-128-cbc';
1330     PRAGMA cipher_use_hmac = OFF;
1331     PRAGMA key = 'testkey';
1332     CREATE table t1(a,b);
1333     INSERT INTO t1 VALUES(1,2);
1334   }
1335   db close
1337   sqlite_orig db test.db
1339   execsql {
1340     PRAGMA key = 'testkey';
1341     SELECT count(*) FROM t1;
1342   }
1344 } {1}
1345 db close
1346 file delete -force test.db
1348 # open a 1.1.8 database (no HMAC), then 
1349 # try to open another 1.1.8 database. The
1350 # attached database should have the same hmac
1351 # setting as the original 
1352 do_test default-use-hmac-attach {
1353   file copy -force sqlcipher-1.1.8-testkey.db test.db
1354   sqlite_orig db test.db
1355   execsql {
1356     PRAGMA cipher_default_use_hmac = OFF;
1357     PRAGMA key = 'testkey';
1358     SELECT count(*) FROM t1;
1359     ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
1360     SELECT count(*) from db2.t1;
1361     PRAGMA cipher_default_use_hmac = ON;
1362   } 
1363 } {4 4}
1364 db close
1365 file delete -force test.db
1367 # open a 2.0 database (with HMAC), then 
1368 # try to a 1.1.8 database. this should 
1369 # fail because the hmac setting for the 
1370 # attached database is not compatible
1371 do_test attach-1.1.8-database-from-2.0-fails {
1372   sqlite_orig db test.db
1373   catchsql {
1374     PRAGMA key = 'testkey';
1375     CREATE table t1(a,b);
1376     ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
1377   } 
1378 } {1 {file is encrypted or is not a database}}
1379 db close
1380 file delete -force test.db
1382 # open a 2.0 database (with HMAC), then 
1383 # set the default hmac setting to OFF.
1384 # try to a 1.1.8 database. this should 
1385 # succeed now that hmac is off by default
1386 # before the attach
1387 do_test change-default-use-hmac-attach {
1388   sqlite_orig db test.db
1389   execsql {
1390     PRAGMA key = 'testkey';
1391     CREATE table t1(a,b);
1392     INSERT INTO t1(a,b) VALUES (1,2);
1393   }
1394   db close
1395   sqlite_orig db test.db
1396   execsql {
1397     PRAGMA key = 'testkey';
1398     SELECT count(*) FROM t1;
1399     PRAGMA cipher_default_use_hmac = OFF;
1400     ATTACH 'sqlcipher-1.1.8-testkey.db' AS db2 KEY 'testkey';
1401     SELECT count(*) from db2.t1;
1402     PRAGMA cipher_default_use_hmac = ON;
1403   } 
1404 } {1 4}
1405 db close
1406 file delete -force test.db
1408 # verify the pragma cipher_version
1409 # returns the currently configured
1410 # sqlcipher version
1411 do_test verify-pragma-cipher-version {
1412     sqlite_orig db test.db
1413     execsql {
1414         PRAGMA cipher_version;
1415     }
1416 } {2.1.1}
1417 db close
1418 file delete -force test.db
1420 # create a new database, insert some data
1421 # and delete some data with 
1422 # auto_vacuum on
1423 do_test auto-vacuum-full {
1424   sqlite_orig db test.db
1426   execsql {
1427     PRAGMA key = 'test123';
1428     PRAGMA auto_vacuum = FULL;
1429     CREATE TABLE t1(a,b);
1430     BEGIN;
1431   }
1433   for {set i 1} {$i<10000} {incr i} {
1434     set r [expr {int(rand()*32767)}]
1435     set r1 [expr {int(rand()*32767)}]
1436     execsql "INSERT INTO t1 VALUES($r,$r1);"
1437   }
1438   set r [expr {int(rand()*32767)}]
1439   execsql "DELETE FROM t1 WHERE a < $r;"
1441   execsql {
1442     COMMIT;
1443     PRAGMA integrity_check;
1444     PRAGMA freelist_count;
1445     SELECT (count(*) > 0) FROM t1;
1446   }
1447 } {ok 0 1}
1448 db close
1449 file delete -force test.db
1451 # create a new database, insert some data
1452 # and delete some data with 
1453 # auto_vacuum incremental 
1454 do_test auto-vacuum-incremental {
1455   sqlite_orig db test.db
1457   execsql {
1458     PRAGMA key = 'test123';
1459     PRAGMA auto_vacuum = INCREMENTAL;
1460     CREATE TABLE t1(a,b);
1461     BEGIN;
1462   }
1464   for {set i 1} {$i<10000} {incr i} {
1465     set r [expr {int(rand()*32767)}]
1466     set r1 [expr {int(rand()*32767)}]
1467     execsql "INSERT INTO t1 VALUES($r,$r1);"
1468   }
1469   set r [expr {int(rand()*32767)}]
1470   execsql "DELETE FROM t1 WHERE a < $r;"
1472   execsql {
1473     COMMIT;
1474     PRAGMA incremental_vacuum;
1475     PRAGMA freelist_count; 
1476     PRAGMA integrity_check;
1477     SELECT (count(*) > 0) FROM t1;
1478   }
1479 } {0 ok 1}
1480 db close
1481 file delete -force test.db
1484 # create a database with many hundred tables such that the schema
1485 # will overflow the first several pages of the database. verify the schema
1486 # is intact on open.
1487 do_test multipage-schema {
1488   sqlite_orig db test.db
1489   execsql {
1490     PRAGMA key = 'testkey';
1491     BEGIN EXCLUSIVE;
1492   } db
1493   
1494   for {set i 1} {$i<=300} {incr i} {
1495     execsql "CREATE TABLE tab$i (a TEXT, b TEXT, c TEXT, d TEXT, e TEXT, f TEXT, g TEXT, h TEXT, i TEXT, j TEXT, k, TEXT, l, m TEXT, n TEXT, o TEXT, p TEXT);" db
1496   }
1498   execsql {
1499     COMMIT;
1500   } db
1502   db close
1503   sqlite_orig db test.db
1505   execsql {
1506     PRAGMA key = 'testkey';
1507     SELECT count(*) FROM sqlite_master where type = 'table';
1508   } db
1510 } {300}
1511 db close
1512 file delete -force test.db
1514 # create a database with many hundred tables such that the schema
1515 # will overflow the first several pages of the database. this time, enable
1516 # autovacuum on the database, which will cause sqlite to do some "short reads"
1517 # after the end of the main database file. verify that there are no HMAC errors
1518 # resulting from the short reads, and that the schema is intact when 
1519 # the database is reopened
1520 do_test multipage-schema-autovacuum-shortread {
1521   sqlite_orig db test.db
1522   execsql {
1523     PRAGMA key = 'testkey';
1524     PRAGMA auto_vacuum = FULL;
1525     BEGIN EXCLUSIVE;
1526   } db
1527   
1528   for {set i 1} {$i<=300} {incr i} {
1529     execsql "CREATE TABLE tab$i (a TEXT, b TEXT, c TEXT, d TEXT, e TEXT, f TEXT, g TEXT, h TEXT, i TEXT, j TEXT, k, TEXT, l, m TEXT, n TEXT, o TEXT, p TEXT);" db
1530   }
1532   execsql {
1533     COMMIT;
1534   } db
1536   db close
1537   sqlite_orig db test.db
1539   execsql {
1540     PRAGMA key = 'testkey';
1541     SELECT count(*) FROM sqlite_master where type = 'table';
1542   } db
1544 } {300}
1545 db close
1546 file delete -force test.db
1548 # same as multi-page-schema-autovacuum-shortread, except
1549 # using write ahead log mode
1550 do_test multipage-schema-autovacuum-shortread-wal {
1551   sqlite_orig db test.db
1552   execsql {
1553     PRAGMA key = 'testkey';
1554     PRAGMA auto_vacuum = FULL;
1555     PRAGMA journal_mode = WAL;
1556     BEGIN EXCLUSIVE;
1557   } db
1558   
1559   for {set i 1} {$i<=300} {incr i} {
1560     execsql "CREATE TABLE tab$i (a TEXT, b TEXT, c TEXT, d TEXT, e TEXT, f TEXT, g TEXT, h TEXT, i TEXT, j TEXT, k, TEXT, l, m TEXT, n TEXT, o TEXT, p TEXT);" db
1561   }
1563   execsql {
1564     COMMIT;
1565   } db
1567   db close
1568   sqlite_orig db test.db
1570   execsql {
1571     PRAGMA key = 'testkey';
1572     SELECT count(*) FROM sqlite_master where type = 'table';
1573   } db
1574 } {300}
1575 db close
1576 file delete -force test.db
1578 # open a 2.0 database with little endian hmac page numbers (default)
1579 # verify it can be opened
1580 do_test open-2.0-le-database {
1581   sqlite_orig db sqlcipher-2.0-le-testkey.db
1582   execsql {
1583     PRAGMA key = 'testkey';
1584     SELECT count(*) FROM t1;
1585     SELECT * FROM t1;
1586   } 
1587 } {4 1 1 one one 1 2 one two}
1588 db close
1590 # open a 2.0 database with big-endian hmac page numbers
1591 # verify it can be opened
1592 do_test open-2.0-be-database {
1593   sqlite_orig db sqlcipher-2.0-be-testkey.db
1594   execsql {
1595     PRAGMA key = 'testkey';
1596     PRAGMA cipher_hmac_pgno = be;
1597     SELECT count(*) FROM t1;
1598     SELECT * FROM t1;
1599   } 
1600 } {4 1 1 one one 1 2 one two}
1601 db close
1603 # open a 2.0 database with big-endian hmac page numbers
1604 # attach a new database with little endian page numbers (default)
1605 # copy schema between the two, and verify the latter 
1606 # can be opened
1607 do_test be-to-le-migration {
1608   sqlite_orig db sqlcipher-2.0-be-testkey.db
1610   execsql {
1611     PRAGMA key = 'testkey';
1612     PRAGMA cipher_hmac_pgno = be;
1613     ATTACH DATABASE 'test.db' AS db2 KEY 'testkey'; 
1614     CREATE TABLE db2.t1(a,b);
1615     INSERT INTO db2.t1 SELECT * FROM main.t1;
1616     DETACH DATABASE db2;
1617   }
1618   db close
1620   sqlite_orig db test.db
1621   execsql {
1622     PRAGMA key = 'testkey';
1623     SELECT count(*) FROM t1;
1624     SELECT * FROM t1;
1625   }
1626 } {4 1 1 one one 1 2 one two}
1627 db close
1628 file delete -force test.db
1630 # verify the pragma cipher_use_hmac
1631 # is set to true be default
1632 do_test verify-pragma-cipher-use-hmac-default {
1633     sqlite_orig db test.db
1634     execsql {
1635         PRAGMA key = 'test';
1636         PRAGMA cipher_use_hmac;
1637     }
1638 } {1}
1639 db close
1640 file delete -force test.db
1642 # verify the pragma cipher_use_hmac
1643 # reports the flag turned off
1644 do_test verify-pragma-cipher-use-hmac-off {
1645     sqlite_orig db test.db
1646     execsql {
1647         PRAGMA key = 'test';
1648         PRAGMA cipher_use_hmac = off;
1649         PRAGMA cipher_use_hmac;
1650     }
1651 } {0}
1652 db close
1653 file delete -force test.db
1655 # verify the pragma default_cipher_use_hmac
1656 # is set to true by default
1657 do_test verify-pragma-cipher-default-use-hmac-default {
1658     sqlite_orig db test.db
1659     execsql {
1660         PRAGMA cipher_default_use_hmac;
1661     }
1662 } {1}
1663 db close
1664 file delete -force test.db
1666 # verify the pragma default_cipher_use_hmac
1667 # reports the flag turned off
1668 do_test verify-pragma-cipher-default-use-hmac-off {
1669     sqlite_orig db test.db
1670     execsql {
1671         PRAGMA cipher_default_use_hmac = off;
1672         PRAGMA cipher_default_use_hmac;
1673         -- Be sure to turn cipher_default_use_hmac
1674         -- back on or it will break later tests 
1675         -- (it's a global flag)
1676         PRAGMA cipher_default_use_hmac = ON;
1677     }
1678 } {0}
1679 db close
1680 file delete -force test.db
1682 # verify the pragma kdf_iter
1683 # reports the default value
1684 do_test verify-pragma-kdf-iter-reports-default {
1685     sqlite_orig db test.db
1686     execsql {
1687         PRAGMA key = 'test';
1688         PRAGMA kdf_iter;
1689     }
1690 } {4000}
1691 db close
1692 file delete -force test.db
1694 # verify the pragma kdf_iter
1695 # reports value changed
1696 do_test verify-pragma-kdf-iter-reports-value-changed {
1697     sqlite_orig db test.db
1698     execsql {
1699         PRAGMA key = 'test';
1700         PRAGMA kdf_iter = 8000;
1701         PRAGMA kdf_iter;
1702     }
1703 } {8000}
1704 db close
1705 file delete -force test.db
1707 # verify the pragma fast_kdf_iter
1708 # reports the default value
1709 do_test verify-pragma-fast-kdf-iter-reports-default {
1710     sqlite_orig db test.db
1711     execsql {
1712         PRAGMA key = 'test';
1713         PRAGMA fast_kdf_iter;
1714     }
1715 } {2}
1716 db close
1717 file delete -force test.db
1719 # verify the pragma fast_kdf_iter
1720 # reports value changed
1721 do_test verify-pragma-kdf-iter-reports-value-changed {
1722     sqlite_orig db test.db
1723     execsql {
1724         PRAGMA key = 'test';
1725         PRAGMA fast_kdf_iter = 4000;
1726         PRAGMA fast_kdf_iter;
1727     }
1728 } {4000}
1729 db close
1730 file delete -force test.db
1732 # verify the pragma cipher_page_size
1733 # reports default value
1734 do_test verify-pragma-cipher-page-size-default {
1735     sqlite_orig db test.db
1736     execsql {
1737         PRAGMA key = 'test';
1738         PRAGMA cipher_page_size;
1739     }
1740 } {1024}
1741 db close
1742 file delete -force test.db
1744 # verify the pragma cipher_page_size
1745 # reports change in value
1746 do_test verify-pragma-cipher-page-size-changed {
1747     sqlite_orig db test.db
1748     execsql {
1749         PRAGMA key = 'test';
1750         PRAGMA cipher_page_size = 4096;
1751         PRAGMA cipher_page_size;
1752     }
1753 } {4096}
1754 db close
1755 file delete -force test.db
1757 # verify the pragma cipher
1758 # reports the default value
1759 do_test verify-pragma-cipher-default {
1760     sqlite_orig db test.db
1761     execsql {
1762         PRAGMA key = 'test';
1763         PRAGMA cipher;
1764     }
1765 } {AES-256-CBC}
1766 db close
1767 file delete -force test.db
1769 # verify the pragma cipher
1770 # reports a change in value
1771 do_test verify-pragma-cipher-changed {
1772     sqlite_orig db test.db
1773     execsql {
1774         PRAGMA key = 'test';
1775         PRAGMA cipher = 'AES-256-ECB';
1776         PRAGMA cipher;
1777     }
1778 } {AES-256-ECB}
1779 db close
1780 file delete -force test.db
1782 # verify the pragma cipher_hmac_salt_mask reports default
1783 do_test verify-pragma-hmac-salt-mask-reports-default {
1784     sqlite_orig db test.db
1785     execsql {
1786         PRAGMA key = 'test';
1787         PRAGMA cipher_hmac_salt_mask;
1788     }
1789 } {3a}
1790 db close
1791 file delete -force test.db
1793 # verify the pragma cipher_hmac_salt_mask reports
1794 # reports value changed
1795 do_test verify-pragma-hmac-salt-mask-reports-value-changed {
1796     sqlite_orig db test.db
1797     execsql {
1798         PRAGMA key = 'test';
1799         PRAGMA cipher_hmac_salt_mask = "x'11'";
1800         PRAGMA cipher_hmac_salt_mask;
1801     }
1802 } {11}
1803 db close
1804 file delete -force test.db
1806 # verify the pragma cipher_hmac_pgno reports default
1807 do_test verify-pragma-hmac-pgno-reports-default {
1808     sqlite_orig db test.db
1809     execsql {
1810         PRAGMA key = 'test';
1811         PRAGMA cipher_hmac_pgno;
1812     }
1813 } {le}
1814 db close
1815 file delete -force test.db
1817 # verify the pragma cipher_hmac_pgno 
1818 # reports value changed
1819 do_test verify-pragma-hmac-pgno-reports-value-changed {
1820     sqlite_orig db test.db
1821     execsql {
1822         PRAGMA key = 'test';
1823         PRAGMA cipher_hmac_pgno = be;
1824         PRAGMA cipher_hmac_pgno;
1825         PRAGMA cipher_hmac_pgno = native;
1826         PRAGMA cipher_hmac_pgno;
1827         PRAGMA cipher_hmac_pgno = le;
1828         PRAGMA cipher_hmac_pgno;
1829     }
1830 } {be native le}
1831 db close
1832 file delete -force test.db
1834 # open a 2.0 beta database with 4000 round hmac kdf and 0x00 
1835 # hmac salt mask 
1836 # verify it can be opened
1837 do_test open-2.0-beta-database {
1838   sqlite_orig db sqlcipher-2.0-beta-testkey.db
1839   execsql {
1840     PRAGMA key = 'testkey';
1841     PRAGMA fast_kdf_iter = 4000;
1842     PRAGMA cipher_hmac_salt_mask = "x'00'";
1843     SELECT count(*) FROM t1;
1844     SELECT * FROM t1;
1845   } 
1846 } {2 test-0-0 test-0-1 test-1-0 test-1-1}
1847 db close
1849 # open a 2.0 beta database 
1850 # attach a new standard database
1851 # copy schema between the two, and verify the latter 
1852 # can be opened
1853 do_test 2.0-beta-to-2.0-migration {
1854   sqlite_orig db sqlcipher-2.0-beta-testkey.db
1856   execsql {
1857     PRAGMA key = 'testkey';
1858     PRAGMA cipher_hmac_salt_mask = "x'00'";
1859     PRAGMA fast_kdf_iter = 4000;
1860     SELECT count(*) FROM sqlite_master;
1862     PRAGMA cipher_hmac_salt_mask = "x'3a'";
1863     ATTACH DATABASE 'test.db' AS db2 KEY 'testkey'; 
1864     
1865     CREATE TABLE db2.t1(a,b);
1866     INSERT INTO db2.t1 SELECT * FROM main.t1;
1867     DETACH DATABASE db2;
1868   }
1869   db close
1871   sqlite_orig db test.db
1872   execsql {
1873     PRAGMA key = 'testkey';
1874     SELECT * FROM t1;
1875   }
1876 } {test-0-0 test-0-1 test-1-0 test-1-1}
1877 db close
1878 file delete -force test.db
1880 finish_test