From 8f2d2c009a4143bee1cbda30e428de2cdf7554d7 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Mon, 13 Nov 2023 11:51:52 +0700 Subject: Move CRT fault countermeasure into RsaCoreEngine --- crypto/src/crypto/engines/RSABlindedEngine.cs | 36 +++++++--------- crypto/src/crypto/engines/RSACoreEngine.cs | 60 ++++++++++++++------------- 2 files changed, 47 insertions(+), 49 deletions(-) diff --git a/crypto/src/crypto/engines/RSABlindedEngine.cs b/crypto/src/crypto/engines/RSABlindedEngine.cs index d207f617c..8bb9a4f8c 100644 --- a/crypto/src/crypto/engines/RSABlindedEngine.cs +++ b/crypto/src/crypto/engines/RSABlindedEngine.cs @@ -110,31 +110,25 @@ namespace Org.BouncyCastle.Crypto.Engines throw new InvalidOperationException("RSA engine not initialised"); BigInteger input = core.ConvertInput(inBuf, inOff, inLen); + BigInteger result = ProcessInput(input); + return core.ConvertOutput(result); + } - BigInteger result; - if (key is RsaPrivateCrtKeyParameters crt) - { - BigInteger e = crt.PublicExponent; - BigInteger m = crt.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); + private BigInteger ProcessInput(BigInteger input) + { + if (!(key is RsaPrivateCrtKeyParameters crt)) + return core.ProcessBlock(input); - BigInteger rInv = BigIntegers.ModOddInverse(m, r); - result = blindedResult.Multiply(rInv).Mod(m); + BigInteger e = crt.PublicExponent; + BigInteger m = crt.Modulus; - // 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); - } + BigInteger r = BigIntegers.CreateRandomInRange(BigInteger.One, m.Subtract(BigInteger.One), random); + BigInteger blind = r.ModPow(e, m); + BigInteger unblind = BigIntegers.ModOddInverse(m, r); - return core.ConvertOutput(result); + BigInteger blindedInput = blind.Multiply(input).Mod(m); + BigInteger blindedResult = core.ProcessBlock(blindedInput); + return unblind.Multiply(blindedResult).Mod(m); } } } diff --git a/crypto/src/crypto/engines/RSACoreEngine.cs b/crypto/src/crypto/engines/RSACoreEngine.cs index ffa448b3d..ee0f86c3f 100644 --- a/crypto/src/crypto/engines/RSACoreEngine.cs +++ b/crypto/src/crypto/engines/RSACoreEngine.cs @@ -113,38 +113,42 @@ namespace Org.BouncyCastle.Crypto.Engines : BigIntegers.AsUnsignedByteArray(result); } - public virtual BigInteger ProcessBlock( - BigInteger input) + public virtual BigInteger ProcessBlock(BigInteger input) { CheckInitialised(); - if (key is RsaPrivateCrtKeyParameters crt) - { - // - // we have the extra factors, use the Chinese Remainder Theorem - the author - // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for - // advice regarding the expression of this. - // - BigInteger p = crt.P; - BigInteger q = crt.Q; - BigInteger dP = crt.DP; - BigInteger dQ = crt.DQ; - BigInteger qInv = crt.QInv; - - // mP = ((input Mod p) ^ dP)) Mod p - BigInteger mP = (input.Remainder(p)).ModPow(dP, p); - - // mQ = ((input Mod q) ^ dQ)) Mod q - BigInteger mQ = (input.Remainder(q)).ModPow(dQ, q); - - // h = qInv * (mP - mQ) Mod p - BigInteger h = mP.Subtract(mQ).Multiply(qInv).Mod(p); - - // m = h * q + mQ - return h.Multiply(q).Add(mQ); - } + if (!(key is RsaPrivateCrtKeyParameters crt)) + return input.ModPow(key.Exponent, key.Modulus); + + // + // we have the extra factors, use the Chinese Remainder Theorem - the author + // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for + // advice regarding the expression of this. + // + BigInteger p = crt.P; + BigInteger q = crt.Q; + BigInteger dP = crt.DP; + BigInteger dQ = crt.DQ; + BigInteger qInv = crt.QInv; + + // mP = ((input Mod p) ^ dP)) Mod p + BigInteger mP = (input.Remainder(p)).ModPow(dP, p); + + // mQ = ((input Mod q) ^ dQ)) Mod q + BigInteger mQ = (input.Remainder(q)).ModPow(dQ, q); + + // h = qInv * (mP - mQ) Mod p + BigInteger h = mP.Subtract(mQ).Multiply(qInv).Mod(p); + + // m = h * q + mQ + BigInteger m = h.Multiply(q).Add(mQ); + + // defence against Arjen Lenstra’s CRT attack + BigInteger check = m.ModPow(crt.PublicExponent, crt.Modulus); + if (!check.Equals(input)) + throw new InvalidOperationException("RSA engine faulty decryption/signing detected"); - return input.ModPow(key.Exponent, key.Modulus); + return m; } } } -- cgit 1.4.1