From 105658813a36c98319e60da1098bb2e0432a171a Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Thu, 20 Jun 2024 21:31:04 +0700 Subject: Improve RC2 effective key bits determination --- crypto/src/crypto/util/CipherFactory.cs | 28 +++++++++++++------ crypto/test/src/cms/test/EnvelopedDataTest.cs | 40 +++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 11 deletions(-) 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"); -- cgit 1.4.1