package com.sun.crypto.provider;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
final class KeyGeneratorCore {
private final String name;
private final int defaultKeySize;
private int keySize;
private SecureRandom random;
KeyGeneratorCore(String name, int defaultKeySize) {
this.name = name;
this.defaultKeySize = defaultKeySize;
implInit(null);
}
void implInit(SecureRandom random) {
this.keySize = defaultKeySize;
this.random = random;
}
void implInit(AlgorithmParameterSpec params, SecureRandom random)
throws InvalidAlgorithmParameterException {
throw new InvalidAlgorithmParameterException
(name + " key generation does not take any parameters");
}
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;
}
SecretKey implGenerateKey() {
if (random == null) {
random = SunJCE.getRandom();
}
byte[] b = new byte[(keySize + 7) >> 3];
random.nextBytes(b);
try {
return new SecretKeySpec(b, name);
} finally {
Arrays.fill(b, (byte)0);
}
}
abstract static class HmacKG extends KeyGeneratorSpi {
private final KeyGeneratorCore core;
protected HmacKG(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 HmacKG {
public SHA224() {
super("HmacSHA224", 224);
}
}
public static final class SHA256 extends HmacKG {
public SHA256() {
super("HmacSHA256", 256);
}
}
public static final class SHA384 extends HmacKG {
public SHA384() {
super("HmacSHA384", 384);
}
}
public static final class SHA512 extends HmacKG {
public SHA512() {
super("HmacSHA512", 512);
}
}
public static final class SHA512_224 extends HmacKG {
public SHA512_224() {
super("HmacSHA512/224", 224);
}
}
public static final class SHA512_256 extends HmacKG {
public SHA512_256() {
super("HmacSHA512/256", 256);
}
}
public static final class SHA3_224 extends HmacKG {
public SHA3_224() {
super("HmacSHA3-224", 224);
}
}
public static final class SHA3_256 extends HmacKG {
public SHA3_256() {
super("HmacSHA3-256", 256);
}
}
public static final class SHA3_384 extends HmacKG {
public SHA3_384() {
super("HmacSHA3-384", 384);
}
}
public static final class SHA3_512 extends HmacKG {
public SHA3_512() {
super("HmacSHA3-512", 512);
}
}
}
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();
}
}
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();
}
}
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();
}
}
}