1 /* 2 * Copyright (c) 2003, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.crypto.provider; 27 28 import java.security.*; 29 import java.security.spec.AlgorithmParameterSpec; 30 31 import javax.crypto.*; 32 import javax.crypto.spec.SecretKeySpec; 33 34 /** 35 * KeyGeneratore core implementation and individual key generator 36 * implementations. Because of US export regulations, we cannot use 37 * subclassing to achieve code sharing between the key generator 38 * implementations for our various algorithms. Instead, we have the 39 * core implementation in this KeyGeneratorCore class, which is used 40 * by the individual implementations. See those further down in this 41 * file. 42 * 43 * @since 1.5 44 * @author Andreas Sterbenz 45 */ 46 final class KeyGeneratorCore { 47 48 // algorithm name to use for the generator keys 49 private final String name; 50 51 // default key size in bits 52 private final int defaultKeySize; 53 54 // current key size in bits 55 private int keySize; 56 57 // PRNG to use 58 private SecureRandom random; 59 60 /** 61 * Construct a new KeyGeneratorCore object with the specified name 62 * and defaultKeySize. Initialize to default key size in case the 63 * application does not call any of the init() methods. 64 */ 65 KeyGeneratorCore(String name, int defaultKeySize) { 66 this.name = name; 67 this.defaultKeySize = defaultKeySize; 68 implInit(null); 69 } 70 71 // implementation for engineInit(), see JCE doc 72 // reset keySize to default 73 void implInit(SecureRandom random) { 74 this.keySize = defaultKeySize; 75 this.random = random; 76 } 77 78 // implementation for engineInit(), see JCE doc 79 // we do not support any parameters 80 void implInit(AlgorithmParameterSpec params, SecureRandom random) 81 throws InvalidAlgorithmParameterException { 82 throw new InvalidAlgorithmParameterException 83 (name + " key generation does not take any parameters"); 84 } 85 86 // implementation for engineInit(), see JCE doc 87 // we enforce a general 40 bit minimum key size for security 88 void implInit(int keysize, SecureRandom random) { 89 if (keysize < 40) { 90 throw new InvalidParameterException 91 ("Key length must be at least 40 bits"); 92 } 93 this.keySize = keysize; 94 this.random = random; 95 } 96 97 // implementation for engineInit(), see JCE doc 98 // generate the key 99 SecretKey implGenerateKey() { 100 if (random == null) { 101 random = SunJCE.getRandom(); 102 } 103 byte[] b = new byte[(keySize + 7) >> 3]; 104 random.nextBytes(b); 105 return new SecretKeySpec(b, name); 106 } 107 108 // nested static classes for the HmacSHA-2 family of key generator 109 abstract static class HmacSHA2KG extends KeyGeneratorSpi { 110 private final KeyGeneratorCore core; 111 protected HmacSHA2KG(String algoName, int len) { 112 core = new KeyGeneratorCore(algoName, len); 113 } 114 protected void engineInit(SecureRandom random) { 115 core.implInit(random); 116 } 117 protected void engineInit(AlgorithmParameterSpec params, 118 SecureRandom random) throws InvalidAlgorithmParameterException { 119 core.implInit(params, random); 120 } 121 protected void engineInit(int keySize, SecureRandom random) { 122 core.implInit(keySize, random); 123 } 124 protected SecretKey engineGenerateKey() { 125 return core.implGenerateKey(); 126 } 127 128 public static final class SHA224 extends HmacSHA2KG { 129 public SHA224() { 130 super("HmacSHA224", 224); 131 } 132 } 133 public static final class SHA256 extends HmacSHA2KG { 134 public SHA256() { 135 super("HmacSHA256", 256); 136 } 137 } 138 public static final class SHA384 extends HmacSHA2KG { 139 public SHA384() { 140 super("HmacSHA384", 384); 141 } 142 } 143 public static final class SHA512 extends HmacSHA2KG { 144 public SHA512() { 145 super("HmacSHA512", 512); 146 } 147 } 148 } 149 150 // nested static class for the RC2 key generator 151 public static final class RC2KeyGenerator extends KeyGeneratorSpi { 152 private final KeyGeneratorCore core; 153 public RC2KeyGenerator() { 154 core = new KeyGeneratorCore("RC2", 128); 155 } 156 protected void engineInit(SecureRandom random) { 157 core.implInit(random); 158 } 159 protected void engineInit(AlgorithmParameterSpec params, 160 SecureRandom random) throws InvalidAlgorithmParameterException { 161 core.implInit(params, random); 162 } 163 protected void engineInit(int keySize, SecureRandom random) { 164 if ((keySize < 40) || (keySize > 1024)) { 165 throw new InvalidParameterException("Key length for RC2" 166 + " must be between 40 and 1024 bits"); 167 } 168 core.implInit(keySize, random); 169 } 170 protected SecretKey engineGenerateKey() { 171 return core.implGenerateKey(); 172 } 173 } 174 175 // nested static class for the ARCFOUR (RC4) key generator 176 public static final class ARCFOURKeyGenerator extends KeyGeneratorSpi { 177 private final KeyGeneratorCore core; 178 public ARCFOURKeyGenerator() { 179 core = new KeyGeneratorCore("ARCFOUR", 128); 180 } 181 protected void engineInit(SecureRandom random) { 182 core.implInit(random); 183 } 184 protected void engineInit(AlgorithmParameterSpec params, 185 SecureRandom random) throws InvalidAlgorithmParameterException { 186 core.implInit(params, random); 187 } 188 protected void engineInit(int keySize, SecureRandom random) { 189 if ((keySize < 40) || (keySize > 1024)) { 190 throw new InvalidParameterException("Key length for ARCFOUR" 191 + " must be between 40 and 1024 bits"); 192 } 193 core.implInit(keySize, random); 194 } 195 protected SecretKey engineGenerateKey() { 196 return core.implGenerateKey(); 197 } 198 } 199 200 }