diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java index 7c6c57ea32..badbfd142f 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/DH.java @@ -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()); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java index ecc9ec8b01..05bf010b30 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/EC.java @@ -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"); diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java index 7983217cb9..a721cc0fa3 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dh/IESCipher.java @@ -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); } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java index 3f4e87dfc8..3c29b2b74e 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/IESCipher.java @@ -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); } } } diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java index 13b0f6e211..d6406a7ad7 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ies/AlgorithmParametersSpi.java @@ -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) { diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/IESUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/IESUtil.java index 67396de3fb..63373b242f 100644 --- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/IESUtil.java +++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/IESUtil.java @@ -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); } } } diff --git a/prov/src/main/java/org/bouncycastle/jce/spec/IESParameterSpec.java b/prov/src/main/java/org/bouncycastle/jce/spec/IESParameterSpec.java index c18a88fdb1..cc29c106f6 100644 --- a/prov/src/main/java/org/bouncycastle/jce/spec/IESParameterSpec.java +++ b/prov/src/main/java/org/bouncycastle/jce/spec/IESParameterSpec.java @@ -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. * diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/DHIESTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/DHIESTest.java index f081d80bef..4cea8a920a 100755 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/DHIESTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/DHIESTest.java @@ -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)) diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESTest.java index f4b29ee8cd..9a5e0128cf 100755 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESTest.java @@ -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)) diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESVectorTest.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESVectorTest.java index 9558956188..cfbdf061f5 100755 --- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESVectorTest.java +++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECIESVectorTest.java @@ -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)));