summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/asn1/x9/DHValidationParms.cs2
-rw-r--r--crypto/src/crypto/IMacDerivationFunction.cs7
-rw-r--r--crypto/src/crypto/generators/KDFCounterBytesGenerator.cs154
-rw-r--r--crypto/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs182
-rw-r--r--crypto/src/crypto/generators/KDFFeedbackBytesGenerator.cs177
-rw-r--r--crypto/src/crypto/parameters/KDFCounterParameters.cs92
-rw-r--r--crypto/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs77
-rw-r--r--crypto/src/crypto/parameters/KDFFeedbackParameters.cs92
-rw-r--r--crypto/src/crypto/signers/Ed25519Signer.cs3
-rw-r--r--crypto/src/crypto/signers/Ed25519ctxSigner.cs3
-rw-r--r--crypto/src/crypto/signers/Ed25519phSigner.cs2
-rw-r--r--crypto/src/crypto/signers/Ed448Signer.cs3
-rw-r--r--crypto/src/crypto/signers/Ed448phSigner.cs2
-rw-r--r--crypto/src/crypto/tls/BasicTlsPskIdentity.cs2
-rw-r--r--crypto/src/crypto/tls/TlsProtocol.cs20
15 files changed, 811 insertions, 7 deletions
diff --git a/crypto/src/asn1/x9/DHValidationParms.cs b/crypto/src/asn1/x9/DHValidationParms.cs

index c63c50205..ec34f8912 100644 --- a/crypto/src/asn1/x9/DHValidationParms.cs +++ b/crypto/src/asn1/x9/DHValidationParms.cs
@@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Asn1.X9 public static DHValidationParms GetInstance(object obj) { - if (obj == null || obj is DHDomainParameters) + if (obj == null || obj is DHValidationParms) return (DHValidationParms)obj; if (obj is Asn1Sequence) diff --git a/crypto/src/crypto/IMacDerivationFunction.cs b/crypto/src/crypto/IMacDerivationFunction.cs new file mode 100644
index 000000000..7297cd854 --- /dev/null +++ b/crypto/src/crypto/IMacDerivationFunction.cs
@@ -0,0 +1,7 @@ +namespace Org.BouncyCastle.Crypto +{ + public interface IMacDerivationFunction:IDerivationFunction + { + IMac GetMac(); + } +} \ No newline at end of file diff --git a/crypto/src/crypto/generators/KDFCounterBytesGenerator.cs b/crypto/src/crypto/generators/KDFCounterBytesGenerator.cs new file mode 100644
index 000000000..9c2b2fdd8 --- /dev/null +++ b/crypto/src/crypto/generators/KDFCounterBytesGenerator.cs
@@ -0,0 +1,154 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class KdfCounterBytesGenerator : IMacDerivationFunction + { + + private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff); + private static readonly BigInteger Two = BigInteger.Two; + + + private readonly IMac prf; + private readonly int h; + + private byte[] fixedInputDataCtrPrefix; + private byte[] fixedInputData_afterCtr; + private int maxSizeExcl; + // ios is i defined as an octet string (the binary representation) + private byte[] ios; + + // operational + private int generatedBytes; + // k is used as buffer for all K(i) values + private byte[] k; + + public KdfCounterBytesGenerator(IMac prf) + { + this.prf = prf; + this.h = prf.GetMacSize(); + this.k = new byte[h]; + } + + public void Init(IDerivationParameters param) + { + KdfCounterParameters kdfParams = param as KdfCounterParameters; + if (kdfParams == null) + { + throw new ArgumentException("Wrong type of arguments given"); + } + + + + // --- init mac based PRF --- + + this.prf.Init(new KeyParameter(kdfParams.Ki)); + + // --- set arguments --- + + this.fixedInputDataCtrPrefix = kdfParams.FixedInputDataCounterPrefix; + this.fixedInputData_afterCtr = kdfParams.FixedInputDataCounterSuffix; + + int r = kdfParams.R; + this.ios = new byte[r / 8]; + + BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h)); + this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ? + Int32.MaxValue : maxSize.IntValue; + + // --- set operational state --- + + generatedBytes = 0; + } + + + public IMac GetMac() + { + return prf; + } + + public IDigest Digest + { + get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; } + } + + public int GenerateBytes(byte[] output, int outOff, int length) + { + int generatedBytesAfter = generatedBytes + length; + if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl) + { + throw new DataLengthException( + "Current KDFCTR may only be used for " + maxSizeExcl + " bytes"); + } + + if (generatedBytes % h == 0) + { + generateNext(); + } + + // copy what is left in the currentT (1..hash + int toGenerate = length; + int posInK = generatedBytes % h; + int leftInK = h - generatedBytes % h; + int toCopy = System.Math.Min(leftInK, toGenerate); + Array.Copy(k, posInK, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + + while (toGenerate > 0) + { + generateNext(); + toCopy = System.Math.Min(h, toGenerate); + Array.Copy(k, 0, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + } + + return length; + + } + + private void generateNext() + { + + int i = generatedBytes / h + 1; + + // encode i into counter buffer + switch (ios.Length) + { + case 4: + ios[0] = (byte)(i >> 24); + goto case 3; + // fall through + case 3: + ios[ios.Length - 3] = (byte)(i >> 16); + // fall through + goto case 2; + case 2: + ios[ios.Length - 2] = (byte)(i >> 8); + // fall through + goto case 1; + case 1: + ios[ios.Length - 1] = (byte)i; + break; + default: + throw new InvalidOperationException("Unsupported size of counter i"); + } + + + + // special case for K(0): K(0) is empty, so no update + prf.BlockUpdate(fixedInputDataCtrPrefix, 0, fixedInputDataCtrPrefix.Length); + prf.BlockUpdate(ios, 0, ios.Length); + prf.BlockUpdate(fixedInputData_afterCtr, 0, fixedInputData_afterCtr.Length); + prf.DoFinal(k, 0); + } + } +} \ No newline at end of file diff --git a/crypto/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs b/crypto/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs new file mode 100644
index 000000000..9010ae2cb --- /dev/null +++ b/crypto/src/crypto/generators/KDFDoublePipelineIterationBytesGenerator.cs
@@ -0,0 +1,182 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class KdfDoublePipelineIterationBytesGenerator : IMacDerivationFunction + { + private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff); + private static readonly BigInteger Two = BigInteger.Two; + + // fields set by the constructor + private readonly IMac prf; + private readonly int h; + + // fields set by init + private byte[] fixedInputData; + private int maxSizeExcl; + // ios is i defined as an octet string (the binary representation) + private byte[] ios; + private bool useCounter; + + // operational + private int generatedBytes; + // k is used as buffer for all K(i) values + private byte[] a; + private byte[] k; + + + public KdfDoublePipelineIterationBytesGenerator(IMac prf) + { + this.prf = prf; + this.h = prf.GetMacSize(); + this.a = new byte[h]; + this.k = new byte[h]; + } + + + public void Init(IDerivationParameters parameters) + { + KdfDoublePipelineIterationParameters dpiParams = parameters as KdfDoublePipelineIterationParameters; + if (dpiParams == null) + { + throw new ArgumentException("Wrong type of arguments given"); + } + + + + // --- init mac based PRF --- + + this.prf.Init(new KeyParameter(dpiParams.Ki)); + + // --- set arguments --- + + this.fixedInputData = dpiParams.FixedInputData; + + int r = dpiParams.R; + this.ios = new byte[r / 8]; + + if (dpiParams.UseCounter) + { + // this is more conservative than the spec + BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h)); + this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ? + Int32.MaxValue : maxSize.IntValue; + } + else + { + this.maxSizeExcl = IntegerMax.IntValue; + } + + this.useCounter = dpiParams.UseCounter; + + // --- set operational state --- + + generatedBytes = 0; + } + + + + + private void generateNext() + { + + if (generatedBytes == 0) + { + // --- step 4 --- + prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length); + prf.DoFinal(a, 0); + } + else + { + // --- step 5a --- + prf.BlockUpdate(a, 0, a.Length); + prf.DoFinal(a, 0); + } + + // --- step 5b --- + prf.BlockUpdate(a, 0, a.Length); + + if (useCounter) + { + int i = generatedBytes / h + 1; + + // encode i into counter buffer + switch (ios.Length) + { + case 4: + ios[0] = (byte)(i >> 24); + // fall through + goto case 3; + case 3: + ios[ios.Length - 3] = (byte)(i >> 16); + // fall through + goto case 2; + case 2: + ios[ios.Length - 2] = (byte)(i >> 8); + // fall through + goto case 1; + case 1: + ios[ios.Length - 1] = (byte)i; + break; + default: + throw new InvalidOperationException("Unsupported size of counter i"); + } + prf.BlockUpdate(ios, 0, ios.Length); + } + + prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length); + prf.DoFinal(k, 0); + } + + public IDigest Digest + { + get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; } + } + + public int GenerateBytes(byte[] output, int outOff, int length) + { + int generatedBytesAfter = generatedBytes + length; + if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl) + { + throw new DataLengthException( + "Current KDFCTR may only be used for " + maxSizeExcl + " bytes"); + } + + if (generatedBytes % h == 0) + { + generateNext(); + } + + // copy what is left in the currentT (1..hash + int toGenerate = length; + int posInK = generatedBytes % h; + int leftInK = h - generatedBytes % h; + int toCopy = System.Math.Min(leftInK, toGenerate); + Array.Copy(k, posInK, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + + while (toGenerate > 0) + { + generateNext(); + toCopy = System.Math.Min(h, toGenerate); + Array.Copy(k, 0, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + } + + return length; + } + + public IMac GetMac() + { + return prf; + } + } +} \ No newline at end of file diff --git a/crypto/src/crypto/generators/KDFFeedbackBytesGenerator.cs b/crypto/src/crypto/generators/KDFFeedbackBytesGenerator.cs new file mode 100644
index 000000000..19ce0ea2e --- /dev/null +++ b/crypto/src/crypto/generators/KDFFeedbackBytesGenerator.cs
@@ -0,0 +1,177 @@ +using System; + +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Crypto.Generators +{ + public class KdfFeedbackBytesGenerator : IMacDerivationFunction + { + private static readonly BigInteger IntegerMax = BigInteger.ValueOf(0x7fffffff); + private static readonly BigInteger Two = BigInteger.Two; + + // please refer to the standard for the meaning of the variable names + // all field lengths are in bytes, not in bits as specified by the standard + + // fields set by the constructor + private readonly IMac prf; + private readonly int h; + + // fields set by init + private byte[] fixedInputData; + private int maxSizeExcl; + // ios is i defined as an octet string (the binary representation) + private byte[] ios; + private byte[] iv; + private bool useCounter; + + // operational + private int generatedBytes; + // k is used as buffer for all K(i) values + private byte[] k; + + public KdfFeedbackBytesGenerator(IMac prf) + { + this.prf = prf; + this.h = prf.GetMacSize(); + this.k = new byte[h]; + } + + + public void Init(IDerivationParameters parameters) + { + KdfFeedbackParameters feedbackParams = parameters as KdfFeedbackParameters; + if (feedbackParams == null) + { + throw new ArgumentException("Wrong type of arguments given"); + } + + + // --- init mac based PRF --- + + this.prf.Init(new KeyParameter(feedbackParams.Ki)); + + // --- set arguments --- + + this.fixedInputData = feedbackParams.FixedInputData; + + int r = feedbackParams.R; + this.ios = new byte[r / 8]; + + if (feedbackParams.UseCounter) + { + // this is more conservative than the spec + BigInteger maxSize = Two.Pow(r).Multiply(BigInteger.ValueOf(h)); + this.maxSizeExcl = maxSize.CompareTo(IntegerMax) == 1 ? + Int32.MaxValue : maxSize.IntValue; + } + else + { + this.maxSizeExcl = Int32.MaxValue; + } + + this.iv = feedbackParams.Iv; + this.useCounter = feedbackParams.UseCounter; + + // --- set operational state --- + + generatedBytes = 0; + } + + public IDigest Digest + { + get { return prf is HMac ? ((HMac)prf).GetUnderlyingDigest() : null; } + } + + public int GenerateBytes(byte[] output, int outOff, int length) + { + int generatedBytesAfter = generatedBytes + length; + if (generatedBytesAfter < 0 || generatedBytesAfter >= maxSizeExcl) + { + throw new DataLengthException( + "Current KDFCTR may only be used for " + maxSizeExcl + " bytes"); + } + + if (generatedBytes % h == 0) + { + generateNext(); + } + + // copy what is left in the currentT (1..hash + int toGenerate = length; + int posInK = generatedBytes % h; + int leftInK = h - generatedBytes % h; + + + int toCopy = System.Math.Min(leftInK, toGenerate); + Array.Copy(k, posInK, output, outOff, toCopy); + + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + + while (toGenerate > 0) + { + generateNext(); + toCopy = System.Math.Min(h, toGenerate); + Array.Copy(k, 0, output, outOff, toCopy); + generatedBytes += toCopy; + toGenerate -= toCopy; + outOff += toCopy; + } + + return length; + } + + private void generateNext() + { + + // TODO enable IV + if (generatedBytes == 0) + { + prf.BlockUpdate(iv, 0, iv.Length); + } + else + { + prf.BlockUpdate(k, 0, k.Length); + } + + if (useCounter) + { + int i = generatedBytes / h + 1; + + // encode i into counter buffer + switch (ios.Length) + { + case 4: + ios[0] = (byte)(i >> 24); + goto case 3; + // fall through + case 3: + ios[ios.Length - 3] = (byte)(i >> 16); + // fall through + goto case 2; + case 2: + ios[ios.Length - 2] = (byte)(i >> 8); + // fall through + goto case 1; + case 1: + ios[ios.Length - 1] = (byte)i; + break; + default: + throw new InvalidOperationException("Unsupported size of counter i"); + } + prf.BlockUpdate(ios, 0, ios.Length); + } + + prf.BlockUpdate(fixedInputData, 0, fixedInputData.Length); + prf.DoFinal(k, 0); + } + + public IMac GetMac() + { + return prf; + } + } +} \ No newline at end of file diff --git a/crypto/src/crypto/parameters/KDFCounterParameters.cs b/crypto/src/crypto/parameters/KDFCounterParameters.cs new file mode 100644
index 000000000..49d6f7da3 --- /dev/null +++ b/crypto/src/crypto/parameters/KDFCounterParameters.cs
@@ -0,0 +1,92 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KdfCounterParameters : IDerivationParameters + { + private byte[] ki; + private byte[] fixedInputDataCounterPrefix; + private byte[] fixedInputDataCounterSuffix; + private int r; + + /// <summary> + /// Base constructor - suffix fixed input data only. + /// </summary> + /// <param name="ki">the KDF seed</param> + /// <param name="fixedInputDataCounterSuffix">fixed input data to follow counter.</param> + /// <param name="r">length of the counter in bits</param> + public KdfCounterParameters(byte[] ki, byte[] fixedInputDataCounterSuffix, int r) : this(ki, null, fixedInputDataCounterSuffix, r) + { + } + + + + /// <summary> + /// Base constructor - prefix and suffix fixed input data. + /// </summary> + /// <param name="ki">the KDF seed</param> + /// <param name="fixedInputDataCounterPrefix">fixed input data to precede counter</param> + /// <param name="fixedInputDataCounterSuffix">fixed input data to follow counter.</param> + /// <param name="r">length of the counter in bits.</param> + public KdfCounterParameters(byte[] ki, byte[] fixedInputDataCounterPrefix, byte[] fixedInputDataCounterSuffix, int r) + { + if (ki == null) + { + throw new ArgumentException("A KDF requires Ki (a seed) as input"); + } + this.ki = Arrays.Clone(ki); + + if (fixedInputDataCounterPrefix == null) + { + this.fixedInputDataCounterPrefix = new byte[0]; + } + else + { + this.fixedInputDataCounterPrefix = Arrays.Clone(fixedInputDataCounterPrefix); + } + + if (fixedInputDataCounterSuffix == null) + { + this.fixedInputDataCounterSuffix = new byte[0]; + } + else + { + this.fixedInputDataCounterSuffix = Arrays.Clone(fixedInputDataCounterSuffix); + } + + if (r != 8 && r != 16 && r != 24 && r != 32) + { + throw new ArgumentException("Length of counter should be 8, 16, 24 or 32"); + } + this.r = r; + } + + public byte[] Ki + { + get { return ki; } + } + + public byte[] FixedInputData + { + get { return Arrays.Clone(fixedInputDataCounterSuffix); } + } + + public byte[] FixedInputDataCounterPrefix + { + get { return Arrays.Clone(fixedInputDataCounterPrefix); } + + } + + public byte[] FixedInputDataCounterSuffix + { + get { return Arrays.Clone(fixedInputDataCounterSuffix); } + } + + public int R + { + get { return r; } + } + } +} \ No newline at end of file diff --git a/crypto/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs b/crypto/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs new file mode 100644
index 000000000..9e2a68b71 --- /dev/null +++ b/crypto/src/crypto/parameters/KDFDoublePipelineIterationParameters.cs
@@ -0,0 +1,77 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KdfDoublePipelineIterationParameters : IDerivationParameters + { + // could be any valid value, using 32, don't know why + private static readonly int UNUSED_R = 32; + + private readonly byte[] ki; + private readonly bool useCounter; + private readonly int r; + private readonly byte[] fixedInputData; + + private KdfDoublePipelineIterationParameters(byte[] ki, byte[] fixedInputData, int r, bool useCounter) + { + if (ki == null) + { + throw new ArgumentException("A KDF requires Ki (a seed) as input"); + } + + this.ki = Arrays.Clone(ki); + + if (fixedInputData == null) + { + this.fixedInputData = new byte[0]; + } + else + { + this.fixedInputData = Arrays.Clone(fixedInputData); + } + + if (r != 8 && r != 16 && r != 24 && r != 32) + { + throw new ArgumentException("Length of counter should be 8, 16, 24 or 32"); + } + + this.r = r; + + this.useCounter = useCounter; + } + + public static KdfDoublePipelineIterationParameters CreateWithCounter( + byte[] ki, byte[] fixedInputData, int r) + { + return new KdfDoublePipelineIterationParameters(ki, fixedInputData, r, true); + } + + public static KdfDoublePipelineIterationParameters CreateWithoutCounter( + byte[] ki, byte[] fixedInputData) + { + return new KdfDoublePipelineIterationParameters(ki, fixedInputData, UNUSED_R, false); + } + + public byte[] Ki + { + get { return Arrays.Clone(ki); } + } + + public bool UseCounter + { + get { return useCounter; } + } + + public int R + { + get { return r; } + } + + public byte[] FixedInputData + { + get { return Arrays.Clone(fixedInputData); } + } + } +} \ No newline at end of file diff --git a/crypto/src/crypto/parameters/KDFFeedbackParameters.cs b/crypto/src/crypto/parameters/KDFFeedbackParameters.cs new file mode 100644
index 000000000..86ea232db --- /dev/null +++ b/crypto/src/crypto/parameters/KDFFeedbackParameters.cs
@@ -0,0 +1,92 @@ +using System; + +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Parameters +{ + public class KdfFeedbackParameters : IDerivationParameters + { + // could be any valid value, using 32, don't know why + private static readonly int UNUSED_R = -1; + + private readonly byte[] ki; + private readonly byte[] iv; + private readonly bool useCounter; + private readonly int r; + private readonly byte[] fixedInputData; + + private KdfFeedbackParameters(byte[] ki, byte[] iv, byte[] fixedInputData, int r, bool useCounter) + { + if (ki == null) + { + throw new ArgumentException("A KDF requires Ki (a seed) as input"); + } + + this.ki = Arrays.Clone(ki); + + if (fixedInputData == null) + { + this.fixedInputData = new byte[0]; + } + else + { + this.fixedInputData = Arrays.Clone(fixedInputData); + } + + this.r = r; + + if (iv == null) + { + this.iv = new byte[0]; + } + else + { + this.iv = Arrays.Clone(iv); + } + + this.useCounter = useCounter; + } + + public static KdfFeedbackParameters CreateWithCounter( + byte[] ki, byte[] iv, byte[] fixedInputData, int r) + { + if (r != 8 && r != 16 && r != 24 && r != 32) + { + throw new ArgumentException("Length of counter should be 8, 16, 24 or 32"); + } + + return new KdfFeedbackParameters(ki, iv, fixedInputData, r, true); + } + + public static KdfFeedbackParameters CreateWithoutCounter( + byte[] ki, byte[] iv, byte[] fixedInputData) + { + return new KdfFeedbackParameters(ki, iv, fixedInputData, UNUSED_R, false); + } + + public byte[] Ki + { + get { return Arrays.Clone(ki); } + } + + public byte[] Iv + { + get { return Arrays.Clone(iv); } + } + + public bool UseCounter + { + get { return useCounter; } + } + + public int R + { + get { return r; } + } + + public byte[] FixedInputData + { + get { return Arrays.Clone(fixedInputData); } + } + } +} \ No newline at end of file diff --git a/crypto/src/crypto/signers/Ed25519Signer.cs b/crypto/src/crypto/signers/Ed25519Signer.cs
index ef8714188..a916601e6 100644 --- a/crypto/src/crypto/signers/Ed25519Signer.cs +++ b/crypto/src/crypto/signers/Ed25519Signer.cs
@@ -99,6 +99,9 @@ namespace Org.BouncyCastle.Crypto.Signers internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] signature) { + if (Ed25519.SignatureSize != signature.Length) + return false; + lock (this) { #if PORTABLE diff --git a/crypto/src/crypto/signers/Ed25519ctxSigner.cs b/crypto/src/crypto/signers/Ed25519ctxSigner.cs
index 60c708019..ab7201b62 100644 --- a/crypto/src/crypto/signers/Ed25519ctxSigner.cs +++ b/crypto/src/crypto/signers/Ed25519ctxSigner.cs
@@ -101,6 +101,9 @@ namespace Org.BouncyCastle.Crypto.Signers internal bool VerifySignature(Ed25519PublicKeyParameters publicKey, byte[] ctx, byte[] signature) { + if (Ed25519.SignatureSize != signature.Length) + return false; + lock (this) { #if PORTABLE diff --git a/crypto/src/crypto/signers/Ed25519phSigner.cs b/crypto/src/crypto/signers/Ed25519phSigner.cs
index 548ca1f29..2538b16f5 100644 --- a/crypto/src/crypto/signers/Ed25519phSigner.cs +++ b/crypto/src/crypto/signers/Ed25519phSigner.cs
@@ -75,6 +75,8 @@ namespace Org.BouncyCastle.Crypto.Signers { if (forSigning || null == publicKey) throw new InvalidOperationException("Ed25519phSigner not initialised for verification"); + if (Ed25519.SignatureSize != signature.Length) + return false; byte[] pk = publicKey.GetEncoded(); return Ed25519.VerifyPrehash(signature, 0, pk, 0, context, prehash); diff --git a/crypto/src/crypto/signers/Ed448Signer.cs b/crypto/src/crypto/signers/Ed448Signer.cs
index 0863e5dd1..b0563d544 100644 --- a/crypto/src/crypto/signers/Ed448Signer.cs +++ b/crypto/src/crypto/signers/Ed448Signer.cs
@@ -101,6 +101,9 @@ namespace Org.BouncyCastle.Crypto.Signers internal bool VerifySignature(Ed448PublicKeyParameters publicKey, byte[] ctx, byte[] signature) { + if (Ed448.SignatureSize != signature.Length) + return false; + lock (this) { #if PORTABLE diff --git a/crypto/src/crypto/signers/Ed448phSigner.cs b/crypto/src/crypto/signers/Ed448phSigner.cs
index 8f451f9e8..d656c1392 100644 --- a/crypto/src/crypto/signers/Ed448phSigner.cs +++ b/crypto/src/crypto/signers/Ed448phSigner.cs
@@ -75,6 +75,8 @@ namespace Org.BouncyCastle.Crypto.Signers { if (forSigning || null == publicKey) throw new InvalidOperationException("Ed448phSigner not initialised for verification"); + if (Ed448.SignatureSize != signature.Length) + return false; byte[] pk = publicKey.GetEncoded(); return Ed448.VerifyPrehash(signature, 0, pk, 0, context, prehash); diff --git a/crypto/src/crypto/tls/BasicTlsPskIdentity.cs b/crypto/src/crypto/tls/BasicTlsPskIdentity.cs
index db5954422..7a3bbe72e 100644 --- a/crypto/src/crypto/tls/BasicTlsPskIdentity.cs +++ b/crypto/src/crypto/tls/BasicTlsPskIdentity.cs
@@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Tls public virtual byte[] GetPsk() { - return mPsk; + return Arrays.Clone(mPsk); } } } diff --git a/crypto/src/crypto/tls/TlsProtocol.cs b/crypto/src/crypto/tls/TlsProtocol.cs
index 394967c37..388eb629f 100644 --- a/crypto/src/crypto/tls/TlsProtocol.cs +++ b/crypto/src/crypto/tls/TlsProtocol.cs
@@ -729,11 +729,19 @@ namespace Org.BouncyCastle.Crypto.Tls } /** + * Equivalent to <code>OfferInput(input, 0, input.length)</code> + * @see TlsProtocol#OfferInput(byte[], int, int) + * @param input The input buffer to offer + * @throws IOException If an error occurs while decrypting or processing a record + */ + public virtual void OfferInput(byte[] input) + { + OfferInput(input, 0, input.Length); + } + + /** * Offer input from an arbitrary source. Only allowed in non-blocking mode.<br/> * <br/> - * After this method returns, the input buffer is "owned" by this object. Other code - * must not attempt to do anything with it.<br/> - * <br/> * This method will decrypt and process all records that are fully available. * If only part of a record is available, the buffer will be retained until the * remainder of the record is offered.<br/> @@ -744,16 +752,18 @@ namespace Org.BouncyCastle.Crypto.Tls * You should always check to see if there is any available output after calling * this method by calling {@link #getAvailableOutputBytes()}. * @param input The input buffer to offer + * @param inputOff The offset within the input buffer that input begins + * @param inputLen The number of bytes of input being offered * @throws IOException If an error occurs while decrypting or processing a record */ - public virtual void OfferInput(byte[] input) + public virtual void OfferInput(byte[] input, int inputOff, int inputLen) { if (mBlocking) throw new InvalidOperationException("Cannot use OfferInput() in blocking mode! Use Stream instead."); if (mClosed) throw new IOException("Connection is closed, cannot accept any more input"); - mInputBuffers.Write(input); + mInputBuffers.Write(input, inputOff, inputLen); // loop while there are enough bytes to read the length of the next record while (mInputBuffers.Available >= RecordStream.TLS_HEADER_SIZE)