what-the-bank/sources/org/bouncycastle/crypto/encodings/OAEPEncoding.java

189 lines
7.7 KiB
Java

package org.bouncycastle.crypto.encodings;
import java.security.SecureRandom;
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.params.ParametersWithRandom;
/* loaded from: classes6.dex */
public class OAEPEncoding implements AsymmetricBlockCipher {
private byte[] defHash;
private AsymmetricBlockCipher engine;
private boolean forEncryption;
private Digest mgf1Hash;
private SecureRandom random;
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public byte[] processBlock(byte[] bArr, int i, int i2) throws InvalidCipherTextException {
return this.forEncryption ? encodeBlock(bArr, i, i2) : decodeBlock(bArr, i, i2);
}
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public void init(boolean z, CipherParameters cipherParameters) {
this.random = cipherParameters instanceof ParametersWithRandom ? ((ParametersWithRandom) cipherParameters).getRandom() : new SecureRandom();
this.engine.init(z, cipherParameters);
this.forEncryption = z;
}
public AsymmetricBlockCipher getUnderlyingCipher() {
return this.engine;
}
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public int getOutputBlockSize() {
int outputBlockSize = this.engine.getOutputBlockSize();
return this.forEncryption ? outputBlockSize : (outputBlockSize - 1) - (this.defHash.length << 1);
}
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
public int getInputBlockSize() {
int inputBlockSize = this.engine.getInputBlockSize();
return this.forEncryption ? (inputBlockSize - 1) - (this.defHash.length << 1) : inputBlockSize;
}
public byte[] encodeBlock(byte[] bArr, int i, int i2) throws InvalidCipherTextException {
if (i2 > getInputBlockSize()) {
throw new DataLengthException("input data too long");
}
int inputBlockSize = getInputBlockSize() + 1 + (this.defHash.length << 1);
byte[] bArr2 = new byte[inputBlockSize];
int i3 = inputBlockSize - i2;
System.arraycopy(bArr, i, bArr2, i3, i2);
bArr2[i3 - 1] = 1;
byte[] bArr3 = this.defHash;
System.arraycopy(bArr3, 0, bArr2, bArr3.length, bArr3.length);
int length = this.defHash.length;
byte[] bArr4 = new byte[length];
this.random.nextBytes(bArr4);
byte[] maskGeneratorFunction1 = maskGeneratorFunction1(bArr4, 0, length, inputBlockSize - this.defHash.length);
for (int length2 = this.defHash.length; length2 != inputBlockSize; length2++) {
bArr2[length2] = (byte) (bArr2[length2] ^ maskGeneratorFunction1[length2 - this.defHash.length]);
}
System.arraycopy(bArr4, 0, bArr2, 0, this.defHash.length);
byte[] bArr5 = this.defHash;
byte[] maskGeneratorFunction12 = maskGeneratorFunction1(bArr2, bArr5.length, inputBlockSize - bArr5.length, bArr5.length);
for (int i4 = 0; i4 != this.defHash.length; i4++) {
bArr2[i4] = (byte) (bArr2[i4] ^ maskGeneratorFunction12[i4]);
}
return this.engine.processBlock(bArr2, 0, inputBlockSize);
}
public byte[] decodeBlock(byte[] bArr, int i, int i2) throws InvalidCipherTextException {
byte[] bArr2;
byte[] bArr3;
byte[] processBlock = this.engine.processBlock(bArr, i, i2);
if (processBlock.length < this.engine.getOutputBlockSize()) {
int outputBlockSize = this.engine.getOutputBlockSize();
byte[] bArr4 = new byte[outputBlockSize];
System.arraycopy(processBlock, 0, bArr4, outputBlockSize - processBlock.length, processBlock.length);
processBlock = bArr4;
}
int length = processBlock.length;
byte[] bArr5 = this.defHash;
if (length < (bArr5.length << 1) + 1) {
throw new InvalidCipherTextException("data too short");
}
byte[] maskGeneratorFunction1 = maskGeneratorFunction1(processBlock, bArr5.length, processBlock.length - bArr5.length, bArr5.length);
int i3 = 0;
while (true) {
bArr2 = this.defHash;
if (i3 == bArr2.length) {
break;
}
processBlock[i3] = (byte) (processBlock[i3] ^ maskGeneratorFunction1[i3]);
i3++;
}
byte[] maskGeneratorFunction12 = maskGeneratorFunction1(processBlock, 0, bArr2.length, processBlock.length - bArr2.length);
for (int length2 = this.defHash.length; length2 != processBlock.length; length2++) {
processBlock[length2] = (byte) (processBlock[length2] ^ maskGeneratorFunction12[length2 - this.defHash.length]);
}
int i4 = 0;
boolean z = false;
while (true) {
bArr3 = this.defHash;
if (i4 == bArr3.length) {
break;
}
if (bArr3[i4] != processBlock[bArr3.length + i4]) {
z = true;
}
i4++;
}
if (z) {
throw new InvalidCipherTextException("data hash wrong");
}
int length3 = bArr3.length << 1;
while (length3 != processBlock.length && processBlock[length3] == 0) {
length3++;
}
if (length3 > processBlock.length - 1 || processBlock[length3] != 1) {
throw new InvalidCipherTextException("data start wrong ".concat(String.valueOf(length3)));
}
int i5 = length3 + 1;
int length4 = processBlock.length - i5;
byte[] bArr6 = new byte[length4];
System.arraycopy(processBlock, i5, bArr6, 0, length4);
return bArr6;
}
private byte[] maskGeneratorFunction1(byte[] bArr, int i, int i2, int i3) {
byte[] bArr2 = new byte[i3];
int digestSize = this.mgf1Hash.getDigestSize();
byte[] bArr3 = new byte[digestSize];
byte[] bArr4 = new byte[4];
this.mgf1Hash.reset();
int i4 = 0;
while (i4 < i3 / digestSize) {
ItoOSP(i4, bArr4);
this.mgf1Hash.update(bArr, i, i2);
this.mgf1Hash.update(bArr4, 0, 4);
this.mgf1Hash.doFinal(bArr3, 0);
System.arraycopy(bArr3, 0, bArr2, i4 * digestSize, digestSize);
i4++;
}
int i5 = digestSize * i4;
if (i5 < i3) {
ItoOSP(i4, bArr4);
this.mgf1Hash.update(bArr, i, i2);
this.mgf1Hash.update(bArr4, 0, 4);
this.mgf1Hash.doFinal(bArr3, 0);
System.arraycopy(bArr3, 0, bArr2, i5, i3 - i5);
}
return bArr2;
}
private void ItoOSP(int i, byte[] bArr) {
bArr[0] = (byte) (i >>> 24);
bArr[1] = (byte) (i >>> 16);
bArr[2] = (byte) (i >>> 8);
bArr[3] = (byte) i;
}
public OAEPEncoding(AsymmetricBlockCipher asymmetricBlockCipher, Digest digest, byte[] bArr) {
this(asymmetricBlockCipher, digest, digest, bArr);
}
public OAEPEncoding(AsymmetricBlockCipher asymmetricBlockCipher, Digest digest, Digest digest2, byte[] bArr) {
this.engine = asymmetricBlockCipher;
this.mgf1Hash = digest2;
this.defHash = new byte[digest.getDigestSize()];
digest.reset();
if (bArr != null) {
digest.update(bArr, 0, bArr.length);
}
digest.doFinal(this.defHash, 0);
}
public OAEPEncoding(AsymmetricBlockCipher asymmetricBlockCipher, Digest digest) {
this(asymmetricBlockCipher, digest, null);
}
public OAEPEncoding(AsymmetricBlockCipher asymmetricBlockCipher) {
this(asymmetricBlockCipher, new SHA1Digest(), null);
}
}