All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.general.EC Maven / Gradle / Ivy

Go to download

The FIPS 140-3 Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms certified to FIPS 140-3 level 1. This jar contains JCE provider and low-level API for the BC-FJA version 2.0.0, FIPS Certificate #4743. Please see certificate for certified platform details.

There is a newer version: 2.0.0
Show newest version
package org.bouncycastle.crypto.general;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.SecureRandom;

import org.bouncycastle.crypto.Algorithm;
import org.bouncycastle.crypto.AsymmetricPrivateKey;
import org.bouncycastle.crypto.AsymmetricPublicKey;
import org.bouncycastle.crypto.DigestAlgorithm;
import org.bouncycastle.crypto.OutputSigner;
import org.bouncycastle.crypto.OutputVerifier;
import org.bouncycastle.crypto.asymmetric.AsymmetricECPrivateKey;
import org.bouncycastle.crypto.asymmetric.AsymmetricECPublicKey;
import org.bouncycastle.crypto.asymmetric.AsymmetricKeyPair;
import org.bouncycastle.crypto.asymmetric.ECDomainParameters;
import org.bouncycastle.crypto.asymmetric.NamedECDomainParameters;
import org.bouncycastle.crypto.fips.FipsEC;
import org.bouncycastle.crypto.fips.FipsSHS;
import org.bouncycastle.crypto.internal.Digest;
import org.bouncycastle.crypto.internal.params.EcDomainParameters;
import org.bouncycastle.crypto.internal.params.EcNamedDomainParameters;
import org.bouncycastle.crypto.internal.params.EcPrivateKeyParameters;
import org.bouncycastle.crypto.internal.params.EcPublicKeyParameters;
import org.bouncycastle.crypto.internal.params.ParametersWithRandom;
import org.bouncycastle.util.Properties;

/**
 * Source class for non-FIPS implementations of Elliptic Curve based algorithms.
 */
public final class EC
{
    private EC()
    {

    }

    /**
     * Basic Elliptic Curve key marker, can be used for creating general purpose Elliptic Curve keys.
     */
    public static final Algorithm ALGORITHM = FipsEC.ALGORITHM;

    private enum Variations
    {
        ECDSA,
        ECDDSA
    }

    /**
     * Elliptic Curve DSA algorithm parameter source - default is SHA-1
     */
    public static final DSAParameters DSA = new DSAParameters(new GeneralAlgorithm(ALGORITHM.getName(), Variations.ECDSA), FipsSHS.Algorithm.SHA1);

    /**
     * Elliptic Curve Deterministic DSA algorithm parameter source - default is SHA-1
     */
    public static final DSAParameters DDSA = new DSAParameters(new GeneralAlgorithm(ALGORITHM.getName(), Variations.ECDDSA), FipsSHS.Algorithm.SHA1);

    /**
     * EC key pair generation parameters for non-FIPS usages.
     */
    public static final class KeyGenParameters
        extends GeneralParameters
    {
        private final ECDomainParameters domainParameters;

        /**
         * Base constructor for specific domain parameters.
         *
         * @param domainParameters the EC domain parameters.
         */
        public KeyGenParameters(ECDomainParameters domainParameters)
        {
            this(ALGORITHM, domainParameters);
        }

        /**
         * Key Generation parameters for a specific algorithm set.
         *
         * @param parameters parameter set representing the algorithm involved.
         * @param domainParameters the EC domain parameters.
         */
        public KeyGenParameters(DSAParameters parameters, ECDomainParameters domainParameters)
        {
            this(parameters.getAlgorithm(), domainParameters);
        }

        private KeyGenParameters(Algorithm algorithm, ECDomainParameters domainParameters)
        {
            super(algorithm);
            this.domainParameters = domainParameters;
        }

        public ECDomainParameters getDomainParameters()
        {
            return domainParameters;
        }
    }

    /**
     * EC DSA signature parameters for non-FIPS algorithms.
     */
    public static final class DSAParameters
        extends GeneralParameters
    {
        private final DigestAlgorithm digestAlgorithm;

        DSAParameters(GeneralAlgorithm type, DigestAlgorithm digestAlgorithm)
        {
            super(type);

            if (type.basicVariation() == Variations.ECDDSA && digestAlgorithm == null)
            {
                throw new IllegalArgumentException("ECDDSA cannot be used with a NULL digest");
            }

            this.digestAlgorithm = digestAlgorithm;
        }

        /**
         * Return the algorithm for the underlying digest these parameters will use.
         *
         * @return the digest algorithm
         */
        public DigestAlgorithm getDigestAlgorithm()
        {
            return digestAlgorithm;
        }

        /**
         * Return a new parameter set with for the passed in digest algorithm.
         *
         * @param digestAlgorithm the digest to use for signature generation.
         * @return a new parameter for signature generation.
         */
        public DSAParameters withDigestAlgorithm(DigestAlgorithm digestAlgorithm)
        {
            return new DSAParameters((GeneralAlgorithm)getAlgorithm(), digestAlgorithm);
        }
    }

    /**
     * EC key pair generator class for non-FIPS usages.
     */
    public static final class KeyPairGenerator
        extends GuardedAsymmetricKeyPairGenerator
    {
        private final FipsEC.KeyPairGenerator kpGen;

        public KeyPairGenerator(KeyGenParameters keyGenParameters, SecureRandom random)
        {
            super(keyGenParameters);

            checkEnabled();

            this.kpGen = new FipsEC.KeyPairGenerator(new FipsEC.KeyGenParameters(keyGenParameters.domainParameters), random);
        }

        @Override
        protected AsymmetricKeyPair doGenerateKeyPair()
        {
            AsymmetricKeyPair kp = kpGen.generateKeyPair();
            final Algorithm algorithm = this.getParameters().getAlgorithm();

            final AsymmetricECPublicKey pubK = (AsymmetricECPublicKey)kp.getPublicKey();
            final AsymmetricECPrivateKey priK = (AsymmetricECPrivateKey)kp.getPrivateKey();

            return AccessController.doPrivileged(new PrivilegedAction()
            {
                public AsymmetricKeyPair run()
                {
                    return new AsymmetricKeyPair(new AsymmetricECPublicKey(algorithm, pubK.getDomainParameters(), pubK.getW()), new AsymmetricECPrivateKey(algorithm, priK.getDomainParameters(), priK.getS(), pubK.getW()));
                }
            });
        }
    }

    /**
     * Operator factory for creating non-FIPS EC DSA based signing and verification operators.
     */
    public static final class DSAOperatorFactory
        extends GuardedSignatureOperatorFactory
    {
        public DSAOperatorFactory()
        {
            checkEnabled();
        }

        @Override
        protected OutputSigner doCreateSigner(AsymmetricPrivateKey key, DSAParameters parameters)
        {
            AsymmetricECPrivateKey k = (AsymmetricECPrivateKey)key;

            Digest digest = (parameters.digestAlgorithm != null) ? Register.createDigest(parameters.digestAlgorithm) : new NullDigest();

            EcDsaSigner ecdsaSigner;
            if (parameters.getAlgorithm() == DSA.getDigestAlgorithm())
            {
                ecdsaSigner = new EcDsaSigner(new RandomDsaKCalculator());
            }
            else
            {
                ecdsaSigner = new EcDsaSigner(new HMacDsaKCalculator(Register.createDigest(parameters.digestAlgorithm)));
            }

            final EcPrivateKeyParameters privateKeyParameters = getLwKey(k);

            return new DSAOutputSigner(ecdsaSigner, digest, parameters, new DSAOutputSigner.Initializer()
            {
                public void initialize(org.bouncycastle.crypto.internal.DSA signer, SecureRandom random)
                {
                    signer.init(true, new ParametersWithRandom(privateKeyParameters, random));
                }
            });
        }

        @Override
        protected OutputVerifier doCreateVerifier(AsymmetricPublicKey key, DSAParameters parameters)
        {
            EcDsaSigner ecdsaSigner = new EcDsaSigner();
            Digest digest = (parameters.digestAlgorithm != null) ? Register.createDigest(parameters.digestAlgorithm) : new NullDigest();

            AsymmetricECPublicKey k = (AsymmetricECPublicKey)key;

            EcPublicKeyParameters publicKeyParameters = new EcPublicKeyParameters(k.getW(), getDomainParams(k.getDomainParameters()));

            ecdsaSigner.init(false, publicKeyParameters);

            return new DSAOutputVerifier(ecdsaSigner, digest, parameters);
        }
    }

    private static void checkEnabled()
    {
        if (Properties.isOverrideSet("org.bouncycastle.ec.disable"))
        {
            throw new UnsupportedOperationException("EC has been disabled by setting \"org.bouncycastle.ec.disable\"");
        }
    }

    private static EcDomainParameters getDomainParams(ECDomainParameters curveParams)
    {
        if (curveParams instanceof NamedECDomainParameters)
        {
            return new EcNamedDomainParameters((NamedECDomainParameters)curveParams);
        }
        return new EcDomainParameters(curveParams);
    }

    private static EcPrivateKeyParameters getLwKey(final AsymmetricECPrivateKey privKey)
    {
        return AccessController.doPrivileged(new PrivilegedAction()
        {
            public EcPrivateKeyParameters run()
            {
                return new EcPrivateKeyParameters(privKey.getS(), getDomainParams(privKey.getDomainParameters()));
            }
        });
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy