DBD-SQLcipher
view release on metacpan or search on metacpan
** managed by the prepared statement S and will be automatically freed when
** S is finalized.
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
** set to the total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
** to the total number of rows examined by all iterations of the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
** <dd>^The "double" variable pointed to by the T parameter will be set to the
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop. If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
** product of this value for all prior loops with the same SELECTID will
** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
int nTableLock; /* Number of locks in aTableLock */
TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
/* Information used while coding trigger programs. */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
int addrSkipPK; /* Address of instruction to skip PRIMARY KEY index */
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
u32 newmask; /* Mask of new.* columns referenced */
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
u8 disableTriggers; /* True to disable triggers */
/************************************************************************
** Above is constant between recursions. Below is reset before and after
** each recursion. The boundary between these two regions is determined
** using offsetof(Parse,nVar) so the nVar field must be the first field
/* possible flags for cipher_ctx->flags */
#define CIPHER_FLAG_HMAC 0x01
#define CIPHER_FLAG_LE_PGNO 0x02
#define CIPHER_FLAG_BE_PGNO 0x04
#ifndef DEFAULT_CIPHER_FLAGS
#define DEFAULT_CIPHER_FLAGS CIPHER_FLAG_HMAC | CIPHER_FLAG_LE_PGNO
#endif
/* by default, sqlcipher will use a reduced number of iterations to generate
the HMAC key / or transform a raw cipher key
*/
#ifndef FAST_PBKDF2_ITER
#define FAST_PBKDF2_ITER 2
#endif
/* this if a fixed random array that will be xor'd with the database salt to ensure that the
salt passed to the HMAC key derivation function is not the same as that used to derive
the encryption key. This can be overridden at compile time but it will make the resulting
binary incompatible with the default builds when using HMAC. A future version of SQLcipher
codec_vdbe_return_static_string(pParse, "cipher",
sqlcipher_codec_ctx_get_cipher(ctx, 2));
}
}
}else
if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){
if(ctx) sqlcipher_codec_ctx_set_cipher(ctx, zRight, 1); // change write cipher only
}else
if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){
if( zRight ) {
sqlcipher_set_default_kdf_iter(atoi(zRight)); // change default KDF iterations
} else {
char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter());
codec_vdbe_return_static_string(pParse, "cipher_default_kdf_iter", kdf_iter);
sqlite3_free(kdf_iter);
}
}else
if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){
if(ctx) {
if( zRight ) {
sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration
if( zRight ) {
sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight), 2); // change of RW PBKDF2 iteration
} else {
char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx, 2));
codec_vdbe_return_static_string(pParse, "fast_kdf_iter", fast_kdf_iter);
sqlite3_free(fast_kdf_iter);
}
}
}else
if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){
if(ctx) sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight), 1); // write iterations only
}else
if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){
if(ctx) {
if( zRight ) {
int size = atoi(zRight);
rc = sqlcipher_codec_ctx_set_pagesize(ctx, size);
if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx);
if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc);
} else {
int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */
const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n"));
cipher_hex2bin(z, n, c_ctx->key);
} else if (c_ctx->pass_sz == (((c_ctx->key_sz + ctx->kdf_salt_sz) * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) == 0) {
const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */
CODEC_TRACE(("cipher_ctx_key_derive: using raw key from hex\n"));
cipher_hex2bin(z, (c_ctx->key_sz * 2), c_ctx->key);
cipher_hex2bin(z + (c_ctx->key_sz * 2), (ctx->kdf_salt_sz * 2), ctx->kdf_salt);
} else {
CODEC_TRACE(("cipher_ctx_key_derive: deriving key using full PBKDF2 with %d iterations\n", c_ctx->kdf_iter));
c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->pass, c_ctx->pass_sz,
ctx->kdf_salt, ctx->kdf_salt_sz, c_ctx->kdf_iter,
c_ctx->key_sz, c_ctx->key);
}
/* set the context "keyspec" containing the hex-formatted key and salt to be used when attaching databases */
if((rc = sqlcipher_cipher_ctx_set_keyspec(c_ctx, c_ctx->key, c_ctx->key_sz, ctx->kdf_salt, ctx->kdf_salt_sz)) != SQLITE_OK) return rc;
/* if this context is setup to use hmac checks, generate a seperate and different
key for HMAC. In this case, we use the output of the previous KDF as the input to
/* start by copying the kdf key into the hmac salt slot
then XOR it with the fixed hmac salt defined at compile time
this ensures that the salt passed in to derive the hmac key, while
easy to derive and publically known, is not the same as the salt used
to generate the encryption key */
memcpy(ctx->hmac_kdf_salt, ctx->kdf_salt, ctx->kdf_salt_sz);
for(i = 0; i < ctx->kdf_salt_sz; i++) {
ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
}
CODEC_TRACE(("cipher_ctx_key_derive: deriving hmac key from encryption key using PBKDF2 with %d iterations\n",
c_ctx->fast_kdf_iter));
c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->key, c_ctx->key_sz,
ctx->hmac_kdf_salt, ctx->kdf_salt_sz, c_ctx->fast_kdf_iter,
c_ctx->key_sz, c_ctx->hmac_key);
}
c_ctx->derive_key = 0;
return SQLITE_OK;
CollSeq *pColl; /* Collating sequence to on a column */
WhereLoop *pLoop; /* The Loop object */
char *zNotUsed; /* Extra space on the end of pIdx */
Bitmask idxCols; /* Bitmap of columns used for indexing */
Bitmask extraCols; /* Bitmap of additional columns */
u8 sentWarning = 0; /* True if a warnning has been issued */
Expr *pPartial = 0; /* Partial Index Expression */
int iContinue = 0; /* Jump here to skip excluded rows */
/* Generate code to skip over the creation and initialization of the
** transient index on 2nd and subsequent iterations of the loop. */
v = pParse->pVdbe;
assert( v!=0 );
addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
nKeyCol = 0;
pTable = pSrc->pTab;
pWCEnd = &pWC->a[pWC->nTerm];
pLoop = pLevel->pWLoop;
** terms only. If it is modified, this value is restored before this
** function returns.
**
** If pProbe->tnum==0, that means pIndex is a fake index used for the
** INTEGER PRIMARY KEY.
*/
static int whereLoopAddBtreeIndex(
WhereLoopBuilder *pBuilder, /* The WhereLoop factory */
struct SrcList_item *pSrc, /* FROM clause term being analyzed */
Index *pProbe, /* An index on pSrc */
LogEst nInMul /* log(Number of iterations due to IN) */
){
WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection malloc context */
WhereLoop *pNew; /* Template WhereLoop under construction */
WhereTerm *pTerm; /* A WhereTerm under consideration */
int opMask; /* Valid operators for constraints */
WhereScan scan; /* Iterator for WHERE terms */
Bitmask saved_prereq; /* Original value of pNew->prereq */
u16 saved_nLTerm; /* Original value of pNew->nLTerm */
** the ORDER BY clause are already in order, where X is the array
** index. */
aSortCost = (LogEst*)pX;
memset(aSortCost, 0, sizeof(LogEst) * nOrderBy);
}
assert( aSortCost==0 || &pSpace[nSpace]==(char*)&aSortCost[nOrderBy] );
assert( aSortCost!=0 || &pSpace[nSpace]==(char*)pX );
/* Seed the search with a single WherePath containing zero WhereLoops.
**
** TUNING: Do not let the number of iterations go above 25. If the cost
** of computing an automatic index is not paid back within the first 25
** rows, then do not use the automatic index. */
aFrom[0].nRow = MIN(pParse->nQueryLoop, 46); assert( 46==sqlite3LogEst(25) );
nFrom = 1;
assert( aFrom[0].isOrdered==0 );
if( nOrderBy ){
/* If nLoop is zero, then there are no FROM terms in the query. Since
** in this case the query may return a maximum of one row, the results
** are already in the requested order. Set isOrdered to nOrderBy to
** indicate this. Or, if nLoop is greater than zero, set isOrdered to
** managed by the prepared statement S and will be automatically freed when
** S is finalized.
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
** set to the total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
** to the total number of rows examined by all iterations of the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
** <dd>^The "double" variable pointed to by the T parameter will be set to the
** query planner's estimate for the average number of rows output from each
** iteration of the X-th loop. If the query planner's estimates was accurate,
** then this value will approximate the quotient NVISIT/NLOOP and the
** product of this value for all prior loops with the same SELECTID will
** be the NLOOP value for the current loop.
**
** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
( run in 1.680 second using v1.01-cache-2.11-cpan-5511b514fd6 )