blob: bbe1b01b2694d0140549a0deeb2c45496982edc2 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_OS_CRYPT_ASYNC_COMMON_ENCRYPTOR_H_
#define COMPONENTS_OS_CRYPT_ASYNC_COMMON_ENCRYPTOR_H_
#include <map>
#include <optional>
#include <string>
#include <vector>
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "mojo/public/cpp/bindings/default_construct_tag.h"
namespace mojo {
template <typename DataViewType, typename T>
struct StructTraits;
} // namespace mojo
namespace os_crypt_async {
namespace mojom {
enum class Algorithm;
class EncryptorDataView;
class KeyDataView;
} // namespace mojom
class EncryptorTestBase;
class OSCryptAsync;
class TestOSCryptAsync;
// This class is used for data encryption. A thread-safe instance can be
// obtained by calling `os_crypt_async::OSCryptAsync::GetInstance`.
class COMPONENT_EXPORT(OS_CRYPT_ASYNC) Encryptor {
public:
// A class used by the Encryptor to hold an encryption key and carry out
// encryption and decryption operations using the specified Algorithm and
// encryption key.
class COMPONENT_EXPORT(OS_CRYPT_ASYNC) Key {
public:
// Moveable, not copyable.
Key(Key&& other);
Key& operator=(Key&& other);
Key(const Key&) = delete;
Key& operator=(const Key&) = delete;
~Key();
static const size_t kAES256GCMKeySize = 256u / 8u;
// Mojo uses this public constructor for serialization.
explicit Key(mojo::DefaultConstruct::Tag);
Key(base::span<const uint8_t> key, const mojom::Algorithm& algo);
bool operator==(const Key& other) const = default;
private:
friend class Encryptor;
// OSCryptAsync and tests need to be able to Clone() keys.
friend class OSCryptAsync;
friend struct mojo::StructTraits<os_crypt_async::mojom::KeyDataView,
os_crypt_async::Encryptor::Key>;
FRIEND_TEST_ALL_PREFIXES(EncryptorTestBase, MultipleKeys);
FRIEND_TEST_ALL_PREFIXES(EncryptorTraitsTest, TraitsRoundTrip);
std::vector<uint8_t> Encrypt(base::span<const uint8_t> plaintext) const;
std::optional<std::vector<uint8_t>> Decrypt(
base::span<const uint8_t> ciphertext) const;
Key Clone() const;
// Algorithm. Can only be std::nullopt if the instance is in the process of
// being serialized to/from mojo.
std::optional<mojom::Algorithm> algorithm_;
std::vector<uint8_t> key_;
};
using KeyRing = std::map</*tag=*/std::string, Key>;
// Mojo uses this public constructor for serialization.
explicit Encryptor(mojo::DefaultConstruct::Tag);
~Encryptor();
// Moveable, not copyable.
Encryptor(Encryptor&& other);
Encryptor& operator=(Encryptor&& other);
Encryptor(const Encryptor&) = delete;
Encryptor& operator=(const Encryptor&) = delete;
// Encrypt a string with the current Encryptor configuration. This can be
// called on any thread.
[[nodiscard]] std::optional<std::vector<uint8_t>> EncryptString(
const std::string& data) const;
// Decrypt data previously encrypted using `EncryptData`. This can be called
// on any thread.
[[nodiscard]] std::optional<std::string> DecryptData(
base::span<const uint8_t> data) const;
// These two APIs are provided for backwards compatibility with OSCrypt. They
// just call the above functions. The two sets of functions are compatible
// with each other.
[[nodiscard]] bool EncryptString(const std::string& plaintext,
std::string* ciphertext) const;
[[nodiscard]] bool DecryptString(const std::string& ciphertext,
std::string* plaintext) const;
private:
friend class TestOSCryptAsync;
friend class EncryptorTestBase;
friend class OSCryptAsync;
friend struct mojo::StructTraits<os_crypt_async::mojom::EncryptorDataView,
os_crypt_async::Encryptor>;
FRIEND_TEST_ALL_PREFIXES(EncryptorTraitsTest, TraitsRoundTrip);
// Create an encryptor with no keys or encryption provider. In this case, all
// encryption operations will be delegated to OSCrypt.
Encryptor();
// Create an encryptor with a set of `keys`. The `provider_for_encryption`
// specifies which provider is used for encryption, and must have a
// corresponding key in `keys`.
Encryptor(KeyRing keys, const std::string& provider_for_encryption);
// Clone is used by the factory to vend instances.
Encryptor Clone() const;
// A KeyRing consists of a set of provider names and Key values. Encrypted
// data is always tagged with the provider name and this is used to look up
// the correct key to use for decryption.
KeyRing keys_;
// The provider with this tag is used when encrypting any new data, the Key to
// use for the encryption is looked up from the entry in the KeyRing.
std::string provider_for_encryption_;
};
} // namespace os_crypt_async
#endif // COMPONENTS_OS_CRYPT_ASYNC_COMMON_ENCRYPTOR_H_