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