| // Copyright 2021 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CRYPTOHOME_AUTH_BLOCKS_AUTH_BLOCK_H_ |
| #define CRYPTOHOME_AUTH_BLOCKS_AUTH_BLOCK_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <utility> |
| #include <vector> |
| |
| #include <base/functional/callback.h> |
| |
| #include "cryptohome/auth_factor/auth_factor.h" |
| #include "cryptohome/error/cryptohome_crypto_error.h" |
| #include "cryptohome/error/cryptohome_error.h" |
| #include "cryptohome/error/locations.h" |
| #include "cryptohome/flatbuffer_schemas/auth_block_state.h" |
| #include "cryptohome/key_objects.h" |
| |
| namespace cryptohome { |
| |
| // Defined in cryptohome_metrics.h |
| enum DerivationType : int; |
| |
| // This is a pure virtual interface designed to be implemented by the different |
| // authentication methods - U2F, PinWeaver, TPM backed passwords, etc. - so that |
| // they take some arbitrary user input and give out a key. |
| class AuthBlock { |
| public: |
| // Enumeration used during derive operations to indicate suggested actions for |
| // auth blocks which are valid but sub-optimal in some way (e.g. the block is |
| // using an old or obsolete format, or a weaker policy). |
| enum class SuggestedAction { |
| // Indicates that it would be best to re-create the block. This is usually |
| // used when the block is obsolete in some manner that can be fixed by |
| // replacing the existing block with a freshly created one. Note that as a |
| // side effect this may even change the block type of the factor. |
| kRecreate, |
| }; |
| |
| virtual ~AuthBlock() = default; |
| |
| // If the operation succeeds, |key_blobs| will contain the constructed |
| // KeyBlobs, AuthBlockState will be populated in |auth_block_state| and |
| // |error| will be an ok status. On failure, error will be populated, |
| // and should not rely on the value of key_blobs and auth_block_state. |
| using CreateCallback = base::OnceCallback<void( |
| CryptohomeStatus error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::unique_ptr<AuthBlockState> auth_block_state)>; |
| |
| // This is implemented by concrete auth methods to create a fresh key from |
| // user input. |
| // This asynchronous API receives a callback to construct the KeyBlobs with |
| // the released TPM secrets in an unblocking way. Once the callback is done, |
| // on success, error will be an ok status, KeyBlobs and AuthBlockState will be |
| // populated. On Failure, the error is assigned the related error value, the |
| // value of KeyBlobs and AuthBlockState are not valid to use. |
| virtual void Create(const AuthInput& user_input, |
| const AuthFactorMetadata& auth_factor_metadata, |
| CreateCallback callback) = 0; |
| |
| // On success, |error| will be OK and |key_blobs| will be populated with the |
| // derived key. The value of |suggested_action| may also be set if there are |
| // any suggested actions with the block, but even if this is set the result of |
| // the derivation is still considered valid. On failure, |error| will be |
| // populated and both |key_blobs| and |suggested_action| are undefined. |
| using DeriveCallback = |
| base::OnceCallback<void(CryptohomeStatus error, |
| std::unique_ptr<KeyBlobs> key_blobs, |
| std::optional<SuggestedAction> suggested_action)>; |
| |
| // This is implemented by concrete auth methods to map the user secret |
| // input/credentials into a key. |
| // This asynchronous API receives a callback to construct the KeyBlobs with |
| // the released TPM secrets in an unblocking way. Once the callback is done, |
| // on success, error will be an ok status, KeyBlobs will be populated. On |
| // Failure, error is assigned the related error value, the value of KeyBlobs |
| // are not valid to use. |
| virtual void Derive(const AuthInput& auth_input, |
| const AuthBlockState& state, |
| DeriveCallback callback) = 0; |
| |
| // This is optionally implemented by concrete auth factor methods which need |
| // to execute additional steps before removal of the AuthFactor from disk. |
| virtual void PrepareForRemoval(const ObfuscatedUsername& obfuscated_username, |
| const AuthBlockState& state, |
| StatusCallback callback) { |
| // By default, do nothing. Subclasses can provide custom behavior. |
| return std::move(callback).Run( |
| hwsec_foundation::status::OkStatus<error::CryptohomeCryptoError>()); |
| } |
| |
| // If the operation succeeds, |auth_input| will contain the constructed |
| // AuthInput used for Derive, |auth_factor| will contain the selected |
| // AuthFactor, and |error| will be an ok status. On failure, error will be |
| // populated, and should not rely on the value of auth_input and auth_factor. |
| using SelectFactorCallback = |
| base::OnceCallback<void(CryptohomeStatus error, |
| std::optional<AuthInput> auth_input, |
| std::optional<AuthFactor> auth_factor)>; |
| |
| // This asynchronous API receives a callback to construct the AuthInput used |
| // for deriving key blobs, and to select the correct AuthFactor that should be |
| // used for deriving the key blobs in the candidates |auth_factors|. |
| virtual void SelectFactor(const AuthInput& auth_input, |
| std::vector<AuthFactor> auth_factors, |
| SelectFactorCallback callback) { |
| std::move(callback).Run( |
| hwsec_foundation::status::MakeStatus<error::CryptohomeCryptoError>( |
| CRYPTOHOME_ERR_LOC(kLocAuthBlockSelectFactorNotSupported), |
| error::ErrorActionSet( |
| {error::PossibleAction::kDevCheckUnexpectedState}), |
| CryptoError::CE_OTHER_CRYPTO), |
| std::nullopt, std::nullopt); |
| } |
| |
| DerivationType derivation_type() const { return derivation_type_; } |
| |
| protected: |
| // This is a virtual interface that should not be directly constructed. |
| explicit AuthBlock(DerivationType derivation_type) |
| : derivation_type_(derivation_type) {} |
| |
| private: |
| // For UMA - keeps track of the encryption type used in Derive(). |
| const DerivationType derivation_type_; |
| }; |
| |
| } // namespace cryptohome |
| |
| #endif // CRYPTOHOME_AUTH_BLOCKS_AUTH_BLOCK_H_ |