1 /*
   2  * Copyright (c) 2015, 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 import java.io.PrintStream;
  25 import java.lang.String;
  26 import java.lang.System;
  27 import java.security.Provider;
  28 import java.security.SecureRandom;
  29 import java.security.Security;
  30 import javax.crypto.KeyGenerator;
  31 import static java.lang.System.out;
  32 
  33 /*
  34  * @test
  35  * @bug 8048607
  36  * @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java
  37  * @summary Test key generation of DES and DESEDE
  38  */
  39 public class TestKGParity {
  40 
  41     private static final String[] ALGORITHM_ARR = {
  42         "deS", "DesEDE"
  43     };
  44 
  45     public static void main(String argv[]) throws Exception {
  46 
  47         TestKGParity test = new TestKGParity();
  48         test.run();
  49     }
  50 
  51     private void run() throws Exception {
  52         Provider[] providers = Security.getProviders();
  53         for (Provider p : providers) {
  54             String prvName = p.getName();
  55             if (prvName.startsWith("SunJCE")
  56                     || prvName.startsWith("SunPKCS11-")) {
  57                 for (String algorithm : ALGORITHM_ARR) {
  58                     if (!runTest(p, algorithm)) {
  59                         throw new RuntimeException(
  60                                 "Test failed with provider/algorithm:"
  61                                         + p.getName() + "/" + algorithm);
  62                     } else {
  63                         out.println("Test passed with provider/algorithm:"
  64                                 + p.getName() + "/" + algorithm);
  65                     }
  66                 }
  67             }
  68         }
  69     }
  70 
  71     public boolean runTest(Provider p, String algo) throws Exception {
  72         byte[] keyValue = null;
  73         try {
  74             // Initialization
  75             SecureRandom sRdm = new SecureRandom();
  76             KeyGenerator kg = KeyGenerator.getInstance(algo, p);
  77             kg.init(sRdm);
  78 
  79             // Generate a SecretKey and retrieve its value
  80             keyValue = kg.generateKey().getEncoded();
  81 
  82             // Verify its parity in the unit of byte
  83             for (int i = 0; i < keyValue.length; i++) {
  84                 if (!checkParity(keyValue[i])) {
  85                     out.println("Testing: "
  86                         + p.getName()
  87                         + "/"
  88                         + algo
  89                         + " failed when verify its parity in the unit of byte:"
  90                         + TestUtility.hexDump(keyValue, i));
  91                     return false;
  92                 }
  93             }
  94             return true;
  95         } catch (Exception ex) {
  96             out.println("Testing: " + p.getName() + "/" + algo
  97                     + " failed with unexpected exception");
  98             ex.printStackTrace();
  99             throw ex;
 100         }
 101     }
 102 
 103     private boolean checkParity(byte keyByte) {
 104         boolean even = false;
 105         byte[] PARITY_BIT_MASK = {
 106                 (byte) 0x40, (byte) 0x20, (byte) 0x10, (byte) 0x08,
 107                 (byte) 0x04, (byte) 0x02, (byte) 0x01
 108         };
 109 
 110         for (int i = 0; i < 7; i++) {
 111             if ((keyByte & PARITY_BIT_MASK[i]) > 0) {
 112                 even = !even;
 113             }
 114         }
 115         if (keyByte < 0) {
 116             even = !even;
 117         }
 118 
 119         return even;
 120     }
 121 }