1 /*
2  * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.security.InvalidKeyException;
25 import java.security.NoSuchAlgorithmException;
26 import java.security.NoSuchProviderException;
27 import java.security.SecureRandom;
28 import javax.crypto.Mac;
29 import javax.crypto.spec.SecretKeySpec;
30 
31 /**
32  * @test
33  * @bug 8048603
34  * @summary Check if doFinal and update operation result in same Mac
35  * @author Yu-Ching Valerie Peng, Bill Situ, Alexander Fomin
36  * @build Utils
37  * @run main MacSameTest
38  * @key randomness
39  */
40 public class MacSameTest implements MacTest {
41 
42     private static final int MESSAGE_SIZE = 25;
43     private static final int OFFSET = 5;
44     private static final int KEY_SIZE = 70;
45 
46     /**
47      * Initialize a message, instantiate a Mac object,
48      * initialize the object with a SecretKey,
49      * feed the message into the Mac object
50      * all at once and get the output MAC as result1.
51      * Reset the Mac object, chop the message into three pieces,
52      * feed into the Mac object sequentially, and get the output MAC as result2.
53      * Finally, compare result1 and result2 and see if they are the same.
54      *
55      * @param args the command line arguments
56      */
main(String[] args)57     public static void main(String[] args) {
58         Utils.runTests(new MacSameTest());
59     }
60 
61     @Override
doTest(String algo)62     public void doTest(String algo) throws NoSuchAlgorithmException,
63             NoSuchProviderException, InvalidKeyException {
64         Mac mac;
65         try {
66             mac = Mac.getInstance(algo, "SunJCE");
67         } catch (NoSuchAlgorithmException nsae) {
68             // depending on Solaris configuration,
69             // it can support HMAC or not with Mac
70             System.out.println("Expected NoSuchAlgorithmException thrown: "
71                     + nsae);
72             return;
73         }
74 
75         byte[] plain = new byte[MESSAGE_SIZE];
76         for (int i = 0; i < MESSAGE_SIZE; i++) {
77             plain[i] = (byte) (i % 256);
78         }
79 
80         byte[] tail = new byte[plain.length - OFFSET];
81         System.arraycopy(plain, OFFSET, tail, 0, tail.length);
82 
83         SecureRandom srdm = new SecureRandom();
84         byte[] keyVal = new byte[KEY_SIZE];
85         srdm.nextBytes(keyVal);
86         SecretKeySpec keySpec = new SecretKeySpec(keyVal, "HMAC");
87 
88         mac.init(keySpec);
89         byte[] result1 = mac.doFinal(plain);
90 
91         mac.reset();
92         mac.update(plain[0]);
93         mac.update(plain, 1, OFFSET - 1);
94         byte[] result2 = mac.doFinal(tail);
95 
96         if (!java.util.Arrays.equals(result1, result2)) {
97             throw new RuntimeException("result1 and result2 are not the same");
98         }
99     }
100 
101 }
102