package org.bouncycastle.crypto.test; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.engines.DESEngine; import org.bouncycastle.crypto.macs.CBCBlockCipherMac; import org.bouncycastle.crypto.macs.CFBBlockCipherMac; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.paddings.PKCS7Padding; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; /** * MAC tester - vectors from * <a href=http://www.itl.nist.gov/fipspubs/fip81.htm>FIP 81</a> and * <a href=http://www.itl.nist.gov/fipspubs/fip113.htm>FIP 113</a>. */ public class MacTest extends SimpleTest { static byte[] keyBytes = Hex.decode("0123456789abcdef"); static byte[] ivBytes = Hex.decode("1234567890abcdef"); static byte[] input1 = Hex.decode("37363534333231204e6f77206973207468652074696d6520666f7220"); static byte[] output1 = Hex.decode("f1d30f68"); static byte[] output2 = Hex.decode("58d2e77e"); static byte[] output3 = Hex.decode("cd647403"); // // these aren't NIST vectors, just for regression testing. // static byte[] input2 = Hex.decode("3736353433323120"); static byte[] output4 = Hex.decode("3af549c9"); static byte[] output5 = Hex.decode("188fbdd5"); static byte[] output6 = Hex.decode("7045eecd"); public MacTest() { } public void performTest() { KeyParameter key = new KeyParameter(keyBytes); BlockCipher cipher = new DESEngine(); Mac mac = new CBCBlockCipherMac(cipher); // // standard DAC - zero IV // mac.init(key); mac.update(input1, 0, input1.length); byte[] out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output1)) { fail("Failed - expected " + new String(Hex.encode(output1)) + " got " + new String(Hex.encode(out))); } // // mac with IV. // ParametersWithIV param = new ParametersWithIV(key, ivBytes); mac.init(param); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output2)) { fail("Failed - expected " + new String(Hex.encode(output2)) + " got " + new String(Hex.encode(out))); } // // CFB mac with IV - 8 bit CFB mode // param = new ParametersWithIV(key, ivBytes); mac = new CFBBlockCipherMac(cipher); mac.init(param); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output3)) { fail("Failed - expected " + new String(Hex.encode(output3)) + " got " + new String(Hex.encode(out))); } // // word aligned data - zero IV // mac.init(key); mac.update(input2, 0, input2.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output4)) { fail("Failed - expected " + new String(Hex.encode(output4)) + " got " + new String(Hex.encode(out))); } // // word aligned data - zero IV - CBC padding // mac = new CBCBlockCipherMac(cipher, new PKCS7Padding()); mac.init(key); mac.update(input2, 0, input2.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output5)) { fail("Failed - expected " + new String(Hex.encode(output5)) + " got " + new String(Hex.encode(out))); } // // non-word aligned data - zero IV - CBC padding // mac.reset(); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output6)) { fail("Failed - expected " + new String(Hex.encode(output6)) + " got " + new String(Hex.encode(out))); } // // non-word aligned data - zero IV - CBC padding // mac.init(key); mac.update(input1, 0, input1.length); out = new byte[4]; mac.doFinal(out, 0); if (!areEqual(out, output6)) { fail("Failed - expected " + new String(Hex.encode(output6)) + " got " + new String(Hex.encode(out))); } } public String getName() { return "Mac"; } public static void main( String[] args) { runTest(new MacTest()); } }