package org.bouncycastle.crypto.prng.drbg; import com.google.common.primitives.UnsignedBytes; import net.sf.scuba.smartcards.ISO7816; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; /* loaded from: classes6.dex */ public class CTRSP800DRBG implements SP80090DRBG { private static final int AES_MAX_BITS_REQUEST = 262144; private static final long AES_RESEED_MAX = 140737488355328L; private static final byte[] K_BITS = Hex.decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); private static final int TDEA_MAX_BITS_REQUEST = 4096; private static final long TDEA_RESEED_MAX = 2147483648L; private byte[] _Key; private byte[] _V; private BlockCipher _engine; private EntropySource _entropySource; private boolean _isTDEA; private int _keySizeInBits; private long _reseedCounter = 0; private int _securityStrength; private int _seedLength; @Override // org.bouncycastle.crypto.prng.drbg.SP80090DRBG public void reseed(byte[] bArr) { CTR_DRBG_Reseed_algorithm(bArr); } @Override // org.bouncycastle.crypto.prng.drbg.SP80090DRBG public int getBlockSize() { return this._V.length << 3; } @Override // org.bouncycastle.crypto.prng.drbg.SP80090DRBG public int generate(byte[] bArr, byte[] bArr2, boolean z) { byte[] bArr3; boolean z2 = this._isTDEA; long j = this._reseedCounter; if (z2) { if (j > TDEA_RESEED_MAX) { return -1; } if (Utils.isTooLarge(bArr, 512)) { throw new IllegalArgumentException("Number of bits per request limited to 4096"); } } else { if (j > AES_RESEED_MAX) { return -1; } if (Utils.isTooLarge(bArr, 32768)) { throw new IllegalArgumentException("Number of bits per request limited to 262144"); } } if (z) { CTR_DRBG_Reseed_algorithm(bArr2); bArr2 = null; } if (bArr2 != null) { bArr3 = Block_Cipher_df(bArr2, this._seedLength); CTR_DRBG_Update(bArr3, this._Key, this._V); } else { bArr3 = new byte[this._seedLength]; } int length = this._V.length; byte[] bArr4 = new byte[length]; this._engine.init(true, new KeyParameter(expandKey(this._Key))); for (int i = 0; i <= bArr.length / length; i++) { int i2 = i * length; int length2 = bArr.length - i2 > length ? length : bArr.length - (this._V.length * i); if (length2 != 0) { addOneTo(this._V); this._engine.processBlock(this._V, 0, bArr4, 0); System.arraycopy(bArr4, 0, bArr, i2, length2); } } CTR_DRBG_Update(bArr3, this._Key, this._V); this._reseedCounter++; return bArr.length << 3; } byte[] expandKey(byte[] bArr) { if (!this._isTDEA) { return bArr; } byte[] bArr2 = new byte[24]; padKey(bArr, 0, bArr2, 0); padKey(bArr, 7, bArr2, 8); padKey(bArr, 14, bArr2, 16); return bArr2; } private void padKey(byte[] bArr, int i, byte[] bArr2, int i2) { bArr2[i2] = (byte) (bArr[i] & 254); int i3 = i + 1; bArr2[i2 + 1] = (byte) ((bArr[i] << 7) | ((bArr[i3] & 252) >>> 1)); byte b = bArr[i3]; int i4 = i + 2; bArr2[i2 + 2] = (byte) ((b << 6) | ((bArr[i4] & 248) >>> 2)); byte b2 = bArr[i4]; int i5 = i + 3; bArr2[i2 + 3] = (byte) ((b2 << 5) | ((bArr[i5] & 240) >>> 3)); byte b3 = bArr[i5]; int i6 = i + 4; bArr2[i2 + 4] = (byte) ((b3 << 4) | ((bArr[i6] & ISO7816.INS_CREATE_FILE) >>> 4)); byte b4 = bArr[i6]; int i7 = i + 5; bArr2[i2 + 5] = (byte) ((b4 << 3) | ((bArr[i7] & ISO7816.INS_GET_RESPONSE) >>> 5)); int i8 = i + 6; bArr2[i2 + 6] = (byte) ((bArr[i7] << 2) | ((bArr[i8] & 128) >>> 6)); int i9 = i2 + 7; bArr2[i9] = (byte) (bArr[i8] << 1); while (i2 <= i9) { byte b5 = bArr2[i2]; bArr2[i2] = (byte) ((b5 & 254) | ((((b5 >> 7) ^ ((((((b5 >> 1) ^ (b5 >> 2)) ^ (b5 >> 3)) ^ (b5 >> 4)) ^ (b5 >> 5)) ^ (b5 >> 6))) ^ 1) & 1)); i2++; } } private boolean isTDEA(BlockCipher blockCipher) { return blockCipher.getAlgorithmName().equals("DESede") || blockCipher.getAlgorithmName().equals("TDEA"); } private int getMaxSecurityStrength(BlockCipher blockCipher, int i) { if (isTDEA(blockCipher) && i == 168) { return 112; } if (blockCipher.getAlgorithmName().equals("AES")) { return i; } return -1; } private byte[] getEntropy() { byte[] entropy = this._entropySource.getEntropy(); if (entropy.length >= (this._securityStrength + 7) / 8) { return entropy; } throw new IllegalStateException("Insufficient entropy provided by entropy source"); } private void copyIntToByteArray(byte[] bArr, int i, int i2) { bArr[i2] = (byte) (i >> 24); bArr[i2 + 1] = (byte) (i >> 16); bArr[i2 + 2] = (byte) (i >> 8); bArr[i2 + 3] = (byte) i; } private void addOneTo(byte[] bArr) { int i = 1; for (int i2 = 1; i2 <= bArr.length; i2++) { int i3 = (bArr[bArr.length - i2] & UnsignedBytes.MAX_VALUE) + i; i = i3 > 255 ? 1 : 0; bArr[bArr.length - i2] = (byte) i3; } } private void XOR(byte[] bArr, byte[] bArr2, byte[] bArr3, int i) { for (int i2 = 0; i2 < bArr.length; i2++) { bArr[i2] = (byte) (bArr2[i2] ^ bArr3[i2 + i]); } } private void CTR_DRBG_Update(byte[] bArr, byte[] bArr2, byte[] bArr3) { int length = bArr.length; byte[] bArr4 = new byte[length]; byte[] bArr5 = new byte[this._engine.getBlockSize()]; int blockSize = this._engine.getBlockSize(); this._engine.init(true, new KeyParameter(expandKey(bArr2))); int i = 0; while (true) { int i2 = i * blockSize; if (i2 >= bArr.length) { XOR(bArr4, bArr, bArr4, 0); System.arraycopy(bArr4, 0, bArr2, 0, bArr2.length); System.arraycopy(bArr4, bArr2.length, bArr3, 0, bArr3.length); return; } else { addOneTo(bArr3); this._engine.processBlock(bArr3, 0, bArr5, 0); int i3 = length - i2; if (i3 > blockSize) { i3 = blockSize; } System.arraycopy(bArr5, 0, bArr4, i2, i3); i++; } } } private void CTR_DRBG_Reseed_algorithm(byte[] bArr) { CTR_DRBG_Update(Block_Cipher_df(Arrays.concatenate(getEntropy(), bArr), this._seedLength), this._Key, this._V); this._reseedCounter = 1L; } private void CTR_DRBG_Instantiate_algorithm(byte[] bArr, byte[] bArr2, byte[] bArr3) { byte[] Block_Cipher_df = Block_Cipher_df(Arrays.concatenate(bArr, bArr2, bArr3), this._seedLength); int blockSize = this._engine.getBlockSize(); byte[] bArr4 = new byte[(this._keySizeInBits + 7) / 8]; this._Key = bArr4; byte[] bArr5 = new byte[blockSize]; this._V = bArr5; CTR_DRBG_Update(Block_Cipher_df, bArr4, bArr5); this._reseedCounter = 1L; } private byte[] Block_Cipher_df(byte[] bArr, int i) { int blockSize = this._engine.getBlockSize(); int length = bArr.length; byte[] bArr2 = new byte[((((length + 9) + blockSize) - 1) / blockSize) * blockSize]; copyIntToByteArray(bArr2, length, 0); copyIntToByteArray(bArr2, i / 8, 4); System.arraycopy(bArr, 0, bArr2, 8, length); bArr2[length + 8] = Byte.MIN_VALUE; int i2 = this._keySizeInBits / 8; int i3 = i2 + blockSize; byte[] bArr3 = new byte[i3]; byte[] bArr4 = new byte[blockSize]; byte[] bArr5 = new byte[blockSize]; byte[] bArr6 = new byte[i2]; System.arraycopy(K_BITS, 0, bArr6, 0, i2); int i4 = 0; while (true) { int i5 = i4 * blockSize; if ((i5 << 3) >= this._keySizeInBits + (blockSize << 3)) { break; } copyIntToByteArray(bArr5, i4, 0); BCC(bArr4, bArr6, bArr5, bArr2); int i6 = i3 - i5; if (i6 > blockSize) { i6 = blockSize; } System.arraycopy(bArr4, 0, bArr3, i5, i6); i4++; } byte[] bArr7 = new byte[blockSize]; System.arraycopy(bArr3, 0, bArr6, 0, i2); System.arraycopy(bArr3, i2, bArr7, 0, blockSize); int i7 = i / 2; byte[] bArr8 = new byte[i7]; this._engine.init(true, new KeyParameter(expandKey(bArr6))); int i8 = 0; while (true) { int i9 = i8 * blockSize; if (i9 >= i7) { return bArr8; } this._engine.processBlock(bArr7, 0, bArr7, 0); int i10 = i7 - i9; if (i10 > blockSize) { i10 = blockSize; } System.arraycopy(bArr7, 0, bArr8, i9, i10); i8++; } } private void BCC(byte[] bArr, byte[] bArr2, byte[] bArr3, byte[] bArr4) { int blockSize = this._engine.getBlockSize(); byte[] bArr5 = new byte[blockSize]; int length = bArr4.length / blockSize; byte[] bArr6 = new byte[blockSize]; this._engine.init(true, new KeyParameter(expandKey(bArr2))); this._engine.processBlock(bArr3, 0, bArr5, 0); for (int i = 0; i < length; i++) { XOR(bArr6, bArr5, bArr4, i * blockSize); this._engine.processBlock(bArr6, 0, bArr5, 0); } System.arraycopy(bArr5, 0, bArr, 0, bArr.length); } public CTRSP800DRBG(BlockCipher blockCipher, int i, int i2, EntropySource entropySource, byte[] bArr, byte[] bArr2) { this._isTDEA = false; this._entropySource = entropySource; this._engine = blockCipher; this._keySizeInBits = i; this._securityStrength = i2; this._seedLength = (blockCipher.getBlockSize() << 3) + i; this._isTDEA = isTDEA(blockCipher); if (i2 > 256) { throw new IllegalArgumentException("Requested security strength is not supported by the derivation function"); } if (getMaxSecurityStrength(blockCipher, i) < i2) { throw new IllegalArgumentException("Requested security strength is not supported by block cipher and key size"); } if (entropySource.entropySize() < i2) { throw new IllegalArgumentException("Not enough entropy for security strength required"); } CTR_DRBG_Instantiate_algorithm(getEntropy(), bArr2, bArr); } }