public void Encrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source, Span <byte> destination, Span <byte> tag, ReadOnlySpan <byte> associatedData = default) { var input = ArrayPool <byte> .Shared.Rent(source.Length); var output = ArrayPool <byte> .Shared.Rent(destination.Length + tag.Length); try { _engine = new BufferedAeadBlockCipher(new GcmBlockCipher(_aes)); _engine.Init(true, new AeadParameters(_key, 128, nonce.ToArray(), associatedData.ToArray())); source.CopyTo(input); _engine.DoFinal(input, 0, source.Length, output, 0); output.AsSpan(0, destination.Length).CopyTo(destination); output.AsSpan(destination.Length, tag.Length).CopyTo(tag); } finally { ArrayPool <byte> .Shared.Return(input); ArrayPool <byte> .Shared.Return(output); } }
public void Decrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source, ReadOnlySpan <byte> tag, Span <byte> destination, ReadOnlySpan <byte> associatedData = default) { var input = ArrayPool <byte> .Shared.Rent(source.Length + tag.Length); var output = ArrayPool <byte> .Shared.Rent(destination.Length); try { _engine.Init(false, new AeadParameters(_key, 128, nonce.ToArray(), associatedData.ToArray())); source.CopyTo(input); tag.CopyTo(input.AsSpan(source.Length)); _engine.DoFinal(input, 0, source.Length + tag.Length, output, 0); output.AsSpan(0, destination.Length).CopyTo(destination); } finally { ArrayPool <byte> .Shared.Return(input); ArrayPool <byte> .Shared.Return(output); } }
/// <summary> /// Create a buffered cipher to encrypt or decrypt a stream as it is being read /// </summary> /// <param name="forEncryption">forEncryption if true the cipher is initialised for encryption, if false for decryption</param> /// <param name="key">Key to be used for encryption</param> /// <param name="nonce">Nonce to be used for encryption</param> /// <param name="tagSize">Tag size in bits for the tag appended in the end of the stream</param> /// <param name="associatedText">Additional associated data</param> /// <returns></returns> internal static IBufferedCipher CreateCipher(bool forEncryption, byte[] key, int tagSize, byte[] nonce, byte[] associatedText) { var aesEngine = new AesEngine(); var blockCipher = new GcmBlockCipher(aesEngine); var aeadBlockCipher = new BufferedAeadBlockCipher(blockCipher); var parameters = new AeadParameters(new KeyParameter(key), tagSize, nonce, associatedText); aeadBlockCipher.Init(forEncryption, parameters); return(aeadBlockCipher); }