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