blob: daf138facc312e80453b5ef034d1a872728faf6b [file] [log] [blame] [view] [edit]
# 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`