summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nikolay Elenkov <nikolayelenkov@google.com> 2024-06-30 06:20:30 +0000
committer Nikolay Elenkov <nikolayelenkov@google.com> 2024-06-30 06:20:30 +0000
commit9cdf9eae2e02a6c3651379c33c4655368b009d13 (patch)
treeb3cbfae779407a57ad99d9388843aa894fe23413
parentde5889aa13af0ad7ba10c4449e012172e9e6e051 (diff)
RESTRICT AUTOMERGE Delete keystore keys from RecoveryService.rebootRecoveryWithCommand()
Adds deleteSecrets() to RecoverySystemService. This method is called from rebootRecoveryWithCommand () before the --wipe_data command is passed to recovery and the device is force-rebooted. deleteSecerts() calls IKeystoreMaintenance.deleteAllKeys() in order to quickly destroy the keys protecting the synthetic password blobs used to derive FBE encryption keys. The intent is to make FBE-encrypted data unrecoverable even if the full data wipe in recovery is interrupted or skipped. Bug: 324321147 Test: Manual - System -> Reset options -> Erase all data. Test: Hold VolDown key to interrupt reboot and stop at bootloader screen. Test: fastboot oem bcd wipe command && fastboot oem bcd wipe recovery Test: fastboot reboot Test: Device reboots into recovery and prompts to factory reset: Test: 'Cannot load Android system. Your data may be corrupt. ...' (cherry picked from https://android-review.googlesource.com/q/commit:0d00031851e9f5d8ef93947205a7e8b5257f0d8d) Merged-In: I5eb8e97f3ae1a18d5e7e7c2c7eca048ebff3440a Change-Id: I5eb8e97f3ae1a18d5e7e7c2c7eca048ebff3440a Ignore-AOSP-First: Security fix backport
-rw-r--r--keystore/java/android/security/AndroidKeyStoreMaintenance.java22
-rw-r--r--services/core/java/com/android/server/recoverysystem/RecoverySystemService.java19
2 files changed, 41 insertions, 0 deletions
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index 919a93b8f107..b2d1755bb860 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -18,8 +18,10 @@ package android.security;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceSpecificException;
+import android.os.StrictMode;
import android.security.maintenance.IKeystoreMaintenance;
import android.system.keystore2.Domain;
import android.system.keystore2.KeyDescriptor;
@@ -183,4 +185,24 @@ public class AndroidKeyStoreMaintenance {
return SYSTEM_ERROR;
}
}
+
+ /**
+ * Deletes all keys in all KeyMint devices.
+ * Called by RecoverySystem before rebooting to recovery in order to delete all KeyMint keys,
+ * including synthetic password protector keys (used by LockSettingsService), as well as keys
+ * protecting DE and metadata encryption keys (used by vold). This ensures that FBE-encrypted
+ * data is unrecoverable even if the data wipe in recovery is interrupted or skipped.
+ */
+ public static void deleteAllKeys() throws KeyStoreException {
+ StrictMode.noteDiskWrite();
+ try {
+ getService().deleteAllKeys();
+ } catch (RemoteException | NullPointerException e) {
+ throw new KeyStoreException(SYSTEM_ERROR,
+ "Failure to connect to Keystore while trying to delete all keys.");
+ } catch (ServiceSpecificException e) {
+ throw new KeyStoreException(e.errorCode,
+ "Keystore error while trying to delete all keys.");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 13218731af70..23941bc338b8 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -52,6 +52,7 @@ import android.os.ShellCallback;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.sysprop.ApexProperties;
+import android.security.AndroidKeyStoreMaintenance;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.FastImmutableArraySet;
@@ -66,6 +67,7 @@ import com.android.internal.widget.RebootEscrowListener;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.pm.ApexManager;
+import com.android.server.utils.Slogf;
import libcore.io.IoUtils;
@@ -117,6 +119,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
static final String LSKF_CAPTURED_TIMESTAMP_PREF = "lskf_captured_timestamp";
static final String LSKF_CAPTURED_COUNT_PREF = "lskf_captured_count";
+ static final String RECOVERY_WIPE_DATA_COMMAND = "--wipe_data";
+
private final Injector mInjector;
private final Context mContext;
@@ -511,17 +515,32 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo
@Override // Binder call
public void rebootRecoveryWithCommand(String command) {
if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
+
+ boolean isForcedWipe = command != null && command.contains(RECOVERY_WIPE_DATA_COMMAND);
synchronized (sRequestLock) {
if (!setupOrClearBcb(true, command)) {
return;
}
+ if (isForcedWipe) {
+ deleteSecrets();
+ }
+
// Having set up the BCB, go ahead and reboot.
PowerManager pm = mInjector.getPowerManager();
pm.reboot(PowerManager.REBOOT_RECOVERY);
}
}
+ private static void deleteSecrets() {
+ Slogf.w(TAG, "deleteSecrets");
+ try {
+ AndroidKeyStoreMaintenance.deleteAllKeys();
+ } catch (android.security.KeyStoreException e) {
+ Log.wtf(TAG, "Failed to delete all keys from keystore.", e);
+ }
+ }
+
private void enforcePermissionForResumeOnReboot() {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY)
!= PackageManager.PERMISSION_GRANTED