diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-08-11 11:54:57 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-08-11 11:54:57 +0700 |
commit | 8c0e3017783a5f41b2028eaffffe335a9046c859 (patch) | |
tree | b92462a67bab6e5aa4cf93ddcb8f06d823ccf752 | |
parent | Update versions and release notes for 1.8.3 (diff) | |
download | BouncyCastle.NET-ed25519-8c0e3017783a5f41b2028eaffffe335a9046c859.tar.xz |
Further work to improve constant time in OAEP. release-1.8.3
-rw-r--r-- | crypto/Readme.html | 2 | ||||
-rw-r--r-- | crypto/src/AssemblyInfo.cs | 2 | ||||
-rw-r--r-- | crypto/src/crypto/encodings/OaepEncoding.cs | 15 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/OAEPTest.cs | 79 |
4 files changed, 89 insertions, 9 deletions
diff --git a/crypto/Readme.html b/crypto/Readme.html index faad344cc..72e97516f 100644 --- a/crypto/Readme.html +++ b/crypto/Readme.html @@ -294,7 +294,7 @@ We state, where EC MQV has not otherwise been disabled or removed: <hr style="WIDTH: 100%; HEIGHT: 2px"> <h3><a class="mozTocH3" name="mozTocId3413"></a>Notes:</h3> - <h4><a class="mozTocH4" name="mozTocId85317"></a>Release 1.8.3, Tuesday August 7, 2018</h4> + <h4><a class="mozTocH4" name="mozTocId85317"></a>Release 1.8.3, Saturday August 11, 2018</h4> <h5>IMPORTANT</h5> <ul> diff --git a/crypto/src/AssemblyInfo.cs b/crypto/src/AssemblyInfo.cs index e1a8f6717..5cc8fcd2f 100644 --- a/crypto/src/AssemblyInfo.cs +++ b/crypto/src/AssemblyInfo.cs @@ -34,7 +34,7 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: [assembly: AssemblyVersion("1.8.3.0")] -[assembly: AssemblyFileVersion("1.8.18219.1")] +[assembly: AssemblyFileVersion("1.8.18223.1")] [assembly: AssemblyInformationalVersion("1.8.3")] // diff --git a/crypto/src/crypto/encodings/OaepEncoding.cs b/crypto/src/crypto/encodings/OaepEncoding.cs index 287876f12..92001589c 100644 --- a/crypto/src/crypto/encodings/OaepEncoding.cs +++ b/crypto/src/crypto/encodings/OaepEncoding.cs @@ -212,10 +212,17 @@ namespace Org.BouncyCastle.Crypto.Encodings // on encryption, we need to make sure our decrypted block comes back // the same size. // + bool wrongData = (block.Length < (2 * defHash.Length) + 1); - Array.Copy(data, 0, block, block.Length - data.Length, data.Length); - - bool shortData = (block.Length < (2 * defHash.Length) + 1); + if (data.Length <= block.Length) + { + Array.Copy(data, 0, block, block.Length - data.Length, data.Length); + } + else + { + Array.Copy(data, 0, block, 0, block.Length); + wrongData = true; + } // // unmask the seed. @@ -269,7 +276,7 @@ namespace Org.BouncyCastle.Crypto.Encodings start++; - if (defHashWrong | shortData | dataStartWrong) + if (defHashWrong | wrongData | dataStartWrong) { Arrays.Fill(block, 0); throw new InvalidCipherTextException("data wrong"); diff --git a/crypto/test/src/crypto/test/OAEPTest.cs b/crypto/test/src/crypto/test/OAEPTest.cs index bc1dd9292..204784cee 100644 --- a/crypto/test/src/crypto/test/OAEPTest.cs +++ b/crypto/test/src/crypto/test/OAEPTest.cs @@ -8,6 +8,7 @@ using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Encodings; using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Security; @@ -780,8 +781,10 @@ namespace Org.BouncyCastle.Crypto.Tests OaepVecTest(1027, 5, pubParam, privParam, seed_1027_5, input_1027_5, output_1027_5); OaepVecTest(1027, 6, pubParam, privParam, seed_1027_6, input_1027_6, output_1027_6); + TestForHighByteError("invalidCiphertextOaepTest 1024", 1024); + // - // OAEP - public encrypt, private decrypt differring hashes + // OAEP - public encrypt, private decrypt, differing hashes // IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest(), new Sha1Digest(), new byte[10]); @@ -822,8 +825,78 @@ namespace Org.BouncyCastle.Crypto.Tests } } - public static void Main( - string[] args) + private void TestForHighByteError(string label, int keySizeBits) + { + // draw a key of the size asked + BigInteger e = BigInteger.One.ShiftLeft(16).Add(BigInteger.One); + + IAsymmetricCipherKeyPairGenerator kpGen = new RsaKeyPairGenerator(); + + kpGen.Init(new RsaKeyGenerationParameters(e, new SecureRandom(), keySizeBits, 100)); + + AsymmetricCipherKeyPair kp = kpGen.GenerateKeyPair(); + + IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine()); + + // obtain a known good ciphertext + cipher.Init(true, new ParametersWithRandom(kp.Public, new VecRand(seed))); + byte[] m = { 42 }; + byte[] c = cipher.ProcessBlock(m, 0, m.Length); + int keySizeBytes = (keySizeBits + 7) / 8; + if (c.Length != keySizeBytes) + { + Fail(label + " failed ciphertext size"); + } + + BigInteger n = ((RsaPrivateCrtKeyParameters)kp.Private).Modulus; + + // decipher + cipher.Init(false, kp.Private); + byte[] r = cipher.ProcessBlock(c, 0, keySizeBytes); + if (r.Length != 1 || r[0] != 42) + { + Fail(label + " failed first decryption of test message"); + } + + // decipher again + r = cipher.ProcessBlock(c, 0, keySizeBytes); + if (r.Length != 1 || r[0] != 42) + { + Fail(label + " failed second decryption of test message"); + } + + // check hapazard incorrect ciphertexts + for (int i = keySizeBytes * 8; --i >= 0; ) + { + c[i / 8] ^= (byte)(1 << (i & 7)); + bool ko = true; + try + { + BigInteger cV = new BigInteger(1, c); + + // don't pass in c if it will be rejected trivially + if (cV.CompareTo(n) < 0) + { + r = cipher.ProcessBlock(c, 0, keySizeBytes); + } + else + { + ko = false; // size errors are picked up at start + } + } + catch (InvalidCipherTextException) + { + ko = false; + } + if (ko) + { + Fail(label + " invalid ciphertext caused no exception"); + } + c[i / 8] ^= (byte)(1 << (i & 7)); + } + } + + public static void Main(string[] args) { RunTest(new OaepTest()); } |