private void InitCipher(ref IntPtr ctx, byte[] iv, bool isCipher) { ctx = Marshal.AllocHGlobal(_cipherInfo[3]); byte[] realkey; if (_method == "rc4-md5") { byte[] temp = new byte[keyLen + ivLen]; realkey = new byte[keyLen]; Array.Copy(_key, 0, temp, 0, keyLen); Array.Copy(iv, 0, temp, keyLen, ivLen); realkey = MD5.Create().ComputeHash(temp); } else { realkey = _key; } if (_cipher == CIPHER_AES) { PolarSSL.aes_init(ctx); // PolarSSL takes key length by bit // since we'll use CFB mode, here we both do enc, not dec PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8); if (isCipher) { _encryptIV = new byte[ivLen]; Array.Copy(iv, _encryptIV, ivLen); } else { _decryptIV = new byte[ivLen]; Array.Copy(iv, _decryptIV, ivLen); } } else if (_cipher == CIPHER_BF) { PolarSSL.blowfish_init(ctx); // PolarSSL takes key length by bit PolarSSL.blowfish_setkey(ctx, realkey, keyLen * 8); if (isCipher) { _encryptIV = new byte[ivLen]; Array.Copy(iv, _encryptIV, ivLen); } else { _decryptIV = new byte[ivLen]; Array.Copy(iv, _decryptIV, ivLen); } } else if (_cipher == CIPHER_RC4) { PolarSSL.arc4_init(ctx); // PolarSSL RC4 takes key length by byte PolarSSL.arc4_setup(ctx, realkey, keyLen); } }
public override void Encrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { if (_encryptCtx == IntPtr.Zero) { randBytes(outbuf, ivLen); InitCipher(ref _encryptCtx, outbuf, true); outlength = length + ivLen; lock (tempbuf) { // C# could be multi-threaded if (_disposed) { throw new ObjectDisposedException(this.ToString()); } switch (_cipher) { case CIPHER_AES: PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf); break; case CIPHER_BF: PolarSSL.blowfish_crypt_cfb64(_encryptCtx, PolarSSL.BLOWFISH_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, tempbuf); break; case CIPHER_RC4: PolarSSL.arc4_crypt(_encryptCtx, length, buf, tempbuf); break; } outlength = length + ivLen; Buffer.BlockCopy(tempbuf, 0, outbuf, ivLen, length); } } else { outlength = length; if (_disposed) { throw new ObjectDisposedException(this.ToString()); } switch (_cipher) { case CIPHER_AES: PolarSSL.aes_crypt_cfb128(_encryptCtx, PolarSSL.AES_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf); break; case CIPHER_BF: PolarSSL.blowfish_crypt_cfb64(_encryptCtx, PolarSSL.BLOWFISH_ENCRYPT, length, ref _encryptIVOffset, _encryptIV, buf, outbuf); break; case CIPHER_RC4: PolarSSL.arc4_crypt(_encryptCtx, length, buf, outbuf); break; } } }
protected virtual void Dispose(bool disposing) { lock (this) { if (_disposed) { return; } _disposed = true; } if (disposing) { if (_encryptCtx != IntPtr.Zero) { switch (_cipher) { case CIPHER_AES: PolarSSL.aes_free(_encryptCtx); break; case CIPHER_BF: PolarSSL.blowfish_free(_encryptCtx); break; case CIPHER_RC4: PolarSSL.arc4_free(_encryptCtx); break; } Marshal.FreeHGlobal(_encryptCtx); _encryptCtx = IntPtr.Zero; } if (_decryptCtx != IntPtr.Zero) { switch (_cipher) { case CIPHER_AES: PolarSSL.aes_free(_decryptCtx); break; case CIPHER_BF: PolarSSL.blowfish_free(_decryptCtx); break; case CIPHER_RC4: PolarSSL.arc4_free(_decryptCtx); break; } Marshal.FreeHGlobal(_decryptCtx); _decryptCtx = IntPtr.Zero; } } }
public override void Decrypt(byte[] buf, int length, byte[] outbuf, out int outlength) { if (_decryptCtx == IntPtr.Zero) { InitCipher(ref _decryptCtx, buf, false); outlength = length - ivLen; lock (tempbuf) { // C# could be multi-threaded Buffer.BlockCopy(buf, ivLen, tempbuf, 0, length - ivLen); if (_disposed) { throw new ObjectDisposedException(this.ToString()); } switch (_cipher) { case CIPHER_AES: PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length - ivLen, ref _decryptIVOffset, _decryptIV, tempbuf, outbuf); break; case CIPHER_RC4: PolarSSL.arc4_crypt(_decryptCtx, length - ivLen, tempbuf, outbuf); break; } } } else { outlength = length; if (_disposed) { throw new ObjectDisposedException(this.ToString()); } switch (_cipher) { case CIPHER_AES: PolarSSL.aes_crypt_cfb128(_decryptCtx, PolarSSL.AES_DECRYPT, length, ref _decryptIVOffset, _decryptIV, buf, outbuf); break; case CIPHER_RC4: PolarSSL.arc4_crypt(_decryptCtx, length, buf, outbuf); break; } } }
protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf) { // C# could be multi-threaded if (_disposed) { throw new ObjectDisposedException(this.ToString()); } byte[] iv; int ivOffset; IntPtr ctx; if (isCipher) { iv = _encryptIV; ivOffset = _encryptIVOffset; ctx = _encryptCtx; } else { iv = _decryptIV; ivOffset = _decryptIVOffset; ctx = _decryptCtx; } switch (_cipher) { case CIPHER_AES: PolarSSL.aes_crypt_cfb128(ctx, isCipher ? PolarSSL.AES_ENCRYPT : PolarSSL.AES_DECRYPT, length, ref ivOffset, iv, buf, outbuf); if (isCipher) { _encryptIVOffset = ivOffset; } else { _decryptIVOffset = ivOffset; } break; case CIPHER_RC4: PolarSSL.arc4_crypt(ctx, length, buf, outbuf); break; } }
protected override void initCipher(byte[] iv, bool isCipher) { base.initCipher(iv, isCipher); IntPtr ctx; ctx = Marshal.AllocHGlobal(_cipherInfo[3]); if (isCipher) { _encryptCtx = ctx; } else { _decryptCtx = ctx; } byte[] realkey; if (_method == "rc4-md5") { byte[] temp = new byte[keyLen + ivLen]; realkey = new byte[keyLen]; Array.Copy(_key, 0, temp, 0, keyLen); Array.Copy(iv, 0, temp, keyLen, ivLen); realkey = MD5.Create().ComputeHash(temp); } else { realkey = _key; } if (_cipher == CIPHER_AES) { PolarSSL.aes_init(ctx); // PolarSSL takes key length by bit // since we'll use CFB mode, here we both do enc, not dec PolarSSL.aes_setkey_enc(ctx, realkey, keyLen * 8); } else if (_cipher == CIPHER_RC4) { PolarSSL.arc4_init(ctx); // PolarSSL RC4 takes key length by byte PolarSSL.arc4_setup(ctx, realkey, keyLen); } }