Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 747a0b78 authored by Eric Biggers's avatar Eric Biggers Committed by Android (Google) Code Review
Browse files

Merge changes from topic "remove-auth-token"

* changes:
  Remove HardwareAuthToken parameter from unlockUserKey
  Remove HardwareAuthToken parameter from clearUserKeyAuth
  Remove HardwareAuthToken parameter from addUserKeyAuth
  Don't pass HardwareAuthToken to unlockUser() in non-SP verifyCredential
  Remove non-SP based setLockCredentialInternal()
  Remove HardwareAuthToken support from FakeStorageManager
parents 4ea37d98 b1bcec9c
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -173,13 +173,13 @@ interface IStorageManager {
    void setDebugFlags(int flags, int mask) = 60;
    void createUserKey(int userId, int serialNumber, boolean ephemeral) = 61;
    void destroyUserKey(int userId) = 62;
    void unlockUserKey(int userId, int serialNumber, in byte[] token, in byte[] secret) = 63;
    void unlockUserKey(int userId, int serialNumber, in byte[] secret) = 63;
    void lockUserKey(int userId) = 64;
    boolean isUserKeyUnlocked(int userId) = 65;
    void prepareUserStorage(in String volumeUuid, int userId, int serialNumber, int flags) = 66;
    void destroyUserStorage(in String volumeUuid, int userId, int flags) = 67;
    boolean isConvertibleToFBE() = 68;
    void addUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 70;
    void addUserKeyAuth(int userId, int serialNumber, in byte[] secret) = 70;
    void fixateNewestUserKeyAuth(int userId) = 71;
    void fstrim(int flags, IVoldTaskListener listener) = 72;
    AppFuseMount mountProxyFileDescriptorBridge() = 73;
@@ -195,7 +195,7 @@ interface IStorageManager {
    void startCheckpoint(int numTries) = 85;
    boolean needsCheckpoint() = 86;
    void abortChanges(in String message, boolean retry) = 87;
    void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88;
    void clearUserKeyAuth(int userId, int serialNumber, in byte[] secret) = 88;
    void fixupAppDir(in String path) = 89;
    void disableAppDataIsolation(in String pkgName, int pid, int userId) = 90;
    PendingIntent getManageSpaceActivityIntent(in String packageName, int requestCode) = 91;
+2 −2
Original line number Diff line number Diff line
@@ -1624,9 +1624,9 @@ public class StorageManager {
    }

    /** {@hide} */
    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
    public void unlockUserKey(int userId, int serialNumber, byte[] secret) {
        try {
            mStorageManager.unlockUserKey(userId, serialNumber, token, secret);
            mStorageManager.unlockUserKey(userId, serialNumber, secret);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+20 −21
Original line number Diff line number Diff line
@@ -1127,8 +1127,7 @@ class StorageManagerService extends IStorageManager.Stub
                    if (initLocked) {
                        mVold.lockUserKey(user.id);
                    } else {
                        mVold.unlockUserKey(user.id, user.serialNumber, encodeBytes(null),
                                encodeBytes(null));
                        mVold.unlockUserKey(user.id, user.serialNumber, encodeBytes(null));
                    }
                } catch (Exception e) {
                    Slog.wtf(TAG, e);
@@ -3470,43 +3469,45 @@ class StorageManagerService extends IStorageManager.Stub
    }

    /*
     * Add this token/secret pair to the set of ways we can recover a disk encryption key.
     * Changing the token/secret for a disk encryption key is done in two phases: first, adding
     * a new token/secret pair with this call, then delting all other pairs with
     * fixateNewestUserKeyAuth. This allows other places where a credential is used, such as
     * Gatekeeper, to be updated between the two calls.
     * Add this secret to the set of ways we can recover a user's disk
     * encryption key.  Changing the secret for a disk encryption key is done in
     * two phases.  First, this method is called to add the new secret binding.
     * Second, fixateNewestUserKeyAuth is called to delete all other bindings.
     * This allows other places where a credential is used, such as Gatekeeper,
     * to be updated between the two calls.
     */
    @Override
    public void addUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) {
    public void addUserKeyAuth(int userId, int serialNumber, byte[] secret) {
        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);

        try {
            mVold.addUserKeyAuth(userId, serialNumber, encodeBytes(token), encodeBytes(secret));
            mVold.addUserKeyAuth(userId, serialNumber, encodeBytes(secret));
        } catch (Exception e) {
            Slog.wtf(TAG, e);
        }
    }

    /*
     * Clear disk encryption key bound to the associated token / secret pair. Removing the user
     * binding of the Disk encryption key is done in two phases: first, this call will retrieve
     * the disk encryption key using the provided token / secret pair and store it by
     * encrypting it with a keymaster key not bound to the user, then fixateNewestUserKeyAuth
     * is called to delete all other bindings of the disk encryption key.
     * Store a user's disk encryption key without secret binding.  Removing the
     * secret for a disk encryption key is done in two phases.  First, this
     * method is called to retrieve the key using the provided secret and store
     * it encrypted with a keystore key not bound to the user.  Second,
     * fixateNewestUserKeyAuth is called to delete the key's other bindings.
     */
    @Override
    public void clearUserKeyAuth(int userId, int serialNumber, byte[] token, byte[] secret) {
    public void clearUserKeyAuth(int userId, int serialNumber, byte[] secret) {
        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);

        try {
            mVold.clearUserKeyAuth(userId, serialNumber, encodeBytes(token), encodeBytes(secret));
            mVold.clearUserKeyAuth(userId, serialNumber, encodeBytes(secret));
        } catch (Exception e) {
            Slog.wtf(TAG, e);
        }
    }

    /*
     * Delete all disk encryption token/secret pairs except the most recently added one
     * Delete all bindings of a user's disk encryption key except the most
     * recently added one.
     */
    @Override
    public void fixateNewestUserKeyAuth(int userId) {
@@ -3520,11 +3521,10 @@ class StorageManagerService extends IStorageManager.Stub
    }

    @Override
    public void unlockUserKey(int userId, int serialNumber, byte[] token, byte[] secret) {
    public void unlockUserKey(int userId, int serialNumber, byte[] secret) {
        boolean isFsEncrypted = StorageManager.isFileEncryptedNativeOrEmulated();
        Slog.d(TAG, "unlockUserKey: " + userId
                + " isFileEncryptedNativeOrEmulated: " + isFsEncrypted
                + " hasToken: " + (token != null)
                + " hasSecret: " + (secret != null));
        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);

@@ -3544,8 +3544,7 @@ class StorageManagerService extends IStorageManager.Stub
                return;
            }
            try {
                mVold.unlockUserKey(userId, serialNumber, encodeBytes(token),
                        encodeBytes(secret));
                mVold.unlockUserKey(userId, serialNumber, encodeBytes(secret));
            } catch (Exception e) {
                Slog.wtf(TAG, e);
                return;
+16 −2
Original line number Diff line number Diff line
@@ -15644,9 +15644,23 @@ public class ActivityManagerService extends IActivityManager.Stub
        return mUserController.startUser(userId, /* foreground */ true, unlockListener);
    }
    /**
     * Unlocks the given user.
     *
     * @param userId The ID of the user to unlock.
     * @param token No longer used.  (This parameter cannot be removed because
     *              this method is marked with UnsupportedAppUsage, so its
     *              signature might not be safe to change.)
     * @param secret The secret needed to unlock the user's credential-encrypted
     *               storage, or null if no secret is needed.
     * @param listener An optional progress listener.
     *
     * @return true if the user was successfully unlocked, otherwise false.
     */
    @Override
    public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
        return mUserController.unlockUser(userId, token, secret, listener);
    public boolean unlockUser(int userId, @Nullable byte[] token, @Nullable byte[] secret,
            @Nullable IProgressListener listener) {
        return mUserController.unlockUser(userId, secret, listener);
    }
    @Override
+12 −21
Original line number Diff line number Diff line
@@ -741,15 +741,9 @@ class UserController implements Handler.Callback {
        if (!Objects.equals(info.lastLoggedInFingerprint, PackagePartitions.FINGERPRINT)
                || SystemProperties.getBoolean("persist.pm.mock-upgrade", false)) {
            // Suppress double notifications for managed profiles that
            // were unlocked automatically as part of their parent user
            // being unlocked.
            final boolean quiet;
            if (info.isManagedProfile()) {
                quiet = !uss.tokenProvided
                        || !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
            } else {
                quiet = false;
            }
            // were unlocked automatically as part of their parent user being
            // unlocked.  TODO(b/217442918): this code doesn't work correctly.
            final boolean quiet = info.isManagedProfile();
            mInjector.sendPreBootBroadcast(userId, quiet,
                    () -> finishUserUnlockedCompleted(uss));
        } else {
@@ -1690,27 +1684,25 @@ class UserController implements Handler.Callback {
        }
    }

    boolean unlockUser(final @UserIdInt int userId, byte[] token, byte[] secret,
            IProgressListener listener) {
    boolean unlockUser(final @UserIdInt int userId, byte[] secret, IProgressListener listener) {
        checkCallingPermission(INTERACT_ACROSS_USERS_FULL, "unlockUser");
        EventLog.writeEvent(EventLogTags.UC_UNLOCK_USER, userId);
        final long binderToken = Binder.clearCallingIdentity();
        try {
            return unlockUserCleared(userId, token, secret, listener);
            return unlockUserCleared(userId, secret, listener);
        } finally {
            Binder.restoreCallingIdentity(binderToken);
        }
    }

    /**
     * Attempt to unlock user without a credential token. This typically
     * succeeds when the device doesn't have credential-encrypted storage, or
     * when the credential-encrypted storage isn't tied to a user-provided
     * PIN or pattern.
     * Attempt to unlock user without a secret. This typically succeeds when the
     * device doesn't have credential-encrypted storage, or when the
     * credential-encrypted storage isn't tied to a user-provided PIN or
     * pattern.
     */
    private boolean maybeUnlockUser(final @UserIdInt int userId) {
        // Try unlocking storage using empty token
        return unlockUserCleared(userId, null, null, null);
        return unlockUserCleared(userId, null, null);
    }

    private static void notifyFinished(@UserIdInt int userId, IProgressListener listener) {
@@ -1721,7 +1713,7 @@ class UserController implements Handler.Callback {
        }
    }

    private boolean unlockUserCleared(final @UserIdInt int userId, byte[] token, byte[] secret,
    private boolean unlockUserCleared(final @UserIdInt int userId, byte[] secret,
            IProgressListener listener) {
        UserState uss;
        if (!StorageManager.isUserKeyUnlocked(userId)) {
@@ -1729,7 +1721,7 @@ class UserController implements Handler.Callback {
            final IStorageManager storageManager = mInjector.getStorageManager();
            try {
                // We always want to unlock user storage, even user is not started yet
                storageManager.unlockUserKey(userId, userInfo.serialNumber, token, secret);
                storageManager.unlockUserKey(userId, userInfo.serialNumber, secret);
            } catch (RemoteException | RuntimeException e) {
                Slogf.w(TAG, "Failed to unlock: " + e.getMessage());
            }
@@ -1739,7 +1731,6 @@ class UserController implements Handler.Callback {
            uss = mStartedUsers.get(userId);
            if (uss != null) {
                uss.mUnlockProgress.addListener(listener);
                uss.tokenProvided = (token != null);
            }
        }
        // Bail if user isn't actually running
Loading