use of com.github.zhenwei.core.crypto.BlockCipher in project LinLong-Java by zhenwei1108.
the class CCMBlockCipher method processPacket.
/**
* Process a packet of data for either CCM decryption or encryption.
*
* @param in data for processing.
* @param inOff offset at which data starts in the input array.
* @param inLen length of the data in the input array.
* @param output output array.
* @param outOff offset into output array to start putting processed bytes.
* @return the number of bytes added to output.
* @throws IllegalStateException if the cipher is not appropriately set up.
* @throws InvalidCipherTextException if the input data is truncated or the mac check fails.
* @throws DataLengthException if output buffer too short.
*/
public int processPacket(byte[] in, int inOff, int inLen, byte[] output, int outOff) throws IllegalStateException, InvalidCipherTextException, DataLengthException {
// Need to keep the CTR and CBC Mac parts around and reset
if (keyParam == null) {
throw new IllegalStateException("CCM cipher unitialized.");
}
int n = nonce.length;
int q = 15 - n;
if (q < 4) {
int limitLen = 1 << (8 * q);
if (inLen >= limitLen) {
throw new IllegalStateException("CCM packet too large for choice of q.");
}
}
byte[] iv = new byte[blockSize];
iv[0] = (byte) ((q - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
BlockCipher ctrCipher = new SICBlockCipher(cipher);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
int outputLen;
int inIndex = inOff;
int outIndex = outOff;
if (forEncryption) {
outputLen = inLen + macSize;
if (output.length < (outputLen + outOff)) {
throw new OutputLengthException("Output buffer too short.");
}
calculateMac(in, inOff, inLen, macBlock);
byte[] encMac = new byte[blockSize];
// S0
ctrCipher.processBlock(macBlock, 0, encMac, 0);
while (// S1...
inIndex < (inOff + inLen - blockSize)) {
ctrCipher.processBlock(in, inIndex, output, outIndex);
outIndex += blockSize;
inIndex += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, inIndex, block, 0, inLen + inOff - inIndex);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outIndex, inLen + inOff - inIndex);
System.arraycopy(encMac, 0, output, outOff + inLen, macSize);
} else {
if (inLen < macSize) {
throw new InvalidCipherTextException("data too short");
}
outputLen = inLen - macSize;
if (output.length < (outputLen + outOff)) {
throw new OutputLengthException("Output buffer too short.");
}
System.arraycopy(in, inOff + outputLen, macBlock, 0, macSize);
ctrCipher.processBlock(macBlock, 0, macBlock, 0);
for (int i = macSize; i != macBlock.length; i++) {
macBlock[i] = 0;
}
while (inIndex < (inOff + outputLen - blockSize)) {
ctrCipher.processBlock(in, inIndex, output, outIndex);
outIndex += blockSize;
inIndex += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, inIndex, block, 0, outputLen - (inIndex - inOff));
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outIndex, outputLen - (inIndex - inOff));
byte[] calculatedMacBlock = new byte[blockSize];
calculateMac(output, outOff, outputLen, calculatedMacBlock);
if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) {
throw new InvalidCipherTextException("mac check in CCM failed");
}
}
return outputLen;
}
use of com.github.zhenwei.core.crypto.BlockCipher in project LinLong-Java by zhenwei1108.
the class GCFBBlockCipher method calculateByte.
protected byte calculateByte(byte b) {
if (counter > 0 && counter % 1024 == 0) {
BlockCipher base = cfbEngine.getUnderlyingCipher();
base.init(false, key);
byte[] nextKey = new byte[32];
base.processBlock(C, 0, nextKey, 0);
base.processBlock(C, 8, nextKey, 8);
base.processBlock(C, 16, nextKey, 16);
base.processBlock(C, 24, nextKey, 24);
key = new KeyParameter(nextKey);
base.init(true, key);
byte[] iv = cfbEngine.getCurrentIV();
base.processBlock(iv, 0, iv, 0);
cfbEngine.init(forEncryption, new ParametersWithIV(key, iv));
}
counter++;
return cfbEngine.calculateByte(b);
}
use of com.github.zhenwei.core.crypto.BlockCipher in project LinLong-Java by zhenwei1108.
the class Mac method cmac.
public byte[] cmac(KeyEnum alg, byte[] key, byte[] source) throws WeGooCryptoException {
BlockCipher engine;
switch(alg) {
case AES_128:
case AES_256:
engine = new AESEngine();
break;
default:
engine = new SM4Engine();
}
CMac cMac = new CMac(engine);
cMac.init(new KeyParameter(key));
cMac.update(source, 0, source.length);
byte[] result = new byte[cMac.getMacSize()];
cMac.doFinal(result, 0);
return result;
}
use of com.github.zhenwei.core.crypto.BlockCipher in project LinLong-Java by zhenwei1108.
the class PEMUtilities method crypt.
static byte[] crypt(boolean encrypt, byte[] bytes, char[] password, String dekAlgName, byte[] iv) throws PEMException {
byte[] ivValue = iv;
String blockMode = "CBC";
BlockCipher engine;
BlockCipherPadding padding = new PKCS7Padding();
KeyParameter sKey;
// Figure out block mode and padding.
if (dekAlgName.endsWith("-CFB")) {
blockMode = "CFB";
padding = null;
}
if (dekAlgName.endsWith("-ECB") || "DES-EDE".equals(dekAlgName) || "DES-EDE3".equals(dekAlgName)) {
// ECB is actually the default (though seldom used) when OpenSSL
// uses DES-EDE (des2) or DES-EDE3 (des3).
blockMode = "ECB";
ivValue = null;
}
if (dekAlgName.endsWith("-OFB")) {
blockMode = "OFB";
padding = null;
}
// Figure out algorithm and key size.
if (dekAlgName.startsWith("DES-EDE")) {
// "DES-EDE" is actually des2 in OpenSSL-speak!
// "DES-EDE3" is des3.
boolean des2 = !dekAlgName.startsWith("DES-EDE3");
sKey = getKey(password, 24, iv, des2);
engine = new DESedeEngine();
} else if (dekAlgName.startsWith("DES-")) {
sKey = getKey(password, 8, iv);
engine = new DESEngine();
} else if (dekAlgName.startsWith("BF-")) {
sKey = getKey(password, 16, iv);
engine = new BlowfishEngine();
} else if (dekAlgName.startsWith("RC2-")) {
int keyBits = 128;
if (dekAlgName.startsWith("RC2-40-")) {
keyBits = 40;
} else if (dekAlgName.startsWith("RC2-64-")) {
keyBits = 64;
}
sKey = new RC2Parameters(getKey(password, keyBits / 8, iv).getKey(), keyBits);
;
engine = new RC2Engine();
} else if (dekAlgName.startsWith("AES-")) {
byte[] salt = iv;
if (salt.length > 8) {
salt = new byte[8];
System.arraycopy(iv, 0, salt, 0, 8);
}
int keyBits;
if (dekAlgName.startsWith("AES-128-")) {
keyBits = 128;
} else if (dekAlgName.startsWith("AES-192-")) {
keyBits = 192;
} else if (dekAlgName.startsWith("AES-256-")) {
keyBits = 256;
} else {
throw new EncryptionException("unknown AES encryption with private key: " + dekAlgName);
}
sKey = getKey(password, keyBits / 8, salt);
engine = new AESEngine();
} else {
throw new EncryptionException("unknown encryption with private key: " + dekAlgName);
}
if (blockMode.equals("CBC")) {
engine = new CBCBlockCipher(engine);
} else if (blockMode.equals("CFB")) {
engine = new CFBBlockCipher(engine, engine.getBlockSize() * 8);
} else if (blockMode.equals("OFB")) {
engine = new OFBBlockCipher(engine, engine.getBlockSize() * 8);
}
try {
BufferedBlockCipher c;
if (padding == null) {
c = new BufferedBlockCipher(engine);
} else {
c = new PaddedBufferedBlockCipher(engine, padding);
}
if (// ECB block mode
ivValue == null) {
c.init(encrypt, sKey);
} else {
c.init(encrypt, new ParametersWithIV(sKey, ivValue));
}
byte[] out = new byte[c.getOutputSize(bytes.length)];
int procLen = c.processBytes(bytes, 0, bytes.length, out, 0);
procLen += c.doFinal(out, procLen);
if (procLen == out.length) {
return out;
} else {
byte[] rv = new byte[procLen];
System.arraycopy(out, 0, rv, 0, procLen);
return rv;
}
} catch (Exception e) {
throw new EncryptionException("exception using cipher - please check password and data.", e);
}
}
use of com.github.zhenwei.core.crypto.BlockCipher in project LinLong-Java by zhenwei1108.
the class CTSBlockCipher method doFinal.
/**
* Process the last block in the buffer.
*
* @param out the array the block currently being held is copied into.
* @param outOff the offset at which the copying starts.
* @return the number of output bytes copied to out.
* @throws DataLengthException if there is insufficient space in out for the output.
* @throws IllegalStateException if the underlying cipher is not initialised.
* @throws InvalidCipherTextException if cipher text decrypts wrongly (in case the exception will
* never get thrown).
*/
public int doFinal(byte[] out, int outOff) throws DataLengthException, IllegalStateException, InvalidCipherTextException {
if (bufOff + outOff > out.length) {
throw new OutputLengthException("output buffer to small in doFinal");
}
int blockSize = cipher.getBlockSize();
int len = bufOff - blockSize;
byte[] block = new byte[blockSize];
if (forEncryption) {
if (bufOff < blockSize) {
throw new DataLengthException("need at least one block of input for CTS");
}
cipher.processBlock(buf, 0, block, 0);
if (bufOff > blockSize) {
for (int i = bufOff; i != buf.length; i++) {
buf[i] = block[i - blockSize];
}
for (int i = blockSize; i != bufOff; i++) {
buf[i] ^= block[i - blockSize];
}
if (cipher instanceof CBCBlockCipher) {
BlockCipher c = ((CBCBlockCipher) cipher).getUnderlyingCipher();
c.processBlock(buf, blockSize, out, outOff);
} else {
cipher.processBlock(buf, blockSize, out, outOff);
}
System.arraycopy(block, 0, out, outOff + blockSize, len);
} else {
System.arraycopy(block, 0, out, outOff, blockSize);
}
} else {
if (bufOff < blockSize) {
throw new DataLengthException("need at least one block of input for CTS");
}
byte[] lastBlock = new byte[blockSize];
if (bufOff > blockSize) {
if (cipher instanceof CBCBlockCipher) {
BlockCipher c = ((CBCBlockCipher) cipher).getUnderlyingCipher();
c.processBlock(buf, 0, block, 0);
} else {
cipher.processBlock(buf, 0, block, 0);
}
for (int i = blockSize; i != bufOff; i++) {
lastBlock[i - blockSize] = (byte) (block[i - blockSize] ^ buf[i]);
}
System.arraycopy(buf, blockSize, block, 0, len);
cipher.processBlock(block, 0, out, outOff);
System.arraycopy(lastBlock, 0, out, outOff + blockSize, len);
} else {
cipher.processBlock(buf, 0, block, 0);
System.arraycopy(block, 0, out, outOff, blockSize);
}
}
int offset = bufOff;
reset();
return offset;
}
Aggregations