From d2c944bc4d057a48840a8ece436e4c43d569e90b Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Mon, 5 Oct 2020 14:33:34 -0700 Subject: [PATCH 1/3] Keystore SPI: Add SecurityLevelEnum to KeyProperties This patch adds the SecurityLevelEnum to KeyProperties. This enum can be used by the public API surface to express levels of enforcements of key properties. And to select a designated residence for a newly generated or imported key. The values UNKNOWN and UNKNOWN_SECURE are used to convey to older target APIs API levels that have not been defined when they where published. Test: None Change-Id: I88681f21b8a8ea9a383d32ba99f3ab7d7c8909c3 --- api/current.txt | 5 ++ core/api/current.txt | 5 ++ .../security/keymaster/KeymasterDefs.java | 5 ++ .../security/keystore/KeyProperties.java | 80 +++++++++++++++++++ 4 files changed, 95 insertions(+) diff --git a/api/current.txt b/api/current.txt index c2e75cd14968d..560b5f6c5cb0d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -42868,6 +42868,11 @@ package android.security.keystore { field public static final int PURPOSE_SIGN = 4; // 0x4 field public static final int PURPOSE_VERIFY = 8; // 0x8 field public static final int PURPOSE_WRAP_KEY = 32; // 0x20 + field public static final int SECURITY_LEVEL_SOFTWARE = 0; // 0x0 + field public static final int SECURITY_LEVEL_STRONGBOX = 2; // 0x2 + field public static final int SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1; // 0x1 + field public static final int SECURITY_LEVEL_UNKNOWN = -2; // 0xfffffffe + field public static final int SECURITY_LEVEL_UNKNOWN_SECURE = -1; // 0xffffffff field public static final String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1"; field public static final String SIGNATURE_PADDING_RSA_PSS = "PSS"; } diff --git a/core/api/current.txt b/core/api/current.txt index ab0aec73346b2..0aa24cf508307 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -41036,6 +41036,11 @@ package android.security.keystore { field public static final int PURPOSE_SIGN = 4; // 0x4 field public static final int PURPOSE_VERIFY = 8; // 0x8 field public static final int PURPOSE_WRAP_KEY = 32; // 0x20 + field public static final int SECURITY_LEVEL_SOFTWARE = 0; // 0x0 + field public static final int SECURITY_LEVEL_STRONGBOX = 2; // 0x2 + field public static final int SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1; // 0x1 + field public static final int SECURITY_LEVEL_UNKNOWN = -2; // 0xfffffffe + field public static final int SECURITY_LEVEL_UNKNOWN_SECURE = -1; // 0xffffffff field public static final String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1"; field public static final String SIGNATURE_PADDING_RSA_PSS = "PSS"; } diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java index f08756a015b24..e32ffa6e9d05a 100644 --- a/core/java/android/security/keymaster/KeymasterDefs.java +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -157,6 +157,11 @@ public final class KeymasterDefs { public static final int HW_AUTH_PASSWORD = 1 << 0; public static final int HW_AUTH_BIOMETRIC = 1 << 1; + // Security Levels. + public static final int KM_SECURITY_LEVEL_SOFTWARE = 0; + public static final int KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1; + public static final int KM_SECURITY_LEVEL_STRONGBOX = 2; + // Error codes. public static final int KM_ERROR_OK = 0; public static final int KM_ERROR_ROOT_OF_TRUST_ALREADY_SET = -1; diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java index c58a1236d475c..63ff866e7a06d 100644 --- a/keystore/java/android/security/keystore/KeyProperties.java +++ b/keystore/java/android/security/keystore/KeyProperties.java @@ -771,4 +771,84 @@ public abstract class KeyProperties { } return result; } + + /** + * @hide + */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = { "SECURITY_LEVEL_" }, value = { + SECURITY_LEVEL_UNKNOWN, + SECURITY_LEVEL_UNKNOWN_SECURE, + SECURITY_LEVEL_SOFTWARE, + SECURITY_LEVEL_TRUSTED_ENVIRONMENT, + SECURITY_LEVEL_STRONGBOX, + }) + public @interface SecurityLevelEnum {} + + /** + * This security level indicates that no assumptions can be made about the security level of the + * respective key. + */ + public static final int SECURITY_LEVEL_UNKNOWN = -2; + /** + * This security level indicates that due to the target API level of the caller no exact + * statement can be made about the security level of the key, however, the security level + * can be considered is at least equivalent to {@link #SECURITY_LEVEL_TRUSTED_ENVIRONMENT}. + */ + public static final int SECURITY_LEVEL_UNKNOWN_SECURE = -1; + + /** Indicates enforcement by system software. */ + public static final int SECURITY_LEVEL_SOFTWARE = 0; + + /** Indicates enforcement by a trusted execution environment. */ + public static final int SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1; + + /** + * Indicates enforcement by environment meeting the Strongbox security profile, + * such as a secure element. + */ + public static final int SECURITY_LEVEL_STRONGBOX = 2; + + /** + * @hide + */ + public abstract static class SecurityLevel { + private SecurityLevel() {} + + /** + * @hide + */ + public static int toKeymaster(int securityLevel) { + switch (securityLevel) { + case SECURITY_LEVEL_SOFTWARE: + return KeymasterDefs.KM_SECURITY_LEVEL_SOFTWARE; + case SECURITY_LEVEL_TRUSTED_ENVIRONMENT: + return KeymasterDefs.KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT; + case SECURITY_LEVEL_STRONGBOX: + return KeymasterDefs.KM_SECURITY_LEVEL_STRONGBOX; + default: + throw new IllegalArgumentException("Unsupported security level: " + + securityLevel); + } + } + + /** + * @hide + */ + @NonNull + public static int fromKeymaster(int securityLevel) { + switch (securityLevel) { + case KeymasterDefs.KM_SECURITY_LEVEL_SOFTWARE: + return SECURITY_LEVEL_SOFTWARE; + case KeymasterDefs.KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT: + return SECURITY_LEVEL_TRUSTED_ENVIRONMENT; + case KeymasterDefs.KM_SECURITY_LEVEL_STRONGBOX: + return SECURITY_LEVEL_STRONGBOX; + default: + throw new IllegalArgumentException("Unsupported security level: " + + securityLevel); + } + } + } + } From 62c1d2869d51bac11593176cdab857abb1c56a2a Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Mon, 19 Oct 2020 18:43:42 -0700 Subject: [PATCH 2/3] Keystore 2.0: KeyProperties SignaturePadding is now public but hidden In anticipation of the new Keystore 2.0 SPI we made this nested class public (like its siblings) so that the new SPI which resides in a different package may access it. It is hidden though because it does not constitute public API surface. Test: None Bug: 171305684 Change-Id: I1dbe3d02c03f97f843813c26c16aaef7152ca478 --- .../android/security/keystore/KeyProperties.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java index 63ff866e7a06d..9050c695eba7e 100644 --- a/keystore/java/android/security/keystore/KeyProperties.java +++ b/keystore/java/android/security/keystore/KeyProperties.java @@ -496,10 +496,16 @@ public abstract class KeyProperties { */ public static final String SIGNATURE_PADDING_RSA_PSS = "PSS"; - static abstract class SignaturePadding { + /** + * @hide + */ + public abstract static class SignaturePadding { private SignaturePadding() {} - static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) { + /** + * @hide + */ + public static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) { switch (padding.toUpperCase(Locale.US)) { case SIGNATURE_PADDING_RSA_PKCS1: return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN; @@ -512,7 +518,7 @@ public abstract class KeyProperties { } @NonNull - static @SignaturePaddingEnum String fromKeymaster(int padding) { + public static @SignaturePaddingEnum String fromKeymaster(int padding) { switch (padding) { case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN: return SIGNATURE_PADDING_RSA_PKCS1; @@ -524,7 +530,7 @@ public abstract class KeyProperties { } @NonNull - static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) { + public static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) { if ((paddings == null) || (paddings.length == 0)) { return EmptyArray.INT; } From 145e11ff938971b63514dde1bbd887ddaa04f7ec Mon Sep 17 00:00:00 2001 From: Janis Danisevskis Date: Mon, 28 Sep 2020 17:37:13 -0700 Subject: [PATCH 3/3] Keystore 2.0 SPI: Adding the keystore AIDL interface to frameworks Adds the dependency to the new Keystore 2.0 AIDL spec to the frameworks module. Bug: 159476414 Test: None Change-Id: Ib3c9affbe0dfcbd78ff47b41907f5650444711a4 --- Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/Android.bp b/Android.bp index 35879df4b852d..8dc2655d78136 100644 --- a/Android.bp +++ b/Android.bp @@ -480,6 +480,7 @@ java_library { "android.hardware.vibrator-V1.1-java", "android.hardware.vibrator-V1.2-java", "android.hardware.vibrator-V1.3-java", + "android.system.keystore2-java", "devicepolicyprotosnano", "com.android.sysprop.apex",