示例#1
0
        /**
         * Derive an encryption key for a cipher contex key based on the raw password.
         *
         * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
         * the key space (i.e 64 hex chars for a 256 bit key) then the key data will be used directly.
         *
         * Otherwise, a key data will be derived using PBKDF2
         *
         * returns SQLITE_OK if initialization was successful
         * returns SQLITE_NOMEM if the key could't be derived (for instance if pass is null or pass_sz is 0)
         */
        static int codec_key_derive(codec_ctx ctx, cipher_ctx c_ctx)
        {
            CODEC_TRACE("codec_key_derive: entered c_ctx.pass=%s, c_ctx.pass_sz=%d ctx.iv=%d ctx.iv_sz=%d c_ctx.kdf_iter=%d c_ctx.key_sz=%d\n",
                        c_ctx.pass, c_ctx.pass_sz, c_ctx.iv, c_ctx.iv_sz, c_ctx.key_sz);

            if (c_ctx.pass != null && c_ctx.pass_sz > 0)
            { // if pass is not null
                if ((c_ctx.pass_sz == (c_ctx.key_sz * 2) + 3) && c_ctx.pass.StartsWith("x'", StringComparison.InvariantCultureIgnoreCase))
                {
                    int    n = c_ctx.pass_sz - 3;       /* adjust for leading x' and tailing ' */
                    string z = c_ctx.pass.Substring(2); // + 2; /* adjust lead offset of x' */
                    CODEC_TRACE("codec_key_derive: deriving key from hex\n");
                    c_ctx.key = sqlite3HexToBlob(null, z, n);
                }
                else
                {
                    CODEC_TRACE("codec_key_derive: deriving key using AES256\n");

                    Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(c_ctx.pass, c_ctx.iv, 2010);
                    c_ctx.key_sz = 32;
                    c_ctx.key    = k1.GetBytes(c_ctx.key_sz);
                }
#if NET_2_0
                Aes.BlockSize    = 0x80;
                Aes.FeedbackSize = 8;
                Aes.KeySize      = 0x100;
                Aes.Mode         = CipherMode.CBC;
#endif
                c_ctx.encryptor = Aes.CreateEncryptor(c_ctx.key, c_ctx.iv);
                c_ctx.decryptor = Aes.CreateDecryptor(c_ctx.key, c_ctx.iv);
                return(SQLITE_OK);
            }
            ;
            return(SQLITE_ERROR);
        }
示例#2
0
        /**
         * Derive an encryption key for a cipher contex key based on the raw password.
         *
         * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
         * the key space (i.e 64 hex chars for a 256 bit key) then the key data will be used directly.
         *
         * Otherwise, a key data will be derived using PBKDF2
         *
         * returns SQLITE_OK if initialization was successful
         * returns SQLITE_NOMEM if the key could't be derived (for instance if pass is null or pass_sz is 0)
         */
        static int codec_key_derive(codec_ctx ctx, cipher_ctx c_ctx)
        {
            CODEC_TRACE("codec_key_derive: entered c_ctx.pass=%s, c_ctx.pass_sz=%d ctx.iv=%d ctx.iv_sz=%d c_ctx.kdf_iter=%d c_ctx.key_sz=%d\n",
                        c_ctx.pass, c_ctx.pass_sz, c_ctx.iv, c_ctx.iv_sz, c_ctx.key_sz);

            if (c_ctx.pass != null && c_ctx.pass_sz > 0)
            { // if pass is not null
                if ((c_ctx.pass_sz == (c_ctx.key_sz * 2) + 3) && sqlite3StrNICmp(c_ctx.pass, "x'", 2) == 0)
                {
                    int    n = c_ctx.pass_sz - 3;       /* adjust for leading x' and tailing ' */
                    string z = c_ctx.pass.Substring(2); // + 2; /* adjust lead offset of x' */
                    CODEC_TRACE("codec_key_derive: deriving key from hex\n");
                    c_ctx.key = sqlite3HexToBlob(null, z, n);
                }
                else
                {
                    CODEC_TRACE("codec_key_derive: deriving key using AES256\n");

                    Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(c_ctx.pass, c_ctx.iv, 2010);
                    c_ctx.key_sz = 32;
                    c_ctx.key    = k1.GetBytes(c_ctx.key_sz);
                }
                c_ctx.encryptor = Aes.CreateEncryptor(c_ctx.key, c_ctx.iv);
                c_ctx.decryptor = Aes.CreateDecryptor(c_ctx.key, c_ctx.iv);
                return(SQLITE_OK);
            }
            ;
            return(SQLITE_ERROR);
        }
示例#3
0
 /**
  * Initialize a new cipher_ctx struct. This function will allocate memory
  * for the cipher context and for the key
  *
  * returns SQLITE_OK if initialization was successful
  * returns SQLITE_NOMEM if an error occured allocating memory
  */
 static int cipher_ctx_init(ref cipher_ctx iCtx)
 {
     iCtx = new cipher_ctx();
     //iCtx = sqlite3Malloc( sizeof( cipher_ctx ) );
     //ctx = *iCtx;
     //if ( ctx == null ) return SQLITE_NOMEM;
     //memset( ctx, 0, sizeof( cipher_ctx ) );
     //ctx.key =  sqlite3Malloc( EVP_MAX_KEY_LENGTH );
     //if ( ctx.key == null ) return SQLITE_NOMEM;
     return(SQLITE_OK);
 }
示例#4
0
 /**
  * Set the raw password / key data for a cipher context
  *
  * returns SQLITE_OK if assignment was successfull
  * returns SQLITE_NOMEM if an error occured allocating memory
  * returns SQLITE_ERROR if the key couldn't be set because the pass was null or size was zero
  */
 static int cipher_ctx_set_pass(cipher_ctx ctx, string zKey, int nKey)
 {
     ctx.pass    = null; // codec_free( ctx.pass, ctx.pass_sz );
     ctx.pass_sz = nKey;
     if (!String.IsNullOrEmpty(zKey) && nKey > 0)
     {
         //ctx.pass = sqlite3Malloc(nKey);
         //if(ctx.pass == null) return SQLITE_NOMEM;
         ctx.pass = zKey;//memcpy(ctx.pass, zKey, nKey);
         return(SQLITE_OK);
     }
     return(SQLITE_ERROR);
 }
示例#5
0
        /**
         * Compare one cipher_ctx to another.
         *
         * returns 0 if all the parameters (except the derived key data) are the same
         * returns 1 otherwise
         */
        static int cipher_ctx_cmp(cipher_ctx c1, cipher_ctx c2)
        {
            CODEC_TRACE("cipher_ctx_cmp: entered c1=%d c2=%d\n", c1, c2);

            if (c1.key_sz == c2.key_sz &&
                c1.pass_sz == c2.pass_sz &&
                c1.pass == c2.pass
                )
            {
                return(0);
            }
            return(1);
        }
示例#6
0
        /**
         * Copy one cipher_ctx to another. For instance, assuming that read_ctx is a
         * fully initialized context, you could copy it to write_ctx and all yet data
         * and pass information across
         *
         * returns SQLITE_OK if initialization was successful
         * returns SQLITE_NOMEM if an error occured allocating memory
         */
        static int cipher_ctx_copy(cipher_ctx target, cipher_ctx source)
        {
            //byte[] key = target.key;
            CODEC_TRACE("cipher_ctx_copy: entered target=%d, source=%d\n", target, source);
            //codec_free(target.pass, target.pass_sz);
            source.CopyTo(target);//memcpy(target, source, sizeof(cipher_ctx);

            //target.key = key; //restore pointer to previously allocated key data
            //memcpy(target.key, source.key, EVP_MAX_KEY_LENGTH);
            //target.pass = sqlite3Malloc(source.pass_sz);
            //if(target.pass == null) return SQLITE_NOMEM;
            //memcpy(target.pass, source.pass, source.pass_sz);
            return(SQLITE_OK);
        }
示例#7
0
        /**
         * free and wipe memory associated with a cipher_ctx
         */
        static void cipher_ctx_free(ref cipher_ctx ictx)
        {
            cipher_ctx ctx = ictx;

            CODEC_TRACE("cipher_ctx_free: entered ictx=%d\n", ictx);
            ctx.pass = null;//codec_free(ctx.pass, ctx.pass_sz);
            if (ctx.key != null)
            {
                Array.Clear(ctx.key, 0, ctx.key.Length);//codec_free(ctx.key, ctx.key_sz);
            }
            if (ctx.iv != null)
            {
                Array.Clear(ctx.iv, 0, ctx.iv.Length);
            }
            ictx = new cipher_ctx();// codec_free( ref ctx, sizeof( cipher_ctx ) );
        }
示例#8
0
 public void CopyTo(cipher_ctx ct)
 {
     ct.derive_key = derive_key;
     ct.pass       = pass;
     ct.pass_sz    = pass_sz;
     if (key != null)
     {
         ct.key = new byte[key.Length];
         key.CopyTo(ct.key, 0);
     }
     ct.key_sz = key_sz;
     if (iv != null)
     {
         ct.iv = new byte[iv.Length];
         iv.CopyTo(ct.iv, 0);
     }
     ct.iv_sz = iv_sz;
 }
示例#9
0
            public cipher_ctx Copy()
            {
                cipher_ctx c = new cipher_ctx();

                c.derive_key = derive_key;
                c.pass       = pass;
                c.pass_sz    = pass_sz;
                if (key != null)
                {
                    c.key = new byte[key.Length];
                    key.CopyTo(c.key, 0);
                }
                c.key_sz = key_sz;
                if (iv != null)
                {
                    c.iv = new byte[iv.Length];
                    iv.CopyTo(c.iv, 0);
                }
                c.iv_sz = iv_sz;
                return(c);
            }
示例#10
0
        /*
         * ctx - codec context
         * pgno - page number in database
         * size - size in bytes of input and output buffers
         * mode - 1 to encrypt, 0 to decrypt
         * in - pointer to input bytes
         * out - pouter to output bytes
         */
        static int codec_cipher(cipher_ctx ctx, Pgno pgno, int mode, int size, byte[] bIn, byte[] bOut)
        {
            //int iv;
            //int tmp_csz, csz;

            CODEC_TRACE("codec_cipher:entered pgno=%d, mode=%d, size=%d\n", pgno, mode, size);

            /* just copy raw data from in to out when key size is 0
             * i.e. during a rekey of a plaintext database */
            if (ctx.key_sz == 0)
            {
                Array.Copy(bIn, bOut, bIn.Length);//memcpy(out, in, size);
                return(SQLITE_OK);
            }

            MemoryStream dataStream = new MemoryStream();
            CryptoStream encryptionStream;

            if (mode == CIPHER_ENCRYPT)
            {
                encryptionStream = new CryptoStream(dataStream, ctx.encryptor, CryptoStreamMode.Write);
            }
            else
            {
                encryptionStream = new CryptoStream(dataStream, ctx.decryptor, CryptoStreamMode.Write);
            }
            encryptionStream.Write(bIn, 0, size);
            encryptionStream.FlushFinalBlock();
            dataStream.Position = 0;

            dataStream.Read(bOut, 0, (int)dataStream.Length);
            encryptionStream.Close();
            dataStream.Close();



            return(SQLITE_OK);
        }
示例#11
0
 public void CopyTo( cipher_ctx ct )
 {
   ct.derive_key = derive_key;
   ct.pass = pass;
   ct.pass_sz = pass_sz;
   if ( key != null ) { ct.key = new byte[key.Length]; key.CopyTo( ct.key, 0 ); }
   ct.key_sz = key_sz;
   if ( iv != null ) { ct.iv = new byte[iv.Length]; iv.CopyTo( ct.iv, 0 ); }
   ct.iv_sz = iv_sz;
   ct.encryptor = encryptor;
   ct.decryptor = decryptor;
 }
示例#12
0
 /**
 * free and wipe memory associated with a cipher_ctx
 */
 static void cipher_ctx_free( ref cipher_ctx ictx )
 {
   cipher_ctx ctx = ictx;
   CODEC_TRACE( "cipher_ctx_free: entered ictx=%d\n", ictx );
   ctx.pass = null;//codec_free(ctx.pass, ctx.pass_sz);
   if ( ctx.key != null ) Array.Clear( ctx.key, 0, ctx.key.Length );//codec_free(ctx.key, ctx.key_sz);
   if ( ctx.iv != null ) Array.Clear( ctx.iv, 0, ctx.iv.Length );
   ictx = new cipher_ctx();// codec_free( ref ctx, sizeof( cipher_ctx ) );
 }
示例#13
0
 /**
 * Initialize a a new cipher_ctx struct. This function will allocate memory
 * for the cipher context and for the key
 *
 * returns SQLITE_OK if initialization was successful
 * returns SQLITE_NOMEM if an error occured allocating memory
 */
 static int cipher_ctx_init( ref cipher_ctx iCtx )
 {
   iCtx = new cipher_ctx();
   //iCtx = sqlite3Malloc( sizeof( cipher_ctx ) );
   //ctx = *iCtx;
   //if ( ctx == null ) return SQLITE_NOMEM;
   //memset( ctx, 0, sizeof( cipher_ctx ) );
   //ctx.key =  sqlite3Malloc( EVP_MAX_KEY_LENGTH );
   //if ( ctx.key == null ) return SQLITE_NOMEM;
   return SQLITE_OK;
 }
示例#14
0
    /**
    * Compare one cipher_ctx to another.
    *
    * returns 0 if all the parameters (except the derived key data) are the same
    * returns 1 otherwise
    */
    static int cipher_ctx_cmp( cipher_ctx c1, cipher_ctx c2 )
    {
      CODEC_TRACE( "cipher_ctx_cmp: entered c1=%d c2=%d\n", c1, c2 );

      if ( c1.key_sz == c2.key_sz
      && c1.pass_sz == c2.pass_sz
      && c1.pass == c2.pass
      ) return 0;
      return 1;
    }
示例#15
0
    /**
    * Copy one cipher_ctx to another. For instance, assuming that read_ctx is a
    * fully initialized context, you could copy it to write_ctx and all yet data
    * and pass information across
    *
    * returns SQLITE_OK if initialization was successful
    * returns SQLITE_NOMEM if an error occured allocating memory
    */
    static int cipher_ctx_copy( cipher_ctx target, cipher_ctx source )
    {
      //byte[] key = target.key;
      CODEC_TRACE( "cipher_ctx_copy: entered target=%d, source=%d\n", target, source );
      //codec_free(target.pass, target.pass_sz);
      source.CopyTo( target );//memcpy(target, source, sizeof(cipher_ctx);

      //target.key = key; //restore pointer to previously allocated key data
      //memcpy(target.key, source.key, EVP_MAX_KEY_LENGTH);
      //target.pass = sqlite3Malloc(source.pass_sz);
      //if(target.pass == null) return SQLITE_NOMEM;
      //memcpy(target.pass, source.pass, source.pass_sz);
      return SQLITE_OK;
    }
示例#16
0
    /**
    * Derive an encryption key for a cipher contex key based on the raw password.
    *
    * If the raw key data is formated as x'hex' and there are exactly enough hex chars to fill
    * the key space (i.e 64 hex chars for a 256 bit key) then the key data will be used directly.
    *
    * Otherwise, a key data will be derived using PBKDF2
    *
    * returns SQLITE_OK if initialization was successful
    * returns SQLITE_NOMEM if the key could't be derived (for instance if pass is null or pass_sz is 0)
    */
    static int codec_key_derive( codec_ctx ctx, cipher_ctx c_ctx )
    {
      CODEC_TRACE( "codec_key_derive: entered c_ctx.pass=%s, c_ctx.pass_sz=%d ctx.iv=%d ctx.iv_sz=%d c_ctx.kdf_iter=%d c_ctx.key_sz=%d\n",
      c_ctx.pass, c_ctx.pass_sz, c_ctx.iv, c_ctx.iv_sz, c_ctx.key_sz );

      if ( c_ctx.pass != null && c_ctx.pass_sz > 0 )
      { // if pass is not null
        if ( ( c_ctx.pass_sz == ( c_ctx.key_sz * 2 ) + 3 ) && sqlite3StrNICmp( c_ctx.pass, "x'", 2 ) == 0 )
        {
          int n = c_ctx.pass_sz - 3; /* adjust for leading x' and tailing ' */
          string z = c_ctx.pass.Substring( 2 );// + 2; /* adjust lead offset of x' */
          CODEC_TRACE( "codec_key_derive: deriving key from hex\n" );
          c_ctx.key = sqlite3HexToBlob( null, z, n);
        }
        else
        {
          CODEC_TRACE( "codec_key_derive: deriving key using AES256\n" );

          Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes( c_ctx.pass, c_ctx.iv, 2010 );
          c_ctx.key_sz = 32;
          c_ctx.key = k1.GetBytes( c_ctx.key_sz );
        }
        c_ctx.encryptor = Aes.CreateEncryptor( c_ctx.key, c_ctx.iv );
        c_ctx.decryptor = Aes.CreateDecryptor( c_ctx.key, c_ctx.iv );
        return SQLITE_OK;
      };
      return SQLITE_ERROR;
    }
示例#17
0
    /*
    * ctx - codec context
    * pgno - page number in database
    * size - size in bytes of input and output buffers
    * mode - 1 to encrypt, 0 to decrypt
    * in - pointer to input bytes
    * out - pouter to output bytes
    */
    static int codec_cipher( cipher_ctx ctx, Pgno pgno, int mode, int size, byte[] bIn, byte[] bOut )
    {
      int iv;
      int tmp_csz, csz;

      CODEC_TRACE( "codec_cipher:entered pgno=%d, mode=%d, size=%d\n", pgno, mode, size );

      /* just copy raw data from in to out when key size is 0
      * i.e. during a rekey of a plaintext database */
      if ( ctx.key_sz == 0 )
      {
        Array.Copy( bIn, bOut, bIn.Length );//memcpy(out, in, size);
        return SQLITE_OK;
      }

      MemoryStream dataStream = new MemoryStream();
      CryptoStream encryptionStream;
      if ( mode == CIPHER_ENCRYPT )
      {
        encryptionStream = new CryptoStream( dataStream, ctx.encryptor, CryptoStreamMode.Write );
      }
      else
      {
        encryptionStream = new CryptoStream( dataStream, ctx.decryptor, CryptoStreamMode.Write );
      }
      encryptionStream.Write( bIn, 0, size );
      encryptionStream.FlushFinalBlock();
      dataStream.Position = 0;

      dataStream.Read( bOut, 0, (int)dataStream.Length );
      encryptionStream.Close();
      dataStream.Close();



      return SQLITE_OK;
    }
示例#18
0
 public cipher_ctx Copy( )
 {
   cipher_ctx c = new cipher_ctx();
   c.derive_key = derive_key;
   c.pass = pass;
   c.pass_sz = pass_sz;
   if ( key != null ) { c.key = new byte[key.Length]; key.CopyTo( c.key, 0 ); }
   c.key_sz = key_sz;
   if ( iv != null ) { c.iv = new byte[iv.Length]; iv.CopyTo( c.iv, 0 ); }
   c.iv_sz = iv_sz;
   c.encryptor = encryptor;
   c.decryptor = decryptor;
   return c;
 }
示例#19
0
        /*
         * ctx - codec context
         * pgno - page number in database
         * size - size in bytes of input and output buffers
         * mode - 1 to encrypt, 0 to decrypt
         * in - pointer to input bytes
         * out - pouter to output bytes
         */
        static int codec_cipher(cipher_ctx ctx, int mode, int size, byte[] bIn, byte[] bOut)
        {
            if (bIn == null || bOut == null)
            {
                throw new ArgumentNullException();
            }
            if (bIn == bOut)
            {
                throw new ArgumentException("bin == bout");
            }
            if (bIn.Length != bOut.Length)
            {
                throw new ArgumentException("Length aren't equal");
            }
            int iv;
            int tmp_csz, csz;

            //CODEC_TRACE("codec_cipher:entered pgno=%d, mode=%d, size=%d\n", pgno, mode, size);

            /* just copy raw data from in to out when key size is 0
             * i.e. during a rekey of a plaintext database */
            if (ctx.key_sz == 0)
            {
                Array.Copy(bIn, bOut, bIn.Length); //memcpy(out, in, size);
                return(SQLITE_OK);
            }
            if (mode == CIPHER_ENCRYPT)
            {
                using (var msEncrypt = new MemoryStream(bIn.Length))
                {
                    using
                    (
                        var csEncrypt = new CryptoStream(
                            msEncrypt,
                            ctx.encryptor,
                            CryptoStreamMode.Write
                            )
                    )
                    {
                        csEncrypt.Write(bIn, 0, bIn.Length);
                    }
                    var msData = msEncrypt.ToArray();
                    Array.Copy(msData, bOut, msData.Length);
                }
            }
            else
            {
                using (var inputMs = new MemoryStream(bIn))
                {
                    using (var outputMs = new MemoryStream(bOut))
                    {
                        var buffer = new byte[4096];
                        using (
                            var csDecrypt = new CryptoStream(
                                inputMs,
                                ctx.decryptor,
                                CryptoStreamMode.Read
                                )
                            )
                        {
                            var read = csDecrypt.Read(buffer, 0, buffer.Length);
                            while (read > 0)
                            {
                                outputMs.Write(buffer, 0, read);
                                read = csDecrypt.Read(buffer, 0, buffer.Length);
                            }
                        }
                        var outputMsData = outputMs.ToArray();
                        if (outputMsData.Length != bOut.Length)
                        {
                            throw new ArgumentException("Length");
                        }
                        Array.Copy(outputMsData, bOut, outputMsData.Length);
                    }
                }
            }

            return(SQLITE_OK);
        }
示例#20
0
 /**
 * Set the raw password / key data for a cipher context
 *
 * returns SQLITE_OK if assignment was successfull
 * returns SQLITE_NOMEM if an error occured allocating memory
 * returns SQLITE_ERROR if the key couldn't be set because the pass was null or size was zero
 */
 static int cipher_ctx_set_pass( cipher_ctx ctx, string zKey, int nKey )
 {
   ctx.pass = null; // codec_free( ctx.pass, ctx.pass_sz );
   ctx.pass_sz = nKey;
   if ( !String.IsNullOrEmpty( zKey ) && nKey > 0 )
   {
     //ctx.pass = sqlite3Malloc(nKey);
     //if(ctx.pass == null) return SQLITE_NOMEM;
     ctx.pass = zKey;//memcpy(ctx.pass, zKey, nKey);
     return SQLITE_OK;
   }
   return SQLITE_ERROR;
 }