예제 #1
0
  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");
      }
    }
  }
예제 #2
0
 /**
  * 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;
   }
 }
예제 #3
0
  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();
    }
  }