1 /* 2 * Copyright (c) 2003, 2020, 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 */ KeyGeneratorCore(String name, int defaultKeySize)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 implInit(SecureRandom random)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 implInit(AlgorithmParameterSpec params, SecureRandom random)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 implInit(int keysize, SecureRandom random)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 implGenerateKey()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 Hmac key generator 109 abstract static class HmacKG extends KeyGeneratorSpi { 110 private final KeyGeneratorCore core; HmacKG(String algoName, int len)111 protected HmacKG(String algoName, int len) { 112 core = new KeyGeneratorCore(algoName, len); 113 } 114 @Override engineInit(SecureRandom random)115 protected void engineInit(SecureRandom random) { 116 core.implInit(random); 117 } 118 @Override engineInit(AlgorithmParameterSpec params, SecureRandom random)119 protected void engineInit(AlgorithmParameterSpec params, 120 SecureRandom random) throws InvalidAlgorithmParameterException { 121 core.implInit(params, random); 122 } 123 @Override engineInit(int keySize, SecureRandom random)124 protected void engineInit(int keySize, SecureRandom random) { 125 core.implInit(keySize, random); 126 } 127 @Override engineGenerateKey()128 protected SecretKey engineGenerateKey() { 129 return core.implGenerateKey(); 130 } 131 132 public static final class SHA224 extends HmacKG { SHA224()133 public SHA224() { 134 super("HmacSHA224", 224); 135 } 136 } 137 public static final class SHA256 extends HmacKG { SHA256()138 public SHA256() { 139 super("HmacSHA256", 256); 140 } 141 } 142 public static final class SHA384 extends HmacKG { SHA384()143 public SHA384() { 144 super("HmacSHA384", 384); 145 } 146 } 147 public static final class SHA512 extends HmacKG { SHA512()148 public SHA512() { 149 super("HmacSHA512", 512); 150 } 151 } 152 public static final class SHA512_224 extends HmacKG { SHA512_224()153 public SHA512_224() { 154 super("HmacSHA512/224", 224); 155 } 156 } 157 public static final class SHA512_256 extends HmacKG { SHA512_256()158 public SHA512_256() { 159 super("HmacSHA512/256", 256); 160 } 161 } 162 public static final class SHA3_224 extends HmacKG { SHA3_224()163 public SHA3_224() { 164 super("HmacSHA3-224", 224); 165 } 166 } 167 public static final class SHA3_256 extends HmacKG { SHA3_256()168 public SHA3_256() { 169 super("HmacSHA3-256", 256); 170 } 171 } 172 public static final class SHA3_384 extends HmacKG { SHA3_384()173 public SHA3_384() { 174 super("HmacSHA3-384", 384); 175 } 176 } 177 public static final class SHA3_512 extends HmacKG { SHA3_512()178 public SHA3_512() { 179 super("HmacSHA3-512", 512); 180 } 181 } 182 } 183 184 // nested static class for the RC2 key generator 185 public static final class RC2KeyGenerator extends KeyGeneratorSpi { 186 private final KeyGeneratorCore core; RC2KeyGenerator()187 public RC2KeyGenerator() { 188 core = new KeyGeneratorCore("RC2", 128); 189 } 190 @Override engineInit(SecureRandom random)191 protected void engineInit(SecureRandom random) { 192 core.implInit(random); 193 } 194 @Override engineInit(AlgorithmParameterSpec params, SecureRandom random)195 protected void engineInit(AlgorithmParameterSpec params, 196 SecureRandom random) throws InvalidAlgorithmParameterException { 197 core.implInit(params, random); 198 } 199 @Override engineInit(int keySize, SecureRandom random)200 protected void engineInit(int keySize, SecureRandom random) { 201 if ((keySize < 40) || (keySize > 1024)) { 202 throw new InvalidParameterException("Key length for RC2" 203 + " must be between 40 and 1024 bits"); 204 } 205 core.implInit(keySize, random); 206 } 207 @Override engineGenerateKey()208 protected SecretKey engineGenerateKey() { 209 return core.implGenerateKey(); 210 } 211 } 212 213 // nested static class for the ARCFOUR (RC4) key generator 214 public static final class ARCFOURKeyGenerator extends KeyGeneratorSpi { 215 private final KeyGeneratorCore core; ARCFOURKeyGenerator()216 public ARCFOURKeyGenerator() { 217 core = new KeyGeneratorCore("ARCFOUR", 128); 218 } 219 @Override engineInit(SecureRandom random)220 protected void engineInit(SecureRandom random) { 221 core.implInit(random); 222 } 223 @Override engineInit(AlgorithmParameterSpec params, SecureRandom random)224 protected void engineInit(AlgorithmParameterSpec params, 225 SecureRandom random) throws InvalidAlgorithmParameterException { 226 core.implInit(params, random); 227 } 228 @Override engineInit(int keySize, SecureRandom random)229 protected void engineInit(int keySize, SecureRandom random) { 230 if ((keySize < 40) || (keySize > 1024)) { 231 throw new InvalidParameterException("Key length for ARCFOUR" 232 + " must be between 40 and 1024 bits"); 233 } 234 core.implInit(keySize, random); 235 } 236 @Override engineGenerateKey()237 protected SecretKey engineGenerateKey() { 238 return core.implGenerateKey(); 239 } 240 } 241 242 // nested static class for the ChaCha20 key generator 243 public static final class ChaCha20KeyGenerator extends KeyGeneratorSpi { 244 private final KeyGeneratorCore core; ChaCha20KeyGenerator()245 public ChaCha20KeyGenerator() { 246 core = new KeyGeneratorCore("ChaCha20", 256); 247 } 248 @Override engineInit(SecureRandom random)249 protected void engineInit(SecureRandom random) { 250 core.implInit(random); 251 } 252 @Override engineInit(AlgorithmParameterSpec params, SecureRandom random)253 protected void engineInit(AlgorithmParameterSpec params, 254 SecureRandom random) throws InvalidAlgorithmParameterException { 255 core.implInit(params, random); 256 } 257 @Override engineInit(int keySize, SecureRandom random)258 protected void engineInit(int keySize, SecureRandom random) { 259 if (keySize != 256) { 260 throw new InvalidParameterException( 261 "Key length for ChaCha20 must be 256 bits"); 262 } 263 core.implInit(keySize, random); 264 } 265 @Override engineGenerateKey()266 protected SecretKey engineGenerateKey() { 267 return core.implGenerateKey(); 268 } 269 } 270 } 271