blob: 0b487fab8edaa099cff50b431c89e7f123fccc54 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_OS_CRYPT_APP_BOUND_ENCRYPTION_WIN_H_
#define CHROME_BROWSER_OS_CRYPT_APP_BOUND_ENCRYPTION_WIN_H_
#include <optional>
#include <string>
#include "base/feature_list.h"
#include "base/win/windows_types.h"
#include "chrome/elevation_service/elevation_service_idl.h"
#include "chrome/elevation_service/elevator.h"
class PrefService;
namespace os_crypt {
namespace features {
// If enabled, App-Bound encryption will attempt re-encryption of decrypted data
// if signaled that it should be re-encrypted.
BASE_DECLARE_FEATURE(kAppBoundDataReencrypt);
} // namespace features
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class SupportLevel {
// kSupported is the only level where both decrypt and encrypt operations are
// fully supported.
kSupported = 0,
// Not running system level means no cryptographic operations are available,
// and all calls will fail.
kNotSystemLevel = 1,
// The following enum values indicate that app-bound encryption can be
// attempted, and decrypt operations may succeed, but encrypt operations
// should not be carried out as the system has indicated that the storage may
// not be fully reliable or disabled by policy.
kNotLocalDisk = 2,
kApiFailed = 3,
kNotUsingDefaultUserDataDir = 4,
kUserDataDirNotLocalDisk = 5,
kDisabledByPolicy = 6,
kDisabledByRoamingWindowsProfile = 7,
kDisabledByRoamingChromeProfile = 8,
kMaxValue = kDisabledByRoamingChromeProfile,
};
// For tests, this can be overriden and a concrete instance passed to
// `SetOverridesForTesting` to override the behavior of App-Bound encryption
// APIs.
class AppBoundEncryptionOverridesForTesting {
public:
virtual ~AppBoundEncryptionOverridesForTesting() = default;
virtual HRESULT EncryptAppBoundString(
ProtectionLevel level,
const std::string& plaintext,
std::string& ciphertext,
DWORD& last_error,
elevation_service::EncryptFlags* flags) = 0;
virtual HRESULT DecryptAppBoundString(
const std::string& ciphertext,
std::string& plaintext,
ProtectionLevel protection_level,
std::optional<std::string>& new_ciphertext,
DWORD& last_error,
elevation_service::EncryptFlags* flags) = 0;
virtual SupportLevel GetAppBoundEncryptionSupportLevel(
PrefService* local_state) = 0;
};
// Returns whether or not app-bound encryption is supported on the current
// platform configuration. If this does not return kSupported then Encrypt and
// Decrypt operations will fail. This can be called on any thread.
SupportLevel GetAppBoundEncryptionSupportLevel(PrefService* local_state);
// Encrypts a string with a Protection level of `level`. See
// `src/chrome/elevation_service/elevation-service_idl.idl` for the definition
// of available protection levels.
//
// If `flags` is supplied, then this can control the behavior of the Encrypt
// operation. See `EncryptFlags` in `elevator.h` for more details.
//
// This returns an HRESULT as defined by src/chrome/elevation_service/elevator.h
// or S_OK for success. If the call fails then `last_error` will be set to the
// value returned from the most recent failing Windows API call or
// ERROR_GEN_FAILURE.
//
// This should be called on a COM-enabled thread.
HRESULT EncryptAppBoundString(ProtectionLevel level,
const std::string& plaintext,
std::string& ciphertext,
DWORD& last_error,
elevation_service::EncryptFlags* flags = nullptr);
// Decrypts a string previously encrypted by a call to EncryptAppBoundString.
//
// This returns an HRESULT as defined by src/chrome/elevation_service/elevator.h
// or S_OK for success. If the call fails then `last_error` will be set to the
// value returned from the most recent failing Windows API call or
// ERROR_GEN_FAILURE.
//
// App-Bound may recommend re-encryption of the data, for example if the key has
// been rotated. If so, `new_ciphertext` will contain the re-encrypted data
// according to the `protection_level` specified with the `flags`, if also
// specified.
//
// This should be called on a COM-enabled thread.
HRESULT DecryptAppBoundString(const std::string& ciphertext,
std::string& plaintext,
ProtectionLevel protection_level,
std::optional<std::string>& new_ciphertext,
DWORD& last_error,
elevation_service::EncryptFlags* flags = nullptr);
// Set to nullptr to reset.
void SetOverridesForTesting(AppBoundEncryptionOverridesForTesting* overrides);
} // namespace os_crypt
#endif // CHROME_BROWSER_OS_CRYPT_APP_BOUND_ENCRYPTION_WIN_H_