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