| // Copyright 2023 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_USER_SECRET_STASH_ENCRYPTED_H_ |
| #define CRYPTOHOME_USER_SECRET_STASH_ENCRYPTED_H_ |
| |
| #include <stdint.h> |
| |
| #include <map> |
| #include <optional> |
| #include <set> |
| #include <string> |
| #include <string_view> |
| |
| #include <brillo/secure_blob.h> |
| |
| #include "cryptohome/error/cryptohome_error.h" |
| #include "cryptohome/flatbuffer_schemas/user_secret_stash_container.h" |
| #include "cryptohome/user_secret_stash/storage.h" |
| |
| namespace cryptohome { |
| |
| // This class represents a raw encrypted User Secret Stash (USS). It can be |
| // constructed directly from a raw representation of the underlying data |
| // structures of the USS but also provides factories to (attempt to) construct |
| // it from one of the forms it can be stored in. |
| // |
| // All of the sensitive data in the USS is kept in its encrypted form, hence the |
| // name ("Encrypted"). The class does provide functions to decrypt the contents |
| // of the USS but it must be given a key to do so. |
| class EncryptedUss { |
| public: |
| // Passkey object used to restrict some functions to DecryptedUss. Only |
| // DecryptedUss can construct this and so functions only it should call |
| // require it as a parameter. |
| class Passkey { |
| private: |
| friend class DecryptedUss; |
| Passkey() = default; |
| }; |
| |
| // Container for a wrapped (encrypted) USS main key. |
| struct WrappedKeyBlock { |
| // The algorithm used for wrapping the USS main key. |
| UserSecretStashEncryptionAlgorithm encryption_algorithm; |
| // This is the encrypted USS main key. |
| brillo::Blob encrypted_key; |
| // The random IV used in the USS main key encryption. |
| brillo::Blob iv; |
| // The GCM tag generated by the block cipher. |
| brillo::Blob gcm_tag; |
| }; |
| |
| // Container for the entire stash. |
| struct Container { |
| // The encrypted ciphertext of the secret stash. |
| brillo::Blob ciphertext; |
| // The random IV used in the ciphertext encryption. |
| brillo::Blob iv; |
| // The GCM tag generated by the block cipher. |
| brillo::Blob gcm_tag; |
| // A map of the wrapped key blocks, using the wrapping ID as key. |
| std::map<std::string, WrappedKeyBlock> wrapped_key_blocks; |
| // The Chrome OS version on which this stash was originally created. |
| std::string created_on_os_version; |
| // Unencrypted user metadata. |
| UserMetadata user_metadata; |
| |
| // Attempt to load a container structure from a serialized USS blob. |
| static CryptohomeStatusOr<Container> FromBlob( |
| const brillo::Blob& flatbuffer); |
| }; |
| |
| // Attempt to construct an encrypted USS from a raw flatbuffer. |
| static CryptohomeStatusOr<EncryptedUss> FromBlob( |
| const brillo::Blob& flatbuffer); |
| // Attempt to construct an encrypted USS from a user's persistent storage. |
| static CryptohomeStatusOr<EncryptedUss> FromStorage( |
| const UserUssStorage& storage); |
| |
| // Create a stash backed by the given container. |
| explicit EncryptedUss(Container container); |
| |
| EncryptedUss(const EncryptedUss&) = delete; |
| EncryptedUss& operator=(const EncryptedUss&) = delete; |
| EncryptedUss(EncryptedUss&&) = default; |
| EncryptedUss& operator=(EncryptedUss&&) = default; |
| |
| // Decrypt the USS ciphertext using the given main key. |
| CryptohomeStatusOr<brillo::SecureBlob> DecryptPayload( |
| const brillo::SecureBlob& main_key) const; |
| |
| // The set of wrapping IDs contained in the store. |
| std::set<std::string_view> WrappedMainKeyIds() const; |
| |
| // Unwrap the main key using the given wrapping ID and key. |
| CryptohomeStatusOr<brillo::SecureBlob> UnwrapMainKey( |
| const std::string& wrapping_id, |
| const brillo::SecureBlob& wrapping_key) const; |
| |
| // The OS version on which this particular user secret stash was originally |
| // created. The format is the one of the CHROMEOS_RELEASE_VERSION field in |
| // /etc/lsb-release, e.g.: "11012.0.2018_08_28_1422". Empty if the version |
| // fetch failed at the creation time. |
| // |
| // !!!WARNING!!!: This value is not authenticated nor validated. It must not |
| // be used for security-critical features. |
| const std::string& created_on_os_version() const { |
| return container_.created_on_os_version; |
| } |
| |
| // The ID of the fingerprint rate limiter, if it exists. |
| std::optional<uint64_t> fingerprint_rate_limiter_id() const { |
| return container_.user_metadata.fingerprint_rate_limiter_id; |
| } |
| |
| // The rollout number of legacy fingerprint migration, if it exists. |
| std::optional<uint64_t> legacy_fingerprint_migration_rollout() const { |
| return container_.user_metadata.legacy_fingerprint_migration_rollout; |
| } |
| |
| // Return the full user metadata. |
| const UserMetadata& user_metadata() const { return container_.user_metadata; } |
| |
| // Return the raw container. Only accessible to specific friend classes. |
| const Container& container(Passkey) const { return container_; } |
| |
| // Convert the container to a raw flatbuffer. This produces output that can be |
| // used with FromBlob. |
| CryptohomeStatusOr<brillo::Blob> ToBlob() const; |
| // Attempt to write the encrypted to a user's persistent storage. |
| CryptohomeStatus ToStorage(UserUssStorage& storage) const; |
| |
| private: |
| Container container_; |
| }; |
| |
| } // namespace cryptohome |
| |
| #endif // CRYPTOHOME_USER_SECRET_STASH_ENCRYPTED_H_ |