summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEran Messeri <eranm@google.com>2022-11-25 15:42:46 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-11-25 15:42:46 +0000
commita9e03a249893b46a600ee72f6dcd87e954cf19aa (patch)
treeb12b70d3e3e9345e49378d41290b083fbadb9222
parent3e58b78907146a22f3340e3a072d51edd9068191 (diff)
parent9db6ee342b7c2748477e7b8c46add353087b8204 (diff)
downloadbase-a9e03a249893b46a600ee72f6dcd87e954cf19aa.tar.gz
Merge "KeyStore: X25519 key import" am: 9db6ee342b
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2183495 Change-Id: I7aa4360491ef7b0ad71ac45ebf15003c39e39dfe Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--keystore/java/android/security/keystore/KeyProperties.java9
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java27
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java12
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java56
-rw-r--r--keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java2
-rw-r--r--keystore/java/android/security/keystore2/KeymasterUtils.java66
6 files changed, 125 insertions, 47 deletions
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index 62455988db34..8c42547caea6 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -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;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java
index 4e73bd9d3c82..4505eaf0c862 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECPublicKey.java
@@ -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;
}
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java
index 4caa47f2078b..7292cd3c5fb1 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyAgreementSpi.java
@@ -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())) {
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
index f05cdc57fb70..91f216f1320a 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java
@@ -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;
- importArgs.add(KeyStore2ParameterUtils.makeEnum(
- KeymasterDefs.KM_TAG_EC_CURVE,
- KeyProperties.EcCurve.toKeymasterCurve(ecKey.getParams())
- ));
- }
+ if (KeymasterDefs.KM_ALGORITHM_EC
+ == KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(
+ key.getAlgorithm())) {
+ importArgs.add(KeyStore2ParameterUtils.makeEnum(
+ KeymasterDefs.KM_TAG_EC_CURVE,
+ 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 {
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java
index 9f3df3d72d86..69138340f653 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPublicKey.java
@@ -88,7 +88,7 @@ public class AndroidKeyStoreXDHPublicKey extends AndroidKeyStorePublicKey implem
getUserKeyDescriptor(),
getKeyIdDescriptor().nspace,
getAuthorizations(),
- "x25519",
+ "XDH",
getSecurityLevel());
}
diff --git a/keystore/java/android/security/keystore2/KeymasterUtils.java b/keystore/java/android/security/keystore2/KeymasterUtils.java
index de4696cea3ac..614e3684c417 100644
--- a/keystore/java/android/security/keystore2/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore2/KeymasterUtils.java
@@ -20,7 +20,12 @@ import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
import android.security.keystore.KeyProperties;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
import java.security.ProviderException;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
/**
* @hide
@@ -121,4 +126,65 @@ public abstract class KeymasterUtils {
break;
}
}
+
+ 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 "";
+ }
+
+ static int getKeymasterEcCurve(String ecCurveName) {
+ if (ecCurveName.equals("secp224r1")) {
+ return android.hardware.security.keymint.EcCurve.P_224;
+ } else if (ecCurveName.equals("secp256r1")) {
+ return android.hardware.security.keymint.EcCurve.P_256;
+ } else if (ecCurveName.equals("secp384r1")) {
+ return android.hardware.security.keymint.EcCurve.P_384;
+ } else if (ecCurveName.equals("secp521r1")) {
+ return android.hardware.security.keymint.EcCurve.P_521;
+ }
+ return -1;
+ }
+
+ static ECParameterSpec getCurveSpec(String name)
+ throws NoSuchAlgorithmException, InvalidParameterSpecException {
+ AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
+ parameters.init(new ECGenParameterSpec(name));
+ return parameters.getParameterSpec(ECParameterSpec.class);
+ }
+
+ static String getCurveName(ECParameterSpec spec) {
+ if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp224r1")) {
+ return "secp224r1";
+ } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp256r1")) {
+ return "secp256r1";
+ } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp384r1")) {
+ return "secp384r1";
+ } else if (KeymasterUtils.isECParameterSpecOfCurve(spec, "secp521r1")) {
+ return "secp521r1";
+ }
+ return null;
+ }
+
+ private static boolean isECParameterSpecOfCurve(ECParameterSpec spec, String curveName) {
+ try {
+ ECParameterSpec curveSpec = KeymasterUtils.getCurveSpec(curveName);
+ if (curveSpec.getCurve().equals(spec.getCurve())
+ && curveSpec.getOrder().equals(spec.getOrder())
+ && curveSpec.getGenerator().equals(spec.getGenerator())) {
+ return true;
+ }
+ } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) {
+ return false;
+ }
+ return false;
+ }
}