From 0f7dea9083a8ce11bf876ce4f8610bb286af6a2e Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 23 Jul 2022 00:28:02 +0000 Subject: [PATCH] Request rollback resistance for SP protector keys When supported, use rollback resistance for synthetic password (SP) protector keys, i.e. the Keystore keys that encrypt the SP for a user. This allows SP protectors to be securely deleted on devices that don't support Weaver, but do support rollback-resistant Keystore keys. Secure deletion of SP protectors is necessary to guarantee that user data cannot be accessed using old LSKFs or deactivated escrow tokens. This also aligns LockSettingsService with vold, which already uses rollback-resistant Keystore keys (when supported) to encrypt all storage keys that aren't bound to the SP. Bug: 239632930 Test: atest com.android.server.locksettings (on Cuttlefish) Test: On Cuttlefish, which doesn't support rollback-resistant keys, set an LSKF and checked for the expected log message from SyntheticPasswordCrypto ("Rollback-resistant keys unavailable.."). Test: On Raven, which supports rollback-resistant keys, set an LSKF and checked for the expected log message from SyntheticPasswordCrypto ("Using rollback-resistant key"). Also made some temporary changes to log the rollback resistance property of the key, and verified that it really got set. Change-Id: I05f3b7e5c139471febe5c266a39e3dc3bca4831f --- .../locksettings/SyntheticPasswordCrypto.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java index 371ef76b1ba6c..b06af8e5a385e 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java @@ -17,6 +17,7 @@ package com.android.server.locksettings; import android.security.AndroidKeyStoreMaintenance; +import android.security.keymaster.KeymasterDefs; import android.security.keystore.KeyProperties; import android.security.keystore.KeyProtection; import android.security.keystore2.AndroidKeyStoreLoadStoreParameter; @@ -210,10 +211,26 @@ public class SyntheticPasswordCrypto { .setBoundToSpecificSecureUserId(sid) .setUserAuthenticationValidityDurationSeconds(USER_AUTHENTICATION_VALIDITY); } + final KeyProtection protNonRollbackResistant = builder.build(); + builder.setRollbackResistant(true); + final KeyProtection protRollbackResistant = builder.build(); + final KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(keyStoreKey); + try { + keyStore.setEntry(keyAlias, entry, protRollbackResistant); + Slog.i(TAG, "Using rollback-resistant key"); + } catch (KeyStoreException e) { + if (!(e.getCause() instanceof android.security.KeyStoreException)) { + throw e; + } + int errorCode = ((android.security.KeyStoreException) e.getCause()).getErrorCode(); + if (errorCode != KeymasterDefs.KM_ERROR_ROLLBACK_RESISTANCE_UNAVAILABLE) { + throw e; + } + Slog.w(TAG, "Rollback-resistant keys unavailable. Falling back to " + + "non-rollback-resistant key"); + keyStore.setEntry(keyAlias, entry, protNonRollbackResistant); + } - keyStore.setEntry(keyAlias, - new KeyStore.SecretKeyEntry(keyStoreKey), - builder.build()); byte[] intermediate = encrypt(protectorSecret, PROTECTOR_SECRET_PERSONALIZATION, data); return encrypt(keyStoreKey, intermediate); } catch (CertificateException | IOException | BadPaddingException