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