|
@@ -23,7 +23,9 @@ import static org.junit.Assert.assertTrue;
|
|
|
import java.io.BufferedInputStream;
|
|
|
import java.io.DataInputStream;
|
|
|
import java.io.IOException;
|
|
|
+import java.math.BigInteger;
|
|
|
import java.security.GeneralSecurityException;
|
|
|
+import java.security.SecureRandom;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
@@ -41,6 +43,8 @@ import org.junit.Assert;
|
|
|
import org.junit.Assume;
|
|
|
import org.junit.Test;
|
|
|
|
|
|
+import com.google.common.primitives.Longs;
|
|
|
+
|
|
|
public class TestCryptoCodec {
|
|
|
private static final Log LOG= LogFactory.getLog(TestCryptoCodec.class);
|
|
|
private static final byte[] key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
|
@@ -230,4 +234,64 @@ public class TestCryptoCodec {
|
|
|
Assert.assertEquals(len, rand1.length);
|
|
|
Assert.assertFalse(Arrays.equals(rand, rand1));
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Regression test for IV calculation, see HADOOP-11343
|
|
|
+ */
|
|
|
+ @Test(timeout=120000)
|
|
|
+ public void testCalculateIV() throws Exception {
|
|
|
+ JceAesCtrCryptoCodec codec = new JceAesCtrCryptoCodec();
|
|
|
+ codec.setConf(conf);
|
|
|
+
|
|
|
+ SecureRandom sr = new SecureRandom();
|
|
|
+ byte[] initIV = new byte[16];
|
|
|
+ byte[] IV = new byte[16];
|
|
|
+
|
|
|
+ long iterations = 1000;
|
|
|
+ long counter = 10000;
|
|
|
+
|
|
|
+ // Overflow test, IV: 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
|
|
|
+ for(int i = 0; i < 8; i++) {
|
|
|
+ initIV[8 + i] = (byte)0xff;
|
|
|
+ }
|
|
|
+
|
|
|
+ for(long j = 0; j < counter; j++) {
|
|
|
+ assertIVCalculation(codec, initIV, j, IV);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Random IV and counter sequence test
|
|
|
+ for(long i = 0; i < iterations; i++) {
|
|
|
+ sr.nextBytes(initIV);
|
|
|
+
|
|
|
+ for(long j = 0; j < counter; j++) {
|
|
|
+ assertIVCalculation(codec, initIV, j, IV);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Random IV and random counter test
|
|
|
+ for(long i = 0; i < iterations; i++) {
|
|
|
+ sr.nextBytes(initIV);
|
|
|
+
|
|
|
+ for(long j = 0; j < counter; j++) {
|
|
|
+ long c = sr.nextLong();
|
|
|
+ assertIVCalculation(codec, initIV, c, IV);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertIVCalculation(CryptoCodec codec, byte[] initIV,
|
|
|
+ long counter, byte[] IV) {
|
|
|
+ codec.calculateIV(initIV, counter, IV);
|
|
|
+
|
|
|
+ BigInteger iv = new BigInteger(1, IV);
|
|
|
+ BigInteger ref = calculateRef(initIV, counter);
|
|
|
+
|
|
|
+ assertTrue("Calculated IV don't match with the reference", iv.equals(ref));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static BigInteger calculateRef(byte[] initIV, long counter) {
|
|
|
+ byte[] cb = Longs.toByteArray(counter);
|
|
|
+ BigInteger bi = new BigInteger(1, initIV);
|
|
|
+ return bi.add(new BigInteger(1, cb));
|
|
|
+ }
|
|
|
}
|