summary refs log tree commit diff
path: root/crypto/src
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2018-09-16 16:21:56 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2018-09-16 16:21:56 +0700
commitba3292784635dc3f06070e4c99c01ed630818940 (patch)
tree7a4c19ad7d721c4c5a9c1e8924fc0a6bc2c199ea /crypto/src
parentReduce single-bit extractions from scalars (diff)
downloadBouncyCastle.NET-ed25519-ba3292784635dc3f06070e4c99c01ed630818940.tar.xz
Fixed Rfc3211WrapEngine processing of messages over 127 bytes.
Diffstat (limited to 'crypto/src')
-rw-r--r--crypto/src/crypto/engines/RFC3211WrapEngine.cs59
1 files changed, 35 insertions, 24 deletions
diff --git a/crypto/src/crypto/engines/RFC3211WrapEngine.cs b/crypto/src/crypto/engines/RFC3211WrapEngine.cs
index 4e3af5227..86480145c 100644
--- a/crypto/src/crypto/engines/RFC3211WrapEngine.cs
+++ b/crypto/src/crypto/engines/RFC3211WrapEngine.cs
@@ -32,10 +32,10 @@ namespace Org.BouncyCastle.Crypto.Engines
 
 			if (param is ParametersWithRandom)
 			{
-				ParametersWithRandom p = (ParametersWithRandom) param;
+				ParametersWithRandom p = (ParametersWithRandom)param;
 
-				this.rand = p.Random;
-				this.param = (ParametersWithIV) p.Parameters;
+                this.rand = p.Random;
+                this.param = p.Parameters as ParametersWithIV;
 			}
 			else
 			{
@@ -44,9 +44,12 @@ namespace Org.BouncyCastle.Crypto.Engines
 					rand = new SecureRandom();
 				}
 
-				this.param = (ParametersWithIV) param;
-			}
-		}
+                this.param = param as ParametersWithIV;
+            }
+
+            if (null == this.param)
+                throw new ArgumentException("RFC3211Wrap requires an IV", "param");
+        }
 
         public virtual string AlgorithmName
 		{
@@ -59,11 +62,11 @@ namespace Org.BouncyCastle.Crypto.Engines
 			int		inLen)
 		{
 			if (!forWrapping)
-			{
 				throw new InvalidOperationException("not set for wrapping");
-			}
+            if (inLen > 255 || inLen < 0)
+                throw new ArgumentException("input must be from 0 to 255 bytes", "inLen");
 
-			engine.Init(true, param);
+            engine.Init(true, param);
 
 			int blockSize = engine.GetBlockSize();
 			byte[] cekBlock;
@@ -78,15 +81,16 @@ namespace Org.BouncyCastle.Crypto.Engines
 			}
 
 			cekBlock[0] = (byte)inLen;
-			cekBlock[1] = (byte)~inBytes[inOff];
-			cekBlock[2] = (byte)~inBytes[inOff + 1];
-			cekBlock[3] = (byte)~inBytes[inOff + 2];
 
 			Array.Copy(inBytes, inOff, cekBlock, 4, inLen);
 
 			rand.NextBytes(cekBlock, inLen + 4, cekBlock.Length - inLen - 4);
 
-			for (int i = 0; i < cekBlock.Length; i += blockSize)
+            cekBlock[1] = (byte)~cekBlock[4];
+            cekBlock[2] = (byte)~cekBlock[4 + 1];
+            cekBlock[3] = (byte)~cekBlock[4 + 2];
+
+            for (int i = 0; i < cekBlock.Length; i += blockSize)
 			{
 				engine.ProcessBlock(cekBlock, i, cekBlock, i);
 			}
@@ -142,27 +146,34 @@ namespace Org.BouncyCastle.Crypto.Engines
 				engine.ProcessBlock(cekBlock, i, cekBlock, i);
 			}
 
-			if ((cekBlock[0] & 0xff) > cekBlock.Length - 4)
-			{
-				throw new InvalidCipherTextException("wrapped key corrupted");
-			}
+            bool invalidLength = (int)cekBlock[0] > (cekBlock.Length - 4);
 
-			byte[] key = new byte[cekBlock[0] & 0xff];
+            byte[] key;
+            if (invalidLength)
+            {
+                key = new byte[cekBlock.Length - 4];
+            }
+            else
+            {
+                key = new byte[cekBlock[0]];
+            }
 
-			Array.Copy(cekBlock, 4, key, 0, cekBlock[0]);
+            Array.Copy(cekBlock, 4, key, 0, key.Length);
 
 			// Note: Using constant time comparison
 			int nonEqual = 0;
 			for (int i = 0; i != 3; i++)
 			{
 				byte check = (byte)~cekBlock[1 + i];
-				nonEqual |= (check ^ key[i]);
-			}
+                nonEqual |= (check ^ cekBlock[4 + i]);
+            }
+
+            Array.Clear(cekBlock, 0, cekBlock.Length);
 
-			if (nonEqual != 0)
-				throw new InvalidCipherTextException("wrapped key fails checksum");
+            if (nonEqual != 0 | invalidLength)
+                throw new InvalidCipherTextException("wrapped key corrupted");
 
-			return key;
+            return key;
 		}
 	}
 }