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

package org.bouncycastle.jcajce.provider.symmetric;

import org.bouncycastle.jcajce.provider.config.ConfigurableProvider;
import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import java.security.InvalidAlgorithmParameterException;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.DerivationParameters;
import org.bouncycastle.crypto.params.HKDFParameters;
import java.security.spec.InvalidKeySpecException;
import org.bouncycastle.jcajce.spec.HKDFParameterSpec;
import javax.crypto.SecretKey;
import java.security.spec.KeySpec;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.generators.HKDFBytesGenerator;
import org.bouncycastle.jcajce.provider.symmetric.util.BaseSecretKeyFactory;

public class HKDF
{
    private HKDF() {
    }
    
    public static class HKDFBase extends BaseSecretKeyFactory
    {
        protected String algName;
        protected HKDFBytesGenerator hkdf;
        
        public HKDFBase(final String algName, final Digest digest, final ASN1ObjectIdentifier asn1ObjectIdentifier) {
            super(algName, asn1ObjectIdentifier);
            this.algName = algName;
            this.hkdf = new HKDFBytesGenerator(digest);
        }
        
        @Override
        protected SecretKey engineGenerateSecret(final KeySpec keySpec) throws InvalidKeySpecException {
            if (!(keySpec instanceof HKDFParameterSpec)) {
                throw new InvalidKeySpecException("invalid KeySpec: expected HKDFParameterSpec, but got " + keySpec.getClass().getName());
            }
            final HKDFParameterSpec hkdfParameterSpec = (HKDFParameterSpec)keySpec;
            final int outputLength = hkdfParameterSpec.getOutputLength();
            this.hkdf.init(new HKDFParameters(hkdfParameterSpec.getIKM(), hkdfParameterSpec.getSalt(), hkdfParameterSpec.getInfo()));
            final byte[] array = new byte[outputLength];
            this.hkdf.generateBytes(array, 0, outputLength);
            return new BCPBEKey(this.algName, new KeyParameter(array));
        }
    }
    
    public static class HKDFwithSHA256 extends HKDFBase
    {
        public HKDFwithSHA256() throws InvalidAlgorithmParameterException {
            super("HKDF-SHA256", new SHA256Digest(), PKCSObjectIdentifiers.id_alg_hkdf_with_sha256);
        }
    }
    
    public static class HKDFwithSHA384 extends HKDFBase
    {
        public HKDFwithSHA384() throws InvalidAlgorithmParameterException {
            super("HKDF-SHA384", new SHA384Digest(), PKCSObjectIdentifiers.id_alg_hkdf_with_sha384);
        }
    }
    
    public static class HKDFwithSHA512 extends HKDFBase
    {
        public HKDFwithSHA512() throws InvalidAlgorithmParameterException {
            super("HKDF-SHA512", new SHA512Digest(), PKCSObjectIdentifiers.id_alg_hkdf_with_sha512);
        }
    }
    
    public static class Mappings extends AlgorithmProvider
    {
        private static final String PREFIX;
        
        @Override
        public void configure(final ConfigurableProvider configurableProvider) {
            configurableProvider.addAlgorithm("SecretKeyFactory.HKDF-SHA256", Mappings.PREFIX + "$HKDFwithSHA256");
            configurableProvider.addAlgorithm("SecretKeyFactory.HKDF-SHA384", Mappings.PREFIX + "$HKDFwithSHA384");
            configurableProvider.addAlgorithm("SecretKeyFactory.HKDF-SHA512", Mappings.PREFIX + "$HKDFwithSHA512");
        }
        
        static {
            PREFIX = HKDF.class.getName();
        }
    }
}
