diff options
author | Sergio Giro <sgiro@google.com> | 2016-02-01 10:41:58 +0000 |
---|---|---|
committer | Sergio Giro <sgiro@google.com> | 2016-02-01 10:41:58 +0000 |
commit | 53b61f9fe9d58034fcc7021137e92460f91b70ce (patch) | |
tree | 90632062175928181977c1ab3ab59951bc1146c3 /bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java | |
parent | 3eebc2629986481f9fc77ab101c0c9b8ff2f2660 (diff) | |
download | bouncycastle-53b61f9fe9d58034fcc7021137e92460f91b70ce.tar.gz |
bouncycastle: Android tree with upstream code for version 1.52
Android tree as of
1af9aad12fedf1d93333e19f5ed0ab86f1cc4e2a
Change-Id: I714fa0954a5d000cd88d1fb78b0b7fe28246d404
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java')
-rw-r--r-- | bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java | 122 |
1 files changed, 118 insertions, 4 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java index d2f14057..7d89515a 100644 --- a/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java +++ b/bcprov/src/main/java/org/bouncycastle/jce/provider/test/AEADTest.java @@ -6,7 +6,9 @@ import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; +import java.security.SecureRandom; import java.security.Security; +import java.security.spec.InvalidParameterSpecException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -46,18 +48,62 @@ public class AEADTest extends SimpleTest public void performTest() throws Exception { + boolean aeadAvailable = false; try { this.getClass().getClassLoader().loadClass("javax.crypto.spec.GCMParameterSpec"); - + aeadAvailable = true; + } + catch (ClassNotFoundException e) + { + } + if (aeadAvailable) + { checkCipherWithAD(K2, N2, A2, P2, C2_short); testGCMParameterSpec(K2, N2, A2, P2, C2); testGCMParameterSpecWithRepeatKey(K2, N2, A2, P2, C2); testGCMGeneric(KGCM, NGCM, new byte[0], new byte[0], CGCM); + testGCMParameterSpecWithMultipleUpdates(K2, N2, A2, P2, C2); } - catch (ClassNotFoundException e) + else + { + System.err.println("GCM AEADTests disabled due to JDK"); + } + testTampering(aeadAvailable); + } + + private void testTampering(boolean aeadAvailable) + throws InvalidKeyException, + InvalidAlgorithmParameterException, + NoSuchAlgorithmException, + NoSuchProviderException, + NoSuchPaddingException, + IllegalBlockSizeException, + BadPaddingException + { + Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC"); + final SecretKeySpec key = new SecretKeySpec(new byte[eax.getBlockSize()], eax.getAlgorithm()); + final IvParameterSpec iv = new IvParameterSpec(new byte[eax.getBlockSize()]); + + eax.init(Cipher.ENCRYPT_MODE, key, iv); + byte[] ciphertext = eax.doFinal(new byte[100]); + ciphertext[0] = (byte)(ciphertext[0] + 1); // Tamper + + try { - System.err.println("AEADTest disabled due to JDK"); + eax.init(Cipher.DECRYPT_MODE, key, iv); + eax.doFinal(ciphertext); + fail("Tampered ciphertext should be invalid"); + } + catch (BadPaddingException e) + { + if (aeadAvailable) + { + if (!e.getClass().getName().equals("javax.crypto.AEADBadTagException")) + { + fail("Tampered AEAD ciphertext should fail with AEADBadTagException when available."); + } + } } } @@ -140,6 +186,62 @@ public class AEADTest extends SimpleTest } } + private void testGCMParameterSpecWithMultipleUpdates(byte[] K, + byte[] N, + byte[] A, + byte[] P, + byte[] C) + throws Exception + { + Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC"); + SecretKeySpec key = new SecretKeySpec(K, "AES"); + SecureRandom random = new SecureRandom(); + + // GCMParameterSpec mapped to AEADParameters and overrides default MAC + // size + GCMParameterSpec spec = new GCMParameterSpec(128, N); + + for (int i = 900; i != 1024; i++) + { + byte[] message = new byte[i]; + + random.nextBytes(message); + + eax.init(Cipher.ENCRYPT_MODE, key, spec); + + byte[] out = new byte[eax.getOutputSize(i)]; + + int offSet = 0; + + int count; + for (count = 0; count < i / 21; count++) + { + offSet += eax.update(message, count * 21, 21, out, offSet); + } + + offSet += eax.doFinal(message, count * 21, i - (count * 21), out, offSet); + + byte[] dec = new byte[i]; + int len = offSet; + + eax.init(Cipher.DECRYPT_MODE, key, spec); + + offSet = 0; + for (count = 0; count < len / 10; count++) + { + offSet += eax.update(out, count * 10, 10, dec, offSet); + } + + offSet += eax.doFinal(out, count * 10, len - (count * 10), dec, offSet); + + if (!Arrays.areEqual(message, dec) || offSet != message.length) + { + fail("message mismatch"); + } + } + } + + private void testGCMParameterSpecWithRepeatKey(byte[] K, byte[] N, byte[] A, @@ -192,7 +294,7 @@ public class AEADTest extends SimpleTest throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, - InvalidAlgorithmParameterException, NoSuchProviderException, IOException + InvalidAlgorithmParameterException, NoSuchProviderException, IOException, InvalidParameterSpecException { Cipher eax = Cipher.getInstance("AES/GCM/NoPadding", "BC"); SecretKeySpec key = new SecretKeySpec(K, "AES"); @@ -230,6 +332,18 @@ public class AEADTest extends SimpleTest { fail("parameters mismatch"); } + + GCMParameterSpec gcmSpec = algParams.getParameterSpec(GCMParameterSpec.class); + + if (!Arrays.areEqual(gcmSpec.getIV(), gcmParameters.getNonce()) || gcmSpec.getTLen() != gcmParameters.getIcvLen() * 8) + { + fail("spec parameters mismatch"); + } + + if (!Arrays.areEqual(eax.getIV(), gcmParameters.getNonce())) + { + fail("iv mismatch"); + } } public static void main(String[] args) throws Exception |