CVE-2016-1000352
Description
In the Bouncy Castle JCE Provider version 1.55 and earlier the ECIES implementation allowed the use of ECB mode. This mode is regarded as unsafe and support for it has been removed from the provider.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Bouncy Castle JCE Provider 1.55 and earlier allowed ECB mode in ECIES, which is unsafe and has been removed.
Vulnerability
The Bouncy Castle JCE Provider version 1.55 and earlier permitted the use of ECB (Electronic Codebook) mode in the Elliptic Curve Integrated Encryption Scheme (ECIES) implementation. ECB mode is considered insecure for general use because identical plaintext blocks produce identical ciphertext blocks, revealing patterns. The vulnerability affects all versions up to and including 1.55 of the Bouncy Castle JCE Provider [1][3][4].
Exploitation
An attacker does not need special network position or authentication to exploit this; any application using the vulnerable Bouncy Castle provider to perform ECIES encryption with ECB mode is at risk. The attacker can observe encrypted messages and, because ECB mode does not hide plaintext patterns, may be able to deduce information about the plaintext content. No user interaction beyond normal operation is required.
Impact
Successful exploitation allows an attacker to obtain information about the encrypted data due to the deterministic nature of ECB mode. This leads to a loss of confidentiality. The severity is considered important as it weakens the security guarantees of ECIES, potentially exposing sensitive data [1][3].
Mitigation
The fix was committed in Bouncy Castle's repository, removing support for non-CBC mode ciphers in IES/ECIES [4]. The patched version is Bouncy Castle JCE Provider 1.56 and later. Red Hat released updates for Red Hat Satellite 6.4 (RHSA-2018:2927) and Red Hat Fuse 7.1 (RHSA-2018:2669) addressing this vulnerability [1][3]. Users should upgrade to the latest version of the Bouncy Castle JCE Provider or apply the relevant vendor patches. There is no known workaround for older versions other than avoiding ECB mode in ECIES.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.bouncycastle:bcprov-jdk14Maven | < 1.56 | 1.56 |
org.bouncycastle:bcprov-jdk15Maven | < 1.56 | 1.56 |
org.bouncycastle:bcprov-jdk15onMaven | < 1.56 | 1.56 |
Affected products
3- ghsa-coords3 versionspkg:maven/org.bouncycastle/bcprov-jdk14pkg:maven/org.bouncycastle/bcprov-jdk15pkg:maven/org.bouncycastle/bcprov-jdk15on
< 1.56+ 2 more
- (no CPE)range: < 1.56
- (no CPE)range: < 1.56
- (no CPE)range: < 1.56
Patches
19385b0ebd277removed support for non-cbc mode ciphers in IES/ECIES
10 files changed · +214 −282
prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java+39 −58 modified@@ -21,27 +21,27 @@ import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; -import org.bouncycastle.crypto.BlockCipher; +import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.agreement.DHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.IESEngine; -import org.bouncycastle.crypto.engines.OldIESEngine; import org.bouncycastle.crypto.generators.DHKeyPairGenerator; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; +import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHKeyParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; -import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.crypto.params.IESWithCipherParameters; +import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.parsers.DHIESPublicKeyParser; import org.bouncycastle.jcajce.provider.asymmetric.util.DHUtil; import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil; @@ -57,6 +57,7 @@ public class IESCipher extends CipherSpi { private final JcaJceHelper helper = new BCJcaJceHelper(); + private final int ivLength; private IESEngine engine; private int state = -1; @@ -71,11 +72,13 @@ public class IESCipher public IESCipher(IESEngine engine) { this.engine = engine; + this.ivLength = 0; } - public IESCipher(OldIESEngine engine) + public IESCipher(IESEngine engine, int ivLength) { this.engine = engine; + this.ivLength = ivLength; } public int engineGetBlockSize() @@ -106,6 +109,10 @@ public int engineGetKeySize(Key key) public byte[] engineGetIV() { + if (engineSpec != null) + { + return engineSpec.getNonce(); + } return null; } @@ -257,7 +264,13 @@ public void engineInit( // Use default parameters (including cipher key size) if none are specified if (engineSpec == null) { - this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher()); + byte[] nonce = null; + if (ivLength != 0 && opmode == Cipher.ENCRYPT_MODE) + { + nonce = new byte[ivLength]; + random.nextBytes(nonce); + } + this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), nonce); } else if (engineSpec instanceof IESParameterSpec) { @@ -268,6 +281,13 @@ else if (engineSpec instanceof IESParameterSpec) throw new InvalidAlgorithmParameterException("must be passed IES parameters"); } + byte[] nonce = this.engineSpec.getNonce(); + + if (ivLength != 0 && (nonce == null || nonce.length != ivLength)) + { + throw new InvalidAlgorithmParameterException("NONCE in IES Parameters needs to be " + ivLength + " bytes long"); + } + // Parse the recipient's key if (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE) { @@ -329,7 +349,7 @@ public void engineInit( } catch (InvalidAlgorithmParameterException e) { - throw new IllegalArgumentException("can't handle supplied parameter spec"); + throw new IllegalArgumentException("cannot handle supplied parameter spec: " + e.getMessage()); } } @@ -376,11 +396,16 @@ public byte[] engineDoFinal( buffer.reset(); // Convert parameters for use in IESEngine - IESParameters params = new IESWithCipherParameters(engineSpec.getDerivationV(), + CipherParameters params = new IESWithCipherParameters(engineSpec.getDerivationV(), engineSpec.getEncodingV(), engineSpec.getMacKeySize(), engineSpec.getCipherKeySize()); + if (engineSpec.getNonce() != null) + { + params = new ParametersWithIV(params, engineSpec.getNonce()); + } + DHParameters dhParams = ((DHKeyParameters)key).getParameters(); byte[] V; @@ -494,71 +519,27 @@ public IES() } } - static public class IESwithDESede + static public class IESwithDESedeCBC extends IESCipher { - public IESwithDESede() + public IESwithDESedeCBC() { super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), - new PaddedBufferedBlockCipher(new DESedeEngine()))); + new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()))), 8); } } - static public class IESwithAES + static public class IESwithAESCBC extends IESCipher { - public IESwithAES() + public IESwithAESCBC() { super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), - new PaddedBufferedBlockCipher(new AESEngine()))); - } - } - - /** - * Backwards compatibility. - */ - static public class OldIESwithCipher - extends IESCipher - { - public OldIESwithCipher(BlockCipher baseCipher) - { - super(new OldIESEngine(new DHBasicAgreement(), - new KDF2BytesGenerator(new SHA1Digest()), - new HMac(new SHA1Digest()), - new PaddedBufferedBlockCipher(baseCipher))); - } - } - - static public class OldIES - extends IESCipher - { - public OldIES() - { - super(new OldIESEngine(new DHBasicAgreement(), - new KDF2BytesGenerator(new SHA1Digest()), - new HMac(new SHA1Digest()))); - } - } - - static public class OldIESwithDESede - extends OldIESwithCipher - { - public OldIESwithDESede() - { - super(new DESedeEngine()); - } - } - - static public class OldIESwithAES - extends OldIESwithCipher - { - public OldIESwithAES() - { - super(new AESEngine()); + new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESFastEngine()))), 16); } } }
prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java+6 −11 modified@@ -38,19 +38,14 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("AlgorithmParameterGenerator.DH", PREFIX + "AlgorithmParameterGeneratorSpi"); provider.addAlgorithm("Cipher.IES", PREFIX + "IESCipher$IES"); - provider.addAlgorithm("Cipher.IESwithAES", PREFIX + "IESCipher$IESwithAES"); - provider.addAlgorithm("Cipher.IESWITHAES", PREFIX + "IESCipher$IESwithAES"); - provider.addAlgorithm("Cipher.IESWITHDESEDE", PREFIX + "IESCipher$IESwithDESede"); + provider.addAlgorithm("Cipher.IESwithAES-CBC", PREFIX + "IESCipher$IESwithAESCBC"); + provider.addAlgorithm("Cipher.IESWITHAES-CBC", PREFIX + "IESCipher$IESwithAESCBC"); + provider.addAlgorithm("Cipher.IESWITHDESEDE-CBC", PREFIX + "IESCipher$IESwithDESedeCBC"); provider.addAlgorithm("Cipher.DHIES", PREFIX + "IESCipher$IES"); - provider.addAlgorithm("Cipher.DHIESwithAES", PREFIX + "IESCipher$IESwithAES"); - provider.addAlgorithm("Cipher.DHIESWITHAES", PREFIX + "IESCipher$IESwithAES"); - provider.addAlgorithm("Cipher.DHIESWITHDESEDE", PREFIX + "IESCipher$IESwithDESede"); - - provider.addAlgorithm("Cipher.OLDDHIES", PREFIX + "IESCipher$OldIES"); - provider.addAlgorithm("Cipher.OLDDHIESwithAES", PREFIX + "IESCipher$OldIESwithAES"); - provider.addAlgorithm("Cipher.OLDDHIESWITHAES", PREFIX + "IESCipher$OldIESwithAES"); - provider.addAlgorithm("Cipher.OLDDHIESWITHDESEDE", PREFIX + "IESCipher$OldIESwithDESede"); + provider.addAlgorithm("Cipher.DHIESwithAES-CBC", PREFIX + "IESCipher$IESwithAESCBC"); + provider.addAlgorithm("Cipher.DHIESWITHAES-CBC", PREFIX + "IESCipher$IESwithAESCBC"); + provider.addAlgorithm("Cipher.DHIESWITHDESEDE-CBC", PREFIX + "IESCipher$IESwithDESedeCBC"); registerOid(provider, PKCSObjectIdentifiers.dhKeyAgreement, "DH", new KeyFactorySpi()); registerOid(provider, X9ObjectIdentifiers.dhpublicnumber, "DH", new KeyFactorySpi());
prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java+16 −110 modified@@ -24,10 +24,9 @@ import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; import org.bouncycastle.crypto.digests.SHA1Digest; -import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.engines.IESEngine; -import org.bouncycastle.crypto.engines.OldIESEngine; import org.bouncycastle.crypto.generators.ECKeyPairGenerator; import org.bouncycastle.crypto.generators.EphemeralKeyPairGenerator; import org.bouncycastle.crypto.generators.KDF2BytesGenerator; @@ -108,6 +107,10 @@ public int engineGetKeySize(Key key) public byte[] engineGetIV() { + if (engineSpec != null) + { + return engineSpec.getNonce(); + } return null; } @@ -264,7 +267,13 @@ public void engineInit( // Use default parameters (including cipher key size) if none are specified if (engineSpec == null) { - this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher()); + byte[] nonce = null; + if (ivLength != 0 && opmode == Cipher.ENCRYPT_MODE) + { + nonce = new byte[ivLength]; + random.nextBytes(nonce); + } + this.engineSpec = IESUtil.guessParameterSpec(engine.getCipher(), nonce); } else if (engineSpec instanceof IESParameterSpec) { @@ -277,16 +286,9 @@ else if (engineSpec instanceof IESParameterSpec) byte[] nonce = this.engineSpec.getNonce(); - if (nonce != null) + if (ivLength != 0 && (nonce == null || nonce.length != ivLength)) { - if (ivLength == 0) - { - throw new InvalidAlgorithmParameterException("NONCE present in IES Parameters when none required"); - } - else if (nonce.length != ivLength) - { - throw new InvalidAlgorithmParameterException("NONCE in IES Parameters needs to be " + ivLength + " bytes long"); - } + throw new InvalidAlgorithmParameterException("NONCE in IES Parameters needs to be " + ivLength + " bytes long"); } // Parse the recipient's key @@ -351,7 +353,7 @@ public void engineInit( } catch (InvalidAlgorithmParameterException e) { - throw new IllegalArgumentException("can't handle supplied parameter spec"); + throw new IllegalArgumentException("cannot handle supplied parameter spec: " + e.getMessage()); } } @@ -513,14 +515,6 @@ public ECIES() static public class ECIESwithCipher extends IESCipher { - public ECIESwithCipher(BlockCipher cipher) - { - super(new IESEngine(new ECDHBasicAgreement(), - new KDF2BytesGenerator(new SHA1Digest()), - new HMac(new SHA1Digest()), - new PaddedBufferedBlockCipher(cipher))); - } - public ECIESwithCipher(BlockCipher cipher, int ivLength) { super(new IESEngine(new ECDHBasicAgreement(), @@ -530,24 +524,6 @@ public ECIESwithCipher(BlockCipher cipher, int ivLength) } } - static public class ECIESwithDESede - extends ECIESwithCipher - { - public ECIESwithDESede() - { - super(new DESedeEngine()); - } - } - - static public class ECIESwithAES - extends ECIESwithCipher - { - public ECIESwithAES() - { - super(new AESEngine()); - } - } - static public class ECIESwithDESedeCBC extends ECIESwithCipher { @@ -562,77 +538,7 @@ static public class ECIESwithAESCBC { public ECIESwithAESCBC() { - super(new CBCBlockCipher(new AESEngine()), 16); - } - } - - /** - * Backwards compatibility - */ - static public class OldECIES - extends IESCipher - { - public OldECIES() - { - super(new OldIESEngine(new ECDHBasicAgreement(), - new KDF2BytesGenerator(new SHA1Digest()), - new HMac(new SHA1Digest()))); - } - } - - static public class OldECIESwithCipher - extends IESCipher - { - public OldECIESwithCipher(BlockCipher baseCipher) - { - super(new OldIESEngine(new ECDHBasicAgreement(), - new KDF2BytesGenerator(new SHA1Digest()), - new HMac(new SHA1Digest()), - new PaddedBufferedBlockCipher(baseCipher))); - } - - public OldECIESwithCipher(BlockCipher baseCipher, int ivLength) - { - super(new OldIESEngine(new ECDHBasicAgreement(), - new KDF2BytesGenerator(new SHA1Digest()), - new HMac(new SHA1Digest()), - new PaddedBufferedBlockCipher(baseCipher)), ivLength); - } - } - - static public class OldECIESwithDESede - extends OldECIESwithCipher - { - public OldECIESwithDESede() - { - super(new DESedeEngine()); - } - } - - static public class OldECIESwithAES - extends OldECIESwithCipher - { - public OldECIESwithAES() - { - super(new AESEngine()); - } - } - - static public class OldECIESwithDESedeCBC - extends OldECIESwithCipher - { - public OldECIESwithDESedeCBC() - { - super(new CBCBlockCipher(new DESedeEngine()), 8); - } - } - - static public class OldECIESwithAESCBC - extends OldECIESwithCipher - { - public OldECIESwithAESCBC() - { - super(new CBCBlockCipher(new AESEngine()), 16); + super(new CBCBlockCipher(new AESFastEngine()), 16); } } }
prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java+1 −14 modified@@ -134,25 +134,12 @@ public void configure(ConfigurableProvider provider) provider.addAlgorithm("KeyPairGenerator.ECIES", PREFIX + "KeyPairGeneratorSpi$ECDH"); provider.addAlgorithm("Cipher.ECIES", PREFIX + "IESCipher$ECIES"); - provider.addAlgorithm("Cipher.ECIESwithAES", PREFIX + "IESCipher$ECIESwithAES"); - provider.addAlgorithm("Cipher.ECIESWITHAES", PREFIX + "IESCipher$ECIESwithAES"); - provider.addAlgorithm("Cipher.ECIESwithDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); - provider.addAlgorithm("Cipher.ECIESWITHDESEDE", PREFIX + "IESCipher$ECIESwithDESede"); + provider.addAlgorithm("Cipher.ECIESwithAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC"); provider.addAlgorithm("Cipher.ECIESWITHAES-CBC", PREFIX + "IESCipher$ECIESwithAESCBC"); provider.addAlgorithm("Cipher.ECIESwithDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC"); provider.addAlgorithm("Cipher.ECIESWITHDESEDE-CBC", PREFIX + "IESCipher$ECIESwithDESedeCBC"); - provider.addAlgorithm("Cipher.OldECIES", PREFIX + "IESCipher$OldECIES"); - provider.addAlgorithm("Cipher.OldECIESwithAES", PREFIX + "IESCipher$OldECIESwithAES"); - provider.addAlgorithm("Cipher.OldECIESWITHAES", PREFIX + "IESCipher$OldECIESwithAES"); - provider.addAlgorithm("Cipher.OldECIESwithDESEDE", PREFIX + "IESCipher$OldECIESwithDESede"); - provider.addAlgorithm("Cipher.OldECIESWITHDESEDE", PREFIX + "IESCipher$OldECIESwithDESede"); - provider.addAlgorithm("Cipher.OldECIESwithAES-CBC", PREFIX + "IESCipher$OldECIESwithAESCBC"); - provider.addAlgorithm("Cipher.OldECIESWITHAES-CBC", PREFIX + "IESCipher$OldECIESwithAESCBC"); - provider.addAlgorithm("Cipher.OldECIESwithDESEDE-CBC", PREFIX + "IESCipher$OldECIESwithDESedeCBC"); - provider.addAlgorithm("Cipher.OldECIESWITHDESEDE-CBC", PREFIX + "IESCipher$OldECIESwithDESedeCBC"); - provider.addAlgorithm("Signature.ECDSA", PREFIX + "SignatureSpi$ecDSA"); provider.addAlgorithm("Signature.NONEwithECDSA", PREFIX + "SignatureSpi$ecDSAnone");
prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java+19 −1 modified@@ -57,7 +57,15 @@ protected byte[] engineGetEncoded() v.add(new DERTaggedObject(false, 1, new DEROctetString(currentSpec.getEncodingV()))); } v.add(new ASN1Integer(currentSpec.getMacKeySize())); + if (currentSpec.getNonce() != null) + { + ASN1EncodableVector cV = new ASN1EncodableVector(); + + cV.add(new ASN1Integer(currentSpec.getCipherKeySize())); + cV.add(new ASN1Integer(currentSpec.getNonce())); + v.add(new DERSequence(cV)); + } return new DERSequence(v).getEncoded(ASN1Encoding.DER); } catch (IOException e) @@ -126,13 +134,23 @@ else if (s.size() == 2) this.currentSpec = new IESParameterSpec(null, ASN1OctetString.getInstance(tagged, false).getOctets(), ASN1Integer.getInstance(s.getObjectAt(1)).getValue().intValue()); } } - else + else if (s.size() == 3) { ASN1TaggedObject tagged1 = ASN1TaggedObject.getInstance(s.getObjectAt(0)); ASN1TaggedObject tagged2 = ASN1TaggedObject.getInstance(s.getObjectAt(1)); this.currentSpec = new IESParameterSpec(ASN1OctetString.getInstance(tagged1, false).getOctets(), ASN1OctetString.getInstance(tagged2, false).getOctets(), ASN1Integer.getInstance(s.getObjectAt(2)).getValue().intValue()); } + else if (s.size() == 4) + { + ASN1TaggedObject tagged1 = ASN1TaggedObject.getInstance(s.getObjectAt(0)); + ASN1TaggedObject tagged2 = ASN1TaggedObject.getInstance(s.getObjectAt(1)); + ASN1Sequence cipherDet = ASN1Sequence.getInstance(s.getObjectAt(3)); + + this.currentSpec = new IESParameterSpec(ASN1OctetString.getInstance(tagged1, false).getOctets(), ASN1OctetString.getInstance(tagged2, false).getOctets(), ASN1Integer.getInstance(s.getObjectAt(2)).getValue().intValue(), + ASN1Integer.getInstance(cipherDet.getObjectAt(0)).getValue().intValue(), + ASN1OctetString.getInstance(cipherDet.getObjectAt(1)).getOctets()); + } } catch (ClassCastException e) {
prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/IESUtil.java+5 −5 modified@@ -6,7 +6,7 @@ public class IESUtil { - public static IESParameterSpec guessParameterSpec(BufferedBlockCipher iesBlockCipher) + public static IESParameterSpec guessParameterSpec(BufferedBlockCipher iesBlockCipher, byte[] nonce) { if (iesBlockCipher == null) { @@ -21,18 +21,18 @@ public static IESParameterSpec guessParameterSpec(BufferedBlockCipher iesBlockCi underlyingCipher.getAlgorithmName().equals("RC5-32") || underlyingCipher.getAlgorithmName().equals("RC5-64")) { - return new IESParameterSpec(null, null, 64, 64); + return new IESParameterSpec(null, null, 64, 64, nonce); } else if (underlyingCipher.getAlgorithmName().equals("SKIPJACK")) { - return new IESParameterSpec(null, null, 80, 80); + return new IESParameterSpec(null, null, 80, 80, nonce); } else if (underlyingCipher.getAlgorithmName().equals("GOST28147")) { - return new IESParameterSpec(null, null, 256, 256); + return new IESParameterSpec(null, null, 256, 256, nonce); } - return new IESParameterSpec(null, null, 128, 128); + return new IESParameterSpec(null, null, 128, 128, nonce); } } }
prov/src/main/java/org/bouncycastle/jce/spec/IESParameterSpec.java+0 −18 modified@@ -33,24 +33,6 @@ public IESParameterSpec( this(derivation, encoding, macKeySize, -1, null, false); } - - /** - * Set the IES engine parameters. - * - * @param derivation the optional derivation vector for the KDF. - * @param encoding the optional encoding vector for the KDF. - * @param macKeySize the key size (in bits) for the MAC. - * @param cipherKeySize the key size (in bits) for the block cipher. - */ - public IESParameterSpec( - byte[] derivation, - byte[] encoding, - int macKeySize, - int cipherKeySize) - { - this(derivation, encoding, macKeySize, cipherKeySize, null, false); - } - /** * Set the IES engine parameters. *
prov/src/test/java/org/bouncycastle/jce/provider/test/DHIESTest.java+71 −31 modified@@ -1,6 +1,7 @@ package org.bouncycastle.jce.provider.test; import java.math.BigInteger; +import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; @@ -18,9 +19,10 @@ import org.bouncycastle.crypto.generators.KDF2BytesGenerator; import org.bouncycastle.crypto.macs.HMac; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jcajce.provider.asymmetric.dh.IESCipher; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.IESParameterSpec; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -65,17 +67,18 @@ public void performTest() // Testing DHIES with default prime in streaming mode KeyPairGenerator g = KeyPairGenerator.getInstance("DH", "BC"); + KeyPairGenerator g512 = KeyPairGenerator.getInstance("DH", "BC"); g.initialize(param); doTest("DHIES with default", g, "DHIES", params); // Testing DHIES with 512-bit prime in streaming mode - g.initialize(512, new SecureRandom()); - doTest("DHIES with 512-bit", g, "DHIES", params); + g512.initialize(512, new SecureRandom()); + doTest("DHIES with 512-bit", g512, "DHIES", params); // Testing ECIES with 1024-bit prime in streaming mode - g.initialize(1024, new SecureRandom()); + g.initialize(param, new SecureRandom()); doTest("DHIES with 1024-bit", g, "DHIES", params); c1 = new IESCipher(new IESEngine(new DHBasicAgreement(), @@ -88,43 +91,79 @@ public void performTest() new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESEngine()))); - params = new IESParameterSpec(derivation, encoding, 128, 192); + params = new IESParameterSpec(derivation, encoding, 128, 192, Hex.decode("0001020304050607")); // Testing DHIES with default prime using DESEDE g = KeyPairGenerator.getInstance("DH", "BC"); - doTest("DHIESwithDES default", g, "DHIESwithDESEDE", params); + doTest("DHIESwithDES default", g, "DHIESwithDESEDE-CBC", params); // Testing DHIES with 512-bit prime using DESEDE - g.initialize(512, new SecureRandom()); - doTest("DHIESwithDES 512-bit", g, "DHIESwithDESEDE", params); + doTest("DHIESwithDES 512-bit", g512, "DHIESwithDESEDE-CBC", params); // Testing DHIES with 1024-bit prime using DESEDE - g.initialize(1024, new SecureRandom()); - doTest("DHIESwithDES 1024-bit", g, "DHIESwithDESEDE", params); + g.initialize(param, new SecureRandom()); + doTest("DHIESwithDES 1024-bit", g, "DHIESwithDESEDE-CBC", params); g = KeyPairGenerator.getInstance("DH", "BC"); g.initialize(param); - c1 = new IESCipher.IESwithAES(); - c2 = new IESCipher.IESwithAES(); - params = new IESParameterSpec(derivation, encoding, 128, 128); + c1 = new IESCipher.IESwithAESCBC(); + c2 = new IESCipher.IESwithAESCBC(); + params = new IESParameterSpec(derivation, encoding, 128, 128, Hex.decode("00010203040506070001020304050607")); - // Testing DHIES with default curve using AES - doTest("DHIESwithAES default", g, "DHIESwithAES", params); + // Testing DHIES with default prime using AES + doTest("DHIESwithAES default", g, "DHIESwithAES-CBC", params); - // Testing DHIES with 512-bit curve using AES - g.initialize(512, new SecureRandom()); - doTest("DHIESwithAES 512-bit", g, "DHIESwithAES", params); - - // Testing DHIES with 1024-bit curve using AES - g.initialize(1024, new SecureRandom()); - doTest("DHIESwithAES 1024-bit", g, "DHIESwithAES", params); + // Testing DHIES with 512-bit prime using AES + doTest("DHIESwithAES 512-bit", g512, "DHIESwithAES-CBC", params); + // Testing DHIES with 1024-bit prime using AES + g.initialize(param, new SecureRandom()); + doTest("DHIESwithAES 1024-bit", g, "DHIESwithAES-CBC", params); + + KeyPair keyPair = g.generateKeyPair(); + DHPublicKey pub = (DHPublicKey)keyPair.getPublic(); + DHPrivateKey priv = (DHPrivateKey)keyPair.getPrivate(); + + Cipher c = Cipher.getInstance("DHIESwithAES-CBC", "BC"); + + try + { + c.init(Cipher.ENCRYPT_MODE, pub, new IESParameterSpec(derivation, encoding, 128, 128, null)); + + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + isTrue("message ", "NONCE in IES Parameters needs to be 16 bytes long".equals(e.getMessage())); + } + + try + { + c.init(Cipher.DECRYPT_MODE, priv); + + fail("no exception"); + } + catch (IllegalArgumentException e) + { + isTrue("message ", "cannot handle supplied parameter spec: NONCE in IES Parameters needs to be 16 bytes long".equals(e.getMessage())); + } + + try + { + c.init(Cipher.DECRYPT_MODE, priv, new IESParameterSpec(derivation, encoding, 128, 128, null)); + + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + isTrue("message ", "NONCE in IES Parameters needs to be 16 bytes long".equals(e.getMessage())); + } } public void doTest( - String testname, - KeyPairGenerator g, + String testname, + KeyPairGenerator g, String cipher, IESParameterSpec p) throws Exception @@ -139,22 +178,23 @@ public void doTest( KeyPair keyPair = g.generateKeyPair(); DHPublicKey pub = (DHPublicKey)keyPair.getPublic(); DHPrivateKey priv = (DHPrivateKey)keyPair.getPrivate(); - - // Testing with null parameters and DHAES mode off + // Testing with default parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, pub, new SecureRandom()); - c2.init(Cipher.DECRYPT_MODE, priv, new SecureRandom()); + c2.init(Cipher.DECRYPT_MODE, priv, c1.getParameters()); + + isTrue("nonce mismatch", Arrays.areEqual(c1.getIV(), c2.getIV())); + out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) { - fail(testname + " test failed with null parameters, DHAES mode false."); + fail(testname + " test failed with default parameters, DHAES mode false."); } - // Testing with given parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, pub, p, new SecureRandom()); - c2.init(Cipher.DECRYPT_MODE, priv, p, new SecureRandom()); + c2.init(Cipher.DECRYPT_MODE, priv, p); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) @@ -164,7 +204,7 @@ public void doTest( c1 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); c2 = Cipher.getInstance(cipher + "/DHAES/PKCS7Padding","BC"); c1.init(Cipher.ENCRYPT_MODE, pub, new SecureRandom()); - c2.init(Cipher.DECRYPT_MODE, priv, new SecureRandom()); + c2.init(Cipher.DECRYPT_MODE, priv, c1.getParameters(), new SecureRandom()); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message))
prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESTest.java+49 −27 modified@@ -22,6 +22,7 @@ import org.bouncycastle.jce.interfaces.ECPublicKey; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.spec.IESParameterSpec; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; @@ -75,19 +76,10 @@ public void performTest() new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESEngine()))); - params = new IESParameterSpec(derivation, encoding, 128, 128); + params = new IESParameterSpec(derivation, encoding, 128, 128, Hex.decode("0001020304050607")); // Testing ECIES with default curve using DES g = KeyPairGenerator.getInstance("EC", "BC"); - doTest("default", g, "ECIESwithDESEDE", params); - - // Testing ECIES with 192-bit curve using DES - g.initialize(192, new SecureRandom()); - doTest("192-bit", g, "ECIESwithDESEDE", params); - - // Testing ECIES with 256-bit curve using DES - g.initialize(256, new SecureRandom()); - doTest("256-bit", g, "ECIESwithDESEDE", params); // Testing ECIES with 256-bit curve using DES-CBC g.initialize(256, new SecureRandom()); @@ -112,21 +104,9 @@ public void performTest() } } - c1 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIESwithAES(); - c2 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIESwithAES(); - params = new IESParameterSpec(derivation, encoding, 128, 128); - - // Testing ECIES with default curve using AES - g = KeyPairGenerator.getInstance("EC", "BC"); - doTest("default", g, "ECIESwithAES", params); - - // Testing ECIES with 192-bit curve using AES - g.initialize(192, new SecureRandom()); - doTest("192-bit", g, "ECIESwithAES", params); - - // Testing ECIES with 256-bit curve using AES - g.initialize(256, new SecureRandom()); - doTest("256-bit", g, "ECIESwithAES", params); + c1 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIESwithAESCBC(); + c2 = new org.bouncycastle.jcajce.provider.asymmetric.ec.IESCipher.ECIESwithAESCBC(); + params = new IESParameterSpec(derivation, encoding, 128, 128, Hex.decode("000102030405060708090a0b0c0d0e0f")); // Testing ECIES with 256-bit curve using AES-CBC g.initialize(256, new SecureRandom()); @@ -151,6 +131,45 @@ public void performTest() } } + KeyPair keyPair = g.generateKeyPair(); + ECPublicKey pub = (ECPublicKey)keyPair.getPublic(); + ECPrivateKey priv = (ECPrivateKey)keyPair.getPrivate(); + + Cipher c = Cipher.getInstance("ECIESwithAES-CBC", "BC"); + + try + { + c.init(Cipher.ENCRYPT_MODE, pub, new IESParameterSpec(derivation, encoding, 128, 128, null)); + + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + isTrue("message ", "NONCE in IES Parameters needs to be 16 bytes long".equals(e.getMessage())); + } + + try + { + c.init(Cipher.DECRYPT_MODE, priv); + + fail("no exception"); + } + catch (IllegalArgumentException e) + { + isTrue("message ", "cannot handle supplied parameter spec: NONCE in IES Parameters needs to be 16 bytes long".equals(e.getMessage())); + } + + try + { + c.init(Cipher.DECRYPT_MODE, priv, new IESParameterSpec(derivation, encoding, 128, 128, null)); + + fail("no exception"); + } + catch (InvalidAlgorithmParameterException e) + { + isTrue("message ", "NONCE in IES Parameters needs to be 16 bytes long".equals(e.getMessage())); + } + sealedObjectTest(); } @@ -204,7 +223,10 @@ public void doTest( // Testing with null parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, Pub, new SecureRandom()); - c2.init(Cipher.DECRYPT_MODE, Priv, new SecureRandom()); + c2.init(Cipher.DECRYPT_MODE, Priv, c1.getParameters()); + + isTrue("nonce mismatch", Arrays.areEqual(c1.getIV(), c2.getIV())); + out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message)) @@ -213,7 +235,7 @@ public void doTest( // Testing with given parameters and DHAES mode off c1.init(Cipher.ENCRYPT_MODE, Pub, p, new SecureRandom()); - c2.init(Cipher.DECRYPT_MODE, Priv, p, new SecureRandom()); + c2.init(Cipher.DECRYPT_MODE, Priv, p); out1 = c1.doFinal(message, 0, message.length); out2 = c2.doFinal(out1, 0, out1.length); if (!areEqual(out2, message))
prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESVectorTest.java+8 −7 modified@@ -117,13 +117,14 @@ public void performTest() doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "ECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding2, 128), p256_1_with_params22); doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "ECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding3, 128), p256_1_with_params23); - doTestNoParams("ECIES with P-256 None", keyPair, "OldECIES", p256_1_eph, old_p256_1_no_params); - doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation1, encoding1, 128), old_p256_1_with_params11); - doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation1, encoding2, 128), old_p256_1_with_params12); - doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation1, encoding3, 128), old_p256_1_with_params13); - doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding1, 128), old_p256_1_with_params21); - doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding2, 128), old_p256_1_with_params22); - doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding3, 128), old_p256_1_with_params23); + // no longer supported +// doTestNoParams("ECIES with P-256 None", keyPair, "OldECIES", p256_1_eph, old_p256_1_no_params); +// doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation1, encoding1, 128), old_p256_1_with_params11); +// doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation1, encoding2, 128), old_p256_1_with_params12); +// doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation1, encoding3, 128), old_p256_1_with_params13); +// doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding1, 128), old_p256_1_with_params21); +// doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding2, 128), old_p256_1_with_params22); +// doTestWithParams("ECIES with P-256 KP1 P11", keyPair, "OldECIES", p256_1_eph, new IESParameterSpec(derivation2, encoding3, 128), old_p256_1_with_params23); keyPair = new KeyPair(ecFact.generatePublic(new X509EncodedKeySpec(p256_2_pub)), ecFact.generatePrivate(new PKCS8EncodedKeySpec(p256_2_pri)));
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- access.redhat.com/errata/RHSA-2018:2669ghsavendor-advisoryx_refsource_REDHATWEB
- access.redhat.com/errata/RHSA-2018:2927ghsavendor-advisoryx_refsource_REDHATWEB
- github.com/advisories/GHSA-w285-wf9q-5w69ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-1000352ghsaADVISORY
- github.com/bcgit/bc-java/commit/9385b0ebd277724b167fe1d1456e3c112112be1fghsax_refsource_CONFIRMWEB
- security.netapp.com/advisory/ntap-20181127-0004ghsaWEB
- security.netapp.com/advisory/ntap-20181127-0004/mitrex_refsource_CONFIRM
- www.oracle.com/security-alerts/cpuoct2020.htmlghsax_refsource_MISCWEB
News mentions
0No linked articles in our index yet.