diff options
5 files changed, 81 insertions, 2 deletions
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java index 8efc5eb6b6ff..e720f1ab1523 100644 --- a/core/java/android/security/keymaster/KeymasterDefs.java +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -65,6 +65,7 @@ public final class KeymasterDefs { public static final int KM_TAG_PADDING = Tag.PADDING; // KM_ENUM_REP | 6; public static final int KM_TAG_CALLER_NONCE = Tag.CALLER_NONCE; // KM_BOOL | 7; public static final int KM_TAG_MIN_MAC_LENGTH = Tag.MIN_MAC_LENGTH; // KM_UINT | 8; + public static final int KM_TAG_EC_CURVE = Tag.EC_CURVE; // KM_ENUM | 10; public static final int KM_TAG_RSA_PUBLIC_EXPONENT = Tag.RSA_PUBLIC_EXPONENT; // KM_ULONG | 200; public static final int KM_TAG_INCLUDE_UNIQUE_ID = Tag.INCLUDE_UNIQUE_ID; // KM_BOOL | 202; diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java index dbd918e35d70..62455988db34 100644 --- a/keystore/java/android/security/keystore/KeyProperties.java +++ b/keystore/java/android/security/keystore/KeyProperties.java @@ -30,6 +30,7 @@ import libcore.util.EmptyArray; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECParameterSpec; import java.security.spec.MGF1ParameterSpec; import java.util.Collection; import java.util.Locale; @@ -914,6 +915,51 @@ public abstract class KeyProperties { } /** + * @hide + */ + public abstract static class EcCurve { + private EcCurve() {} + + /** + * @hide + */ + public static int toKeymasterCurve(ECParameterSpec spec) { + int keySize = spec.getCurve().getField().getFieldSize(); + switch (keySize) { + case 224: + return android.hardware.security.keymint.EcCurve.P_224; + case 256: + return android.hardware.security.keymint.EcCurve.P_256; + case 384: + return android.hardware.security.keymint.EcCurve.P_384; + case 521: + return android.hardware.security.keymint.EcCurve.P_521; + default: + return -1; + } + } + + /** + * @hide + */ + public static int fromKeymasterCurve(int ecCurve) { + switch (ecCurve) { + case android.hardware.security.keymint.EcCurve.P_224: + return 224; + case android.hardware.security.keymint.EcCurve.P_256: + case android.hardware.security.keymint.EcCurve.CURVE_25519: + return 256; + case android.hardware.security.keymint.EcCurve.P_384: + return 384; + case android.hardware.security.keymint.EcCurve.P_521: + return 521; + default: + return -1; + } + } + } + + /** * Namespaces provide system developers and vendors with a way to use keystore without * requiring an applications uid. Namespaces can be configured using SEPolicy. * See <a href="https://source.android.com/security/keystore#access-control"> diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java index 5216a908826b..ace2053cc1a7 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreECDSASignatureSpi.java @@ -203,6 +203,11 @@ abstract class AndroidKeyStoreECDSASignatureSpi extends AndroidKeyStoreSignature for (Authorization a : key.getAuthorizations()) { if (a.keyParameter.tag == KeymasterDefs.KM_TAG_KEY_SIZE) { keySizeBits = KeyStore2ParameterUtils.getUnsignedInt(a); + break; + } else if (a.keyParameter.tag == KeymasterDefs.KM_TAG_EC_CURVE) { + keySizeBits = KeyProperties.EcCurve.fromKeymasterCurve( + a.keyParameter.value.getEcCurve()); + break; } } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index 9d424e904d59..f05cdc57fb70 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -66,6 +66,7 @@ import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.interfaces.ECKey; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -566,6 +567,22 @@ 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()) + )); + } + } + /* 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); } diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java index 42589640d2b7..610207263b34 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreXDHPrivateKey.java @@ -22,8 +22,9 @@ import android.system.keystore2.Authorization; import android.system.keystore2.KeyDescriptor; import java.security.PrivateKey; -import java.security.interfaces.EdECKey; +import java.security.interfaces.XECPrivateKey; import java.security.spec.NamedParameterSpec; +import java.util.Optional; /** * X25519 Private Key backed by Keystore. @@ -31,7 +32,8 @@ import java.security.spec.NamedParameterSpec; * * @hide */ -public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey implements EdECKey { +public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey + implements XECPrivateKey { public AndroidKeyStoreXDHPrivateKey( @NonNull KeyDescriptor descriptor, long keyId, @NonNull Authorization[] authorizations, @@ -44,4 +46,12 @@ public class AndroidKeyStoreXDHPrivateKey extends AndroidKeyStorePrivateKey impl public NamedParameterSpec getParams() { return NamedParameterSpec.X25519; } + + @Override + public Optional<byte[]> getScalar() { + /* An empty Optional if the scalar cannot be extracted (e.g. if the provider is a hardware + * token and the private key is not allowed to leave the crypto boundary). + */ + return Optional.empty(); + } } |