private void ctrCounterTest() { CipherParameters params = new ParametersWithIV( new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("000000000000000000000000000000")); SICBlockCipher engine = new SICBlockCipher(new AESEngine()); engine.init(true, params); SecureRandom rand = new SecureRandom(); byte[] cipher = new byte[256 * 16]; byte[] plain = new byte[255 * 16]; rand.nextBytes(plain); engine.processBytes(plain, 0, plain.length, cipher, 0); engine.init(true, params); byte[] fragment = new byte[20]; plain = new byte[256 * 16]; engine.init(true, params); try { engine.processBytes(plain, 0, plain.length, cipher, 0); fail("out of range data not caught"); } catch (IllegalStateException e) { if (!"Counter in CTR/SIC mode out of range.".equals(e.getMessage())) { fail("wrong exception"); } } }
/** * Write hard to identify random data to the OutputStream. Does not drain the global secure random * number generator, and is significantly faster than it. * * @param os The stream to write to. * @param length The number of bytes to write. * @throws IOException If unable to write to the stream. */ public static void fill(OutputStream os, long length) throws IOException { long remaining = length; byte[] buffer = new byte[BUFFER_SIZE]; int read = 0; while ((remaining == -1) || (remaining > 0)) { synchronized (FileUtil.class) { if (cis == null || cisCounter > Long.MAX_VALUE / 2) { // Reset it well before the birthday paradox (note this is actually counting bytes). byte[] key = new byte[16]; byte[] iv = new byte[16]; SecureRandom rng = NodeStarter.getGlobalSecureRandom(); rng.nextBytes(key); rng.nextBytes(iv); AESFastEngine e = new AESFastEngine(); SICBlockCipher ctr = new SICBlockCipher(e); ctr.init(true, new ParametersWithIV(new KeyParameter(key), iv)); cis = new CipherInputStream(zis, new BufferedBlockCipher(ctr)); cisCounter = 0; } read = cis.read( buffer, 0, ((remaining > BUFFER_SIZE) || (remaining == -1)) ? BUFFER_SIZE : (int) remaining); cisCounter += read; } if (read == -1) { if (length == -1) { return; } throw new EOFException("stream reached eof"); } os.write(buffer, 0, read); if (remaining > 0) remaining -= read; } }
private void skipTest() { CipherParameters params = new ParametersWithIV( new KeyParameter(Hex.decode("5F060D3716B345C253F6749ABAC10917")), Hex.decode("00000000000000000000000000000000")); SICBlockCipher engine = new SICBlockCipher(new AESEngine()); engine.init(true, params); SecureRandom rand = new SecureRandom(); byte[] plain = new byte[50000]; byte[] cipher = new byte[50000]; rand.nextBytes(plain); engine.processBytes(plain, 0, plain.length, cipher, 0); byte[] fragment = new byte[20]; engine.init(true, params); engine.skip(10); if (engine.getPosition() != 10) { fail("skip position incorrect - 10 got " + engine.getPosition()); } engine.processBytes(plain, 10, fragment.length, fragment, 0); if (!areEqual(cipher, 10, fragment, 0)) { fail("skip forward 10 failed"); } engine.skip(1000); if (engine.getPosition() != 1010 + fragment.length) { fail( "skip position incorrect - " + (1010 + fragment.length) + " got " + engine.getPosition()); } engine.processBytes(plain, 1010 + fragment.length, fragment.length, fragment, 0); if (!areEqual(cipher, 1010 + fragment.length, fragment, 0)) { fail("skip forward 1000 failed"); } engine.skip(-10); if (engine.getPosition() != 1010 + 2 * fragment.length - 10) { fail( "skip position incorrect - " + (1010 + 2 * fragment.length - 10) + " got " + engine.getPosition()); } engine.processBytes(plain, 1010 + 2 * fragment.length - 10, fragment.length, fragment, 0); if (!areEqual(cipher, 1010 + 2 * fragment.length - 10, fragment, 0)) { fail("skip back 10 failed"); } engine.skip(-1000); if (engine.getPosition() != 60) { fail("skip position incorrect - " + 60 + " got " + engine.getPosition()); } engine.processBytes(plain, 60, fragment.length, fragment, 0); if (!areEqual(cipher, 60, fragment, 0)) { fail("skip back 1000 failed"); } long pos = engine.seekTo(1010); if (pos != 1010) { fail("position incorrect - " + 1010 + " got " + pos); } engine.processBytes(plain, 1010, fragment.length, fragment, 0); if (!areEqual(cipher, 1010, fragment, 0)) { fail("seek to 1010 failed"); } engine.reset(); for (int i = 0; i != 5000; i++) { engine.skip(i); if (engine.getPosition() != i) { fail("skip forward at wrong position"); } engine.processBytes(plain, i, fragment.length, fragment, 0); if (!areEqual(cipher, i, fragment, 0)) { fail("skip forward i failed: " + i); } if (engine.getPosition() != i + fragment.length) { fail("cipher at wrong position: " + engine.getPosition() + " [" + i + "]"); } engine.skip(-fragment.length); if (engine.getPosition() != i) { fail("skip back at wrong position"); } engine.processBytes(plain, i, fragment.length, fragment, 0); if (!areEqual(cipher, i, fragment, 0)) { fail("skip back i failed: " + i); } engine.reset(); } }