/*
 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.crypto.provider;

import java.security.*;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;

KeyGeneratore core implementation and individual key generator implementations. Because of US export regulations, we cannot use subclassing to achieve code sharing between the key generator implementations for our various algorithms. Instead, we have the core implementation in this KeyGeneratorCore class, which is used by the individual implementations. See those further down in this file.
Author: Andreas Sterbenz
Since: 1.5
/** * KeyGeneratore core implementation and individual key generator * implementations. Because of US export regulations, we cannot use * subclassing to achieve code sharing between the key generator * implementations for our various algorithms. Instead, we have the * core implementation in this KeyGeneratorCore class, which is used * by the individual implementations. See those further down in this * file. * * @since 1.5 * @author Andreas Sterbenz */
final class KeyGeneratorCore { // algorithm name to use for the generator keys private final String name; // default key size in bits private final int defaultKeySize; // current key size in bits private int keySize; // PRNG to use private SecureRandom random;
Construct a new KeyGeneratorCore object with the specified name and defaultKeySize. Initialize to default key size in case the application does not call any of the init() methods.
/** * Construct a new KeyGeneratorCore object with the specified name * and defaultKeySize. Initialize to default key size in case the * application does not call any of the init() methods. */
KeyGeneratorCore(String name, int defaultKeySize) { this.name = name; this.defaultKeySize = defaultKeySize; implInit(null); } // implementation for engineInit(), see JCE doc // reset keySize to default void implInit(SecureRandom random) { this.keySize = defaultKeySize; this.random = random; } // implementation for engineInit(), see JCE doc // we do not support any parameters void implInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { throw new InvalidAlgorithmParameterException (name + " key generation does not take any parameters"); } // implementation for engineInit(), see JCE doc // we enforce a general 40 bit minimum key size for security void implInit(int keysize, SecureRandom random) { if (keysize < 40) { throw new InvalidParameterException ("Key length must be at least 40 bits"); } this.keySize = keysize; this.random = random; } // implementation for engineInit(), see JCE doc // generate the key SecretKey implGenerateKey() { if (random == null) { random = SunJCE.getRandom(); } byte[] b = new byte[(keySize + 7) >> 3]; random.nextBytes(b); return new SecretKeySpec(b, name); } // nested static classes for the HmacSHA-2 family of key generator abstract static class HmacSHA2KG extends KeyGeneratorSpi { private final KeyGeneratorCore core; protected HmacSHA2KG(String algoName, int len) { core = new KeyGeneratorCore(algoName, len); } @Override protected void engineInit(SecureRandom random) { core.implInit(random); } @Override protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { core.implInit(params, random); } @Override protected void engineInit(int keySize, SecureRandom random) { core.implInit(keySize, random); } @Override protected SecretKey engineGenerateKey() { return core.implGenerateKey(); } public static final class SHA224 extends HmacSHA2KG { public SHA224() { super("HmacSHA224", 224); } } public static final class SHA256 extends HmacSHA2KG { public SHA256() { super("HmacSHA256", 256); } } public static final class SHA384 extends HmacSHA2KG { public SHA384() { super("HmacSHA384", 384); } } public static final class SHA512 extends HmacSHA2KG { public SHA512() { super("HmacSHA512", 512); } } } // nested static class for the RC2 key generator public static final class RC2KeyGenerator extends KeyGeneratorSpi { private final KeyGeneratorCore core; public RC2KeyGenerator() { core = new KeyGeneratorCore("RC2", 128); } @Override protected void engineInit(SecureRandom random) { core.implInit(random); } @Override protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { core.implInit(params, random); } @Override protected void engineInit(int keySize, SecureRandom random) { if ((keySize < 40) || (keySize > 1024)) { throw new InvalidParameterException("Key length for RC2" + " must be between 40 and 1024 bits"); } core.implInit(keySize, random); } @Override protected SecretKey engineGenerateKey() { return core.implGenerateKey(); } } // nested static class for the ARCFOUR (RC4) key generator public static final class ARCFOURKeyGenerator extends KeyGeneratorSpi { private final KeyGeneratorCore core; public ARCFOURKeyGenerator() { core = new KeyGeneratorCore("ARCFOUR", 128); } @Override protected void engineInit(SecureRandom random) { core.implInit(random); } @Override protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { core.implInit(params, random); } @Override protected void engineInit(int keySize, SecureRandom random) { if ((keySize < 40) || (keySize > 1024)) { throw new InvalidParameterException("Key length for ARCFOUR" + " must be between 40 and 1024 bits"); } core.implInit(keySize, random); } @Override protected SecretKey engineGenerateKey() { return core.implGenerateKey(); } } // nested static class for the ChaCha20 key generator public static final class ChaCha20KeyGenerator extends KeyGeneratorSpi { private final KeyGeneratorCore core; public ChaCha20KeyGenerator() { core = new KeyGeneratorCore("ChaCha20", 256); } @Override protected void engineInit(SecureRandom random) { core.implInit(random); } @Override protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { core.implInit(params, random); } @Override protected void engineInit(int keySize, SecureRandom random) { if (keySize != 256) { throw new InvalidParameterException( "Key length for ChaCha20 must be 256 bits"); } core.implInit(keySize, random); } @Override protected SecretKey engineGenerateKey() { return core.implGenerateKey(); } } }