summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/crypto/test/ISO9797Alg3MacTest.java
blob: 96b5fc46459ae5f186b4231efa2716438a8d68bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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.ISO9797Alg3Mac;
import org.bouncycastle.crypto.paddings.ISO7816d4Padding;
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;

public class ISO9797Alg3MacTest
    extends SimpleTest
{
    static byte[] keyBytes = Hex.decode("7CA110454A1A6E570131D9619DC1376E");

    static byte[] input1 = "Hello World !!!!".getBytes();

    static byte[] output1 = Hex.decode("F09B856213BAB83B");

    public ISO9797Alg3MacTest()
    {
    }

    public void performTest()
    {
        KeyParameter key = new KeyParameter(keyBytes);
        BlockCipher cipher = new DESEngine();
        Mac mac = new ISO9797Alg3Mac(cipher);

        //
        // standard DAC - zero IV
        //
        mac.init(key);

        mac.update(input1, 0, input1.length);

        byte[] out = new byte[8];

        mac.doFinal(out, 0);

        if (!areEqual(out, output1))
        {
            fail("Failed - expected " + new String(Hex.encode(output1)) + " got " + new String(Hex.encode(out)));
        }

        //
        //  reset
        //
        mac.reset();

        mac.init(key);

        for (int i = 0; i != input1.length / 2; i++)
        {
            mac.update(input1[i]);
        }

        mac.update(input1, input1.length / 2, input1.length - (input1.length / 2));

        mac.doFinal(out, 0);

        if (!areEqual(out, output1))
        {
            fail("Reset failed - expected " + new String(Hex.encode(output1)) + " got " + new String(Hex.encode(out)));
        }

        testMacWithIv();
    }

    private void testMacWithIv()
    {
        byte[] inputData = new byte[]{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
        byte[] key = new byte[]{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
        byte[] zeroIv = new byte[8];
        byte[] nonZeroIv = new byte[]{0x5, 0x6, 0x7, 0x8, 0x1, 0x2, 0x3, 0x4};

        KeyParameter simpleParameter = new KeyParameter(key);
        ParametersWithIV zeroIvParameter = new ParametersWithIV(new KeyParameter(key), zeroIv);

        ISO9797Alg3Mac mac1 = new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding());

        // we calculate a reference MAC with a null IV
        mac1.init(simpleParameter);
        mac1.update(inputData, 0, inputData.length);
        byte[] output1 = new byte[mac1.getMacSize()];
        mac1.doFinal(output1, 0);

        // we then check that passing a vector of 0s is the same as not using any IV
        ISO9797Alg3Mac mac2 = new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding());
        mac2.init(zeroIvParameter);
        mac2.update(inputData, 0, inputData.length);
        byte[] output2 = new byte[mac2.getMacSize()];
        mac2.doFinal(output2, 0);
        if (!Arrays.areEqual(output1, output2))
        {
            fail("zero IV test failed");
        }

        // and then check that a non zero IV parameter produces a different results.
        ParametersWithIV nonZeroIvParameter = new ParametersWithIV(new KeyParameter(key), nonZeroIv);
        mac2 = new ISO9797Alg3Mac(new DESEngine(), new ISO7816d4Padding());
        mac2.init(nonZeroIvParameter);
        mac2.update(inputData, 0, inputData.length);
        output2 = new byte[mac2.getMacSize()];
        mac2.doFinal(output2, 0);
        if (Arrays.areEqual(output1, output2))
        {
            fail("non-zero IV test failed");
        }
    }

    public String getName()
    {
        return "ISO9797Alg3Mac";
    }

    public static void main(
        String[] args)
    {
        runTest(new ISO9797Alg3MacTest());
    }
}