VYPR
High severityNVD Advisory· Published Jun 4, 2018· Updated Aug 6, 2024

CVE-2016-1000352

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.

PackageAffected versionsPatched versions
org.bouncycastle:bcprov-jdk14Maven
< 1.561.56
org.bouncycastle:bcprov-jdk15Maven
< 1.561.56
org.bouncycastle:bcprov-jdk15onMaven
< 1.561.56

Affected products

3

Patches

1
9385b0ebd277

removed support for non-cbc mode ciphers in IES/ECIES

https://github.com/bcgit/bc-javaDavid HookAug 27, 2016via ghsa
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

News mentions

0

No linked articles in our index yet.