Fix work profile with unified challenge in HSUM

Manually set the SID for the auth-bound key that protects unified
challenge to the one of the parent user.

Bug: 248248444
Test: atest com.android.server.locksettings
      atest ManagedProfilePasswordTest
Change-Id: I8dc9f5c4aed3d2eaa0104e526d7cdaa7edf92770
This commit is contained in:
Rubin Xu
2023-01-24 16:16:47 +00:00
parent 5c6c582940
commit 85a0ffe976
2 changed files with 21 additions and 11 deletions

View File

@@ -420,7 +420,7 @@ public class LockSettingsService extends ILockSettings.Stub {
try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) {
setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId,
/* isLockTiedToParent= */ true);
tieProfileLockToParent(profileUserId, unifiedProfilePassword);
tieProfileLockToParent(profileUserId, parentId, unifiedProfilePassword);
mManagedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword);
}
}
@@ -1887,34 +1887,43 @@ public class LockSettingsService extends ILockSettings.Stub {
}
@VisibleForTesting /** Note: this method is overridden in unit tests */
protected void tieProfileLockToParent(int userId, LockscreenCredential password) {
if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId);
protected void tieProfileLockToParent(int profileUserId, int parentUserId,
LockscreenCredential password) {
if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + profileUserId);
final byte[] iv;
final byte[] ciphertext;
final long parentSid;
try {
parentSid = getGateKeeperService().getSecureUserId(parentUserId);
} catch (RemoteException e) {
throw new IllegalStateException("Failed to talk to GateKeeper service", e);
}
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES);
keyGenerator.init(new SecureRandom());
SecretKey secretKey = keyGenerator.generateKey();
try {
mJavaKeyStore.setEntry(
PROFILE_KEY_NAME_ENCRYPT + userId,
PROFILE_KEY_NAME_ENCRYPT + profileUserId,
new java.security.KeyStore.SecretKeyEntry(secretKey),
new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());
mJavaKeyStore.setEntry(
PROFILE_KEY_NAME_DECRYPT + userId,
PROFILE_KEY_NAME_DECRYPT + profileUserId,
new java.security.KeyStore.SecretKeyEntry(secretKey),
new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setUserAuthenticationRequired(true)
.setBoundToSpecificSecureUserId(parentSid)
.setUserAuthenticationValidityDurationSeconds(30)
.build());
// Key imported, obtain a reference to it.
SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey(
PROFILE_KEY_NAME_ENCRYPT + userId, null);
PROFILE_KEY_NAME_ENCRYPT + profileUserId, null);
Cipher cipher = Cipher.getInstance(
KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/"
+ KeyProperties.ENCRYPTION_PADDING_NONE);
@@ -1923,7 +1932,7 @@ public class LockSettingsService extends ILockSettings.Stub {
iv = cipher.getIV();
} finally {
// The original key can now be discarded.
mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + userId);
mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + profileUserId);
}
} catch (UnrecoverableKeyException
| BadPaddingException | IllegalBlockSizeException | KeyStoreException
@@ -1933,7 +1942,7 @@ public class LockSettingsService extends ILockSettings.Stub {
if (iv.length != PROFILE_KEY_IV_SIZE) {
throw new IllegalArgumentException("Invalid iv length: " + iv.length);
}
mStorage.writeChildProfileLock(userId, ArrayUtils.concat(iv, ciphertext));
mStorage.writeChildProfileLock(profileUserId, ArrayUtils.concat(iv, ciphertext));
}
private void setUserKeyProtection(@UserIdInt int userId, byte[] secret) {
@@ -2045,7 +2054,7 @@ public class LockSettingsService extends ILockSettings.Stub {
LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i);
if (piUserId != -1 && piUserDecryptedPassword != null) {
if (DEBUG) Slog.v(TAG, "Restore tied profile lock");
tieProfileLockToParent(piUserId, piUserDecryptedPassword);
tieProfileLockToParent(piUserId, userId, piUserDecryptedPassword);
}
if (piUserDecryptedPassword != null) {
piUserDecryptedPassword.zeroize();

View File

@@ -165,10 +165,11 @@ public class LockSettingsServiceTestable extends LockSettingsService {
}
@Override
protected void tieProfileLockToParent(int userId, LockscreenCredential password) {
protected void tieProfileLockToParent(int profileUserId, int parentUserId,
LockscreenCredential password) {
Parcel parcel = Parcel.obtain();
parcel.writeParcelable(password, 0);
mStorage.writeChildProfileLock(userId, parcel.marshall());
mStorage.writeChildProfileLock(profileUserId, parcel.marshall());
parcel.recycle();
}