diff options
Diffstat (limited to 'libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/RFC3211WrapTest.java')
-rw-r--r-- | libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/RFC3211WrapTest.java | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/RFC3211WrapTest.java b/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/RFC3211WrapTest.java new file mode 100644 index 000000000..8568e5903 --- /dev/null +++ b/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/RFC3211WrapTest.java @@ -0,0 +1,220 @@ +package org.spongycastle.crypto.test; + +import org.spongycastle.crypto.BlockCipher; +import org.spongycastle.crypto.InvalidCipherTextException; +import org.spongycastle.crypto.Wrapper; +import org.spongycastle.crypto.engines.DESEngine; +import org.spongycastle.crypto.engines.DESedeEngine; +import org.spongycastle.crypto.engines.RFC3211WrapEngine; +import org.spongycastle.crypto.modes.CBCBlockCipher; +import org.spongycastle.crypto.params.KeyParameter; +import org.spongycastle.crypto.params.ParametersWithIV; +import org.spongycastle.crypto.params.ParametersWithRandom; +import org.spongycastle.util.Arrays; +import org.spongycastle.util.encoders.Hex; +import org.spongycastle.util.test.SimpleTest; + +import java.security.SecureRandom; + +/** + * Wrap Test based on RFC3211 test vectors + */ +public class RFC3211WrapTest + extends SimpleTest +{ + SecureRandom r1 = new SecureRandom() + { + int[] ints = { 0xC4, 0x36, 0xF5, 0x41 }; + int count = 0; + + public int nextInt() + { + return ints[count++]; + } + }; + + SecureRandom r2 = new SecureRandom() + { + int[] ints = { 0xFA, 0x06, 0x0A, 0x45 }; + int count = 0; + + public int nextInt() + { + return ints[count++]; + } + }; + + public String getName() + { + return "RFC3211Wrap"; + } + + private void wrapTest( + int id, + BlockCipher engine, + byte[] kek, + byte[] iv, + SecureRandom rand, + byte[] in, + byte[] out) + throws Exception + { + Wrapper wrapper = new RFC3211WrapEngine(engine); + + wrapper.init(true, new ParametersWithRandom(new ParametersWithIV(new KeyParameter(kek), iv), rand)); + + byte[] cText = wrapper.wrap(in, 0, in.length); + if (!Arrays.areEqual(cText, out)) + { + fail("failed wrap test " + id + " expected " + new String(Hex.encode(out)) + " got " + new String(Hex.encode(cText))); + } + + wrapper.init(false, new ParametersWithIV(new KeyParameter(kek), iv)); + + byte[] pText = wrapper.unwrap(out, 0, out.length); + if (!Arrays.areEqual(pText, in)) + { + fail("rfailed unwrap test " + id + " expected " + new String(Hex.encode(in)) + " got " + new String(Hex.encode(pText))); + } + } + + private void testCorruption() + throws InvalidCipherTextException + { + byte[] kek = Hex.decode("D1DAA78615F287E6"); + byte[] iv = Hex.decode("EFE598EF21B33D6D"); + + Wrapper wrapper = new RFC3211WrapEngine(new DESEngine()); + + wrapper.init(false, new ParametersWithIV(new KeyParameter(kek), iv)); + + byte[] block = Hex.decode("ff739D838C627C897323A2F8C436F541"); + encryptBlock(kek, iv, block); + + try + { + wrapper.unwrap(block, 0, block.length); + + fail("bad length not detected"); + } + catch (InvalidCipherTextException e) + { + if (!e.getMessage().equals("wrapped key corrupted")) + { + fail("wrong exception on length"); + } + } + + block = Hex.decode("08639D838C627C897323A2F8C436F541"); + testChecksum(kek, iv, block, wrapper); + + block = Hex.decode("08736D838C627C897323A2F8C436F541"); + testChecksum(kek, iv, block, wrapper); + + block = Hex.decode("08739D638C627C897323A2F8C436F541"); + testChecksum(kek, iv, block, wrapper); + } + + private void testChecksum(byte[] kek, byte[] iv, byte[] block, Wrapper wrapper) + { + encryptBlock(kek, iv, block); + + try + { + wrapper.unwrap(block, 0, block.length); + + fail("bad checksum not detected"); + } + catch (InvalidCipherTextException e) + { + if (!e.getMessage().equals("wrapped key fails checksum")) + { + fail("wrong exception"); + } + } + } + + private void encryptBlock(byte[] key, byte[] iv, byte[] cekBlock) + { + BlockCipher engine = new CBCBlockCipher(new DESEngine()); + + engine.init(true, new ParametersWithIV(new KeyParameter(key), iv)); + + for (int i = 0; i < cekBlock.length; i += 8) + { + engine.processBlock(cekBlock, i, cekBlock, i); + } + + for (int i = 0; i < cekBlock.length; i += 8) + { + engine.processBlock(cekBlock, i, cekBlock, i); + } + } + + public void performTest() + throws Exception + { + wrapTest(1, new DESEngine(), Hex.decode("D1DAA78615F287E6"), Hex.decode("EFE598EF21B33D6D"), r1, Hex.decode("8C627C897323A2F8"), Hex.decode("B81B2565EE373CA6DEDCA26A178B0C10")); + wrapTest(2, new DESedeEngine(), Hex.decode("6A8970BF68C92CAEA84A8DF28510858607126380CC47AB2D"), Hex.decode("BAF1CA7931213C4E"), r2, + Hex.decode("8C637D887223A2F965B566EB014B0FA5D52300A3F7EA40FFFC577203C71BAF3B"), + Hex.decode("C03C514ABDB9E2C5AAC038572B5E24553876B377AAFB82ECA5A9D73F8AB143D9EC74E6CAD7DB260C")); + + testCorruption(); + + Wrapper wrapper = new RFC3211WrapEngine(new DESEngine()); + ParametersWithIV params = new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16]); + byte[] buf = new byte[16]; + + try + { + wrapper.init(true, params); + + wrapper.unwrap(buf, 0, buf.length); + + fail("failed unwrap state test."); + } + catch (IllegalStateException e) + { + // expected + } + catch (InvalidCipherTextException e) + { + fail("unexpected exception: " + e, e); + } + + try + { + wrapper.init(false, params); + + wrapper.wrap(buf, 0, buf.length); + + fail("failed unwrap state test."); + } + catch (IllegalStateException e) + { + // expected + } + + // + // short test + // + try + { + wrapper.init(false, params); + + wrapper.unwrap(buf, 0, buf.length / 2); + + fail("failed unwrap short test."); + } + catch (InvalidCipherTextException e) + { + // expected + } + } + + public static void main( + String[] args) + { + runTest(new RFC3211WrapTest()); + } +} |