blob: 93342cbb6daaf1c2a2d826133011b00494612f0d [file] [log] [blame]
package org.bouncycastle.crypto.test;
import java.security.SecureRandom;
import org.bouncycastle.crypto.Wrapper;
import org.bouncycastle.crypto.engines.AESWrapPadEngine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
/**
* This is a test harness I use because I cannot modify the BC test harness without
* invalidating the signature on their signed provider library. The code here is not
* high quality but it does test the RFC vectors as well as randomly generated values.
* The RFC test vectors are tested by making sure both the ciphertext and decrypted
* values match the expected values whereas the random values are just checked to make
* sure that:
* <p>unwrap(wrap(random_value, random_kek), random_kek) == random_value.</p>
*/
public class AESWrapPadTest
extends SimpleTest
{
private final int numOfRandomIterations = 100;
public AESWrapPadTest()
{
}
private void wrapAndUnwrap(byte[] kek, byte[] key, byte[] expected)
throws Exception
{
Wrapper wrapper = new AESWrapPadEngine();
wrapper.init(true, new KeyParameter(kek));
byte[] cipherText = wrapper.wrap(key, 0, key.length);
if (!areEqual(cipherText, expected))
{
fail("Wrapped value does not match expected.");
}
wrapper.init(false, new KeyParameter(kek));
byte[] plainText = wrapper.unwrap(cipherText, 0, cipherText.length);
if (!areEqual(key, plainText))
{
fail("Unwrapped value does not match original.");
}
}
private void wrapAndUnwrap(byte[] kek, byte[] key)
throws Exception
{
Wrapper wrapper = new AESWrapPadEngine();
wrapper.init(true, new KeyParameter(kek));
byte[] cipherText = wrapper.wrap(key, 0, key.length);
wrapper.init(false, new KeyParameter(kek));
byte[] plainText = wrapper.unwrap(cipherText, 0, cipherText.length);
if (!areEqual(key, plainText))
{
fail("Unwrapped value does not match original.");
}
}
private void wrapWithIVTest()
throws Exception
{
byte[] kek = Hex.decode("5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8");
byte[] key = Hex.decode("c37b7e6492584340bed12207808941155068f738");
byte[] expected = Hex.decode("5cbdb3fb71351d0e628b85dbcba1a1890d4db26d1335e11d1aabea11124caad0");
Wrapper wrapper = new AESWrapPadEngine();
wrapper.init(true, new ParametersWithIV(new KeyParameter(kek), Hex.decode("33333333")));
byte[] cipherText = wrapper.wrap(key, 0, key.length);
if (!areEqual(cipherText, expected))
{
fail("Wrapped value does not match expected.");
}
wrapper.init(false, new ParametersWithIV(new KeyParameter(kek), Hex.decode("33333333")));
byte[] plainText = wrapper.unwrap(cipherText, 0, cipherText.length);
if (!areEqual(key, plainText))
{
fail("Unwrapped value does not match original.");
}
}
public String getName()
{
return "AESWrapPad";
}
public void performTest()
throws Exception
{
// test RFC 5649 test vectors
byte[] kek = Hex.decode("5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8");
byte[] key = Hex.decode("c37b7e6492584340bed12207808941155068f738");
byte[] wrap = Hex.decode("138bdeaa9b8fa7fc61f97742e72248ee5ae6ae5360d1ae6a5f54f373fa543b6a");
wrapAndUnwrap(kek, key, wrap);
wrap = Hex.decode("afbeb0f07dfbf5419200f2ccb50bb24f");
key = Hex.decode("466f7250617369");
wrapAndUnwrap(kek, key, wrap);
wrapWithIVTest();
//
// offset test
//
Wrapper wrapper = new AESWrapPadEngine();
byte[] pText = new byte[5 + key.length];
byte[] cText;
System.arraycopy(key, 0, pText, 5, key.length);
wrapper.init(true, new KeyParameter(kek));
cText = wrapper.wrap(pText, 5, key.length);
if (!Arrays.areEqual(cText, wrap))
{
fail("failed offset wrap test expected " + new String(Hex.encode(wrap)) + " got " + new String(Hex.encode(cText)));
}
wrapper.init(false, new KeyParameter(kek));
cText = new byte[6 + wrap.length];
System.arraycopy(wrap, 0, cText, 6, wrap.length);
pText = wrapper.unwrap(cText, 6, wrap.length);
if (!Arrays.areEqual(pText, key))
{
fail("failed offset unwrap test expected " + new String(Hex.encode(key)) + " got " + new String(Hex.encode(pText)));
}
// test random values
SecureRandom rnd = new SecureRandom();
for (int i = 0; i < numOfRandomIterations; i++)
{
int kekLength = 128;
boolean shouldIncrease = (rnd.nextInt() & 0x01) != 0;
if (shouldIncrease)
{
kekLength = 256;
}
kek = new byte[kekLength / 8];
rnd.nextBytes(kek);
int keyToWrapSize = RNGUtils.nextInt(rnd, 256 / 8 - 8) + 8;
byte[] keyToWrap = new byte[keyToWrapSize];
rnd.nextBytes(keyToWrap);
wrapAndUnwrap(kek, keyToWrap);
}
}
public static void main(
String[] args)
{
runTest(new AESWrapPadTest());
}
}