use of org.bouncycastle.crypto.BlockCipher in project robovm by robovm.
the class CCMBlockCipher method processPacket.
public byte[] processPacket(byte[] in, int inOff, int inLen) throws IllegalStateException, InvalidCipherTextException {
// 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 index = inOff;
int outOff = 0;
byte[] output;
if (forEncryption) {
output = new byte[inLen + macSize];
calculateMac(in, inOff, inLen, macBlock);
// S0
ctrCipher.processBlock(macBlock, 0, macBlock, 0);
while (// S1...
index < inLen - blockSize) {
ctrCipher.processBlock(in, index, output, outOff);
outOff += blockSize;
index += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, index, block, 0, inLen - index);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outOff, inLen - index);
outOff += inLen - index;
System.arraycopy(macBlock, 0, output, outOff, output.length - outOff);
} else {
output = new byte[inLen - macSize];
System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize);
ctrCipher.processBlock(macBlock, 0, macBlock, 0);
for (int i = macSize; i != macBlock.length; i++) {
macBlock[i] = 0;
}
while (outOff < output.length - blockSize) {
ctrCipher.processBlock(in, index, output, outOff);
outOff += blockSize;
index += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, index, block, 0, output.length - outOff);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, output, outOff, output.length - outOff);
byte[] calculatedMacBlock = new byte[blockSize];
calculateMac(output, 0, output.length, calculatedMacBlock);
if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) {
throw new InvalidCipherTextException("mac check in CCM failed");
}
}
return output;
}
use of org.bouncycastle.crypto.BlockCipher in project XobotOS by xamarin.
the class CCMBlockCipher method processPacket.
public byte[] processPacket(byte[] in, int inOff, int inLen) throws IllegalStateException, InvalidCipherTextException {
if (keyParam == null) {
throw new IllegalStateException("CCM cipher unitialized.");
}
BlockCipher ctrCipher = new SICBlockCipher(cipher);
byte[] iv = new byte[blockSize];
byte[] out;
iv[0] = (byte) (((15 - nonce.length) - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
if (forEncryption) {
int index = inOff;
int outOff = 0;
out = new byte[inLen + macSize];
calculateMac(in, inOff, inLen, macBlock);
// S0
ctrCipher.processBlock(macBlock, 0, macBlock, 0);
while (// S1...
index < inLen - blockSize) {
ctrCipher.processBlock(in, index, out, outOff);
outOff += blockSize;
index += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, index, block, 0, inLen - index);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, out, outOff, inLen - index);
outOff += inLen - index;
System.arraycopy(macBlock, 0, out, outOff, out.length - outOff);
} else {
int index = inOff;
int outOff = 0;
out = new byte[inLen - macSize];
System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize);
ctrCipher.processBlock(macBlock, 0, macBlock, 0);
for (int i = macSize; i != macBlock.length; i++) {
macBlock[i] = 0;
}
while (outOff < out.length - blockSize) {
ctrCipher.processBlock(in, index, out, outOff);
outOff += blockSize;
index += blockSize;
}
byte[] block = new byte[blockSize];
System.arraycopy(in, index, block, 0, out.length - outOff);
ctrCipher.processBlock(block, 0, block, 0);
System.arraycopy(block, 0, out, outOff, out.length - outOff);
byte[] calculatedMacBlock = new byte[blockSize];
calculateMac(out, 0, out.length, calculatedMacBlock);
if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock)) {
throw new InvalidCipherTextException("mac check in CCM failed");
}
}
return out;
}
use of org.bouncycastle.crypto.BlockCipher in project oxAuth by GluuFederation.
the class JweDecrypterImpl method decryptCipherText.
@Override
public String decryptCipherText(String encodedCipherText, byte[] contentMasterKey, byte[] initializationVector, byte[] authenticationTag, byte[] additionalAuthenticatedData) throws InvalidJweException {
if (getBlockEncryptionAlgorithm() == null) {
throw new InvalidJweException("The block encryption algorithm is null");
}
if (contentMasterKey == null) {
throw new InvalidJweException("The content master key (CMK) is null");
}
if (initializationVector == null) {
throw new InvalidJweException("The initialization vector is null");
}
if (authenticationTag == null) {
throw new InvalidJweException("The authentication tag is null");
}
if (additionalAuthenticatedData == null) {
throw new InvalidJweException("The additional authentication data is null");
}
try {
if (getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A128GCM || getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A256GCM) {
final int MAC_SIZE_BITS = 128;
byte[] cipherText = Base64Util.base64urldecode(encodedCipherText);
KeyParameter key = new KeyParameter(contentMasterKey);
AEADParameters aeadParameters = new AEADParameters(key, MAC_SIZE_BITS, initializationVector, additionalAuthenticatedData);
SecretKeySpec sks = new SecretKeySpec(contentMasterKey, "AES");
BlockCipher blockCipher = new AESEngine();
CipherParameters params = new KeyParameter(sks.getEncoded());
blockCipher.init(false, params);
GCMBlockCipher aGCMBlockCipher = new GCMBlockCipher(blockCipher);
aGCMBlockCipher.init(false, aeadParameters);
byte[] input = new byte[cipherText.length + authenticationTag.length];
System.arraycopy(cipherText, 0, input, 0, cipherText.length);
System.arraycopy(authenticationTag, 0, input, cipherText.length, authenticationTag.length);
int len = aGCMBlockCipher.getOutputSize(input.length);
byte[] out = new byte[len];
int outOff = aGCMBlockCipher.processBytes(input, 0, input.length, out, 0);
aGCMBlockCipher.doFinal(out, outOff);
String plaintext = new String(out, Charset.forName(Util.UTF8_STRING_ENCODING));
return plaintext;
} else if (getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A128CBC_PLUS_HS256 || getBlockEncryptionAlgorithm() == BlockEncryptionAlgorithm.A256CBC_PLUS_HS512) {
byte[] cipherText = Base64Util.base64urldecode(encodedCipherText);
byte[] cek = KeyDerivationFunction.generateCek(contentMasterKey, getBlockEncryptionAlgorithm());
Cipher cipher = Cipher.getInstance(getBlockEncryptionAlgorithm().getAlgorithm());
IvParameterSpec ivParameter = new IvParameterSpec(initializationVector);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(cek, "AES"), ivParameter);
byte[] decodedPlainTextBytes = cipher.doFinal(cipherText);
String decodedPlainText = new String(decodedPlainTextBytes, Charset.forName(Util.UTF8_STRING_ENCODING));
// Integrity check
String securedInputValue = new String(additionalAuthenticatedData, Charset.forName(Util.UTF8_STRING_ENCODING)) + "." + encodedCipherText;
byte[] cik = KeyDerivationFunction.generateCik(contentMasterKey, getBlockEncryptionAlgorithm());
SecretKey secretKey = new SecretKeySpec(cik, getBlockEncryptionAlgorithm().getIntegrityValueAlgorithm());
Mac mac = Mac.getInstance(getBlockEncryptionAlgorithm().getIntegrityValueAlgorithm());
mac.init(secretKey);
byte[] integrityValue = mac.doFinal(securedInputValue.getBytes(Util.UTF8_STRING_ENCODING));
if (!Arrays.equals(integrityValue, authenticationTag)) {
throw new InvalidJweException("The authentication tag is not valid");
}
return decodedPlainText;
} else {
throw new InvalidJweException("The block encryption algorithm is not supported");
}
} catch (InvalidCipherTextException e) {
throw new InvalidJweException(e);
} catch (NoSuchPaddingException e) {
throw new InvalidJweException(e);
} catch (BadPaddingException e) {
throw new InvalidJweException(e);
} catch (InvalidAlgorithmParameterException e) {
throw new InvalidJweException(e);
} catch (NoSuchAlgorithmException e) {
throw new InvalidJweException(e);
} catch (IllegalBlockSizeException e) {
throw new InvalidJweException(e);
} catch (UnsupportedEncodingException e) {
throw new InvalidJweException(e);
} catch (NoSuchProviderException e) {
throw new InvalidJweException(e);
} catch (InvalidKeyException e) {
throw new InvalidJweException(e);
} catch (InvalidParameterException e) {
throw new InvalidJweException(e);
}
}
use of org.bouncycastle.crypto.BlockCipher in project robovm by robovm.
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.
* @exception DataLengthException if there is insufficient space in out for
* the output.
* @exception IllegalStateException if the underlying cipher is not
* initialised.
* @exception 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 DataLengthException("output buffer to small in doFinal");
}
int blockSize = cipher.getBlockSize();
int len = bufOff - blockSize;
byte[] block = new byte[blockSize];
if (forEncryption) {
cipher.processBlock(buf, 0, block, 0);
if (bufOff < blockSize) {
throw new DataLengthException("need at least one block of input for CTS");
}
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 {
byte[] lastBlock = new byte[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);
}
int offset = bufOff;
reset();
return offset;
}
use of org.bouncycastle.crypto.BlockCipher in project XobotOS by xamarin.
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.
* @exception DataLengthException if there is insufficient space in out for
* the output.
* @exception IllegalStateException if the underlying cipher is not
* initialised.
* @exception 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 DataLengthException("output buffer to small in doFinal");
}
int blockSize = cipher.getBlockSize();
int len = bufOff - blockSize;
byte[] block = new byte[blockSize];
if (forEncryption) {
cipher.processBlock(buf, 0, block, 0);
if (bufOff < blockSize) {
throw new DataLengthException("need at least one block of input for CTS");
}
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 {
byte[] lastBlock = new byte[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);
}
int offset = bufOff;
reset();
return offset;
}
Aggregations