Skip to content

Commit 8c0e301

Browse files
committed
Further work to improve constant time in OAEP.
1 parent c01bc53 commit 8c0e301

File tree

4 files changed

+89
-9
lines changed

4 files changed

+89
-9
lines changed

crypto/Readme.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ <h3><a class="mozTocH3" name="mozTocId358608"></a>For first time users.</h3>
294294
<hr style="WIDTH: 100%; HEIGHT: 2px">
295295
<h3><a class="mozTocH3" name="mozTocId3413"></a>Notes:</h3>
296296

297-
<h4><a class="mozTocH4" name="mozTocId85317"></a>Release 1.8.3, Tuesday August 7, 2018</h4>
297+
<h4><a class="mozTocH4" name="mozTocId85317"></a>Release 1.8.3, Saturday August 11, 2018</h4>
298298

299299
<h5>IMPORTANT</h5>
300300
<ul>

crypto/src/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
// by using the '*' as shown below:
3535

3636
[assembly: AssemblyVersion("1.8.3.0")]
37-
[assembly: AssemblyFileVersion("1.8.18219.1")]
37+
[assembly: AssemblyFileVersion("1.8.18223.1")]
3838
[assembly: AssemblyInformationalVersion("1.8.3")]
3939

4040
//

crypto/src/crypto/encodings/OaepEncoding.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,17 @@ private byte[] DecodeBlock(
212212
// on encryption, we need to make sure our decrypted block comes back
213213
// the same size.
214214
//
215+
bool wrongData = (block.Length < (2 * defHash.Length) + 1);
215216

216-
Array.Copy(data, 0, block, block.Length - data.Length, data.Length);
217-
218-
bool shortData = (block.Length < (2 * defHash.Length) + 1);
217+
if (data.Length <= block.Length)
218+
{
219+
Array.Copy(data, 0, block, block.Length - data.Length, data.Length);
220+
}
221+
else
222+
{
223+
Array.Copy(data, 0, block, 0, block.Length);
224+
wrongData = true;
225+
}
219226

220227
//
221228
// unmask the seed.
@@ -269,7 +276,7 @@ private byte[] DecodeBlock(
269276

270277
start++;
271278

272-
if (defHashWrong | shortData | dataStartWrong)
279+
if (defHashWrong | wrongData | dataStartWrong)
273280
{
274281
Arrays.Fill(block, 0);
275282
throw new InvalidCipherTextException("data wrong");

crypto/test/src/crypto/test/OAEPTest.cs

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Org.BouncyCastle.Crypto.Digests;
99
using Org.BouncyCastle.Crypto.Encodings;
1010
using Org.BouncyCastle.Crypto.Engines;
11+
using Org.BouncyCastle.Crypto.Generators;
1112
using Org.BouncyCastle.Crypto.Parameters;
1213
using Org.BouncyCastle.Math;
1314
using Org.BouncyCastle.Security;
@@ -780,8 +781,10 @@ public override void PerformTest()
780781
OaepVecTest(1027, 5, pubParam, privParam, seed_1027_5, input_1027_5, output_1027_5);
781782
OaepVecTest(1027, 6, pubParam, privParam, seed_1027_6, input_1027_6, output_1027_6);
782783

784+
TestForHighByteError("invalidCiphertextOaepTest 1024", 1024);
785+
783786
//
784-
// OAEP - public encrypt, private decrypt differring hashes
787+
// OAEP - public encrypt, private decrypt, differing hashes
785788
//
786789
IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine(), new Sha256Digest(), new Sha1Digest(), new byte[10]);
787790

@@ -822,8 +825,78 @@ public override void PerformTest()
822825
}
823826
}
824827

825-
public static void Main(
826-
string[] args)
828+
private void TestForHighByteError(string label, int keySizeBits)
829+
{
830+
// draw a key of the size asked
831+
BigInteger e = BigInteger.One.ShiftLeft(16).Add(BigInteger.One);
832+
833+
IAsymmetricCipherKeyPairGenerator kpGen = new RsaKeyPairGenerator();
834+
835+
kpGen.Init(new RsaKeyGenerationParameters(e, new SecureRandom(), keySizeBits, 100));
836+
837+
AsymmetricCipherKeyPair kp = kpGen.GenerateKeyPair();
838+
839+
IAsymmetricBlockCipher cipher = new OaepEncoding(new RsaEngine());
840+
841+
// obtain a known good ciphertext
842+
cipher.Init(true, new ParametersWithRandom(kp.Public, new VecRand(seed)));
843+
byte[] m = { 42 };
844+
byte[] c = cipher.ProcessBlock(m, 0, m.Length);
845+
int keySizeBytes = (keySizeBits + 7) / 8;
846+
if (c.Length != keySizeBytes)
847+
{
848+
Fail(label + " failed ciphertext size");
849+
}
850+
851+
BigInteger n = ((RsaPrivateCrtKeyParameters)kp.Private).Modulus;
852+
853+
// decipher
854+
cipher.Init(false, kp.Private);
855+
byte[] r = cipher.ProcessBlock(c, 0, keySizeBytes);
856+
if (r.Length != 1 || r[0] != 42)
857+
{
858+
Fail(label + " failed first decryption of test message");
859+
}
860+
861+
// decipher again
862+
r = cipher.ProcessBlock(c, 0, keySizeBytes);
863+
if (r.Length != 1 || r[0] != 42)
864+
{
865+
Fail(label + " failed second decryption of test message");
866+
}
867+
868+
// check hapazard incorrect ciphertexts
869+
for (int i = keySizeBytes * 8; --i >= 0; )
870+
{
871+
c[i / 8] ^= (byte)(1 << (i & 7));
872+
bool ko = true;
873+
try
874+
{
875+
BigInteger cV = new BigInteger(1, c);
876+
877+
// don't pass in c if it will be rejected trivially
878+
if (cV.CompareTo(n) < 0)
879+
{
880+
r = cipher.ProcessBlock(c, 0, keySizeBytes);
881+
}
882+
else
883+
{
884+
ko = false; // size errors are picked up at start
885+
}
886+
}
887+
catch (InvalidCipherTextException)
888+
{
889+
ko = false;
890+
}
891+
if (ko)
892+
{
893+
Fail(label + " invalid ciphertext caused no exception");
894+
}
895+
c[i / 8] ^= (byte)(1 << (i & 7));
896+
}
897+
}
898+
899+
public static void Main(string[] args)
827900
{
828901
RunTest(new OaepTest());
829902
}

0 commit comments

Comments
 (0)