1 /* 2 * Copyright (c) 2018, 2019, 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 8080462 27 * @library /test/lib .. 28 * @modules jdk.crypto.cryptoki 29 * @run main TestKATForGCM 30 * @summary Known Answer Test for AES cipher with GCM mode support in 31 * PKCS11 provider. 32 */ 33 import java.security.GeneralSecurityException; 34 import java.security.Provider; 35 import java.util.Arrays; 36 import javax.crypto.Cipher; 37 import javax.crypto.SecretKey; 38 import javax.crypto.spec.GCMParameterSpec; 39 import javax.crypto.spec.SecretKeySpec; 40 41 public class TestKATForGCM extends PKCS11Test { 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 217 "d74e99d1bdaa712864eec422ac507bddbe2b0d4633cd3dff29ce5059b49fe868526c59a2a3a604457bc2afea866e7606", 218 "ba80e244b7fc9025cd031d0f63677e06", 219 "d84a8c3eac57d1bb0e890a8f461d1065"), 220 new TestVector("bd7c5c63b7542b56a00ebe71336a1588", 221 "87721f23ba9c3c8ea5571abc", 222 "de15ddbb1e202161e8a79af6a55ac6f3", 223 224 "a6ec8075a0d3370eb7598918f3b93e48444751624997b899a87fa6a9939f844e008aa8b70e9f4c3b1a19d3286bf543e7127bfecba1ad17a5ec53fccc26faecacc4c75369498eaa7d706aef634d0009279b11e4ba6c993e5e9ed9", 225 "41eb28c0fee4d762de972361c863bc80", 226 "9cb567220d0b252eb97bff46e4b00ff8"), 227 // 8/1024-bit iv w/ 128-bit tag, no plain text, no aad 228 new TestVector("1672c3537afa82004c6b8a46f6f0d026", 229 "05", 230 null, null, null, 231 "8e2ad721f9455f74d8b53d3141f27e8e"), 232 new TestVector("d0f1f4defa1e8c08b4b26d576392027c", 233 234 "42b4f01eb9f5a1ea5b1eb73b0fb0baed54f387ecaa0393c7d7dffc6af50146ecc021abf7eb9038d4303d91f8d741a11743166c0860208bcc02c6258fd9511a2fa626f96d60b72fcff773af4e88e7a923506e4916ecbd814651e9f445adef4ad6a6b6c7290cc13b956130eef5b837c939fcac0cbbcc9656cd75b13823ee5acdac", 235 null, null, null, 236 "7ab49b57ddf5f62c427950111c5c4f0d"), 237 // 8-bit iv w/ 128-bit tag, 13-byte plain text, 90-byte aad 238 new TestVector("9f79239f0904eace50784b863e723f6b", 239 "d9", 240 "bdb0bb10c87965acd34d146171", 241 242 "44db436089327726c5f01139e1f339735c9e85514ccc2f167bad728010fb34a9072a9794c8a5e7361b1d0dbcdc9ac4091e354bb2896561f0486645252e9c78c86beece91bfa4f7cc4a8794ce1f305b1b735efdbf1ed1563c0be0", 243 "7e5a7c8dadb3f0c7335b4d9d8d", 244 "6b6ef1f53723a89f3bb7c6d043840717"), 245 // 1024-bit iv w/ 128-bit tag, 51-byte plain text, 48-byte aad 246 new TestVector("141f1ce91989b07e7eb6ae1dbd81ea5e", 247 248 "49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e194aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e57df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470dee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea2e8f05dd3a1396f", 249 250 "d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec2fe87719dadf1eb0aef212b51e74c9c5b934104a43", 251 252 "630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba323951727666c947a21894a079ef061ee159c05beeb4", 253 254 "f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83240446b28dc088abd42b0fc687f208190ff24c0548", 255 "dbb93bbb56d0439cd09f620a57687f5d"), 256 }; 257 258 public boolean execute(TestVector[] testValues, Cipher c) throws Exception { 259 boolean testFailed = false; 260 for (int i = 0; i < testValues.length; i++) { 261 try { 262 c.init(Cipher.ENCRYPT_MODE, testValues[i].key, testValues[i].spec); 263 c.updateAAD(testValues[i].aad); 264 byte[] ctPlusTag = c.doFinal(testValues[i].plainText); 265 266 c.init(Cipher.DECRYPT_MODE, testValues[i].key, testValues[i].spec); 267 c.updateAAD(testValues[i].aad); 268 byte[] pt = c.doFinal(ctPlusTag); // should fail if tag mismatched 269 270 // check encryption/decryption results just to be sure 271 if (!Arrays.equals(testValues[i].plainText, pt)) { 272 System.out.println("PlainText diff failed for test# " + i); 273 testFailed = true; 274 } 275 int ctLen = testValues[i].cipherText.length; 276 if (!Arrays.equals(testValues[i].cipherText, 277 Arrays.copyOf(ctPlusTag, ctLen))) { 278 System.out.println("CipherText diff failed for test# " + i); 279 testFailed = true; 280 } 281 int tagLen = testValues[i].tag.length; 282 if (!Arrays.equals 283 (testValues[i].tag, 284 Arrays.copyOfRange(ctPlusTag, ctLen, ctLen+tagLen))) { 285 System.out.println("Tag diff failed for test# " + i); 286 testFailed = true; 287 } 288 } catch (Exception ex) { 289 // continue testing other test vectors 290 System.out.println("Failed Test Vector: " + testValues[i]); 291 ex.printStackTrace(); 292 testFailed = true; 293 continue; 294 } 295 } 296 if (testFailed) { 297 throw new Exception("Test Failed"); 298 } 299 // passed all tests...hooray! 300 return true; 301 } 302 303 public static void main(String[] args) throws Exception { 304 main(new TestKATForGCM(), args); 305 } 306 307 @Override 308 public void main(Provider p) throws Exception { 309 Cipher c; 310 String transformation = "AES/GCM/NoPadding"; 311 try { 312 c = Cipher.getInstance(transformation, p); 313 } catch (GeneralSecurityException e) { 314 System.out.println("Skip testing " + p.getName() + 315 ", no support for " + transformation); 316 return; 317 } 318 try { 319 if (execute(testValues, c)) { 320 System.out.println("Test Passed!"); 321 } 322 } catch (Exception e) { 323 System.out.println("Exception occured using " + p.getName() + " version " + p.getVersionStr()); 324 325 if (isNSS(p)) { 326 double ver = getNSSInfo("nss"); 327 String osName = System.getProperty("os.name"); 328 if (ver > 3.139 && ver < 3.15 && osName.equals("Linux")) { 329 // warn about buggy behaviour on Linux with nss 3.14 330 System.out.println("Warning: old NSS " + ver + " might be problematic, consider upgrading it"); 331 } 332 } 333 throw e; 334 } 335 } 336 } 337