diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-01 15:13:01 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-01 15:13:01 +0700 |
commit | 4b8ca91cabe63d889f2dd770f629ba62444ed1ac (patch) | |
tree | 147c0e2818f464d5bb099ddbc241cc5c76a78603 /crypto | |
parent | Span-based variants for IAeadCipher.ProcessByte(s) (diff) | |
download | BouncyCastle.NET-ed25519-4b8ca91cabe63d889f2dd770f629ba62444ed1ac.tar.xz |
Span-base variants for IBufferedCipher
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/src/crypto/BufferedAeadBlockCipher.cs | 27 | ||||
-rw-r--r-- | crypto/src/crypto/BufferedAeadCipher.cs | 21 | ||||
-rw-r--r-- | crypto/src/crypto/BufferedAsymmetricBlockCipher.cs | 35 | ||||
-rw-r--r-- | crypto/src/crypto/BufferedBlockCipher.cs | 72 | ||||
-rw-r--r-- | crypto/src/crypto/BufferedCipherBase.cs | 15 | ||||
-rw-r--r-- | crypto/src/crypto/BufferedIesCipher.cs | 27 | ||||
-rw-r--r-- | crypto/src/crypto/BufferedStreamCipher.cs | 25 | ||||
-rw-r--r-- | crypto/src/crypto/IBufferedCipher.cs | 9 |
8 files changed, 208 insertions, 23 deletions
diff --git a/crypto/src/crypto/BufferedAeadBlockCipher.cs b/crypto/src/crypto/BufferedAeadBlockCipher.cs index 7ba41090f..92eab9dd4 100644 --- a/crypto/src/crypto/BufferedAeadBlockCipher.cs +++ b/crypto/src/crypto/BufferedAeadBlockCipher.cs @@ -172,7 +172,14 @@ namespace Org.BouncyCastle.Crypto return cipher.ProcessBytes(input, inOff, length, output, outOff); } - public override byte[] DoFinal() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + return cipher.ProcessBytes(input, output); + } +#endif + + public override byte[] DoFinal() { byte[] outBytes = new byte[GetOutputSize(0)]; @@ -235,11 +242,25 @@ namespace Org.BouncyCastle.Crypto return cipher.DoFinal(output, outOff); } - /** +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int DoFinal(Span<byte> output) + { + return cipher.DoFinal(output); + } + + public override int DoFinal(ReadOnlySpan<byte> input, Span<byte> output) + { + int len = cipher.ProcessBytes(input, output); + len += cipher.DoFinal(output[len..]); + return len; + } +#endif + + /** * Reset the buffer and cipher. After resetting the object is in the same * state as it was after the last init (if there was one). */ - public override void Reset() + public override void Reset() { cipher.Reset(); } diff --git a/crypto/src/crypto/BufferedAeadCipher.cs b/crypto/src/crypto/BufferedAeadCipher.cs index c689c1eab..aba64f0f4 100644 --- a/crypto/src/crypto/BufferedAeadCipher.cs +++ b/crypto/src/crypto/BufferedAeadCipher.cs @@ -171,6 +171,13 @@ namespace Org.BouncyCastle.Crypto return cipher.ProcessBytes(input, inOff, length, output, outOff); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + return cipher.ProcessBytes(input, output); + } +#endif + public override byte[] DoFinal() { byte[] outBytes = new byte[GetOutputSize(0)]; @@ -234,6 +241,20 @@ namespace Org.BouncyCastle.Crypto return cipher.DoFinal(output, outOff); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int DoFinal(Span<byte> output) + { + return cipher.DoFinal(output); + } + + public override int DoFinal(ReadOnlySpan<byte> input, Span<byte> output) + { + int len = cipher.ProcessBytes(input, output); + len += cipher.DoFinal(output[len..]); + return len; + } +#endif + /** * Reset the buffer and cipher. After resetting the object is in the same * state as it was after the last init (if there was one). diff --git a/crypto/src/crypto/BufferedAsymmetricBlockCipher.cs b/crypto/src/crypto/BufferedAsymmetricBlockCipher.cs index bf00f3ece..83c2fe70c 100644 --- a/crypto/src/crypto/BufferedAsymmetricBlockCipher.cs +++ b/crypto/src/crypto/BufferedAsymmetricBlockCipher.cs @@ -1,7 +1,4 @@ using System; -using System.Diagnostics; - -using Org.BouncyCastle.Crypto.Engines; namespace Org.BouncyCastle.Crypto { @@ -111,7 +108,18 @@ namespace Org.BouncyCastle.Crypto return null; } - /** +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + Check.DataLength(input, buffer.Length - bufOff, "attempt to process message too long for cipher"); + + input.CopyTo(buffer.AsSpan(bufOff)); + bufOff += input.Length; + return 0; + } +#endif + + /** * process the contents of the buffer using the underlying * cipher. * @@ -139,7 +147,24 @@ namespace Org.BouncyCastle.Crypto return DoFinal(); } - /// <summary>Reset the buffer</summary> +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int DoFinal(Span<byte> output) + { + int result = 0; + if (bufOff > 0) + { + byte[] outBytes = cipher.ProcessBlock(buffer, 0, bufOff); + outBytes.CopyTo(output); + result = outBytes.Length; + } + + Reset(); + + return result; + } +#endif + + /// <summary>Reset the buffer</summary> public override void Reset() { if (buffer != null) diff --git a/crypto/src/crypto/BufferedBlockCipher.cs b/crypto/src/crypto/BufferedBlockCipher.cs index c87d2daf9..3b000ed59 100644 --- a/crypto/src/crypto/BufferedBlockCipher.cs +++ b/crypto/src/crypto/BufferedBlockCipher.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using Org.BouncyCastle.Crypto.Parameters; @@ -228,14 +227,14 @@ namespace Org.BouncyCastle.Crypto int resultLen = 0; int gapLen = buf.Length - bufOff; - if (length > gapLen) + if (length >= gapLen) { Array.Copy(input, inOff, buf, bufOff, gapLen); resultLen += cipher.ProcessBlock(buf, 0, output, outOff); bufOff = 0; length -= gapLen; inOff += gapLen; - while (length > buf.Length) + while (length >= buf.Length) { resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); length -= blockSize; @@ -244,15 +243,44 @@ namespace Org.BouncyCastle.Crypto } Array.Copy(input, inOff, buf, bufOff, length); bufOff += length; - if (bufOff == buf.Length) - { - resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); - bufOff = 0; - } return resultLen; } - public override byte[] DoFinal() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + if (input.IsEmpty) + return 0; + + int blockSize = GetBlockSize(); + int outLength = GetUpdateOutputSize(input.Length); + + if (outLength > 0) + { + Check.OutputLength(output, outLength, "output buffer too short"); + } + + int resultLen = 0; + int gapLen = buf.Length - bufOff; + if (input.Length >= gapLen) + { + input[..gapLen].CopyTo(buf.AsSpan(bufOff)); + resultLen += cipher.ProcessBlock(buf, output); + bufOff = 0; + input = input[gapLen..]; + while (input.Length >= buf.Length) + { + resultLen += cipher.ProcessBlock(input, output[resultLen..]); + input = input[blockSize..]; + } + } + input.CopyTo(buf.AsSpan(bufOff)); + bufOff += input.Length; + return resultLen; + } +#endif + + public override byte[] DoFinal() { byte[] outBytes = EmptyBuffer; @@ -352,7 +380,31 @@ namespace Org.BouncyCastle.Crypto } } - /** +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int DoFinal(Span<byte> output) + { + try + { + if (bufOff != 0) + { + Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); + Check.OutputLength(output, bufOff, "output buffer too short for DoFinal()"); + + // NB: Can't copy directly, or we may write too much output + cipher.ProcessBlock(buf, buf); + buf.AsSpan(0, bufOff).CopyTo(output); + } + + return bufOff; + } + finally + { + Reset(); + } + } +#endif + + /** * Reset the buffer and cipher. After resetting the object is in the same * state as it was after the last init (if there was one). */ diff --git a/crypto/src/crypto/BufferedCipherBase.cs b/crypto/src/crypto/BufferedCipherBase.cs index 9d8610211..4b3069d0d 100644 --- a/crypto/src/crypto/BufferedCipherBase.cs +++ b/crypto/src/crypto/BufferedCipherBase.cs @@ -64,6 +64,10 @@ namespace Org.BouncyCastle.Crypto return outBytes.Length; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public abstract int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output); +#endif + public abstract byte[] DoFinal(); public virtual byte[] DoFinal( @@ -108,6 +112,17 @@ namespace Org.BouncyCastle.Crypto return len; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public abstract int DoFinal(Span<byte> output); + + public virtual int DoFinal(ReadOnlySpan<byte> input, Span<byte> output) + { + int len = ProcessBytes(input, output); + len += DoFinal(output[len..]); + return len; + } +#endif + public abstract void Reset(); } } diff --git a/crypto/src/crypto/BufferedIesCipher.cs b/crypto/src/crypto/BufferedIesCipher.cs index b0330e416..1aff47ab4 100644 --- a/crypto/src/crypto/BufferedIesCipher.cs +++ b/crypto/src/crypto/BufferedIesCipher.cs @@ -2,8 +2,6 @@ using System; using System.IO; using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto { @@ -87,7 +85,15 @@ namespace Org.BouncyCastle.Crypto return null; } - public override byte[] DoFinal() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + buffer.Write(input); + return 0; + } +#endif + + public override byte[] DoFinal() { byte[] buf = buffer.ToArray(); @@ -105,7 +111,20 @@ namespace Org.BouncyCastle.Crypto return DoFinal(); } - public override void Reset() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int DoFinal(Span<byte> output) + { + byte[] buf = buffer.ToArray(); + + Reset(); + + byte[] block = engine.ProcessBlock(buf, 0, buf.Length); + block.CopyTo(output); + return block.Length; + } +#endif + + public override void Reset() { buffer.SetLength(0); } diff --git a/crypto/src/crypto/BufferedStreamCipher.cs b/crypto/src/crypto/BufferedStreamCipher.cs index 2d4987bba..8307429cb 100644 --- a/crypto/src/crypto/BufferedStreamCipher.cs +++ b/crypto/src/crypto/BufferedStreamCipher.cs @@ -101,6 +101,14 @@ namespace Org.BouncyCastle.Crypto return length; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output) + { + cipher.ProcessBytes(input, output); + return input.Length; + } +#endif + public override byte[] DoFinal() { Reset(); @@ -123,7 +131,22 @@ namespace Org.BouncyCastle.Crypto return output; } - public override void Reset() +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public override int DoFinal(Span<byte> output) + { + Reset(); + return 0; + } + + public virtual int DoFinal(ReadOnlySpan<byte> input, Span<byte> output) + { + int len = ProcessBytes(input, output); + Reset(); + return len; + } +#endif + + public override void Reset() { cipher.Reset(); } diff --git a/crypto/src/crypto/IBufferedCipher.cs b/crypto/src/crypto/IBufferedCipher.cs index 69dec9596..ddfb524c9 100644 --- a/crypto/src/crypto/IBufferedCipher.cs +++ b/crypto/src/crypto/IBufferedCipher.cs @@ -28,6 +28,10 @@ namespace Org.BouncyCastle.Crypto int ProcessBytes(byte[] input, byte[] output, int outOff); int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output); +#endif + byte[] DoFinal(); byte[] DoFinal(byte[] input); byte[] DoFinal(byte[] input, int inOff, int length); @@ -35,6 +39,11 @@ namespace Org.BouncyCastle.Crypto int DoFinal(byte[] input, byte[] output, int outOff); int DoFinal(byte[] input, int inOff, int length, byte[] output, int outOff); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + int DoFinal(Span<byte> output); + int DoFinal(ReadOnlySpan<byte> input, Span<byte> output); +#endif + /// <summary> /// Reset the cipher. After resetting the cipher is in the same state /// as it was after the last init (if there was one). |