158 lines
5.5 KiB
Java
158 lines
5.5 KiB
Java
package org.bouncycastle.crypto.modes;
|
|
|
|
import com.google.common.base.Ascii;
|
|
import com.google.common.primitives.UnsignedBytes;
|
|
import org.bouncycastle.crypto.BlockCipher;
|
|
import org.bouncycastle.crypto.CipherParameters;
|
|
import org.bouncycastle.crypto.DataLengthException;
|
|
import org.bouncycastle.crypto.StreamBlockCipher;
|
|
import org.bouncycastle.crypto.params.ParametersWithIV;
|
|
import org.bouncycastle.crypto.tls.CipherSuite;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class GOFBBlockCipher extends StreamBlockCipher {
|
|
static final int C1 = 16843012;
|
|
static final int C2 = 16843009;
|
|
private byte[] IV;
|
|
int N3;
|
|
int N4;
|
|
private final int blockSize;
|
|
private int byteCount;
|
|
private final BlockCipher cipher;
|
|
boolean firstStep;
|
|
private byte[] ofbOutV;
|
|
private byte[] ofbV;
|
|
|
|
@Override // org.bouncycastle.crypto.BlockCipher
|
|
public void reset() {
|
|
this.firstStep = true;
|
|
this.N3 = 0;
|
|
this.N4 = 0;
|
|
byte[] bArr = this.IV;
|
|
System.arraycopy(bArr, 0, this.ofbV, 0, bArr.length);
|
|
this.byteCount = 0;
|
|
this.cipher.reset();
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.BlockCipher
|
|
public int processBlock(byte[] bArr, int i, byte[] bArr2, int i2) throws DataLengthException, IllegalStateException {
|
|
processBytes(bArr, i, this.blockSize, bArr2, i2);
|
|
return this.blockSize;
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.BlockCipher
|
|
public void init(boolean z, CipherParameters cipherParameters) throws IllegalArgumentException {
|
|
BlockCipher blockCipher;
|
|
this.firstStep = true;
|
|
this.N3 = 0;
|
|
this.N4 = 0;
|
|
if (cipherParameters instanceof ParametersWithIV) {
|
|
ParametersWithIV parametersWithIV = (ParametersWithIV) cipherParameters;
|
|
byte[] iv = parametersWithIV.getIV();
|
|
int length = iv.length;
|
|
byte[] bArr = this.IV;
|
|
if (length < bArr.length) {
|
|
System.arraycopy(iv, 0, bArr, bArr.length - iv.length, iv.length);
|
|
int i = 0;
|
|
while (true) {
|
|
byte[] bArr2 = this.IV;
|
|
if (i >= bArr2.length - iv.length) {
|
|
break;
|
|
}
|
|
bArr2[i] = 0;
|
|
i++;
|
|
}
|
|
} else {
|
|
System.arraycopy(iv, 0, bArr, 0, bArr.length);
|
|
}
|
|
reset();
|
|
if (parametersWithIV.getParameters() == null) {
|
|
return;
|
|
}
|
|
blockCipher = this.cipher;
|
|
cipherParameters = parametersWithIV.getParameters();
|
|
} else {
|
|
reset();
|
|
if (cipherParameters == null) {
|
|
return;
|
|
} else {
|
|
blockCipher = this.cipher;
|
|
}
|
|
}
|
|
blockCipher.init(true, cipherParameters);
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.BlockCipher
|
|
public int getBlockSize() {
|
|
return this.blockSize;
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.BlockCipher
|
|
public String getAlgorithmName() {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append(this.cipher.getAlgorithmName());
|
|
sb.append("/GCTR");
|
|
return sb.toString();
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.StreamBlockCipher
|
|
public byte calculateByte(byte b) {
|
|
if (this.byteCount == 0) {
|
|
if (this.firstStep) {
|
|
this.firstStep = false;
|
|
this.cipher.processBlock(this.ofbV, 0, this.ofbOutV, 0);
|
|
this.N3 = bytesToint(this.ofbOutV, 0);
|
|
this.N4 = bytesToint(this.ofbOutV, 4);
|
|
}
|
|
int i = this.N3 + 16843009;
|
|
this.N3 = i;
|
|
this.N4 += 16843012;
|
|
intTobytes(i, this.ofbV, 0);
|
|
intTobytes(this.N4, this.ofbV, 4);
|
|
this.cipher.processBlock(this.ofbV, 0, this.ofbOutV, 0);
|
|
}
|
|
byte[] bArr = this.ofbOutV;
|
|
int i2 = this.byteCount;
|
|
int i3 = i2 + 1;
|
|
this.byteCount = i3;
|
|
byte b2 = (byte) (b ^ bArr[i2]);
|
|
int i4 = this.blockSize;
|
|
if (i3 == i4) {
|
|
this.byteCount = 0;
|
|
byte[] bArr2 = this.ofbV;
|
|
System.arraycopy(bArr2, i4, bArr2, 0, bArr2.length - i4);
|
|
byte[] bArr3 = this.ofbOutV;
|
|
byte[] bArr4 = this.ofbV;
|
|
int length = bArr4.length;
|
|
int i5 = this.blockSize;
|
|
System.arraycopy(bArr3, 0, bArr4, length - i5, i5);
|
|
}
|
|
return b2;
|
|
}
|
|
|
|
private void intTobytes(int i, byte[] bArr, int i2) {
|
|
bArr[i2 + 3] = (byte) (i >>> 24);
|
|
bArr[i2 + 2] = (byte) (i >>> 16);
|
|
bArr[i2 + 1] = (byte) (i >>> 8);
|
|
bArr[i2] = (byte) i;
|
|
}
|
|
|
|
private int bytesToint(byte[] bArr, int i) {
|
|
return ((bArr[i + 3] << Ascii.CAN) & (-16777216)) + ((bArr[i + 2] << 16) & 16711680) + ((bArr[i + 1] << 8) & CipherSuite.DRAFT_TLS_DHE_RSA_WITH_AES_128_OCB) + (bArr[i] & UnsignedBytes.MAX_VALUE);
|
|
}
|
|
|
|
public GOFBBlockCipher(BlockCipher blockCipher) {
|
|
super(blockCipher);
|
|
this.firstStep = true;
|
|
this.cipher = blockCipher;
|
|
int blockSize = blockCipher.getBlockSize();
|
|
this.blockSize = blockSize;
|
|
if (blockSize != 8) {
|
|
throw new IllegalArgumentException("GCTR only for 64 bit block ciphers");
|
|
}
|
|
this.IV = new byte[blockCipher.getBlockSize()];
|
|
this.ofbV = new byte[blockCipher.getBlockSize()];
|
|
this.ofbOutV = new byte[blockCipher.getBlockSize()];
|
|
}
|
|
}
|