TestKATForGCM.java revision 6339:46e6a4b7ca26
1/*
2 * Copyright (c) 2013, 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/*
25 * @test
26 * @bug 6996769
27 * @library ../UTIL
28 * @build TestUtil
29 * @run main TestKATForGCM
30 * @summary Known Answer Test for AES cipher with GCM mode support in
31 * SunJCE provider.
32 * @author Valerie Peng
33 */
34
35
36import java.security.*;
37import javax.crypto.*;
38import javax.crypto.spec.*;
39import java.math.*;
40import com.sun.crypto.provider.*;
41
42import java.util.*;
43
44public class TestKATForGCM {
45
46    // Utility methods
47    private static byte[] HexToBytes(String hexVal) {
48        if (hexVal == null) return new byte[0];
49        byte[] result = new byte[hexVal.length()/2];
50        for (int i = 0; i < result.length; i++) {
51            // 2 characters at a time
52            String byteVal = hexVal.substring(2*i, 2*i +2);
53            result[i] = Integer.valueOf(byteVal, 16).byteValue();
54        }
55        return result;
56    }
57
58    private static class TestVector {
59        SecretKey key;
60        byte[] plainText;
61        byte[] aad;
62        byte[] cipherText;
63        byte[] tag;
64        GCMParameterSpec spec;
65        String info;
66
67        TestVector(String key, String iv, String pt, String aad,
68                   String ct, String tag) {
69            this.key = new SecretKeySpec(HexToBytes(key), "AES");
70            this.plainText = HexToBytes(pt);
71            this.aad = HexToBytes(aad);
72            this.cipherText = HexToBytes(ct);
73            this.tag = HexToBytes(tag);
74            this.spec = new GCMParameterSpec(this.tag.length * 8, HexToBytes(iv));
75            this.info = "key=" + key + ", iv=" + iv + ", pt=" + pt +
76                ",aad=" + aad + ", ct=" + ct + ", tag=" + tag;
77        }
78
79        public String toString() {
80            return info;
81        }
82    }
83
84    // These test vectors are found off NIST's CAVP page
85    // http://csrc.nist.gov/groups/STM/cavp/index.html
86    // inside the link named "GCM Test Vectors", i.e.
87    // http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip
88    // CAVS 14.0, set of test vectors w/ count = 0, keysize = 128
89    private static TestVector[] testValues = {
90        // 96-bit iv w/ 128/120/112/104/96-bit tags
91        // no plain text, no aad
92        new TestVector("11754cd72aec309bf52f7687212e8957",
93                       "3c819d9a9bed087615030b65",
94                       null, null, null,
95                       "250327c674aaf477aef2675748cf6971"),
96        new TestVector("272f16edb81a7abbea887357a58c1917",
97                       "794ec588176c703d3d2a7a07",
98                       null, null, null,
99                       "b6e6f197168f5049aeda32dafbdaeb"),
100        new TestVector("81b6844aab6a568c4556a2eb7eae752f",
101                       "ce600f59618315a6829bef4d",
102                       null, null, null,
103                       "89b43e9dbc1b4f597dbbc7655bb5"),
104        new TestVector("cde2f9a9b1a004165ef9dc981f18651b",
105                       "29512c29566c7322e1e33e8e",
106                       null, null, null,
107                       "2e58ce7dabd107c82759c66a75"),
108        new TestVector("b01e45cc3088aaba9fa43d81d481823f",
109                       "5a2c4a66468713456a4bd5e1",
110                       null, null, null,
111                       "014280f944f53c681164b2ff"),
112        // 96-bit iv w/ 128/120/112/104/96-bit tags
113        // no plain text, 16-byte aad
114        new TestVector("77be63708971c4e240d1cb79e8d77feb",
115                       "e0e00f19fed7ba0136a797f3",
116                       null,
117                       "7a43ec1d9c0a5a78a0b16533a6213cab",
118                       null,
119                       "209fcc8d3675ed938e9c7166709dd946"),
120        new TestVector("da0b615656135194ba6d3c851099bc48",
121                       "d39d4b4d3cc927885090e6c3",
122                       null,
123                       "e7e5e6f8dac913036cb2ff29e8625e0e",
124                       null,
125                       "ab967711a5770461724460b07237e2"),
126        new TestVector("7e0986937a88eef894235aba4a2f43b2",
127                       "92c4a631695907166b422d60",
128                       null,
129                       "85c185f8518f9f2cd597a8f9208fc76b",
130                       null,
131                       "3bb916b728df94fe9d1916736be1"),
132        new TestVector("c3db570d7f0c21e86b028f11465d1dc9",
133                       "f86970f58ceef89fc7cb679e",
134                       null,
135                       "c095240708c0f57c288d86090ae34ee1",
136                       null,
137                       "e043c52160d652e82c7262fcf4"),
138        new TestVector("bea48ae4980d27f357611014d4486625",
139                       "32bddb5c3aa998a08556454c",
140                       null,
141                       "8a50b0b8c7654bced884f7f3afda2ead",
142                       null,
143                       "8e0f6d8bf05ffebe6f500eb1"),
144        // 96-bit iv w/ 128/120/112/104/96-bit tags
145        // no plain text, 20-byte aad
146        new TestVector("2fb45e5b8f993a2bfebc4b15b533e0b4",
147                       "5b05755f984d2b90f94b8027",
148                       null,
149                       "e85491b2202caf1d7dce03b97e09331c32473941",
150                       null,
151                       "c75b7832b2a2d9bd827412b6ef5769db"),
152        new TestVector("9bf406339fcef9675bbcf156aa1a0661",
153                       "8be4a9543d40f542abacac95",
154                       null,
155                       "7167cbf56971793186333a6685bbd58d47d379b3",
156                       null,
157                       "5e7968d7bbd5ba58cfcc750e2ef8f1"),
158        new TestVector("a2e962fff70fd0f4d63be728b80556fc",
159                       "1fa7103483de43d09bc23db4",
160                       null,
161                       "2a58edf1d53f46e4e7ee5e77ee7aeb60fc360658",
162                       null,
163                       "fa37f2dbbefab1451eae1d0d74ca"),
164        new TestVector("6bf4fdce82926dcdfc52616ed5f23695",
165                       "cc0f5899a10615567e1193ed",
166                       null,
167                       "3340655592374c1da2f05aac3ee111014986107f",
168                       null,
169                       "8ad3385cce3b5e7c985908192c"),
170        new TestVector("4df7a13e43c3d7b66b1a72fac5ba398e",
171                       "97179a3a2d417908dcf0fb28",
172                       null,
173                       "cbb7fc0010c255661e23b07dbd804b1e06ae70ac",
174                       null,
175                       "37791edae6c137ea946cfb40"),
176        // 96-bit iv w/ 128-bit tags, 13/16/32/51-byte plain text, no aad
177        new TestVector("fe9bb47deb3a61e423c2231841cfd1fb",
178                       "4d328eb776f500a2f7fb47aa",
179                       "f1cc3818e421876bb6b8bbd6c9",
180                       null,
181                       "b88c5c1977b35b517b0aeae967",
182                       "43fd4727fe5cdb4b5b42818dea7ef8c9"),
183        new TestVector("7fddb57453c241d03efbed3ac44e371c",
184                       "ee283a3fc75575e33efd4887",
185                       "d5de42b461646c255c87bd2962d3b9a2",
186                       null,
187                       "2ccda4a5415cb91e135c2a0f78c9b2fd",
188                       "b36d1df9b9d5e596f83e8b7f52971cb3"),
189        new TestVector("9971071059abc009e4f2bd69869db338",
190                       "07a9a95ea3821e9c13c63251",
191                       "f54bc3501fed4f6f6dfb5ea80106df0bd836e6826225b75c0222f6e859b35983",
192                       null,
193                       "0556c159f84ef36cb1602b4526b12009c775611bffb64dc0d9ca9297cd2c6a01",
194                       "7870d9117f54811a346970f1de090c41"),
195        new TestVector("594157ec4693202b030f33798b07176d",
196                       "49b12054082660803a1df3df",
197
198"3feef98a976a1bd634f364ac428bb59cd51fb159ec1789946918dbd50ea6c9d594a3a31a5269b0da6936c29d063a5fa2cc8a1c",
199                      null,
200
201"c1b7a46a335f23d65b8db4008a49796906e225474f4fe7d39e55bf2efd97fd82d4167de082ae30fa01e465a601235d8d68bc69",
202                      "ba92d3661ce8b04687e8788d55417dc2"),
203        // 96-bit iv w/ 128-bit tags, 16-byte plain text, 16/20/48/90-byte aad
204        new TestVector("c939cc13397c1d37de6ae0e1cb7c423c",
205                       "b3d8cc017cbb89b39e0f67e2",
206                       "c3b3c41f113a31b73d9a5cd432103069",
207                       "24825602bd12a984e0092d3e448eda5f",
208                       "93fe7d9e9bfd10348a5606e5cafa7354",
209                       "0032a1dc85f1c9786925a2e71d8272dd"),
210        new TestVector("d4a22488f8dd1d5c6c19a7d6ca17964c",
211                       "f3d5837f22ac1a0425e0d1d5",
212                       "7b43016a16896497fb457be6d2a54122",
213                       "f1c5d424b83f96c6ad8cb28ca0d20e475e023b5a",
214                       "c2bd67eef5e95cac27e3b06e3031d0a8",
215                       "f23eacf9d1cdf8737726c58648826e9c"),
216        new TestVector("89850dd398e1f1e28443a33d40162664",
217                       "e462c58482fe8264aeeb7231",
218                       "2805cdefb3ef6cc35cd1f169f98da81a",
219
220"d74e99d1bdaa712864eec422ac507bddbe2b0d4633cd3dff29ce5059b49fe868526c59a2a3a604457bc2afea866e7606",
221                       "ba80e244b7fc9025cd031d0f63677e06",
222                       "d84a8c3eac57d1bb0e890a8f461d1065"),
223        new TestVector("bd7c5c63b7542b56a00ebe71336a1588",
224                       "87721f23ba9c3c8ea5571abc",
225                       "de15ddbb1e202161e8a79af6a55ac6f3",
226
227"a6ec8075a0d3370eb7598918f3b93e48444751624997b899a87fa6a9939f844e008aa8b70e9f4c3b1a19d3286bf543e7127bfecba1ad17a5ec53fccc26faecacc4c75369498eaa7d706aef634d0009279b11e4ba6c993e5e9ed9",
228                       "41eb28c0fee4d762de972361c863bc80",
229                       "9cb567220d0b252eb97bff46e4b00ff8"),
230        // 8/1024-bit iv w/ 128-bit tag, no plain text, no aad
231        new TestVector("1672c3537afa82004c6b8a46f6f0d026",
232                       "05",
233                       null, null, null,
234                       "8e2ad721f9455f74d8b53d3141f27e8e"),
235        new TestVector("d0f1f4defa1e8c08b4b26d576392027c",
236
237"42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac",
238                       null, null, null,
239                       "7ab49b57ddf5f62c427950111c5c4f0d"),
240        // 8-bit iv w/ 128-bit tag, 13-byte plain text, 90-byte aad
241        new TestVector("9f79239f0904eace50784b863e723f6b",
242                       "d9",
243                       "bdb0bb10c87965acd34d146171",
244
245"44db436089327726c5f01139e1f339735c9e85514ccc2f167bad728010fb34a9072a9794c8a5e7361b1d0dbcdc9ac4091e354bb2896561f0486645252e9c78c86beece91bfa4f7cc4a8794ce1f305b1b735efdbf1ed1563c0be0",
246                       "7e5a7c8dadb3f0c7335b4d9d8d",
247                       "6b6ef1f53723a89f3bb7c6d043840717"),
248        // 1024-bit iv w/ 128-bit tag, 51-byte plain text, 48-byte aad
249        new TestVector("141f1ce91989b07e7eb6ae1dbd81ea5e",
250
251"49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e194aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e57df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470dee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea2e8f05dd3a1396f",
252
253"d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec2fe87719dadf1eb0aef212b51e74c9c5b934104a43",
254
255"630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba323951727666c947a21894a079ef061ee159c05beeb4",
256
257"f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83240446b28dc088abd42b0fc687f208190ff24c0548",
258                      "dbb93bbb56d0439cd09f620a57687f5d"),
259    };
260
261    public boolean execute(TestVector[] testValues) throws Exception {
262        boolean testFailed = false;
263        Cipher c = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
264        for (int i = 0; i < testValues.length; i++) {
265            try {
266                c.init(Cipher.ENCRYPT_MODE, testValues[i].key, testValues[i].spec);
267                c.updateAAD(testValues[i].aad);
268                byte[] ctPlusTag = c.doFinal(testValues[i].plainText);
269
270                c.init(Cipher.DECRYPT_MODE, testValues[i].key, testValues[i].spec);
271                c.updateAAD(testValues[i].aad);
272                byte[] pt = c.doFinal(ctPlusTag); // should fail if tag mismatched
273
274                // check encryption/decryption results just to be sure
275                if (!Arrays.equals(testValues[i].plainText, pt)) {
276                    System.out.println("PlainText diff failed for test# " + i);
277                    testFailed = true;
278                }
279                int ctLen = testValues[i].cipherText.length;
280                if (!Arrays.equals(testValues[i].cipherText,
281                                   Arrays.copyOf(ctPlusTag, ctLen))) {
282                    System.out.println("CipherText diff failed for test# " + i);
283                    testFailed = true;
284                }
285                int tagLen = testValues[i].tag.length;
286                if (!Arrays.equals
287                    (testValues[i].tag,
288                     Arrays.copyOfRange(ctPlusTag, ctLen, ctLen+tagLen))) {
289                    System.out.println("Tag diff failed for test# " + i);
290                    testFailed = true;
291                }
292            } catch (Exception ex) {
293                // continue testing other test vectors
294                System.out.println("Failed Test Vector: " + testValues[i]);
295                ex.printStackTrace();
296                testFailed = true;
297                continue;
298            }
299        }
300        if (testFailed) {
301            throw new Exception("Test Failed");
302        }
303        // passed all tests...hooray!
304        return true;
305    }
306
307    public static void main (String[] args) throws Exception {
308        TestKATForGCM test = new TestKATForGCM();
309        if (test.execute(testValues)) {
310            System.out.println("Test Passed!");
311        }
312    }
313}
314
315