summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2015-10-14 13:53:25 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2015-10-14 13:53:25 +0700
commite6aa0cac548933ea29e4eb8abab505af740a49ea (patch)
tree9317a5821e621bbbdeb37720cfe1c60fb994fac0
parentAdded extra OIDs. (diff)
downloadBouncyCastle.NET-ed25519-e6aa0cac548933ea29e4eb8abab505af740a49ea.tar.xz
Added "Lenstra" check
-rw-r--r--crypto/src/crypto/engines/RSABlindedEngine.cs198
1 files changed, 101 insertions, 97 deletions
diff --git a/crypto/src/crypto/engines/RSABlindedEngine.cs b/crypto/src/crypto/engines/RSABlindedEngine.cs
index 037abf7e9..f95f145f6 100644
--- a/crypto/src/crypto/engines/RSABlindedEngine.cs
+++ b/crypto/src/crypto/engines/RSABlindedEngine.cs
@@ -7,118 +7,122 @@ using Org.BouncyCastle.Utilities;
 
 namespace Org.BouncyCastle.Crypto.Engines
 {
-	/**
-	 * this does your basic RSA algorithm with blinding
-	 */
-	public class RsaBlindedEngine
-		: IAsymmetricBlockCipher
-	{
-		private readonly RsaCoreEngine core = new RsaCoreEngine();
-		private RsaKeyParameters key;
-		private SecureRandom random;
+    /**
+     * this does your basic RSA algorithm with blinding
+     */
+    public class RsaBlindedEngine
+        : IAsymmetricBlockCipher
+    {
+        private readonly RsaCoreEngine core = new RsaCoreEngine();
+        private RsaKeyParameters key;
+        private SecureRandom random;
 
         public virtual string AlgorithmName
-		{
-			get { return "RSA"; }
-		}
+        {
+            get { return "RSA"; }
+        }
 
-		/**
-		 * initialise the RSA engine.
-		 *
-		 * @param forEncryption true if we are encrypting, false otherwise.
-		 * @param param the necessary RSA key parameters.
-		 */
+        /**
+         * initialise the RSA engine.
+         *
+         * @param forEncryption true if we are encrypting, false otherwise.
+         * @param param the necessary RSA key parameters.
+         */
         public virtual void Init(
-			bool				forEncryption,
-			ICipherParameters	param)
-		{
-			core.Init(forEncryption, param);
+            bool forEncryption,
+            ICipherParameters param)
+        {
+            core.Init(forEncryption, param);
 
-			if (param is ParametersWithRandom)
-			{
-				ParametersWithRandom rParam = (ParametersWithRandom)param;
+            if (param is ParametersWithRandom)
+            {
+                ParametersWithRandom rParam = (ParametersWithRandom)param;
 
-				key = (RsaKeyParameters)rParam.Parameters;
-				random = rParam.Random;
-			}
-			else
-			{
-				key = (RsaKeyParameters)param;
-				random = new SecureRandom();
-			}
-		}
+                key = (RsaKeyParameters)rParam.Parameters;
+                random = rParam.Random;
+            }
+            else
+            {
+                key = (RsaKeyParameters)param;
+                random = new SecureRandom();
+            }
+        }
 
-		/**
-		 * Return the maximum size for an input block to this engine.
-		 * For RSA this is always one byte less than the key size on
-		 * encryption, and the same length as the key size on decryption.
-		 *
-		 * @return maximum size for an input block.
-		 */
+        /**
+         * Return the maximum size for an input block to this engine.
+         * For RSA this is always one byte less than the key size on
+         * encryption, and the same length as the key size on decryption.
+         *
+         * @return maximum size for an input block.
+         */
         public virtual int GetInputBlockSize()
-		{
-			return core.GetInputBlockSize();
-		}
+        {
+            return core.GetInputBlockSize();
+        }
 
-		/**
-		 * Return the maximum size for an output block to this engine.
-		 * For RSA this is always one byte less than the key size on
-		 * decryption, and the same length as the key size on encryption.
-		 *
-		 * @return maximum size for an output block.
-		 */
+        /**
+         * Return the maximum size for an output block to this engine.
+         * For RSA this is always one byte less than the key size on
+         * decryption, and the same length as the key size on encryption.
+         *
+         * @return maximum size for an output block.
+         */
         public virtual int GetOutputBlockSize()
-		{
-			return core.GetOutputBlockSize();
-		}
+        {
+            return core.GetOutputBlockSize();
+        }
 
-		/**
-		 * Process a single block using the basic RSA algorithm.
-		 *
-		 * @param inBuf the input array.
-		 * @param inOff the offset into the input buffer where the data starts.
-		 * @param inLen the length of the data to be processed.
-		 * @return the result of the RSA process.
-		 * @exception DataLengthException the input block is too large.
-		 */
+        /**
+         * Process a single block using the basic RSA algorithm.
+         *
+         * @param inBuf the input array.
+         * @param inOff the offset into the input buffer where the data starts.
+         * @param inLen the length of the data to be processed.
+         * @return the result of the RSA process.
+         * @exception DataLengthException the input block is too large.
+         */
         public virtual byte[] ProcessBlock(
-			byte[]	inBuf,
-			int		inOff,
-			int		inLen)
-		{
-			if (key == null)
-				throw new InvalidOperationException("RSA engine not initialised");
+            byte[] inBuf,
+            int inOff,
+            int inLen)
+        {
+            if (key == null)
+                throw new InvalidOperationException("RSA engine not initialised");
 
-			BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
+            BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
 
-			BigInteger result;
-			if (key is RsaPrivateCrtKeyParameters)
-			{
-				RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key;
-				BigInteger e = k.PublicExponent;
-				if (e != null)   // can't do blinding without a public exponent
-				{
-					BigInteger m = k.Modulus;
-					BigInteger r = BigIntegers.CreateRandomInRange(
-						BigInteger.One, m.Subtract(BigInteger.One), random);
+            BigInteger result;
+            if (key is RsaPrivateCrtKeyParameters)
+            {
+                RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key;
+                BigInteger e = k.PublicExponent;
+                if (e != null)   // can't do blinding without a public exponent
+                {
+                    BigInteger m = k.Modulus;
+                    BigInteger r = BigIntegers.CreateRandomInRange(
+                        BigInteger.One, m.Subtract(BigInteger.One), random);
 
-					BigInteger blindedInput = r.ModPow(e, m).Multiply(input).Mod(m);
-					BigInteger blindedResult = core.ProcessBlock(blindedInput);
+                    BigInteger blindedInput = r.ModPow(e, m).Multiply(input).Mod(m);
+                    BigInteger blindedResult = core.ProcessBlock(blindedInput);
 
-					BigInteger rInv = r.ModInverse(m);
-					result = blindedResult.Multiply(rInv).Mod(m);
-				}
-				else
-				{
-					result = core.ProcessBlock(input);
-				}
-			}
-			else
-			{
-				result = core.ProcessBlock(input);
-			}
+                    BigInteger rInv = r.ModInverse(m);
+                    result = blindedResult.Multiply(rInv).Mod(m);
 
-			return core.ConvertOutput(result);
-		}
-	}
+                    // defence against Arjen Lenstra’s CRT attack
+                    if (!input.Equals(result.ModPow(e, m)))
+                        throw new InvalidOperationException("RSA engine faulty decryption/signing detected");
+                }
+                else
+                {
+                    result = core.ProcessBlock(input);
+                }
+            }
+            else
+            {
+                result = core.ProcessBlock(input);
+            }
+
+            return core.ConvertOutput(result);
+        }
+    }
 }