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

Commit 03e7318d authored by Eran Messeri's avatar Eran Messeri Committed by Automerger Merge Worker
Browse files

Merge "KeyStore: X25519 key import" am: 9db6ee34

parents 19143a0e 9db6ee34
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -196,6 +196,7 @@ public abstract class KeyProperties {
    @StringDef(prefix = { "KEY_" }, value = {
        KEY_ALGORITHM_RSA,
        KEY_ALGORITHM_EC,
        KEY_ALGORITHM_XDH,
        KEY_ALGORITHM_AES,
        KEY_ALGORITHM_HMAC_SHA1,
        KEY_ALGORITHM_HMAC_SHA224,
@@ -211,6 +212,11 @@ public abstract class KeyProperties {
    /** Elliptic Curve (EC) Cryptography key. */
    public static final String KEY_ALGORITHM_EC = "EC";

    /** Curve 25519 based Agreement key.
     * @hide
     */
    public static final String KEY_ALGORITHM_XDH = "XDH";

    /** Advanced Encryption Standard (AES) key. */
    public static final String KEY_ALGORITHM_AES = "AES";

@@ -246,7 +252,8 @@ public abstract class KeyProperties {

        public static int toKeymasterAsymmetricKeyAlgorithm(
                @NonNull @KeyAlgorithmEnum String algorithm) {
            if (KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) {
            if (KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)
                    || KEY_ALGORITHM_XDH.equalsIgnoreCase(algorithm)) {
                return KeymasterDefs.KM_ALGORITHM_EC;
            } else if (KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) {
                return KeymasterDefs.KM_ALGORITHM_RSA;
+1 −26
Original line number Diff line number Diff line
@@ -24,13 +24,9 @@ import android.system.keystore2.Authorization;
import android.system.keystore2.KeyDescriptor;
import android.system.keystore2.KeyMetadata;

import java.security.AlgorithmParameters;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.InvalidParameterSpecException;

/**
 * {@link ECPublicKey} backed by keystore.
@@ -62,34 +58,13 @@ public class AndroidKeyStoreECPublicKey extends AndroidKeyStorePublicKey impleme
        }
    }

    private static String getEcCurveFromKeymaster(int ecCurve) {
        switch (ecCurve) {
            case android.hardware.security.keymint.EcCurve.P_224:
                return "secp224r1";
            case android.hardware.security.keymint.EcCurve.P_256:
                return "secp256r1";
            case android.hardware.security.keymint.EcCurve.P_384:
                return "secp384r1";
            case android.hardware.security.keymint.EcCurve.P_521:
                return "secp521r1";
        }
        return "";
    }

    private ECParameterSpec getCurveSpec(String name)
            throws NoSuchAlgorithmException, InvalidParameterSpecException {
        AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
        parameters.init(new ECGenParameterSpec(name));
        return parameters.getParameterSpec(ECParameterSpec.class);
    }

    @Override
    public AndroidKeyStorePrivateKey getPrivateKey() {
        ECParameterSpec params = mParams;
        for (Authorization a : getAuthorizations()) {
            try {
                if (a.keyParameter.tag == KeymasterDefs.KM_TAG_EC_CURVE) {
                    params = getCurveSpec(getEcCurveFromKeymaster(
                    params = KeymasterUtils.getCurveSpec(KeymasterUtils.getEcCurveFromKeymaster(
                            a.keyParameter.value.getEcCurve()));
                    break;
                }
+8 −4
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import java.security.ProviderException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.ECKey;
import java.security.interfaces.XECKey;
import java.security.spec.AlgorithmParameterSpec;
import java.util.ArrayList;
import java.util.List;
@@ -134,10 +133,15 @@ public class AndroidKeyStoreKeyAgreementSpi extends KeyAgreementSpi
            throw new InvalidKeyException("key == null");
        } else if (!(key instanceof PublicKey)) {
            throw new InvalidKeyException("Only public keys supported. Key: " + key);
        } else if (!(mKey instanceof ECKey && key instanceof ECKey)
                && !(mKey instanceof XECKey && key instanceof XECKey)) {
        } else if (mKey instanceof ECKey && !(key instanceof ECKey)
                /*&& !(mKey instanceof XECKey && key instanceof XECKey)*/) {
        /** TODO This condition is temporary modified, because OpenSSL implementation does not
         * implement OpenSSLX25519PublicKey from XECKey interface (b/214203951).
         * This change has to revert once conscrypt implements OpenSSLX25519PublicKey from
         * XECKey interface.
         */
            throw new InvalidKeyException(
                    "Public and Private key should be of the same type:");
                    "Public and Private key should be of the same type.");
        } else if (mKey instanceof ECKey
                && !((ECKey) key).getParams().getCurve()
                .equals(((ECKey) mKey).getParams().getCurve())) {
+41 −15
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.security.keystore2.AndroidKeyStoreCipherSpiBase.DEFAULT_MG

import android.annotation.NonNull;
import android.hardware.biometrics.BiometricManager;
import android.hardware.security.keymint.EcCurve;
import android.hardware.security.keymint.HardwareAuthenticatorType;
import android.hardware.security.keymint.KeyParameter;
import android.hardware.security.keymint.SecurityLevel;
@@ -67,6 +68,14 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECKey;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.EdECKey;
import java.security.interfaces.EdECPrivateKey;
import java.security.interfaces.XECKey;
import java.security.interfaces.XECPrivateKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.NamedParameterSpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -567,22 +576,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
                        spec.getMaxUsageCount()
                ));
            }
            if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(key.getAlgorithm())) {
                if (key instanceof ECKey) {
                    ECKey ecKey = (ECKey) key;
            if (KeymasterDefs.KM_ALGORITHM_EC
                    == KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(
                            key.getAlgorithm())) {
                importArgs.add(KeyStore2ParameterUtils.makeEnum(
                        KeymasterDefs.KM_TAG_EC_CURVE,
                            KeyProperties.EcCurve.toKeymasterCurve(ecKey.getParams())
                        getKeymasterEcCurve(key)
                ));
            }
            }
            /* TODO: check for Ed25519(EdDSA) or X25519(XDH) key algorithm and
             *  add import args for KM_TAG_EC_CURVE as EcCurve.CURVE_25519.
             *  Currently conscrypt does not support EdDSA key import and XDH keys are not an
             *  instance of XECKey, hence these conditions are not added, once it is fully
             *  implemented by conscrypt, we can add CURVE_25519 argument for EdDSA and XDH
             *  algorithms.
             */
        } catch (IllegalArgumentException | IllegalStateException e) {
            throw new KeyStoreException(e);
        }
@@ -608,6 +609,31 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
        }
    }

    private int getKeymasterEcCurve(PrivateKey key) {
        if (key instanceof ECKey) {
            ECParameterSpec param = ((ECPrivateKey) key).getParams();
            int kmECCurve = KeymasterUtils.getKeymasterEcCurve(KeymasterUtils.getCurveName(param));
            if (kmECCurve >= 0) {
                return kmECCurve;
            }
        } else if (key instanceof XECKey) {
            AlgorithmParameterSpec param = ((XECPrivateKey) key).getParams();
            if (param.equals(NamedParameterSpec.X25519)) {
                return EcCurve.CURVE_25519;
            }
        } else if (key.getAlgorithm().equals("XDH")) {
            // TODO com.android.org.conscrypt.OpenSSLX25519PrivateKey does not implement XECKey,
            //  this case is not required once it implements XECKey interface(b/214203951).
            return EcCurve.CURVE_25519;
        } else if (key instanceof EdECKey) {
            AlgorithmParameterSpec param = ((EdECPrivateKey) key).getParams();
            if (param.equals(NamedParameterSpec.ED25519)) {
                return EcCurve.CURVE_25519;
            }
        }
        throw new IllegalArgumentException("Unexpected Key " + key.getClass().getName());
    }

    private static void assertCanReplace(String alias, @Domain int targetDomain,
            int targetNamespace, KeyDescriptor descriptor)
            throws KeyStoreException {
+1 −1
Original line number Diff line number Diff line
@@ -88,7 +88,7 @@ public class AndroidKeyStoreXDHPublicKey extends AndroidKeyStorePublicKey implem
                getUserKeyDescriptor(),
                getKeyIdDescriptor().nspace,
                getAuthorizations(),
                "x25519",
                "XDH",
                getSecurityLevel());
    }

Loading