public static int Encrypt(byte[] plaintext, int offset, int len, byte[] additionalData, byte[] nonce, byte[] key, byte[] outBuffer) { lock (mutex) { if (cipher == null) { cipher = new ChaCha7539Engine(); } else { cipher.Reset(); } if (_encryptKey == null) { _encryptKey = new KeyParameter(key); } else { _encryptKey.Reset(); _encryptKey.SetKey(key); } if (_temp_Params == null) { _temp_Params = new ParametersWithIV(_encryptKey, nonce); } else { _temp_Params.Reset(); _temp_Params.Set(_encryptKey, nonce); } cipher.Init(true, _temp_Params); byte[] firstBlock = BufferPool.GetBuffer(64); KeyParameter macKey = GenerateRecordMacKey(cipher, firstBlock); cipher.ProcessBytes(plaintext, offset, len, outBuffer, 0); byte[] mac = BufferPool.GetBuffer(16); int macsize = CalculateRecordMac(macKey, additionalData, outBuffer, 0, len, mac); Array.Copy(mac, 0, outBuffer, len, macsize); BufferPool.ReturnBuffer(mac); BufferPool.ReturnBuffer(firstBlock); return(len + 16); } }
private void Reset(bool clearMac, bool resetCipher) { Array.Clear(mBuf, 0, mBuf.Length); if (clearMac) { Array.Clear(mMac, 0, mMac.Length); } this.mAadCount = 0UL; this.mDataCount = 0UL; this.mBufPos = 0; switch (mState) { case State.DecInit: case State.EncInit: break; case State.DecAad: case State.DecData: case State.DecFinal: this.mState = State.DecInit; break; case State.EncAad: case State.EncData: case State.EncFinal: this.mState = State.EncFinal; return; default: throw new InvalidOperationException(); } if (resetCipher) { mChacha20.Reset(); } InitMac(); if (null != mInitialAad) { ProcessAadBytes(mInitialAad, 0, mInitialAad.Length); } }