Skip to content

Commit

Permalink
compatibility updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dghgit committed Aug 12, 2017
1 parent 6838810 commit b3153c0
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.engines.DSTU7624Engine;
import org.bouncycastle.crypto.modes.AEADBlockCipher;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.modes.CCMBlockCipher;
Expand All @@ -39,6 +40,9 @@
import org.bouncycastle.crypto.modes.GCFBBlockCipher;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.modes.GOFBBlockCipher;
import org.bouncycastle.crypto.modes.KCCMBlockCipher;
import org.bouncycastle.crypto.modes.KCTRBlockCipher;
import org.bouncycastle.crypto.modes.KGCMBlockCipher;
import org.bouncycastle.crypto.modes.OCBBlockCipher;
import org.bouncycastle.crypto.modes.OFBBlockCipher;
import org.bouncycastle.crypto.modes.OpenPGPCFBBlockCipher;
Expand All @@ -62,6 +66,7 @@
import org.bouncycastle.jcajce.PBKDF1KeyWithParameters;
import org.bouncycastle.jcajce.PKCS12Key;
import org.bouncycastle.jcajce.PKCS12KeyWithParameters;
import org.bouncycastle.jcajce.spec.AEADParameterSpec;
import org.bouncycastle.jcajce.spec.GOST28147ParameterSpec;
import org.bouncycastle.jcajce.spec.RepeatedSecretKeySpec;
import org.bouncycastle.util.Strings;
Expand All @@ -80,9 +85,9 @@ public class BaseBlockCipher
RC2ParameterSpec.class,
RC5ParameterSpec.class,
gcmSpecClass,
GOST28147ParameterSpec.class,
IvParameterSpec.class,
PBEParameterSpec.class,
GOST28147ParameterSpec.class
PBEParameterSpec.class
};

private BlockCipher baseEngine;
Expand Down Expand Up @@ -141,9 +146,9 @@ protected BaseBlockCipher(
protected BaseBlockCipher(
AEADBlockCipher engine)
{
baseEngine = engine.getUnderlyingCipher();
ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(engine);
this.baseEngine = engine.getUnderlyingCipher();
this.ivLength = baseEngine.getBlockSize();
this.cipher = new AEADGenericBlockCipher(engine);
}

protected BaseBlockCipher(
Expand Down Expand Up @@ -220,31 +225,31 @@ protected AlgorithmParameters engineGetParameters()
return null;
}
}
else if (ivParam != null)
else if (aeadParams != null)
{
String name = cipher.getUnderlyingCipher().getAlgorithmName();

if (name.indexOf('/') >= 0)
{
name = name.substring(0, name.indexOf('/'));
}

try
{
engineParams = createParametersInstance(name);
engineParams.init(ivParam.getIV());
engineParams = createParametersInstance("GCM");
engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
}
else if (aeadParams != null)
else if (ivParam != null)
{
String name = cipher.getUnderlyingCipher().getAlgorithmName();

if (name.indexOf('/') >= 0)
{
name = name.substring(0, name.indexOf('/'));
}

try
{
engineParams = createParametersInstance("GCM");
engineParams.init(new GCMParameters(aeadParams.getNonce(), aeadParams.getMacSize() / 8).getEncoded());
engineParams = createParametersInstance(name);
engineParams.init(new IvParameterSpec(ivParam.getIV()));
}
catch (Exception e)
{
Expand Down Expand Up @@ -334,8 +339,16 @@ else if (modeName.startsWith("CTR"))
{
ivLength = baseEngine.getBlockSize();
fixedIv = false;
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
new SICBlockCipher(baseEngine)));
if (baseEngine instanceof DSTU7624Engine)
{
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
new KCTRBlockCipher(baseEngine)));
}
else
{
cipher = new BufferedGenericBlockCipher(new BufferedBlockCipher(
new SICBlockCipher(baseEngine)));
}
}
else if (modeName.startsWith("GOFB"))
{
Expand All @@ -357,7 +370,14 @@ else if (modeName.startsWith("CTS"))
else if (modeName.startsWith("CCM"))
{
ivLength = 13; // CCM nonce 7..13 bytes
cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
if (baseEngine instanceof DSTU7624Engine)
{
cipher = new AEADGenericBlockCipher(new KCCMBlockCipher(baseEngine));
}
else
{
cipher = new AEADGenericBlockCipher(new CCMBlockCipher(baseEngine));
}
}
else if (modeName.startsWith("OCB"))
{
Expand All @@ -382,7 +402,14 @@ else if (modeName.startsWith("EAX"))
else if (modeName.startsWith("GCM"))
{
ivLength = baseEngine.getBlockSize();
cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
if (baseEngine instanceof DSTU7624Engine)
{
cipher = new AEADGenericBlockCipher(new KGCMBlockCipher(baseEngine));
}
else
{
cipher = new AEADGenericBlockCipher(new GCMBlockCipher(baseEngine));
}
}
else
{
Expand Down Expand Up @@ -465,7 +492,7 @@ protected void engineInit(
//
if (!(key instanceof SecretKey))
{
throw new InvalidKeyException("Key for algorithm " + key.getAlgorithm() + " not suitable for symmetric enryption.");
throw new InvalidKeyException("Key for algorithm " + ((key != null) ? key.getAlgorithm() : null) + " not suitable for symmetric enryption.");
}

//
Expand Down Expand Up @@ -617,7 +644,27 @@ else if (!(key instanceof RepeatedSecretKeySpec))
param = null;
}

if (params instanceof IvParameterSpec)
if (params instanceof AEADParameterSpec)
{
if (!isAEADModeName(modeName) && !(cipher instanceof AEADGenericBlockCipher))
{
throw new InvalidAlgorithmParameterException("AEADParameterSpec can only be used with AEAD modes.");
}

AEADParameterSpec aeadSpec = (AEADParameterSpec)params;

KeyParameter keyParam;
if (param instanceof ParametersWithIV)
{
keyParam = (KeyParameter)((ParametersWithIV)param).getParameters();
}
else
{
keyParam = (KeyParameter)param;
}
param = aeadParams = new AEADParameters(keyParam, aeadSpec.getMacSizeInBits(), aeadSpec.getNonce(), aeadSpec.getAssociatedData());
}
else if (params instanceof IvParameterSpec)
{
if (ivLength != 0)
{
Expand Down Expand Up @@ -780,6 +827,8 @@ else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0)
}
}



if (random != null && padded)
{
param = new ParametersWithRandom(param, random);
Expand All @@ -800,16 +849,17 @@ else if (cipher.getUnderlyingCipher().getAlgorithmName().indexOf("PGPCFB") < 0)
default:
throw new InvalidParameterException("unknown opmode " + opmode + " passed");
}

if (cipher instanceof AEADGenericBlockCipher && aeadParams == null)
{
AEADBlockCipher aeadCipher = ((AEADGenericBlockCipher)cipher).cipher;

aeadParams = new AEADParameters((KeyParameter)ivParam.getParameters(), aeadCipher.getMac().length * 8, ivParam.getIV());
}
}
catch (final Exception e)
{
throw new InvalidKeyException(e.getMessage())
{
public Throwable getCause()
{
return e;
}
};
throw new InvalidKeyOrParametersException(e.getMessage(), e);
}
}

Expand Down Expand Up @@ -1177,7 +1227,7 @@ private static class AEADGenericBlockCipher
private static final Constructor aeadBadTagConstructor;

static {
Class aeadBadTagClass = lookup("javax.crypto.AEADBadTagException");
Class aeadBadTagClass = ClassUtil.loadClass(BaseBlockCipher.class, "javax.crypto.AEADBadTagException");
if (aeadBadTagClass != null)
{
aeadBadTagConstructor = findExceptionConstructor(aeadBadTagClass);
Expand Down Expand Up @@ -1282,4 +1332,21 @@ public int doFinal(byte[] out, int outOff) throws IllegalStateException, BadPadd
}
}
}

private static class InvalidKeyOrParametersException
extends InvalidKeyException
{
private final Throwable cause;

InvalidKeyOrParametersException(String msg, Throwable cause)
{
super(msg);
this.cause = cause;
}

public Throwable getCause()
{
return cause;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.bouncycastle.pqc.jcajce.interfaces;

import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.cert.Certificate;

/**
* This interface is implemented by Signature classes returned by the PQC provider where the signature
* algorithm is one where the private key is updated for each signature generated. Examples of these
* are algorithms such as GMSS, XMSS, and XMSS^MT.
*/
public interface StateAwareSignature
{
void initVerify(PublicKey publicKey)
throws InvalidKeyException;

void initVerify(Certificate certificate)
throws InvalidKeyException;

void initSign(PrivateKey privateKey)
throws InvalidKeyException;

void initSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException;

byte[] sign()
throws SignatureException;

int sign(byte[] outbuf, int offset, int len)
throws SignatureException;

boolean verify(byte[] signature)
throws SignatureException;

boolean verify(byte[] signature, int offset, int length)
throws SignatureException;

void update(byte b)
throws SignatureException;

void update(byte[] data)
throws SignatureException;

void update(byte[] data, int off, int len)
throws SignatureException;

String getAlgorithm();

/**
* Return the current version of the private key with the updated state.
* <p>
* <b>Note:</b> calling this method will effectively disable the Signature object from being used for further
* signature generation without another call to init().
* </p>
* @return an updated private key object, which can be used for later signature generation.
*/
PrivateKey getUpdatedPrivateKey();
}

0 comments on commit b3153c0

Please sign in to comment.