コード例 #1
0
ファイル: crypto.c プロジェクト: TheDleo/ocRosa
/*
 * sqlite3Codec can be called in multiple modes.
 * encrypt mode - expected to return a pointer to the 
 *   encrypted data without altering pData.
 * decrypt mode - expected to return a pointer to pData, with
 *   the data decrypted in the input buffer
 */
void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) {
  codec_ctx *ctx = (codec_ctx *) iCtx;
  int pg_sz = SQLITE_DEFAULT_PAGE_SIZE;
  int offset = 0;
  unsigned char *pData = (unsigned char *) data;
 
  CODEC_TRACE(("sqlite3Codec: entered pgno=%d, mode=%d, ctx->mode_rekey=%d, pg_sz=%d\n", pgno, mode, ctx->mode_rekey, pg_sz));

  /* derive key on first use if necessary */
  if(ctx->read_ctx->derive_key) {
    codec_key_derive(ctx, ctx->read_ctx);
    ctx->read_ctx->derive_key = 0;
  }

  if(ctx->write_ctx->derive_key) {
    if(cipher_ctx_cmp(ctx->write_ctx, ctx->read_ctx) == 0) {
      cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx); // the relevant parameters are the same, just copy read key
    } else {
      codec_key_derive(ctx, ctx->write_ctx);
      ctx->write_ctx->derive_key = 0;
    }
  }


  if(pgno == 1) offset = FILE_HEADER_SZ; /* adjust starting pointers in data page for header offset on first page*/

  CODEC_TRACE(("sqlite3Codec: switch mode=%d offset=%d\n",  mode, offset));
  switch(mode) {
    case 0: /* decrypt */
    case 2:
    case 3:
      if(pgno == 1) memcpy(ctx->buffer, SQLITE_FILE_HEADER, FILE_HEADER_SZ); /* copy file header to the first 16 bytes of the page */ 
      codec_cipher(ctx->read_ctx, pgno, CIPHER_DECRYPT, pg_sz - offset, pData + offset, ctx->buffer + offset);
      memcpy(pData, ctx->buffer, pg_sz); /* copy buffer data back to pData and return */
      return pData;
      break;
    case 6: /* encrypt */
      if(pgno == 1) memcpy(ctx->buffer, ctx->kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */ 
      codec_cipher(ctx->write_ctx, pgno, CIPHER_ENCRYPT, pg_sz - offset, pData + offset, ctx->buffer + offset);
      return ctx->buffer; /* return persistent buffer data, pData remains intact */
      break;
    case 7:
      if(pgno == 1) memcpy(ctx->buffer, ctx->kdf_salt, FILE_HEADER_SZ); /* copy salt to output buffer */ 
      codec_cipher(ctx->read_ctx, pgno, CIPHER_ENCRYPT, pg_sz - offset, pData + offset, ctx->buffer + offset);
      return ctx->buffer; /* return persistent buffer data, pData remains intact */
      break;
    default:
      return pData;
      break;
  }
}
コード例 #2
0
ファイル: crypto.c プロジェクト: qianwang/sqlcipher
/*
 * sqlite3Codec can be called in multiple modes.
 * encrypt mode - expected to return a pointer to the 
 *   encrypted data without altering pData.
 * decrypt mode - expected to return a pointer to pData, with
 *   the data decrypted in the input buffer
 */
void* sqlite3Codec(void *iCtx, void *pData, Pgno pgno, int mode) {
  int emode;
  codec_ctx *ctx = (codec_ctx *) iCtx;
  int pg_sz = sqlite3BtreeGetPageSize(ctx->pBt);
 
  switch(mode) {
    case 0: /* decrypt */
    case 2:
    case 3:
      emode = CIPHER_DECRYPT;
      break;
    case 6: /* encrypt */
    case 7:
      emode = CIPHER_ENCRYPT;
      break;
    default:
      return pData;
      break;
  }

  if(pgno == 1) { 
    /* if this is a read & decrypt operation on the first page then copy the 
       first 16 bytes off the page into the context's random salt buffer
    */
    if(emode == CIPHER_ENCRYPT) {
      memcpy(ctx->buffer, ctx->salt, FILE_HEADER_SZ);
    } else {
      memcpy(ctx->buffer, SQLITE_FILE_HEADER, FILE_HEADER_SZ);
    }
    
    /* adjust starting pointers in data page for header offset */
    codec_cipher(ctx, pgno, emode, pg_sz - FILE_HEADER_SZ, pData + FILE_HEADER_SZ, ctx->buffer + FILE_HEADER_SZ);
  } else {
    codec_cipher(ctx, pgno, emode, pg_sz, pData, ctx->buffer);
  }
 
  if(emode == CIPHER_ENCRYPT) {
    return ctx->buffer; /* return persistent buffer data, pData remains intact */
  } else {
    memcpy(pData, ctx->buffer, pg_sz); /* copy buffer data back to pData and return */
    return pData;
  }
}