what-the-bank/sources/org/bouncycastle/crypto/macs/CMac.java

227 lines
6.9 KiB
Java
Raw Normal View History

2024-07-27 18:17:47 +07:00
package org.bouncycastle.crypto.macs;
import com.google.common.primitives.UnsignedBytes;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Pack;
import org.jmrtd.PassportService;
/* loaded from: classes6.dex */
public class CMac implements Mac {
private byte[] Lu;
private byte[] Lu2;
private byte[] ZEROES;
private byte[] buf;
private int bufOff;
private BlockCipher cipher;
private byte[] mac;
private int macSize;
private byte[] poly;
void validate(CipherParameters cipherParameters) {
if (cipherParameters != null && !(cipherParameters instanceof KeyParameter)) {
throw new IllegalArgumentException("CMac mode only permits key to be set.");
}
}
@Override // org.bouncycastle.crypto.Mac
public void update(byte[] bArr, int i, int i2) {
if (i2 < 0) {
throw new IllegalArgumentException("Can't have a negative input length!");
}
int blockSize = this.cipher.getBlockSize();
int i3 = this.bufOff;
int i4 = blockSize - i3;
if (i2 > i4) {
System.arraycopy(bArr, i, this.buf, i3, i4);
this.cipher.processBlock(this.buf, 0, this.mac, 0);
this.bufOff = 0;
i2 -= i4;
i += i4;
while (i2 > blockSize) {
this.cipher.processBlock(bArr, i, this.mac, 0);
i2 -= blockSize;
i += blockSize;
}
}
System.arraycopy(bArr, i, this.buf, this.bufOff, i2);
this.bufOff += i2;
}
@Override // org.bouncycastle.crypto.Mac
public void update(byte b) {
int i = this.bufOff;
byte[] bArr = this.buf;
if (i == bArr.length) {
this.cipher.processBlock(bArr, 0, this.mac, 0);
this.bufOff = 0;
}
byte[] bArr2 = this.buf;
int i2 = this.bufOff;
this.bufOff = i2 + 1;
bArr2[i2] = b;
}
@Override // org.bouncycastle.crypto.Mac
public void reset() {
int i = 0;
while (true) {
byte[] bArr = this.buf;
if (i >= bArr.length) {
this.bufOff = 0;
this.cipher.reset();
return;
} else {
bArr[i] = 0;
i++;
}
}
}
@Override // org.bouncycastle.crypto.Mac
public void init(CipherParameters cipherParameters) {
validate(cipherParameters);
this.cipher.init(true, cipherParameters);
byte[] bArr = this.ZEROES;
byte[] bArr2 = new byte[bArr.length];
this.cipher.processBlock(bArr, 0, bArr2, 0);
byte[] doubleLu = doubleLu(bArr2);
this.Lu = doubleLu;
this.Lu2 = doubleLu(doubleLu);
reset();
}
@Override // org.bouncycastle.crypto.Mac
public int getMacSize() {
return this.macSize;
}
@Override // org.bouncycastle.crypto.Mac
public String getAlgorithmName() {
return this.cipher.getAlgorithmName();
}
@Override // org.bouncycastle.crypto.Mac
public int doFinal(byte[] bArr, int i) {
byte[] bArr2;
if (this.bufOff == this.cipher.getBlockSize()) {
bArr2 = this.Lu;
} else {
new ISO7816d4Padding().addPadding(this.buf, this.bufOff);
bArr2 = this.Lu2;
}
int i2 = 0;
while (true) {
byte[] bArr3 = this.mac;
if (i2 >= bArr3.length) {
this.cipher.processBlock(this.buf, 0, bArr3, 0);
System.arraycopy(this.mac, 0, bArr, i, this.macSize);
reset();
return this.macSize;
}
byte[] bArr4 = this.buf;
bArr4[i2] = (byte) (bArr4[i2] ^ bArr2[i2]);
i2++;
}
}
private static int shiftLeft(byte[] bArr, byte[] bArr2) {
int length = bArr.length;
int i = 0;
while (true) {
length--;
if (length < 0) {
return i;
}
int i2 = bArr[length] & UnsignedBytes.MAX_VALUE;
bArr2[length] = (byte) (i | (i2 << 1));
i = (i2 >>> 7) & 1;
}
}
private static byte[] lookupPoly(int i) {
int i2;
int i3 = i << 3;
switch (i3) {
case 64:
case 320:
i2 = 27;
break;
case 128:
case 192:
i2 = 135;
break;
case 160:
i2 = 45;
break;
case PassportService.DEFAULT_MAX_BLOCKSIZE /* 224 */:
i2 = 777;
break;
case 256:
i2 = 1061;
break;
case 384:
i2 = 4109;
break;
case 448:
i2 = 2129;
break;
case 512:
i2 = 293;
break;
case 768:
i2 = 655377;
break;
case 1024:
i2 = 524355;
break;
case 2048:
i2 = 548865;
break;
default:
throw new IllegalArgumentException("Unknown block size for CMAC: ".concat(String.valueOf(i3)));
}
return Pack.intToBigEndian(i2);
}
private byte[] doubleLu(byte[] bArr) {
byte[] bArr2 = new byte[bArr.length];
int i = (-shiftLeft(bArr, bArr2)) & 255;
int length = bArr.length - 3;
byte b = bArr2[length];
byte[] bArr3 = this.poly;
bArr2[length] = (byte) (b ^ (bArr3[1] & i));
int length2 = bArr.length - 2;
bArr2[length2] = (byte) ((bArr3[2] & i) ^ bArr2[length2]);
int length3 = bArr.length - 1;
bArr2[length3] = (byte) ((i & bArr3[3]) ^ bArr2[length3]);
return bArr2;
}
public CMac(BlockCipher blockCipher, int i) {
if (i % 8 != 0) {
throw new IllegalArgumentException("MAC size must be multiple of 8");
}
if (i > (blockCipher.getBlockSize() << 3)) {
StringBuilder sb = new StringBuilder("MAC size must be less or equal to ");
sb.append(blockCipher.getBlockSize() << 3);
throw new IllegalArgumentException(sb.toString());
}
this.cipher = new CBCBlockCipher(blockCipher);
this.macSize = i / 8;
this.poly = lookupPoly(blockCipher.getBlockSize());
this.mac = new byte[blockCipher.getBlockSize()];
this.buf = new byte[blockCipher.getBlockSize()];
this.ZEROES = new byte[blockCipher.getBlockSize()];
this.bufOff = 0;
}
public CMac(BlockCipher blockCipher) {
this(blockCipher, blockCipher.getBlockSize() << 3);
}
}