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

package com.google.crypto.tink.aead;

import com.google.protobuf.MessageLite;
import com.google.protobuf.Parser;
import com.google.crypto.tink.internal.LegacyKeyManagerImpl;
import com.google.crypto.tink.proto.KeyData;
import com.google.crypto.tink.subtle.EncryptThenAuthenticate;
import com.google.crypto.tink.internal.TinkBugException;
import com.google.crypto.tink.KeyTemplate;
import com.google.crypto.tink.internal.KeyManagerRegistry;
import com.google.crypto.tink.internal.MutableKeyCreationRegistry;
import com.google.crypto.tink.internal.MutableParametersRegistry;
import com.google.crypto.tink.internal.MutablePrimitiveRegistry;
import com.google.crypto.tink.aead.internal.AesCtrHmacAeadProtoSerialization;
import java.util.Collections;
import java.util.HashMap;
import com.google.crypto.tink.Parameters;
import java.util.Map;
import com.google.crypto.tink.util.SecretBytes;
import com.google.crypto.tink.AccessesPartialKey;
import com.google.crypto.tink.internal.Util;
import com.google.crypto.tink.SecretKeyAccess;
import javax.annotation.Nullable;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import com.google.crypto.tink.config.internal.TinkFipsUtil;
import com.google.crypto.tink.internal.KeyCreator;
import com.google.crypto.tink.internal.MutableKeyDerivationRegistry;
import com.google.crypto.tink.KeyManager;
import com.google.crypto.tink.Aead;
import com.google.crypto.tink.internal.PrimitiveConstructor;

public final class AesCtrHmacAeadKeyManager
{
    private static final PrimitiveConstructor<AesCtrHmacAeadKey, Aead> AES_CTR_HMAC_AEAD_PRIMITIVE_CONSTRUCTOR;
    private static final KeyManager<Aead> legacyKeyManager;
    private static final MutableKeyDerivationRegistry.InsecureKeyCreator<AesCtrHmacAeadParameters> KEY_DERIVER;
    private static final KeyCreator<AesCtrHmacAeadParameters> KEY_CREATOR;
    private static final TinkFipsUtil.AlgorithmFipsCompatibility FIPS;
    
    private static void validate(final AesCtrHmacAeadParameters parameters) throws GeneralSecurityException {
        if (parameters.getAesKeySizeBytes() != 16 && parameters.getAesKeySizeBytes() != 32) {
            throw new GeneralSecurityException("AES key size must be 16 or 32 bytes");
        }
    }
    
    static String getKeyType() {
        return "type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey";
    }
    
    @AccessesPartialKey
    static AesCtrHmacAeadKey createAesCtrHmacAeadKeyFromRandomness(final AesCtrHmacAeadParameters parameters, final InputStream stream, @Nullable final Integer idRequirement, final SecretKeyAccess access) throws GeneralSecurityException {
        return AesCtrHmacAeadKey.builder().setParameters(parameters).setIdRequirement(idRequirement).setAesKeyBytes(Util.readIntoSecretBytes(stream, parameters.getAesKeySizeBytes(), access)).setHmacKeyBytes(Util.readIntoSecretBytes(stream, parameters.getHmacKeySizeBytes(), access)).build();
    }
    
    @AccessesPartialKey
    static AesCtrHmacAeadKey createAesCtrHmacAeadKey(final AesCtrHmacAeadParameters parameters, @Nullable final Integer idRequirement) throws GeneralSecurityException {
        validate(parameters);
        return AesCtrHmacAeadKey.builder().setParameters(parameters).setIdRequirement(idRequirement).setAesKeyBytes(SecretBytes.randomBytes(parameters.getAesKeySizeBytes())).setHmacKeyBytes(SecretBytes.randomBytes(parameters.getHmacKeySizeBytes())).build();
    }
    
    private static Map<String, Parameters> namedParameters() throws GeneralSecurityException {
        final Map<String, Parameters> result = new HashMap<String, Parameters>();
        result.put("AES128_CTR_HMAC_SHA256", PredefinedAeadParameters.AES128_CTR_HMAC_SHA256);
        result.put("AES128_CTR_HMAC_SHA256_RAW", AesCtrHmacAeadParameters.builder().setAesKeySizeBytes(16).setHmacKeySizeBytes(32).setTagSizeBytes(16).setIvSizeBytes(16).setHashType(AesCtrHmacAeadParameters.HashType.SHA256).setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX).build());
        result.put("AES256_CTR_HMAC_SHA256", PredefinedAeadParameters.AES256_CTR_HMAC_SHA256);
        result.put("AES256_CTR_HMAC_SHA256_RAW", AesCtrHmacAeadParameters.builder().setAesKeySizeBytes(32).setHmacKeySizeBytes(32).setTagSizeBytes(32).setIvSizeBytes(16).setHashType(AesCtrHmacAeadParameters.HashType.SHA256).setVariant(AesCtrHmacAeadParameters.Variant.NO_PREFIX).build());
        return Collections.unmodifiableMap((Map<? extends String, ? extends Parameters>)result);
    }
    
    public static void register(final boolean newKeyAllowed) throws GeneralSecurityException {
        if (!AesCtrHmacAeadKeyManager.FIPS.isCompatible()) {
            throw new GeneralSecurityException("Can not use AES-CTR-HMAC in FIPS-mode, as BoringCrypto module is not available.");
        }
        AesCtrHmacAeadProtoSerialization.register();
        MutablePrimitiveRegistry.globalInstance().registerPrimitiveConstructor(AesCtrHmacAeadKeyManager.AES_CTR_HMAC_AEAD_PRIMITIVE_CONSTRUCTOR);
        MutableParametersRegistry.globalInstance().putAll(namedParameters());
        MutableKeyDerivationRegistry.globalInstance().add(AesCtrHmacAeadKeyManager.KEY_DERIVER, AesCtrHmacAeadParameters.class);
        MutableKeyCreationRegistry.globalInstance().add(AesCtrHmacAeadKeyManager.KEY_CREATOR, AesCtrHmacAeadParameters.class);
        KeyManagerRegistry.globalInstance().registerKeyManagerWithFipsCompatibility(AesCtrHmacAeadKeyManager.legacyKeyManager, AesCtrHmacAeadKeyManager.FIPS, newKeyAllowed);
    }
    
    public static final KeyTemplate aes128CtrHmacSha256Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(AesCtrHmacAeadParameters.builder().setAesKeySizeBytes(16).setHmacKeySizeBytes(32).setIvSizeBytes(16).setTagSizeBytes(16).setHashType(AesCtrHmacAeadParameters.HashType.SHA256).setVariant(AesCtrHmacAeadParameters.Variant.TINK).build()));
    }
    
    public static final KeyTemplate aes256CtrHmacSha256Template() {
        return TinkBugException.exceptionIsBug(() -> KeyTemplate.createFrom(AesCtrHmacAeadParameters.builder().setAesKeySizeBytes(32).setHmacKeySizeBytes(32).setIvSizeBytes(16).setTagSizeBytes(32).setHashType(AesCtrHmacAeadParameters.HashType.SHA256).setVariant(AesCtrHmacAeadParameters.Variant.TINK).build()));
    }
    
    private AesCtrHmacAeadKeyManager() {
    }
    
    static {
        AES_CTR_HMAC_AEAD_PRIMITIVE_CONSTRUCTOR = PrimitiveConstructor.create(EncryptThenAuthenticate::create, AesCtrHmacAeadKey.class, Aead.class);
        legacyKeyManager = LegacyKeyManagerImpl.create(getKeyType(), Aead.class, KeyData.KeyMaterialType.SYMMETRIC, com.google.crypto.tink.proto.AesCtrHmacAeadKey.parser());
        KEY_DERIVER = AesCtrHmacAeadKeyManager::createAesCtrHmacAeadKeyFromRandomness;
        KEY_CREATOR = AesCtrHmacAeadKeyManager::createAesCtrHmacAeadKey;
        FIPS = TinkFipsUtil.AlgorithmFipsCompatibility.ALGORITHM_REQUIRES_BORINGCRYPTO;
    }
}
