diff --git a/crypto/src/crypto/util/CipherFactory.cs b/crypto/src/crypto/util/CipherFactory.cs
index 725159bfd..d29b3b2c7 100644
--- a/crypto/src/crypto/util/CipherFactory.cs
+++ b/crypto/src/crypto/util/CipherFactory.cs
@@ -42,6 +42,20 @@ namespace Org.BouncyCastle.Crypto.Utilities
0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd
};
+ private static int GetRC2EffectiveKeyBits(RC2CbcParameter rc2CbcParameter)
+ {
+ var version = rc2CbcParameter.RC2ParameterVersionData;
+ if (version == null)
+ return 32;
+
+ int encoding = version.IntPositiveValueExact;
+ if (encoding >= 256)
+ return encoding;
+
+ // TODO Why an entire table when RFC 8018 B.2.3. says only 160, 120, 58, 256+ are defined?
+ return RC2Ekb[encoding];
+ }
+
public static object CreateContentCipher(bool forEncryption, ICipherParameters encKey,
AlgorithmIdentifier encryptionAlgID)
{
@@ -81,14 +95,12 @@ namespace Org.BouncyCastle.Crypto.Utilities
}
else if (encAlg.Equals(PkcsObjectIdentifiers.RC2Cbc))
{
- RC2CbcParameter cbcParams = RC2CbcParameter.GetInstance(sParams);
-
- cipher.Init(forEncryption,
- new ParametersWithIV(
- new RC2Parameters(
- ((KeyParameter)encKey).GetKey(),
- RC2Ekb[cbcParams.RC2ParameterVersion.IntValue]),
- cbcParams.GetIV()));
+ var rc2CbcParameter = RC2CbcParameter.GetInstance(sParams);
+ var rc2Parameters = new RC2Parameters(
+ ((KeyParameter)encKey).GetKey(),
+ GetRC2EffectiveKeyBits(rc2CbcParameter));
+
+ cipher.Init(forEncryption, new ParametersWithIV(rc2Parameters, rc2CbcParameter.IV.GetOctets()));
}
else
{
diff --git a/crypto/test/src/cms/test/EnvelopedDataTest.cs b/crypto/test/src/cms/test/EnvelopedDataTest.cs
index 6c3c8991d..800998700 100644
--- a/crypto/test/src/cms/test/EnvelopedDataTest.cs
+++ b/crypto/test/src/cms/test/EnvelopedDataTest.cs
@@ -3,14 +3,13 @@ using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
+
using Org.BouncyCastle.Asn1;
-using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
-using Org.BouncyCastle.Asn1.Rosstandart;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Operators;
@@ -364,7 +363,42 @@ namespace Org.BouncyCastle.Cms.Tests
}
}
- [Test]
+ [Test]
+ public void TestKeyTransRC2bit40()
+ {
+ byte[] data = Encoding.ASCII.GetBytes("WallaWallaBouncyCastle");
+
+ CmsEnvelopedDataGenerator edGen = new CmsEnvelopedDataGenerator();
+
+ edGen.AddKeyTransRecipient(ReciCert);
+
+ CmsEnvelopedData ed = edGen.Generate(
+ new CmsProcessableByteArray(data),
+ CmsEnvelopedGenerator.RC2Cbc,
+ keySize: 40);
+
+ RecipientInformationStore recipients = ed.GetRecipientInfos();
+
+ Assert.AreEqual(ed.EncryptionAlgOid, CmsEnvelopedGenerator.RC2Cbc);
+
+ RC2CbcParameter rc2P = RC2CbcParameter.GetInstance(ed.EncryptionAlgorithmID.Parameters);
+ Assert.AreEqual(160, rc2P.RC2ParameterVersion.IntValueExact);
+
+ var c = recipients.GetRecipients();
+
+ Assert.AreEqual(1, c.Count);
+
+ foreach (RecipientInformation recipient in c)
+ {
+ Assert.True(recipient.RecipientID.Match(ReciCert));
+
+ byte[] recData = recipient.GetContent(ReciKP.Private);
+
+ Assert.IsTrue(Arrays.AreEqual(data, recData));
+ }
+ }
+
+ [Test]
public void TestKeyTransRC4()
{
byte[] data = Encoding.ASCII.GetBytes("WallaWallaBouncyCastle");
|