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