jdk/test/com/sun/crypto/provider/Cipher/AES/TestGHASH.java
changeset 28851 e4c16ed7bffa
child 31462 1d0b519af651
equal deleted inserted replaced
28850:4996a75e8bfb 28851:e4c16ed7bffa
       
     1 /*
       
     2  * Copyright (c) 2015, Red Hat, Inc.
       
     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 8069072
       
    27  * @summary Test vectors for com.sun.crypto.provider.GHASH
       
    28  */
       
    29 import java.lang.reflect.Constructor;
       
    30 import java.lang.reflect.Method;
       
    31 import java.nio.ByteBuffer;
       
    32 
       
    33 public class TestGHASH {
       
    34 
       
    35     private final Constructor<?> GHASH;
       
    36     private final Method UPDATE;
       
    37     private final Method DIGEST;
       
    38 
       
    39     TestGHASH(String className) throws Exception {
       
    40         Class<?> cls = Class.forName(className);
       
    41         GHASH = cls.getDeclaredConstructor(byte[].class);
       
    42         GHASH.setAccessible(true);
       
    43         UPDATE = cls.getDeclaredMethod("update", byte[].class);
       
    44         UPDATE.setAccessible(true);
       
    45         DIGEST = cls.getDeclaredMethod("digest");
       
    46         DIGEST.setAccessible(true);
       
    47     }
       
    48 
       
    49 
       
    50     private Object newGHASH(byte[] H) throws Exception {
       
    51         return GHASH.newInstance(H);
       
    52     }
       
    53 
       
    54     private void updateGHASH(Object hash, byte[] data)
       
    55             throws Exception {
       
    56         UPDATE.invoke(hash, data);
       
    57     }
       
    58 
       
    59     private byte[] digestGHASH(Object hash) throws Exception {
       
    60         return (byte[]) DIGEST.invoke(hash);
       
    61     }
       
    62 
       
    63     private static final String HEX_DIGITS = "0123456789abcdef";
       
    64 
       
    65     private static String hex(byte[] bs) {
       
    66         StringBuilder sb = new StringBuilder(2 * bs.length);
       
    67         for (byte b : bs) {
       
    68             sb.append(HEX_DIGITS.charAt((b >> 4) & 0xF));
       
    69             sb.append(HEX_DIGITS.charAt(b & 0xF));
       
    70         }
       
    71         return sb.toString();
       
    72     }
       
    73 
       
    74     private static byte[] bytes(String hex) {
       
    75         if ((hex.length() & 1) != 0) {
       
    76             throw new AssertionError();
       
    77         }
       
    78         byte[] result = new byte[hex.length() / 2];
       
    79         for (int i = 0; i < result.length; ++i) {
       
    80             int a = HEX_DIGITS.indexOf(hex.charAt(2 * i));
       
    81             int b = HEX_DIGITS.indexOf(hex.charAt(2 * i + 1));
       
    82             if ((a | b) < 0) {
       
    83                 if (a < 0) {
       
    84                     throw new AssertionError(
       
    85                             "bad character " + (int) hex.charAt(2 * i));
       
    86                 }
       
    87                 throw new AssertionError(
       
    88                         "bad character " + (int) hex.charAt(2 * i + 1));
       
    89             }
       
    90             result[i] = (byte) ((a << 4) | b);
       
    91         }
       
    92         return result;
       
    93     }
       
    94 
       
    95     private static byte[] bytes(long L0, long L1) {
       
    96         return ByteBuffer.allocate(16)
       
    97                 .putLong(L0)
       
    98                 .putLong(L1)
       
    99                 .array();
       
   100     }
       
   101 
       
   102     private void check(int testCase, String H, String A,
       
   103             String C, String expected) throws Exception {
       
   104         int lenA = A.length() * 4;
       
   105         while ((A.length() % 32) != 0) {
       
   106             A += '0';
       
   107         }
       
   108         int lenC = C.length() * 4;
       
   109         while ((C.length() % 32) != 0) {
       
   110             C += '0';
       
   111         }
       
   112 
       
   113         Object hash = newGHASH(bytes(H));
       
   114         updateGHASH(hash, bytes(A));
       
   115         updateGHASH(hash, bytes(C));
       
   116         updateGHASH(hash, bytes(lenA, lenC));
       
   117         byte[] digest = digestGHASH(hash);
       
   118         String actual = hex(digest);
       
   119         if (!expected.equals(actual)) {
       
   120             throw new AssertionError(String.format("%d: expected %s, got %s",
       
   121                     testCase, expected, actual));
       
   122         }
       
   123     }
       
   124 
       
   125     public static void main(String[] args) throws Exception {
       
   126         TestGHASH test;
       
   127         if (args.length == 0) {
       
   128             test = new TestGHASH("com.sun.crypto.provider.GHASH");
       
   129         } else {
       
   130             test = new TestGHASH(args[0]);
       
   131         }
       
   132 
       
   133         // Test vectors from David A. McGrew, John Viega,
       
   134         // "The Galois/Counter Mode of Operation (GCM)", 2005.
       
   135         // <http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf>
       
   136 
       
   137         test.check(1, "66e94bd4ef8a2c3b884cfa59ca342b2e", "", "",
       
   138                 "00000000000000000000000000000000");
       
   139         test.check(2,
       
   140                 "66e94bd4ef8a2c3b884cfa59ca342b2e", "",
       
   141                 "0388dace60b6a392f328c2b971b2fe78",
       
   142                 "f38cbb1ad69223dcc3457ae5b6b0f885");
       
   143         test.check(3,
       
   144                 "b83b533708bf535d0aa6e52980d53b78", "",
       
   145                 "42831ec2217774244b7221b784d0d49c" +
       
   146                 "e3aa212f2c02a4e035c17e2329aca12e" +
       
   147                 "21d514b25466931c7d8f6a5aac84aa05" +
       
   148                 "1ba30b396a0aac973d58e091473f5985",
       
   149                 "7f1b32b81b820d02614f8895ac1d4eac");
       
   150         test.check(4,
       
   151                 "b83b533708bf535d0aa6e52980d53b78",
       
   152                 "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
       
   153                 "42831ec2217774244b7221b784d0d49c" +
       
   154                 "e3aa212f2c02a4e035c17e2329aca12e" +
       
   155                 "21d514b25466931c7d8f6a5aac84aa05" +
       
   156                 "1ba30b396a0aac973d58e091",
       
   157                 "698e57f70e6ecc7fd9463b7260a9ae5f");
       
   158         test.check(5, "b83b533708bf535d0aa6e52980d53b78",
       
   159                 "feedfacedeadbeeffeedfacedeadbeef" + "abaddad2",
       
   160                 "61353b4c2806934a777ff51fa22a4755" +
       
   161                 "699b2a714fcdc6f83766e5f97b6c7423" +
       
   162                 "73806900e49f24b22b097544d4896b42" +
       
   163                 "4989b5e1ebac0f07c23f4598",
       
   164                 "df586bb4c249b92cb6922877e444d37b");
       
   165     }
       
   166 }