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); } }
protected static KeyParameter GenerateRecordMacKey(IStreamCipher cipher, byte[] firstBlock) { cipher.ProcessBytes(firstBlock, 0, firstBlock.Length, firstBlock, 0); if (_macKey == null) { _macKey = new KeyParameter(firstBlock, 0, 32); } else { _macKey.Reset(); _macKey.SetKey(firstBlock, 0, 32); } Arrays.Fill(firstBlock, (byte)0); return(_macKey); }
public static int Decrypt(byte[] ciphertext, int offset, int len, byte[] additionalData, byte[] nonce, byte[] key, byte[] outBuffer) { lock (mutex) { if (cipher == null) { cipher = new ChaCha7539Engine(); } else { cipher.Reset(); } if (_decryptKey == null) { _decryptKey = new KeyParameter(key); } else { _decryptKey.Reset(); _decryptKey.SetKey(key); } if (_temp_Params == null) { _temp_Params = new ParametersWithIV(_decryptKey, nonce); } else { _temp_Params.Reset(); _temp_Params.Set(_decryptKey, nonce); } cipher.Init(false, _temp_Params); byte[] firstBlock = BufferPool.GetBuffer(64); KeyParameter macKey = GenerateRecordMacKey(cipher, firstBlock); int plaintextLength = len - 16; byte[] calculatedMac = BufferPool.GetBuffer(16); CalculateRecordMac(macKey, additionalData, ciphertext, offset, plaintextLength, calculatedMac); byte[] receivedMac = BufferPool.GetBuffer(16); Array.Copy(ciphertext, offset + plaintextLength, receivedMac, 0, receivedMac.Length); if (!Arrays.ConstantTimeAreEqual(calculatedMac, receivedMac)) { BufferPool.ReturnBuffer(calculatedMac); BufferPool.ReturnBuffer(receivedMac); BufferPool.ReturnBuffer(firstBlock); throw new TlsFatalAlert(AlertDescription.bad_record_mac); } BufferPool.ReturnBuffer(calculatedMac); BufferPool.ReturnBuffer(receivedMac); BufferPool.ReturnBuffer(firstBlock); cipher.ProcessBytes(ciphertext, offset, plaintextLength, outBuffer, 0); return(plaintextLength); } }