Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a3c8805 authored by Janis Danisevskis's avatar Janis Danisevskis
Browse files

Keystore 2.0 SPI: Add EC_CURVE tag on key generation.

The KeyMint spec requires the specification of the EC_CURVE tag when
generating an EC key. This patch adds the correct curve tag parameter to
the parameter list.

Test: CtsVerifier Protected confirmation test.
Bug: 192908276
Change-Id: I2e7dd4868abda85d244e73592ff12d688f5c21fc
parent 5f5e03d3
Loading
Loading
Loading
Loading
+54 −29
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityThread;
import android.app.ActivityThread;
import android.content.Context;
import android.content.Context;
import android.hardware.security.keymint.EcCurve;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.KeyPurpose;
import android.hardware.security.keymint.KeyPurpose;
import android.hardware.security.keymint.SecurityLevel;
import android.hardware.security.keymint.SecurityLevel;
@@ -122,6 +123,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
            new HashMap<String, Integer>();
            new HashMap<String, Integer>();
    private static final List<String> SUPPORTED_EC_NIST_CURVE_NAMES = new ArrayList<String>();
    private static final List<String> SUPPORTED_EC_NIST_CURVE_NAMES = new ArrayList<String>();
    private static final List<Integer> SUPPORTED_EC_NIST_CURVE_SIZES = new ArrayList<Integer>();
    private static final List<Integer> SUPPORTED_EC_NIST_CURVE_SIZES = new ArrayList<Integer>();

    static {
    static {
        // Aliases for NIST P-224
        // Aliases for NIST P-224
        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-224", 224);
        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-224", 224);
@@ -175,6 +177,23 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
        mOriginalKeymasterAlgorithm = keymasterAlgorithm;
        mOriginalKeymasterAlgorithm = keymasterAlgorithm;
    }
    }


    private @EcCurve int keySize2EcCurve(int keySizeBits)
            throws InvalidAlgorithmParameterException {
        switch (keySizeBits) {
            case 224:
                return EcCurve.P_224;
            case 256:
                return EcCurve.P_256;
            case 384:
                return EcCurve.P_384;
            case 521:
                return EcCurve.P_521;
            default:
                throw new InvalidAlgorithmParameterException(
                        "Unsupported EC curve keysize: " + keySizeBits);
        }
    }

    @SuppressWarnings("deprecation")
    @SuppressWarnings("deprecation")
    @Override
    @Override
    public void initialize(int keysize, SecureRandom random) {
    public void initialize(int keysize, SecureRandom random) {
@@ -459,8 +478,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
    private void initAlgorithmSpecificParameters() throws InvalidAlgorithmParameterException {
    private void initAlgorithmSpecificParameters() throws InvalidAlgorithmParameterException {
        AlgorithmParameterSpec algSpecificSpec = mSpec.getAlgorithmParameterSpec();
        AlgorithmParameterSpec algSpecificSpec = mSpec.getAlgorithmParameterSpec();
        switch (mKeymasterAlgorithm) {
        switch (mKeymasterAlgorithm) {
            case KeymasterDefs.KM_ALGORITHM_RSA:
            case KeymasterDefs.KM_ALGORITHM_RSA: {
            {
                BigInteger publicExponent = null;
                BigInteger publicExponent = null;
                if (algSpecificSpec instanceof RSAKeyGenParameterSpec) {
                if (algSpecificSpec instanceof RSAKeyGenParameterSpec) {
                    RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) algSpecificSpec;
                    RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec) algSpecificSpec;
@@ -487,7 +505,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
                        || (publicExponent.compareTo(KeymasterArguments.UINT64_MAX_VALUE) > 0)) {
                        || (publicExponent.compareTo(KeymasterArguments.UINT64_MAX_VALUE) > 0)) {
                    throw new InvalidAlgorithmParameterException(
                    throw new InvalidAlgorithmParameterException(
                            "Unsupported RSA public exponent: " + publicExponent
                            "Unsupported RSA public exponent: " + publicExponent
                            + ". Maximum supported value: " + KeymasterArguments.UINT64_MAX_VALUE);
                                    + ". Maximum supported value: "
                                    + KeymasterArguments.UINT64_MAX_VALUE);
                }
                }
                mRSAPublicExponent = publicExponent.longValue();
                mRSAPublicExponent = publicExponent.longValue();
                break;
                break;
@@ -605,7 +624,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
                    throw p;
                    throw p;
            }
            }
        } catch (UnrecoverableKeyException | IllegalArgumentException
        } catch (UnrecoverableKeyException | IllegalArgumentException
                    | DeviceIdAttestationException e) {
                | DeviceIdAttestationException | InvalidAlgorithmParameterException e) {
            throw new ProviderException(
            throw new ProviderException(
                    "Failed to construct key object from newly generated key pair.", e);
                    "Failed to construct key object from newly generated key pair.", e);
        } finally {
        } finally {
@@ -715,12 +734,20 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
    }
    }


    private Collection<KeyParameter> constructKeyGenerationArguments()
    private Collection<KeyParameter> constructKeyGenerationArguments()
            throws DeviceIdAttestationException, IllegalArgumentException {
            throws DeviceIdAttestationException, IllegalArgumentException,
            InvalidAlgorithmParameterException {
        List<KeyParameter> params = new ArrayList<>();
        List<KeyParameter> params = new ArrayList<>();
        params.add(KeyStore2ParameterUtils.makeInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits));
        params.add(KeyStore2ParameterUtils.makeInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits));
        params.add(KeyStore2ParameterUtils.makeEnum(
        params.add(KeyStore2ParameterUtils.makeEnum(
                KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm
                KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm
        ));
        ));

        if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
            params.add(KeyStore2ParameterUtils.makeEnum(
                    Tag.EC_CURVE, keySize2EcCurve(mKeySizeBits)
            ));
        }

        ArrayUtils.forEach(mKeymasterPurposes, (purpose) -> {
        ArrayUtils.forEach(mKeymasterPurposes, (purpose) -> {
            params.add(KeyStore2ParameterUtils.makeEnum(
            params.add(KeyStore2ParameterUtils.makeEnum(
                    KeymasterDefs.KM_TAG_PURPOSE, purpose
                    KeymasterDefs.KM_TAG_PURPOSE, purpose
@@ -892,8 +919,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
            return null;
            return null;
        }
        }
        switch (keymasterAlgorithm) {
        switch (keymasterAlgorithm) {
            case KeymasterDefs.KM_ALGORITHM_EC:
            case KeymasterDefs.KM_ALGORITHM_EC: {
            {
                Set<Integer> availableKeymasterDigests = getAvailableKeymasterSignatureDigests(
                Set<Integer> availableKeymasterDigests = getAvailableKeymasterSignatureDigests(
                        spec.getDigests(),
                        spec.getDigests(),
                        AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests());
                        AndroidKeyStoreBCWorkaroundProvider.getSupportedEcdsaSignatureDigests());
@@ -940,8 +966,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
                return KeyProperties.Digest.fromKeymasterToSignatureAlgorithmDigest(
                return KeyProperties.Digest.fromKeymasterToSignatureAlgorithmDigest(
                        bestKeymasterDigest) + "WithECDSA";
                        bestKeymasterDigest) + "WithECDSA";
            }
            }
            case KeymasterDefs.KM_ALGORITHM_RSA:
            case KeymasterDefs.KM_ALGORITHM_RSA: {
            {
                // Check whether this key is authorized for PKCS#1 signature padding.
                // Check whether this key is authorized for PKCS#1 signature padding.
                // We use Bouncy Castle to generate self-signed RSA certificates. Bouncy Castle
                // We use Bouncy Castle to generate self-signed RSA certificates. Bouncy Castle
                // only supports RSA certificates signed using PKCS#1 padding scheme. The key needs
                // only supports RSA certificates signed using PKCS#1 padding scheme. The key needs