374 lines
16 KiB
Java
374 lines
16 KiB
Java
package org.bouncycastle.jcajce.provider.asymmetric.dh;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.security.AlgorithmParameters;
|
|
import java.security.InvalidAlgorithmParameterException;
|
|
import java.security.InvalidKeyException;
|
|
import java.security.Key;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.PrivateKey;
|
|
import java.security.PublicKey;
|
|
import java.security.SecureRandom;
|
|
import java.security.spec.AlgorithmParameterSpec;
|
|
import javax.crypto.BadPaddingException;
|
|
import javax.crypto.CipherSpi;
|
|
import javax.crypto.IllegalBlockSizeException;
|
|
import javax.crypto.NoSuchPaddingException;
|
|
import javax.crypto.ShortBufferException;
|
|
import javax.crypto.interfaces.DHKey;
|
|
import javax.crypto.interfaces.DHPrivateKey;
|
|
import javax.crypto.interfaces.DHPublicKey;
|
|
import org.bouncycastle.crypto.BlockCipher;
|
|
import org.bouncycastle.crypto.BufferedBlockCipher;
|
|
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.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.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.IESWithCipherParameters;
|
|
import org.bouncycastle.crypto.parsers.DHIESPublicKeyParser;
|
|
import org.bouncycastle.jcajce.provider.asymmetric.util.DHUtil;
|
|
import org.bouncycastle.jcajce.provider.asymmetric.util.IESUtil;
|
|
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
|
|
import org.bouncycastle.jcajce.util.JcaJceHelper;
|
|
import org.bouncycastle.jce.interfaces.IESKey;
|
|
import org.bouncycastle.jce.spec.IESParameterSpec;
|
|
import org.bouncycastle.util.BigIntegers;
|
|
import org.bouncycastle.util.Strings;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class IESCipher extends CipherSpi {
|
|
private IESEngine engine;
|
|
private AsymmetricKeyParameter key;
|
|
private SecureRandom random;
|
|
private final JcaJceHelper helper = new BCJcaJceHelper();
|
|
private int state = -1;
|
|
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
private AlgorithmParameters engineParam = null;
|
|
private IESParameterSpec engineSpec = null;
|
|
private boolean dhaesMode = false;
|
|
private AsymmetricKeyParameter otherKeyParameter = null;
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public byte[] engineGetIV() {
|
|
return null;
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public byte[] engineUpdate(byte[] bArr, int i, int i2) {
|
|
this.buffer.write(bArr, i, i2);
|
|
return null;
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public int engineUpdate(byte[] bArr, int i, int i2, byte[] bArr2, int i3) {
|
|
this.buffer.write(bArr, i, i2);
|
|
return 0;
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public void engineSetPadding(String str) throws NoSuchPaddingException {
|
|
String upperCase = Strings.toUpperCase(str);
|
|
if (!upperCase.equals("NOPADDING") && !upperCase.equals("PKCS5PADDING") && !upperCase.equals("PKCS7PADDING")) {
|
|
throw new NoSuchPaddingException("padding not available with IESCipher");
|
|
}
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public void engineSetMode(String str) throws NoSuchAlgorithmException {
|
|
boolean z;
|
|
String upperCase = Strings.toUpperCase(str);
|
|
if (upperCase.equals("NONE")) {
|
|
z = false;
|
|
} else {
|
|
if (!upperCase.equals("DHAES")) {
|
|
throw new IllegalArgumentException("can't support mode ".concat(String.valueOf(str)));
|
|
}
|
|
z = true;
|
|
}
|
|
this.dhaesMode = z;
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public void engineInit(int i, Key key, AlgorithmParameterSpec algorithmParameterSpec, SecureRandom secureRandom) throws InvalidAlgorithmParameterException, InvalidKeyException {
|
|
IESParameterSpec iESParameterSpec;
|
|
AsymmetricKeyParameter generatePublicKeyParameter;
|
|
PrivateKey privateKey;
|
|
if (algorithmParameterSpec == null) {
|
|
iESParameterSpec = IESUtil.guessParameterSpec(this.engine.getCipher());
|
|
} else {
|
|
if (!(algorithmParameterSpec instanceof IESParameterSpec)) {
|
|
throw new InvalidAlgorithmParameterException("must be passed IES parameters");
|
|
}
|
|
iESParameterSpec = (IESParameterSpec) algorithmParameterSpec;
|
|
}
|
|
this.engineSpec = iESParameterSpec;
|
|
if (i == 1 || i == 3) {
|
|
if (!(key instanceof DHPublicKey)) {
|
|
if (!(key instanceof IESKey)) {
|
|
throw new InvalidKeyException("must be passed recipient's public DH key for encryption");
|
|
}
|
|
IESKey iESKey = (IESKey) key;
|
|
this.key = DHUtil.generatePublicKeyParameter(iESKey.getPublic());
|
|
this.otherKeyParameter = DHUtil.generatePrivateKeyParameter(iESKey.getPrivate());
|
|
this.random = secureRandom;
|
|
this.state = i;
|
|
this.buffer.reset();
|
|
}
|
|
generatePublicKeyParameter = DHUtil.generatePublicKeyParameter((PublicKey) key);
|
|
} else {
|
|
if (i != 2 && i != 4) {
|
|
throw new InvalidKeyException("must be passed EC key");
|
|
}
|
|
if (key instanceof DHPrivateKey) {
|
|
privateKey = (PrivateKey) key;
|
|
} else {
|
|
if (!(key instanceof IESKey)) {
|
|
throw new InvalidKeyException("must be passed recipient's private DH key for decryption");
|
|
}
|
|
IESKey iESKey2 = (IESKey) key;
|
|
this.otherKeyParameter = DHUtil.generatePublicKeyParameter(iESKey2.getPublic());
|
|
privateKey = iESKey2.getPrivate();
|
|
}
|
|
generatePublicKeyParameter = DHUtil.generatePrivateKeyParameter(privateKey);
|
|
}
|
|
this.key = generatePublicKeyParameter;
|
|
this.random = secureRandom;
|
|
this.state = i;
|
|
this.buffer.reset();
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public void engineInit(int i, Key key, SecureRandom secureRandom) throws InvalidKeyException {
|
|
try {
|
|
engineInit(i, key, (AlgorithmParameterSpec) null, secureRandom);
|
|
} catch (InvalidAlgorithmParameterException unused) {
|
|
throw new IllegalArgumentException("can't handle supplied parameter spec");
|
|
}
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public void engineInit(int i, Key key, AlgorithmParameters algorithmParameters, SecureRandom secureRandom) throws InvalidKeyException, InvalidAlgorithmParameterException {
|
|
AlgorithmParameterSpec parameterSpec;
|
|
if (algorithmParameters != null) {
|
|
try {
|
|
parameterSpec = algorithmParameters.getParameterSpec(IESParameterSpec.class);
|
|
} catch (Exception e) {
|
|
StringBuilder sb = new StringBuilder("cannot recognise parameters: ");
|
|
sb.append(e.toString());
|
|
throw new InvalidAlgorithmParameterException(sb.toString());
|
|
}
|
|
} else {
|
|
parameterSpec = null;
|
|
}
|
|
this.engineParam = algorithmParameters;
|
|
engineInit(i, key, parameterSpec, secureRandom);
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public AlgorithmParameters engineGetParameters() {
|
|
if (this.engineParam == null && this.engineSpec != null) {
|
|
try {
|
|
AlgorithmParameters createAlgorithmParameters = this.helper.createAlgorithmParameters("IES");
|
|
this.engineParam = createAlgorithmParameters;
|
|
createAlgorithmParameters.init(this.engineSpec);
|
|
} catch (Exception e) {
|
|
throw new RuntimeException(e.toString());
|
|
}
|
|
}
|
|
return this.engineParam;
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public int engineGetOutputSize(int i) {
|
|
int size;
|
|
BufferedBlockCipher cipher;
|
|
if (this.key == null) {
|
|
throw new IllegalStateException("cipher not initialised");
|
|
}
|
|
int macSize = this.engine.getMac().getMacSize();
|
|
int bitLength = this.otherKeyParameter == null ? (((((DHKeyParameters) this.key).getParameters().getP().bitLength() + 7) << 1) / 8) + 1 : 0;
|
|
if (this.engine.getCipher() != null) {
|
|
int i2 = this.state;
|
|
if (i2 == 1 || i2 == 3) {
|
|
cipher = this.engine.getCipher();
|
|
} else {
|
|
if (i2 != 2 && i2 != 4) {
|
|
throw new IllegalStateException("cipher not initialised");
|
|
}
|
|
cipher = this.engine.getCipher();
|
|
i = (i - macSize) - bitLength;
|
|
}
|
|
i = cipher.getOutputSize(i);
|
|
}
|
|
int i3 = this.state;
|
|
if (i3 == 1 || i3 == 3) {
|
|
size = this.buffer.size() + macSize + bitLength;
|
|
} else {
|
|
if (i3 != 2 && i3 != 4) {
|
|
throw new IllegalStateException("IESCipher not initialised");
|
|
}
|
|
size = (this.buffer.size() - macSize) - bitLength;
|
|
}
|
|
return size + i;
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public int engineGetKeySize(Key key) {
|
|
if (key instanceof DHKey) {
|
|
return ((DHKey) key).getParams().getP().bitLength();
|
|
}
|
|
throw new IllegalArgumentException("not a DH key");
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public int engineGetBlockSize() {
|
|
if (this.engine.getCipher() != null) {
|
|
return this.engine.getCipher().getBlockSize();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public byte[] engineDoFinal(byte[] bArr, int i, int i2) throws IllegalBlockSizeException, BadPaddingException {
|
|
if (i2 != 0) {
|
|
this.buffer.write(bArr, i, i2);
|
|
}
|
|
byte[] byteArray = this.buffer.toByteArray();
|
|
this.buffer.reset();
|
|
IESWithCipherParameters iESWithCipherParameters = new IESWithCipherParameters(this.engineSpec.getDerivationV(), this.engineSpec.getEncodingV(), this.engineSpec.getMacKeySize(), this.engineSpec.getCipherKeySize());
|
|
DHParameters parameters = ((DHKeyParameters) this.key).getParameters();
|
|
AsymmetricKeyParameter asymmetricKeyParameter = this.otherKeyParameter;
|
|
if (asymmetricKeyParameter != null) {
|
|
try {
|
|
int i3 = this.state;
|
|
if (i3 == 1 || i3 == 3) {
|
|
this.engine.init(true, asymmetricKeyParameter, this.key, iESWithCipherParameters);
|
|
} else {
|
|
this.engine.init(false, this.key, asymmetricKeyParameter, iESWithCipherParameters);
|
|
}
|
|
return this.engine.processBlock(byteArray, 0, byteArray.length);
|
|
} catch (Exception e) {
|
|
throw new BadPaddingException(e.getMessage());
|
|
}
|
|
}
|
|
int i4 = this.state;
|
|
if (i4 == 1 || i4 == 3) {
|
|
DHKeyPairGenerator dHKeyPairGenerator = new DHKeyPairGenerator();
|
|
dHKeyPairGenerator.init(new DHKeyGenerationParameters(this.random, parameters));
|
|
try {
|
|
this.engine.init(this.key, iESWithCipherParameters, new EphemeralKeyPairGenerator(dHKeyPairGenerator, new KeyEncoder(this) { // from class: org.bouncycastle.jcajce.provider.asymmetric.dh.IESCipher.1
|
|
final IESCipher this$0;
|
|
|
|
@Override // org.bouncycastle.crypto.KeyEncoder
|
|
public byte[] getEncoded(AsymmetricKeyParameter asymmetricKeyParameter2) {
|
|
int bitLength = (((DHKeyParameters) asymmetricKeyParameter2).getParameters().getP().bitLength() + 7) / 8;
|
|
byte[] bArr2 = new byte[bitLength];
|
|
byte[] asUnsignedByteArray = BigIntegers.asUnsignedByteArray(((DHPublicKeyParameters) asymmetricKeyParameter2).getY());
|
|
if (asUnsignedByteArray.length > bitLength) {
|
|
throw new IllegalArgumentException("Senders's public key longer than expected.");
|
|
}
|
|
System.arraycopy(asUnsignedByteArray, 0, bArr2, bitLength - asUnsignedByteArray.length, asUnsignedByteArray.length);
|
|
return bArr2;
|
|
}
|
|
|
|
{
|
|
this.this$0 = this;
|
|
}
|
|
}));
|
|
return this.engine.processBlock(byteArray, 0, byteArray.length);
|
|
} catch (Exception e2) {
|
|
throw new BadPaddingException(e2.getMessage());
|
|
}
|
|
}
|
|
if (i4 != 2 && i4 != 4) {
|
|
throw new IllegalStateException("IESCipher not initialised");
|
|
}
|
|
try {
|
|
IESEngine iESEngine = this.engine;
|
|
AsymmetricKeyParameter asymmetricKeyParameter2 = this.key;
|
|
iESEngine.init(asymmetricKeyParameter2, iESWithCipherParameters, new DHIESPublicKeyParser(((DHKeyParameters) asymmetricKeyParameter2).getParameters()));
|
|
return this.engine.processBlock(byteArray, 0, byteArray.length);
|
|
} catch (InvalidCipherTextException e3) {
|
|
throw new BadPaddingException(e3.getMessage());
|
|
}
|
|
}
|
|
|
|
@Override // javax.crypto.CipherSpi
|
|
public int engineDoFinal(byte[] bArr, int i, int i2, byte[] bArr2, int i3) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
|
|
byte[] engineDoFinal = engineDoFinal(bArr, i, i2);
|
|
System.arraycopy(engineDoFinal, 0, bArr2, i3, engineDoFinal.length);
|
|
return engineDoFinal.length;
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
public static class IES extends IESCipher {
|
|
public IES() {
|
|
super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())));
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
public static class IESwithAES extends IESCipher {
|
|
public IESwithAES() {
|
|
super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new AESEngine())));
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
public static class IESwithDESede extends IESCipher {
|
|
public IESwithDESede() {
|
|
super(new IESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(new DESedeEngine())));
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
public static class OldIES extends IESCipher {
|
|
public OldIES() {
|
|
super(new OldIESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())));
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
public static class OldIESwithAES extends OldIESwithCipher {
|
|
public OldIESwithAES() {
|
|
super(new AESEngine());
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
public static class OldIESwithCipher extends IESCipher {
|
|
public OldIESwithCipher(BlockCipher blockCipher) {
|
|
super(new OldIESEngine(new DHBasicAgreement(), new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest()), new PaddedBufferedBlockCipher(blockCipher)));
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
public static class OldIESwithDESede extends OldIESwithCipher {
|
|
public OldIESwithDESede() {
|
|
super(new DESedeEngine());
|
|
}
|
|
}
|
|
|
|
public IESCipher(OldIESEngine oldIESEngine) {
|
|
this.engine = oldIESEngine;
|
|
}
|
|
|
|
public IESCipher(IESEngine iESEngine) {
|
|
this.engine = iESEngine;
|
|
}
|
|
}
|