private void testModes(BlockCipher cipher1, BlockCipher cipher2, int keySize) throws Exception { final KeyParameter key = new KeyParameter(new byte[keySize]); final int blockSize = getBlockSize(cipher1); final CipherParameters withIv = new ParametersWithIV(key, new byte[blockSize]); if (blockSize > 1) { testMode(new PaddedBufferedBlockCipher(cipher1, new PKCS7Padding()), key); testMode(new PaddedBufferedBlockCipher(new CBCBlockCipher(cipher1), new PKCS7Padding()), withIv); testMode(new BufferedBlockCipher(new OFBBlockCipher(cipher1, blockSize)), withIv); testMode(new BufferedBlockCipher(new CFBBlockCipher(cipher1, blockSize)), withIv); testMode(new BufferedBlockCipher(new SICBlockCipher(cipher1)), withIv); } // CTS requires at least one block if (blockSize <= 16 && streamSize >= blockSize) { testMode(new CTSBlockCipher(cipher1), key); } if (blockSize <= 16 && streamSize >= blockSize) { testMode(new NISTCTSBlockCipher(NISTCTSBlockCipher.CS1, cipher1), key); testMode(new NISTCTSBlockCipher(NISTCTSBlockCipher.CS2, cipher1), key); testMode(new NISTCTSBlockCipher(NISTCTSBlockCipher.CS3, cipher1), key); } if (blockSize == 8 || blockSize == 16) { testMode(new EAXBlockCipher(cipher1), withIv); } if (blockSize == 16) { testMode(new CCMBlockCipher(cipher1), new ParametersWithIV(key, new byte[7])); testMode(new GCMBlockCipher(cipher1), withIv); testMode(new OCBBlockCipher(cipher1, cipher2), new ParametersWithIV(key, new byte[15])); } }
private void runTestCase(String testName, String[] testVector, int macLengthBits) throws InvalidCipherTextException { byte[] key = Hex.decode(K); byte[] nonce = Hex.decode(N); int pos = 0; byte[] A = Hex.decode(testVector[pos++]); byte[] P = Hex.decode(testVector[pos++]); byte[] C = Hex.decode(testVector[pos++]); int macLengthBytes = macLengthBits / 8; // TODO Variations processing AAD and cipher bytes incrementally KeyParameter keyParameter = new KeyParameter(key); AEADParameters aeadParameters = new AEADParameters(keyParameter, macLengthBits, nonce, A); OCBBlockCipher encCipher = initCipher(true, aeadParameters); OCBBlockCipher decCipher = initCipher(false, aeadParameters); checkTestCase(encCipher, decCipher, testName, macLengthBytes, P, C); checkTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C); // TODO Key reuse }
private AEADBlockCipher createOCBCipher() { return new OCBBlockCipher(createUnderlyingCipher(), createUnderlyingCipher()); }
private static AEADBlockCipher createOCBCipher(boolean forEncryption, AEADParameters parameters) { AEADBlockCipher c = new OCBBlockCipher(new AESEngine(), new AESEngine()); c.init(forEncryption, parameters); return c; }
private OCBBlockCipher initCipher(boolean forEncryption, AEADParameters parameters) { OCBBlockCipher c = new OCBBlockCipher(new AESFastEngine(), new AESFastEngine()); c.init(forEncryption, parameters); return c; }
private void runLongerTestCase(int aesKeySize, int tagLen, byte[] expectedOutput) throws InvalidCipherTextException { KeyParameter key = new KeyParameter(new byte[aesKeySize / 8]); byte[] N = new byte[12]; AEADBlockCipher c1 = new OCBBlockCipher(new AESFastEngine(), new AESFastEngine()); c1.init(true, new AEADParameters(key, tagLen, N)); AEADBlockCipher c2 = new OCBBlockCipher(new AESFastEngine(), new AESFastEngine()); long total = 0; byte[] S = new byte[128]; for (int i = 0; i < 128; ++i) { N[11] = (byte)i; c2.init(true, new AEADParameters(key, tagLen, N)); total += updateCiphers(c1, c2, S, i, true, true); total += updateCiphers(c1, c2, S, i, false, true); total += updateCiphers(c1, c2, S, i, true, false); } long expectedTotal = 16256 + (48 * tagLen); if (total != expectedTotal) { fail("test generated the wrong amount of input: " + total); } byte[] output = new byte[c1.getOutputSize(0)]; c1.doFinal(output, 0); if (!areEqual(expectedOutput, output)) { fail("incorrect encrypt in long-form test"); } }