blob: 2e76fd4db73c874ef4003e1cde03dae907f7efbf [file] [log] [blame] [edit]
// 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_