Cryptohome Modernization APIs Reference

Authors: hardikgoyal@chromium.org, kerrnel@chromium.org

Objective

This document describes the external behavior of the new APIs introduced for the cryptohome modernization project. These APIs are being implemented as of January 2022, and expected to be complete by June 2022.

Background

These APIs cover three large areas of functionality.

  1. Storage - The storage APIs create a user's backing store on disk, and mount the decrypted files using supplied credentials.
  2. AuthSessions - AuthSessions represent a user in cryptohome, and allow multiple API calls to work with an authenticated user. Rather than passing the credentials to each API call, the credential is passed once to Authenticate, and the unique auth session ID is passed to each other call.
  3. AuthFactors - AuthFactors represent the various types of credentials used on Chrome OS. The simplest is the password. There are also smart cards, Android phones (SmartLock), PINs, etc.

Backing Storage Information

There are two separate backing key stores on Chrome OS. VaultKeyset is the legacy keystore, soon to be replaced by UserSecretStash. A user has a copy of a VaultKeyset per credential, making it hard to scale these key stores. UserSecretStash is a universal key store which each credential wraps.

Storage APIs

The user storage APIs are now split into two operations: Create and Prepare, with Create being available for persistent users. All the users (Guest, Ephemeral and Persistent) will call Prepare<type>Vault. The Prepare<type> calls used to be called Mount, but Prepare better reflects that the call is doing many things (setting up device mappers, registering file system keys, bind mounting) and not only a mount.

Here is more about the APIs:

  1. PrepareGuestVault - This request is intended to happen when a user wants to login to ChromeOS as a guest.
    • Input: None
    • Reply: - CryptohomeErrorCode - Returns if any error occurred. - sanitized_username: A hash of the username, which is part of the path of the mounted homedir.
  2. PrepareEphemeralVault - This request is intended when a policy (either device or enterprise) has enabled ephemeral users. An ephemeral user is created in a memory filesystem only and is never actually persisted to disk.
    • Input: auth_session_id
    • Reply: - CryptohomeErrorCode - Returns if any error occurred. - sanitized_username: A hash of the username, which is part of the path of the mounted homedir.
  3. CreatePersistentUser - This will create user directories needed to store keys and download policies. This will usually be called when a new user is registering.
    • Input: auth_session_id
    • Reply: CryptohomeErrorCode - Returns if any error occurred.
  4. PreparePersistentVault - This makes available user directories for them to use.
    • Input:
      • auth_sesion_id: AuthSession Id of an Authenticated AuthSession.
      • block_ecryptfs: Whether ecryptfs mount should be prohibited.
      • encryption_type - Expected encryption_type.
    • Reply: - CryptohomeErrorCode - Returns if any error occurred. - sanitized_username: A hash of the username, which is part of the path of the mounted homedir.
  5. PrepareVaultForMigration - Mounts vault in order to perform the migration of encryption. StartMigration can work only with the vault mounted with PrepareVaultForMigration.
    • Input:
      • auth_session_id: AuthSession Id of an Authenticated AuthSession.
    • Reply:
      • CryptohomeErrorCode - Returns if any error occurred.
      • sanitized_username: A hash of the username, which is part of the path of the mounted homedir.

AuthSession APIs

These are the APIs that AuthSession supports:

  1. StartAuthSession - This will start an AuthSession for a given user.
    • Input: - Account_id - user’s username
      • flags - These determine how an AuthSession is configured. There is only one flag configured as of now, which is for ephemeral users.
    • Reply: - CryptohomeErrorCode - Returns if any error occurred.
      • Auth_session_id - This will be used to identify AuthSession after this call.
      • user_exists - Returns if the user exists.
      • map<string, cryptohome.KeyData> - Map to return label and public key data for the available keysets.
    • Note: - By default this AuthSession is valid for 5 minutes from the time the session reaches an Authenticated State. ExtendAuthSession can be called to extend the session or StartAuthSession to start over.
    • Note: - Running parallel operations on the same AuthSession auth_session_id is prohibited. This means that in order to run any dbus call on the session, you must wait for the previous call to finish.
    • Note: - However, while there are no restrictions on operations for AuthSessions with different auth_session_id’s, there is also no guarantee of synchronized user state for AuthSessions with the same user. This is a current grey area for cryptohome.
  2. InvalidateAuthSession - This call is used to invalidate an AuthSession once the need for one no longer exists.
    • Input: auth_session_id - AuthSession to invalidate.
    • Reply: CryptohomeErrorCode - Returns if there is any error.
  3. ExtendAuthSession - This call is used to extend the duration of AuthSession that it should be valid for.
    • Input:
      • auth_session_id - AuthSession that needs extending.
      • extend_duration - The number of seconds to extend the AuthSession by. If nothing is provided, this would default to 60 seconds.
    • Reply: Cryptohome Error Code

AuthFactor APIs

Here are the APIs that are used to work with AuthFactors .

  1. AddAuthFactor - This call adds an AuthFactor for a user. The call goes through an authenticated AuthSession.

    • Input:
      • auth_session_id - AuthSession used to identify users. The AuthSession needs to be authenticated for this call to be a success.
      • auth_factor - AuthFactor information about the new factor to be added.
      • auth_input - This is set if any input is required for the AuthFactor, such as text for a Password AuthFactor.
    • Reply:
      • CryptohomeErrorCode - Returns if there is any error
      • AuthFactorWithStatus - Returns the newly updated AuthFactor with a list of intents the factor is available for.
  2. AuthenticateAuthFactor - Authenticates an existing AuthFactor and sets the AuthSession's authorized_for intents based on the type of authentication that occurred. If the factor that is authenticated enables more intents than requested, the AuthSession will be authorized for those intents. Calling AuthenticateAuthFactor again on an already authenticated AuthSession will not downgrade the intents, but it may upgrade the authorized_for intents based on the factor used, and will reset timer for AuthSession to the default, five minutes.

    • Input:
      • auth_session_id - AuthSession used to identify users. The AuthSession needs to be authenticated for this call to be a success.
      • auth_factor_label - The label that will be used to identify an AuthFactor to authenticate.
      • auth_input - This is set if any input is required for the AuthFactor, such as text for a PasswordAuthFactor.
    • Reply:
      • CryptohomeErrorCode - Returns if there is any error
  3. UpdateAuthFactor - This call will be used in the case of a user wanting to update an AuthFactor. (E.g. Changing pin or password).

    • Input: -auth_session_id - AuthSession used to identify users. The AuthSession needs to be authenticated for this call to be a success.
      • auth_factor_label - The label that will be used to identify an AuthFactor to update.
      • auth_factor - AuthFactor information about the new factor that will replace the existing.
      • auth_input - This is set if any input is required for the AuthFactor, such as text for a Password AuthFactor.
    • Reply:
      • CryptohomeErrorCode - Returns if there is any error.
      • AuthFactorWithStatus - Returns the newly updated AuthFactor with a list of intents the factor is available for.
  4. RemoveAuthFactor - This is called when a user wants to remove an AuthFactor.

    • Input:
      • auth_session_id - AuthSession used to identify users. The AuthSession needs to be authenticated for this call to be a success.
      • auth_factor_label - The label that will be used to identify an AuthFactor to remove.
    • Reply:
      • CryptohomeErrorCode - Returns if there is any error
  5. ListAuthFactor - This call will list all of the configured AuthFactors for a given user as well as the supported types of auth factors.

    • Input:
      • account_id - The username of the user.
    • Reply:
      • CryptohomeErrorCode - Returns if there is any error.
      • configured_auth_factors - The persistent auth factors that have currently been configured (e.g. by a prior AddAuthFactor call) for this user.
      • supported_auth_factors - The types of auth factors supported for this user. Should include all configured factor types as well as any additional types that could be added.
    • Usage:
      • The user specified does not have to be in an authenticated state. However, if the user does not exist (on-disk) or have an active session then this will report an INVALID_ARGUMENT error.
      • The configured factors reported will be all currently persisted factors. This list can be empty, for example if the user is emphemeral, or if a persistent user has been created but no factors have yet been added.
      • The supported factor types reported are based on the type of user (persistent or ephemeral), the local hardware available, and the set of existing configured factors. Some examples of how these factors could impact what is supported:
        • Support for PIN factors depends on having sufficiently advanced TPM hardware and firmware.
        • If the user has a Kiosk factor configured, all other types of factors will be unavailable.
        • Conversely, if the user has at least one non-Kiosk factor configured then a Kiosk factor will not be reported as a supported option.
  6. PrepareAuthFactor - This call is required for specific types of non-knowledge-based auth factors before AuthenticateAuthFactor or AddAuthFactor is called with those auth factors. It usually stats a sensor session for the specified auth factor type. It also initiates a signal sender broadcasting a AuthScanResult signal, which contains the scan result for the specified auth factor type.

    • Input:
      • auth_session_id - AuthSession used to identify users.
      • auth_factor_type - The type of AuthFactor that is being prepared.
      • purpose - A enum to identify the following action after this PrepareAuthFactor completes.
    • Reply
      • CryptohomeErrorCode - Returns if there is any error.
    • Usage:
      • Set the purpose to PURPOSE_ADD_AUTH_FACTOR, when we intend to have a follow up AddAuthFactor. The auth session should be already authenticated.
      • Set the purpose to PURPOSE_AUTHENTICATE_AUTH_FACTOR, when we intend to have a follow up AuthenticateAuthFactor. The auth session may not be already authenticated.
  7. TerminateAuthFactor - This call is required after PrepareAuthFactor is called with an auth factor type. It will shut down any underlying sensor sessions. It will also shut down the signal sender associated with the auth factor type.

    • Input:
      • auth_session_id - AuthSession used to identify users.
      • auth_factor_type - The type of AuthFactor that is being prepared.
    • Reply
      • CryptohomeErrorCode - Returns if there is any error.
    • Usage:
      • Properly terminate the underlying sensor session.
  8. UpdateAuthFactorMetadata - This call will be used in the case of a user wanting to update an AuthFactor's metadata. (E.g. Changing FP Label).

    • Input: -auth_session_id - AuthSession used to identify users. The AuthSession needs to be authenticated for this call to be a success.
      • auth_factor_label - The label that will be used to identify an AuthFactor to update.
      • auth_factor - AuthFactor information about the existing factor that will replace the existing. Note: No new AuthFactor will be created here and no secrets are modified.
    • Reply:
      • CryptohomeErrorCode - Returns if there is any error.
      • AuthFactorWithStatus - Returns the newly updated AuthFactor with a list of intents the factor is available for.

Order of Operations

Add New User to Chromebook

  1. StartAuthSession – Chrome initiates an AuthSession.
  2. CreatePersistentUser – Creates on-disk user representation and put the AuthSession into authenticated state.
  3. PreparePersistentVault - At this point it is safe to fetch any userpolicy.
  4. AddAuthFactor
    • Upon adding the first AuthFactor, cryptohome will save the USS to disk. If there is a crash before this call is successful, the user is not persisted.
    • This can be called multiple times. If there is a need ExtendAuthSession should be used.
  5. InvalidateAuthSession

Chrome Sign in an Existing User

  1. StartAuthSession – Chrome initiates an AuthSession. This time user_exists should return true and AuthSession will not start in an authenticated state.
  2. AuthenticateAuthFactor
    • If this call is a success, then move to the next step.
  3. PreparePersistentVault
    • At this point it is safe to fetch any userpolicy.
  4. InvalidateAuthSession

Chrome Adds an AuthFactor for an Existing User

  1. StartAuthSession – Chrome initiates an AuthSession. This time user_exists should return true and AuthSession will not start in an authenticated state.
  2. AuthenticateAuthFactor
    • If this call is a success, then move to the next step.
  3. AddAuthFactor
    • This can be called multiple times. If there is a need ExtendAuthSession should be used.
  4. InvalidateAuthSession

Chrome Removes a user

This case can happen when a user forgets their password and chooses to start as a fresh user.

  1. StartAuthSession – Chrome initiates an AuthSession. This time user_exists should return true and AuthSession will not start in an authenticated state.
  2. Remove
    • This call will take AuthSessionId as input. Upon successful completion, it will invalidate AuthSession to ensure a clean removal of user.

Chrome starts a Guest Session

There will not be any requirement for AuthSession here as this account is totally temporary.

  1. PrepareGuestVault

Chrome starts an Ephemeral User Session

  1. StartAuthSession – Chrome initiates an AuthSession.
  2. PrepareEpehemeralVault
  3. AddAuthFactor
    • This is in case of managed guest session (adding a temporary pin).
  4. InvalidateAuthSession

Note that if the global ephemeral policy is enabled, Chrome will need to remove any persistent users present.

Chrome wants to migrate eCryptfs to DirCrypto encryption scheme

  1. StartAuthSession – Chrome initiates an AuthSession.
  2. AuthenticateAuthFactor
  3. PrepareVaultForMigration
  4. StartMigrateToDircrypto
    • Ensure that this is called with the auth_session_id field set.
  5. InvalidateAuthSession

Chrome wants to do fingerprint screen unlock

  1. StartAuthSession - Chrome initiates an AuthSession with AuthIntent Verify.
  2. PrepareAuthFactor
    • PrepareAuthFactorRequest expects to contain an auth factor type of LegacyFingerprint.
    • An fingerprint sensor session is started to collect a fingerprint press.
    • A success response indicates an fingerprint session has started.
    • A failure response means the session start has failed.
    • Upon a successful invocation, a signal sender that broadcasts signal AuthScanResult for legacy fingerprint is initialized.
  3. Listen on crypthome signal AuthScanResult.
    • It is a success. Chrome should proceed to call AuthenticationAuthFactor to find out the authentication result.
    • It is a failure and indicating fingerprint auth has been locked out. Chrome should tell the user the fingerprint auth has failed for the current AuthSession. No fingerprint attempt will be accepted in the current fingerprint sensor session.
  4. AuthenticateAuthFactor
    • It is a auth success, the fingerprint is matched.
    • It is a auth failure. Chrome should continue listen for another fingerprint scan attempt.
    • Chrome should ask the user to make another fingerprint attempt.
    • It is a auth failure and indicating fingerprint retry limit has been reached, Chrome should tell the user the fingerprint auth has failed for the current AuthSession. No further fingerprint attempt will be accepted in the current fingerprint sensor session.
  5. TerminateAuthFactor
    • End the active fingerprint sensor session.
    • The sender that broadcasts AuthScanResult for legacy fingerprint is terminated.
  6. InvalidateAuthSession
    • If there are any outstanding snesor sessions, they will be ended automatically, similar to what TerminateAuthFactor has done.

Chrome wants to do fingerprint WebAuthn

  1. StartAuthSession - Chrome initiates an AuthSession with AuthIntent WebAuthn.
  2. PrepareAuthFactor
    • An fingerprint sensor session is started to collect a fingerprint press.
    • The fingerprint session is ended after a fingerprint image is captured.
  3. AuthenticateAuthFactor
    • It is a success, the fingerprint is matched and WebAuthn is fulfilled.
    • It is a failure and indicating another auth retry is possible, Chrome should repeat from Step 2 PrepareAuthFactor for another attempt.
    • It is a failure and indicating fingerprint retry limit has been reached, Chrome should not further attempt fingerprint auth in the same AuthSession.
  4. TerminateAuthFactor
    • The completion of PrepareAuthFactor (receiving error or successful result) should ensure no further signals will be emitted and fingerprint sensor session ended. However, in case Chrome wants to abort the session early, TerminateAuthFactor has to be called. Also, it's a good idea to always call TerminateAuthFactor when the WebAuthn dialog is destructed.
  5. InvalidateAuthSession
    • Now the prepared WebAuthn secret resides outside the auth session, so it‘s safe for Chrome to call InvalidateAuthSession here. In the future when we move WebAuthn secret into auth session, Chrome shouldn’t process this step, but return the auth session ID to u2fd in a successful response of WebAuthn verification, then let u2fd do the InvalidateAuthSession.

Chrome wants to do PIN/password WebAuthn

  1. StartAuthSession - Chrome initiates an AuthSession with AuthIntent WebAuthn.
  2. AuthenticateAuthFactor
    • It is a success, WebAuthn is fulfilled.
    • It is a failure, retry using password or PIN if not locked out yet.
  3. InvalidateAuthSession
    • Now the prepared WebAuthn secret resides outside the auth session, so it‘s safe for Chrome to call InvalidateAuthSession here. In the future when we move WebAuthn secret into auth session, Chrome shouldn’t process this step, but return the auth session ID to u2fd in a successful response of WebAuthn verification, then let u2fd do the InvalidateAuthSession.

Chrome wants to do UpdateAuthFactorMetata for Any Factor

  1. StartAuthSession - Chrome initiates an AuthSession with AUTH_INTENT_DECRYPT AuthIntent.
  2. AuthenticateAuthFactor
  3. UpdateAuthFactorMetadata -
    • Ensure that AuthFactor provided has all information, existing and any new information that needs to be updated.
    • Any metadata field that is updated by cryptohome will be ignored.
  4. InvalidateAuthSession