static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) { int rc, page_sz, reserve_sz; page_sz = sqlcipher_codec_ctx_get_pagesize(ctx); reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx); sqlite3_mutex_enter(db->mutex); db->nextPagesize = page_sz; pDb->pBt->pBt->pageSizeFixed = 0; CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz)); rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0); sqlite3_mutex_leave(db->mutex); return rc; }
static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) { int rc, page_sz, reserve_sz; page_sz = sqlcipher_codec_ctx_get_pagesize(ctx); reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx); sqlite3_mutex_enter(db->mutex); db->nextPagesize = page_sz; /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else sqliteBtreeSetPageSize will block the change */ pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; CODEC_TRACE(("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz)); rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0); sqlite3_mutex_leave(db->mutex); return rc; }
int sqliterkCryptoSetCipher(sqliterk_pager *pager, sqliterk_file *fd, const sqliterk_cipher_conf *conf) { codec_ctx *codec = NULL; int rc; if (conf) { // Check arguments. if (!conf->key || conf->key_len <= 0) return SQLITERK_MISUSE; // SQLite library must be initialized before calling sqlcipher_activate(), // or it will cause a deadlock. sqlite3_initialize(); sqlcipher_activate(); // XXX: fake BTree structure passed to sqlcipher_codec_ctx_init. // Member of such structure is assigned but never used by repair kit. int fake_db[8]; sqlite3_file_rkredir file; struct sqlite3_io_methods methods = {0}; methods.xRead = sqliterkRead; file.pMethods = &methods; file.fd = fd; file.kdf_salt = conf->kdf_salt; // Initialize codec context. rc = sqlcipher_codec_ctx_init(&codec, fake_db, NULL, &file, conf->key, conf->key_len); if (rc != SQLITE_OK) goto bail_sqlite_errstr; // Set cipher. if (conf->cipher_name) { rc = sqlcipher_codec_ctx_set_cipher(codec, conf->cipher_name, CIPHER_READWRITE_CTX); if (rc != SQLITE_OK) goto bail_sqlite_errstr; } // Set page size. if (conf->page_size > 0) { rc = sqlcipher_codec_ctx_set_pagesize(codec, conf->page_size); if (rc != SQLITE_OK) goto bail_sqlite_errstr; } // Set HMAC usage. if (conf->use_hmac >= 0) { rc = sqlcipher_codec_ctx_set_use_hmac(codec, conf->use_hmac); if (rc != SQLITE_OK) goto bail_sqlite_errstr; } // Set KDF Iteration. if (conf->kdf_iter > 0) { rc = sqlcipher_codec_ctx_set_kdf_iter(codec, conf->kdf_iter, CIPHER_READWRITE_CTX); if (rc != SQLITE_OK) goto bail; } // Update pager page size. int page_sz = sqlcipher_codec_ctx_get_pagesize(codec); int reserve_sz = sqlcipher_codec_ctx_get_reservesize(codec); pager->pagesize = page_sz; pager->reservedBytes = reserve_sz; } if (pager->codec) { sqlcipher_codec_ctx_free(&pager->codec); sqlcipher_deactivate(); } pager->codec = codec; return SQLITERK_OK; bail_sqlite_errstr: sqliterkOSError(SQLITERK_CANTOPEN, "Failed to initialize cipher context: %s", sqlite3_errstr(rc)); rc = SQLITERK_CANTOPEN; bail: if (codec) sqlcipher_codec_ctx_free(&codec); sqlcipher_deactivate(); return rc; }