Loading services/core/java/com/android/server/locksettings/LockSettingsService.java +18 −9 Original line number Original line Diff line number Diff line Loading @@ -420,7 +420,7 @@ public class LockSettingsService extends ILockSettings.Stub { try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) { try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) { setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId, setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId, /* isLockTiedToParent= */ true); /* isLockTiedToParent= */ true); tieProfileLockToParent(profileUserId, unifiedProfilePassword); tieProfileLockToParent(profileUserId, parentId, unifiedProfilePassword); mManagedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword); mManagedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword); } } } } Loading Loading @@ -1887,34 +1887,43 @@ public class LockSettingsService extends ILockSettings.Stub { } } @VisibleForTesting /** Note: this method is overridden in unit tests */ @VisibleForTesting /** Note: this method is overridden in unit tests */ protected void tieProfileLockToParent(int userId, LockscreenCredential password) { protected void tieProfileLockToParent(int profileUserId, int parentUserId, if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId); LockscreenCredential password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + profileUserId); final byte[] iv; final byte[] iv; final byte[] ciphertext; 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 { try { KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); keyGenerator.init(new SecureRandom()); keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); SecretKey secretKey = keyGenerator.generateKey(); try { try { mJavaKeyStore.setEntry( mJavaKeyStore.setEntry( PROFILE_KEY_NAME_ENCRYPT + userId, PROFILE_KEY_NAME_ENCRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .build()); .build()); mJavaKeyStore.setEntry( mJavaKeyStore.setEntry( PROFILE_KEY_NAME_DECRYPT + userId, PROFILE_KEY_NAME_DECRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setUserAuthenticationRequired(true) .setUserAuthenticationRequired(true) .setBoundToSpecificSecureUserId(parentSid) .setUserAuthenticationValidityDurationSeconds(30) .setUserAuthenticationValidityDurationSeconds(30) .build()); .build()); // Key imported, obtain a reference to it. // Key imported, obtain a reference to it. SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey( SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey( PROFILE_KEY_NAME_ENCRYPT + userId, null); PROFILE_KEY_NAME_ENCRYPT + profileUserId, null); Cipher cipher = Cipher.getInstance( Cipher cipher = Cipher.getInstance( KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE); + KeyProperties.ENCRYPTION_PADDING_NONE); Loading @@ -1923,7 +1932,7 @@ public class LockSettingsService extends ILockSettings.Stub { iv = cipher.getIV(); iv = cipher.getIV(); } finally { } finally { // The original key can now be discarded. // The original key can now be discarded. mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + userId); mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + profileUserId); } } } catch (UnrecoverableKeyException } catch (UnrecoverableKeyException | BadPaddingException | IllegalBlockSizeException | KeyStoreException | BadPaddingException | IllegalBlockSizeException | KeyStoreException Loading @@ -1933,7 +1942,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (iv.length != PROFILE_KEY_IV_SIZE) { if (iv.length != PROFILE_KEY_IV_SIZE) { throw new IllegalArgumentException("Invalid iv length: " + iv.length); 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) { private void setUserKeyProtection(@UserIdInt int userId, byte[] secret) { Loading Loading @@ -2045,7 +2054,7 @@ public class LockSettingsService extends ILockSettings.Stub { LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i); LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i); if (piUserId != -1 && piUserDecryptedPassword != null) { if (piUserId != -1 && piUserDecryptedPassword != null) { if (DEBUG) Slog.v(TAG, "Restore tied profile lock"); if (DEBUG) Slog.v(TAG, "Restore tied profile lock"); tieProfileLockToParent(piUserId, piUserDecryptedPassword); tieProfileLockToParent(piUserId, userId, piUserDecryptedPassword); } } if (piUserDecryptedPassword != null) { if (piUserDecryptedPassword != null) { piUserDecryptedPassword.zeroize(); piUserDecryptedPassword.zeroize(); Loading services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -165,10 +165,11 @@ public class LockSettingsServiceTestable extends LockSettingsService { } } @Override @Override protected void tieProfileLockToParent(int userId, LockscreenCredential password) { protected void tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password) { Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain(); parcel.writeParcelable(password, 0); parcel.writeParcelable(password, 0); mStorage.writeChildProfileLock(userId, parcel.marshall()); mStorage.writeChildProfileLock(profileUserId, parcel.marshall()); parcel.recycle(); parcel.recycle(); } } Loading Loading
services/core/java/com/android/server/locksettings/LockSettingsService.java +18 −9 Original line number Original line Diff line number Diff line Loading @@ -420,7 +420,7 @@ public class LockSettingsService extends ILockSettings.Stub { try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) { try (LockscreenCredential unifiedProfilePassword = generateRandomProfilePassword()) { setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId, setLockCredentialInternal(unifiedProfilePassword, profileUserPassword, profileUserId, /* isLockTiedToParent= */ true); /* isLockTiedToParent= */ true); tieProfileLockToParent(profileUserId, unifiedProfilePassword); tieProfileLockToParent(profileUserId, parentId, unifiedProfilePassword); mManagedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword); mManagedProfilePasswordCache.storePassword(profileUserId, unifiedProfilePassword); } } } } Loading Loading @@ -1887,34 +1887,43 @@ public class LockSettingsService extends ILockSettings.Stub { } } @VisibleForTesting /** Note: this method is overridden in unit tests */ @VisibleForTesting /** Note: this method is overridden in unit tests */ protected void tieProfileLockToParent(int userId, LockscreenCredential password) { protected void tieProfileLockToParent(int profileUserId, int parentUserId, if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId); LockscreenCredential password) { if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + profileUserId); final byte[] iv; final byte[] iv; final byte[] ciphertext; 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 { try { KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); keyGenerator.init(new SecureRandom()); keyGenerator.init(new SecureRandom()); SecretKey secretKey = keyGenerator.generateKey(); SecretKey secretKey = keyGenerator.generateKey(); try { try { mJavaKeyStore.setEntry( mJavaKeyStore.setEntry( PROFILE_KEY_NAME_ENCRYPT + userId, PROFILE_KEY_NAME_ENCRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .build()); .build()); mJavaKeyStore.setEntry( mJavaKeyStore.setEntry( PROFILE_KEY_NAME_DECRYPT + userId, PROFILE_KEY_NAME_DECRYPT + profileUserId, new java.security.KeyStore.SecretKeyEntry(secretKey), new java.security.KeyStore.SecretKeyEntry(secretKey), new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setUserAuthenticationRequired(true) .setUserAuthenticationRequired(true) .setBoundToSpecificSecureUserId(parentSid) .setUserAuthenticationValidityDurationSeconds(30) .setUserAuthenticationValidityDurationSeconds(30) .build()); .build()); // Key imported, obtain a reference to it. // Key imported, obtain a reference to it. SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey( SecretKey keyStoreEncryptionKey = (SecretKey) mJavaKeyStore.getKey( PROFILE_KEY_NAME_ENCRYPT + userId, null); PROFILE_KEY_NAME_ENCRYPT + profileUserId, null); Cipher cipher = Cipher.getInstance( Cipher cipher = Cipher.getInstance( KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE); + KeyProperties.ENCRYPTION_PADDING_NONE); Loading @@ -1923,7 +1932,7 @@ public class LockSettingsService extends ILockSettings.Stub { iv = cipher.getIV(); iv = cipher.getIV(); } finally { } finally { // The original key can now be discarded. // The original key can now be discarded. mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + userId); mJavaKeyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + profileUserId); } } } catch (UnrecoverableKeyException } catch (UnrecoverableKeyException | BadPaddingException | IllegalBlockSizeException | KeyStoreException | BadPaddingException | IllegalBlockSizeException | KeyStoreException Loading @@ -1933,7 +1942,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (iv.length != PROFILE_KEY_IV_SIZE) { if (iv.length != PROFILE_KEY_IV_SIZE) { throw new IllegalArgumentException("Invalid iv length: " + iv.length); 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) { private void setUserKeyProtection(@UserIdInt int userId, byte[] secret) { Loading Loading @@ -2045,7 +2054,7 @@ public class LockSettingsService extends ILockSettings.Stub { LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i); LockscreenCredential piUserDecryptedPassword = profileUserDecryptedPasswords.get(i); if (piUserId != -1 && piUserDecryptedPassword != null) { if (piUserId != -1 && piUserDecryptedPassword != null) { if (DEBUG) Slog.v(TAG, "Restore tied profile lock"); if (DEBUG) Slog.v(TAG, "Restore tied profile lock"); tieProfileLockToParent(piUserId, piUserDecryptedPassword); tieProfileLockToParent(piUserId, userId, piUserDecryptedPassword); } } if (piUserDecryptedPassword != null) { if (piUserDecryptedPassword != null) { piUserDecryptedPassword.zeroize(); piUserDecryptedPassword.zeroize(); Loading
services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +3 −2 Original line number Original line Diff line number Diff line Loading @@ -165,10 +165,11 @@ public class LockSettingsServiceTestable extends LockSettingsService { } } @Override @Override protected void tieProfileLockToParent(int userId, LockscreenCredential password) { protected void tieProfileLockToParent(int profileUserId, int parentUserId, LockscreenCredential password) { Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain(); parcel.writeParcelable(password, 0); parcel.writeParcelable(password, 0); mStorage.writeChildProfileLock(userId, parcel.marshall()); mStorage.writeChildProfileLock(profileUserId, parcel.marshall()); parcel.recycle(); parcel.recycle(); } } Loading