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 31 import java.security.*; 32 import javax.crypto.*; 33 import javax.crypto.spec.*; 34 import java.math.*; 35 36 import java.util.*; 37 38 public 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