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

Commit 1cfd95ec authored by Max Bires's avatar Max Bires
Browse files

Fixing how SIDs are added to keys during generation time

SIDs were not being properly applied to key parameters under the new
authentication rework. Now that biometric/credential unlocks are valid
for either auth-per-op or timeout auth bound keys, the SIDs need to be
tacked on appropriately in each authentication flow.

Bug: 148425329
Test: CtsVerifier
Change-Id: I73733b00d2da5ac78db6d77c53de144f4473bb54
parent 6e6e2330
Loading
Loading
Loading
Loading
+59 −44
Original line number Diff line number Diff line
@@ -82,38 +82,22 @@ public abstract class KeymasterUtils {
        }
    }

    /**
     * Adds keymaster arguments to express the key's authorization policy supported by user
     * authentication.
     *
     * @param args The arguments sent to keymaster that need to be populated from the spec
     * @param spec The user authentication relevant portions of the spec passed in from the caller.
     *        This spec will be translated into the relevant keymaster tags to be loaded into args.
     * @throws IllegalStateException if user authentication is required but the system is in a wrong
     *         state (e.g., secure lock screen not set up) for generating or importing keys that
     *         require user authentication.
     */
    public static void addUserAuthArgs(KeymasterArguments args, UserAuthArgs spec) {

        if (spec.isUserConfirmationRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
        }

        if (spec.isUserPresenceRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
        }

        if (spec.isUnlockedDeviceRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_UNLOCKED_DEVICE_REQUIRED);
        }

        if (!spec.isUserAuthenticationRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
            return;
    private static void addSids(KeymasterArguments args, UserAuthArgs spec) {
        // If both biometric and credential are accepted, then just use the root sid from gatekeeper
        if (spec.getUserAuthenticationType() == (KeyProperties.AUTH_BIOMETRIC_STRONG
                                                 | KeyProperties.AUTH_DEVICE_CREDENTIAL)) {
            if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
                args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
                        KeymasterArguments.toUint64(spec.getBoundToSpecificSecureUserId()));
            } else {
                // The key is authorized for use for the specified amount of time after the user has
                // authenticated. Whatever unlocks the secure lock screen should authorize this key.
                args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
                        KeymasterArguments.toUint64(getRootSid()));
            }

        if (spec.getUserAuthenticationValidityDurationSeconds() == 0) {
            // Every use of this key needs to be authorized by the user.
        } else {
            List<Long> sids = new ArrayList<>();
            if ((spec.getUserAuthenticationType() & KeyProperties.AUTH_BIOMETRIC_STRONG) != 0) {
                final BiometricManager bm = KeyStore.getApplicationContext()
                        .getSystemService(BiometricManager.class);

@@ -128,7 +112,6 @@ public abstract class KeymasterUtils {
                            + " authentication for every use");
                }

            List<Long> sids = new ArrayList<>();
                if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
                    sids.add(spec.getBoundToSpecificSecureUserId());
                } else if (spec.isInvalidatedByBiometricEnrollment()) {
@@ -142,12 +125,53 @@ public abstract class KeymasterUtils {
                    // enrolled fingerprints, allowing the key to remain valid.
                    sids.add(getRootSid());
                }
            } else if ((spec.getUserAuthenticationType() & KeyProperties.AUTH_DEVICE_CREDENTIAL)
                            != 0) {
                sids.add(getRootSid());
            } else {
                throw new IllegalStateException("Invalid or no authentication type specified.");
            }

            for (int i = 0; i < sids.size(); i++) {
                args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
                        KeymasterArguments.toUint64(sids.get(i)));
            }
        }
    }

    /**
     * Adds keymaster arguments to express the key's authorization policy supported by user
     * authentication.
     *
     * @param args The arguments sent to keymaster that need to be populated from the spec
     * @param spec The user authentication relevant portions of the spec passed in from the caller.
     *        This spec will be translated into the relevant keymaster tags to be loaded into args.
     * @throws IllegalStateException if user authentication is required but the system is in a wrong
     *         state (e.g., secure lock screen not set up) for generating or importing keys that
     *         require user authentication.
     */
    public static void addUserAuthArgs(KeymasterArguments args, UserAuthArgs spec) {

        if (spec.isUserConfirmationRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
        }

        if (spec.isUserPresenceRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
        }

        if (spec.isUnlockedDeviceRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_UNLOCKED_DEVICE_REQUIRED);
        }

        if (!spec.isUserAuthenticationRequired()) {
            args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
            return;
        }

        if (spec.getUserAuthenticationValidityDurationSeconds() == 0) {
            // Every use of this key needs to be authorized by the user.
            addSids(args, spec);
            args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, spec.getUserAuthenticationType());

            if (spec.isUserAuthenticationValidWhileOnBody()) {
@@ -155,16 +179,7 @@ public abstract class KeymasterUtils {
                        + "supported for keys requiring fingerprint authentication");
            }
        } else {
            long sid;
            if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
                sid = spec.getBoundToSpecificSecureUserId();
            } else {
                // The key is authorized for use for the specified amount of time after the user has
                // authenticated. Whatever unlocks the secure lock screen should authorize this key.
                sid = getRootSid();
            }
            args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
                    KeymasterArguments.toUint64(sid));
            addSids(args, spec);
            args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, spec.getUserAuthenticationType());
            args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
                    spec.getUserAuthenticationValidityDurationSeconds());