use of org.bouncycastle.crypto.params.AEADParameters in project robovm by robovm.
the class GCMBlockCipher method init.
public void init(boolean forEncryption, CipherParameters params) throws IllegalArgumentException {
this.forEncryption = forEncryption;
this.macBlock = null;
KeyParameter keyParam;
if (params instanceof AEADParameters) {
AEADParameters param = (AEADParameters) params;
nonce = param.getNonce();
initialAssociatedText = param.getAssociatedText();
int macSizeBits = param.getMacSize();
if (macSizeBits < 96 || macSizeBits > 128 || macSizeBits % 8 != 0) {
throw new IllegalArgumentException("Invalid value for MAC size: " + macSizeBits);
}
macSize = macSizeBits / 8;
keyParam = param.getKey();
} else if (params instanceof ParametersWithIV) {
ParametersWithIV param = (ParametersWithIV) params;
nonce = param.getIV();
initialAssociatedText = null;
macSize = 16;
keyParam = (KeyParameter) param.getParameters();
} else {
throw new IllegalArgumentException("invalid parameters passed to GCM");
}
int bufLength = forEncryption ? BLOCK_SIZE : (BLOCK_SIZE + macSize);
this.bufBlock = new byte[bufLength];
if (nonce == null || nonce.length < 1) {
throw new IllegalArgumentException("IV must be at least 1 byte");
}
// if keyParam is null we're reusing the last key.
if (keyParam != null) {
cipher.init(true, keyParam);
this.H = new byte[BLOCK_SIZE];
cipher.processBlock(H, 0, H, 0);
// GCMMultiplier tables don't change unless the key changes (and are expensive to init)
multiplier.init(H);
exp = null;
}
this.J0 = new byte[BLOCK_SIZE];
if (nonce.length == 12) {
System.arraycopy(nonce, 0, J0, 0, nonce.length);
this.J0[BLOCK_SIZE - 1] = 0x01;
} else {
gHASH(J0, nonce, nonce.length);
byte[] X = new byte[BLOCK_SIZE];
Pack.longToBigEndian((long) nonce.length * 8, X, 8);
gHASHBlock(J0, X);
}
this.S = new byte[BLOCK_SIZE];
this.S_at = new byte[BLOCK_SIZE];
this.S_atPre = new byte[BLOCK_SIZE];
this.atBlock = new byte[BLOCK_SIZE];
this.atBlockPos = 0;
this.atLength = 0;
this.atLengthPre = 0;
this.counter = Arrays.clone(J0);
this.bufOff = 0;
this.totalLength = 0;
if (initialAssociatedText != null) {
processAADBytes(initialAssociatedText, 0, initialAssociatedText.length);
}
}
use of org.bouncycastle.crypto.params.AEADParameters in project syncany by syncany.
the class AesGcmCipherSpec method newCipherOutputStream.
@Override
public OutputStream newCipherOutputStream(OutputStream underlyingOutputStream, byte[] secretKey, byte[] iv) throws CipherException {
AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
cipher.init(true, new AEADParameters(new KeyParameter(secretKey), MAC_SIZE, iv));
return new org.bouncycastle.crypto.io.CipherOutputStream(underlyingOutputStream, cipher);
}
use of org.bouncycastle.crypto.params.AEADParameters in project syncany by syncany.
the class TwofishGcmCipherSpec method newCipherOutputStream.
@Override
public OutputStream newCipherOutputStream(OutputStream underlyingOutputStream, byte[] secretKey, byte[] iv) throws CipherException {
AEADBlockCipher cipher = new GCMBlockCipher(new TwofishEngine());
cipher.init(true, new AEADParameters(new KeyParameter(secretKey), MAC_SIZE, iv));
return new org.bouncycastle.crypto.io.CipherOutputStream(underlyingOutputStream, cipher);
}
use of org.bouncycastle.crypto.params.AEADParameters in project syncany by syncany.
the class AesGcmWithBcInputStreamTest method testE_BouncyCastleCipherInputStreamWithAesGcmLongPlaintext.
@Test
public void testE_BouncyCastleCipherInputStreamWithAesGcmLongPlaintext() throws InvalidKeyException, InvalidAlgorithmParameterException, IOException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
// Encrypt (not interesting in this example)
byte[] randomKey = createRandomArray(16);
byte[] randomIv = createRandomArray(16);
// <<<< 4080 bytes fails, 4079 bytes works!
byte[] originalPlaintext = createRandomArray(4080);
byte[] originalCiphertext = encryptWithAesGcm(originalPlaintext, randomKey, randomIv);
// Decrypt with BouncyCastle implementation of CipherInputStream
AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
cipher.init(false, new AEADParameters(new KeyParameter(randomKey), 128, randomIv));
try {
readFromStream(new org.bouncycastle.crypto.io.CipherInputStream(new ByteArrayInputStream(originalCiphertext), cipher));
// ^^^^^^^^^^^^^^^ INTERESTING PART ^^^^^^^^^^^^^^^^
//
// In this example, the BouncyCastle implementation of the CipherInputStream throws an ArrayIndexOutOfBoundsException.
// The only difference to the example above is that the plaintext is now 4080 bytes long! For 4079 bytes plaintexts,
// everything works just fine.
System.out.println("Test E: org.bouncycastle.crypto.io.CipherInputStream: OK, throws no exception");
} catch (IOException e) {
fail("Test E: org.bouncycastle.crypto.io.CipherInputStream: NOT OK throws: " + e.getMessage());
}
}
use of org.bouncycastle.crypto.params.AEADParameters in project syncany by syncany.
the class AesGcmWithBcInputStreamTest method testD_BouncyCastleCipherInputStreamWithAesGcm.
@Test
public void testD_BouncyCastleCipherInputStreamWithAesGcm() throws InvalidKeyException, InvalidAlgorithmParameterException, IOException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
// Encrypt (not interesting in this example)
byte[] randomKey = createRandomArray(16);
byte[] randomIv = createRandomArray(16);
byte[] originalPlaintext = "Confirm 100$ pay".getBytes("ASCII");
byte[] originalCiphertext = encryptWithAesGcm(originalPlaintext, randomKey, randomIv);
// Attack / alter ciphertext (an attacker would do this!)
byte[] alteredCiphertext = Arrays.clone(originalCiphertext);
// <<< Change 100$ to 900$
alteredCiphertext[8] = (byte) (alteredCiphertext[8] ^ 0x08);
// Decrypt with BouncyCastle implementation of CipherInputStream
AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine());
cipher.init(false, new AEADParameters(new KeyParameter(randomKey), 128, randomIv));
try {
readFromStream(new org.bouncycastle.crypto.io.CipherInputStream(new ByteArrayInputStream(alteredCiphertext), cipher));
// ^^^^^^^^^^^^^^^ INTERESTING PART ^^^^^^^^^^^^^^^^
//
// The BouncyCastle implementation of the CipherInputStream detects MAC verification errors and
// throws a InvalidCipherTextIOException if an error occurs. Nice! A more or less minor issue
// however is that it is incompatible with the standard JCE Cipher class from the javax.crypto
// package. The new interface AEADBlockCipher must be used. The code below is not executed.
fail("Test D: org.bouncycastle.crypto.io.CipherInputStream: NOT OK, tampering not detected");
} catch (InvalidCipherTextIOException e) {
System.out.println("Test D: org.bouncycastle.crypto.io.CipherInputStream: OK, tampering detected");
}
}
Aggregations