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