// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.jcajce.provider.kdf.pbepbkdf2;

import org.bouncycastle.crypto.digests.SHA224Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.digests.SHA512tDigest;
import org.bouncycastle.crypto.digests.GOST3411Digest;
import org.bouncycastle.crypto.digests.SHA3Digest;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.params.KeyParameter;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.InvalidAlgorithmParameterException;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.SHA1Digest;
import javax.crypto.KDFParameters;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.PasswordConverter;
import javax.crypto.KDFSpi;

class PBEPBKDF2Spi extends KDFSpi
{
    final PasswordConverter pwdConverter;
    final PKCS5S2ParametersGenerator generator;
    
    protected PBEPBKDF2Spi(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
        this(kdfParameters, new SHA1Digest(), PasswordConverter.UTF8);
    }
    
    protected PBEPBKDF2Spi(final KDFParameters kdfParameters, final Digest digest) throws InvalidAlgorithmParameterException {
        this(kdfParameters, digest, PasswordConverter.UTF8);
    }
    
    protected PBEPBKDF2Spi(final KDFParameters kdfParameters, final Digest digest, final PasswordConverter pwdConverter) throws InvalidAlgorithmParameterException {
        super(requireNull(kdfParameters, "PBEPBKDF2 does not support parameters"));
        this.pwdConverter = pwdConverter;
        this.generator = new PKCS5S2ParametersGenerator(digest);
    }
    
    protected KDFParameters engineGetParameters() {
        return null;
    }
    
    protected SecretKey engineDeriveKey(final String algorithm, final AlgorithmParameterSpec algorithmParameterSpec) throws InvalidAlgorithmParameterException, NoSuchAlgorithmException {
        return new SecretKeySpec(this.engineDeriveData(algorithmParameterSpec), algorithm);
    }
    
    protected byte[] engineDeriveData(final AlgorithmParameterSpec algorithmParameterSpec) throws InvalidAlgorithmParameterException {
        if (!(algorithmParameterSpec instanceof PBEKeySpec)) {
            throw new InvalidAlgorithmParameterException("Invalid AlgorithmParameterSpec provided");
        }
        final PBEKeySpec pbeKeySpec = (PBEKeySpec)algorithmParameterSpec;
        final char[] password = pbeKeySpec.getPassword();
        final byte[] salt = pbeKeySpec.getSalt();
        final int iterationCount = pbeKeySpec.getIterationCount();
        final int keyLength = pbeKeySpec.getKeyLength();
        if (password == null || salt == null) {
            throw new InvalidAlgorithmParameterException("Password and salt cannot be null");
        }
        this.generator.init(this.pwdConverter.convert(password), salt, iterationCount);
        final byte[] key = ((KeyParameter)this.generator.generateDerivedParameters(keyLength)).getKey();
        Arrays.fill(password, '\0');
        return key;
    }
    
    private static KDFParameters requireNull(final KDFParameters kdfParameters, final String msg) throws InvalidAlgorithmParameterException {
        if (kdfParameters != null) {
            throw new InvalidAlgorithmParameterException(msg);
        }
        return null;
    }
    
    public static class PBKDF2withSM3 extends PBEPBKDF2Spi
    {
        public PBKDF2withSM3(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SM3Digest());
        }
        
        public PBKDF2withSM3() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2with8BIT extends PBEPBKDF2Spi
    {
        public PBKDF2with8BIT(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA1Digest(), PasswordConverter.ASCII);
        }
        
        public PBKDF2with8BIT() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA3_512 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA3_512(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA3Digest(512));
        }
        
        public PBKDF2withSHA3_512() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA3_384 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA3_384(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA3Digest(384));
        }
        
        public PBKDF2withSHA3_384() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA3_256 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA3_256(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA3Digest(256));
        }
        
        public PBKDF2withSHA3_256() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA3_224 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA3_224(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA3Digest(224));
        }
        
        public PBKDF2withSHA3_224() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withGOST3411 extends PBEPBKDF2Spi
    {
        public PBKDF2withGOST3411(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new GOST3411Digest());
        }
        
        public PBKDF2withGOST3411() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA512_256 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA512_256(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA512tDigest(256));
        }
        
        public PBKDF2withSHA512_256() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA512_224 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA512_224(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA512tDigest(224));
        }
        
        public PBKDF2withSHA512_224() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA512 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA512(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA512Digest());
        }
        
        public PBKDF2withSHA512() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA384 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA384(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA384Digest());
        }
        
        public PBKDF2withSHA384() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA256 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA256(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA256Digest());
        }
        
        public PBKDF2withSHA256() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withSHA224 extends PBEPBKDF2Spi
    {
        public PBKDF2withSHA224(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA224Digest());
        }
        
        public PBKDF2withSHA224() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
    
    public static class PBKDF2withUTF8 extends PBEPBKDF2Spi
    {
        public PBKDF2withUTF8(final KDFParameters kdfParameters) throws InvalidAlgorithmParameterException {
            super(kdfParameters, (Digest)new SHA1Digest());
        }
        
        public PBKDF2withUTF8() throws InvalidAlgorithmParameterException {
            this(null);
        }
    }
}
