From 12b644d275b121dd952a4a564fa65b9c18c9b22c Mon Sep 17 00:00:00 2001 From: Rubin Xu Date: Fri, 21 Apr 2017 19:21:42 +0100 Subject: Introduce KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION This flag is used by system server to mark keys used during the synthetic password auth flow. keys marked with this flag will not be super encrypted because super encryption requires knowledge of the synthetic password, causing a chicken-and-egg problem. Bug: 35849499 Bug: 34600579 Test: cts-tradefed run cts-dev -m CtsDevicePolicyManagerTestCases -t com.android.cts.devicepolicy.MixedProfileOwnerTest#testResetPasswordWithToken Change-Id: I474822f2e026f24ce6f6de1aa58b5012922f7b13 --- keystore/java/android/security/KeyStore.java | 10 +++++++ .../security/keystore/AndroidKeyStoreSpi.java | 9 +++++- .../android/security/keystore/KeyProtection.java | 33 ++++++++++++++++++++-- .../android/server/SyntheticPasswordCrypto.java | 4 ++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 00d786a93626..244d6e5be6fd 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -93,6 +93,16 @@ public class KeyStore { */ public static final int FLAG_ENCRYPTED = 1; + /** + * A private flag that's only available to system server to indicate that this key is part of + * device encryption flow so it receives special treatment from keystore. For example this key + * will not be super encrypted, and it will be stored separately under an unique UID instead + * of the caller UID i.e. SYSTEM. + * + * Need to be in sync with KeyStoreFlag in system/security/keystore/include/keystore/keystore.h + */ + public static final int FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3; + // States public enum State { UNLOCKED, LOCKED, UNINITIALIZED }; diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java index 64b10ab6eacb..bab4010b90e8 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java @@ -351,6 +351,9 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { } } else if (param instanceof KeyProtection) { spec = (KeyProtection) param; + if (spec.isCriticalToDeviceEncryption()) { + flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION; + } } else { throw new KeyStoreException( "Unsupported protection parameter class:" + param.getClass().getName() @@ -719,6 +722,10 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { } catch (IllegalArgumentException | IllegalStateException e) { throw new KeyStoreException(e); } + int flags = 0; + if (params.isCriticalToDeviceEncryption()) { + flags |= KeyStore.FLAG_CRITICAL_TO_DEVICE_ENCRYPTION; + } Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias, mUid); String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias; @@ -728,7 +735,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { KeymasterDefs.KM_KEY_FORMAT_RAW, keyMaterial, mUid, - 0, // flags + flags, new KeyCharacteristics()); if (errorCode != KeyStore.NO_ERROR) { throw new KeyStoreException("Failed to import secret key. Keystore error code: " diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java index 2592a97468d3..2eb06631c228 100644 --- a/keystore/java/android/security/keystore/KeyProtection.java +++ b/keystore/java/android/security/keystore/KeyProtection.java @@ -227,6 +227,7 @@ public final class KeyProtection implements ProtectionParameter { private final boolean mUserAuthenticationValidWhileOnBody; private final boolean mInvalidatedByBiometricEnrollment; private final long mBoundToSecureUserId; + private final boolean mCriticalToDeviceEncryption; private KeyProtection( Date keyValidityStart, @@ -242,7 +243,8 @@ public final class KeyProtection implements ProtectionParameter { int userAuthenticationValidityDurationSeconds, boolean userAuthenticationValidWhileOnBody, boolean invalidatedByBiometricEnrollment, - long boundToSecureUserId) { + long boundToSecureUserId, + boolean criticalToDeviceEncryption) { mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart); mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd); mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd); @@ -259,6 +261,7 @@ public final class KeyProtection implements ProtectionParameter { mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody; mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment; mBoundToSecureUserId = boundToSecureUserId; + mCriticalToDeviceEncryption = criticalToDeviceEncryption; } /** @@ -457,6 +460,16 @@ public final class KeyProtection implements ProtectionParameter { return mBoundToSecureUserId; } + /** + * Return whether this key is critical to the device encryption flow. + * + * @see android.security.KeyStore#FLAG_CRITICAL_TO_DEVICE_ENCRYPTION + * @hide + */ + public boolean isCriticalToDeviceEncryption() { + return mCriticalToDeviceEncryption; + } + /** * Builder of {@link KeyProtection} instances. */ @@ -477,6 +490,7 @@ public final class KeyProtection implements ProtectionParameter { private boolean mInvalidatedByBiometricEnrollment = true; private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID; + private boolean mCriticalToDeviceEncryption = false; /** * Creates a new instance of the {@code Builder}. * @@ -816,6 +830,20 @@ public final class KeyProtection implements ProtectionParameter { return this; } + /** + * Set whether this key is critical to the device encryption flow + * + * This is a special flag only available to system servers to indicate the current key + * is part of the device encryption flow. + * + * @see android.security.KeyStore#FLAG_CRITICAL_TO_DEVICE_ENCRYPTION + * @hide + */ + public Builder setCriticalToDeviceEncryption(boolean critical) { + mCriticalToDeviceEncryption = critical; + return this; + } + /** * Builds an instance of {@link KeyProtection}. * @@ -837,7 +865,8 @@ public final class KeyProtection implements ProtectionParameter { mUserAuthenticationValidityDurationSeconds, mUserAuthenticationValidWhileOnBody, mInvalidatedByBiometricEnrollment, - mBoundToSecureUserId); + mBoundToSecureUserId, + mCriticalToDeviceEncryption); } } } diff --git a/services/core/java/com/android/server/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/SyntheticPasswordCrypto.java index 12d91c57cdad..71ab2a554071 100644 --- a/services/core/java/com/android/server/SyntheticPasswordCrypto.java +++ b/services/core/java/com/android/server/SyntheticPasswordCrypto.java @@ -139,12 +139,14 @@ public class SyntheticPasswordCrypto { keyStore.load(null); KeyProtection.Builder builder = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE); + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .setCriticalToDeviceEncryption(true); if (sid != 0) { builder.setUserAuthenticationRequired(true) .setBoundToSpecificSecureUserId(sid) .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY); } + keyStore.setEntry(keyAlias, new KeyStore.SecretKeyEntry(secretKey), builder.build()); -- cgit v1.2.3-59-g8ed1b