1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CRYPTO_ENCRYPTOR_H_ 6 #define CRYPTO_ENCRYPTOR_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <memory> 12 #include <optional> 13 #include <string> 14 #include <string_view> 15 16 #include "base/containers/span.h" 17 #include "base/memory/raw_ptr.h" 18 #include "build/build_config.h" 19 #include "crypto/crypto_export.h" 20 21 namespace crypto { 22 23 class SymmetricKey; 24 25 // This class implements encryption without authentication, which is usually 26 // unsafe. Prefer crypto::Aead for new code. If using this class, prefer the 27 // base::span and std::vector overloads over the std::string_view and 28 // std::string overloads. 29 class CRYPTO_EXPORT Encryptor { 30 public: 31 enum Mode { 32 CBC, 33 CTR, 34 }; 35 36 Encryptor(); 37 ~Encryptor(); 38 39 // Initializes the encryptor using |key| and |iv|. Returns false if either the 40 // key or the initialization vector cannot be used. 41 // 42 // If |mode| is CBC, |iv| must not be empty; if it is CTR, then |iv| must be 43 // empty. 44 bool Init(const SymmetricKey* key, Mode mode, std::string_view iv); 45 bool Init(const SymmetricKey* key, Mode mode, base::span<const uint8_t> iv); 46 47 // Encrypts |plaintext| into |ciphertext|. |plaintext| may only be empty if 48 // the mode is CBC. 49 bool Encrypt(std::string_view plaintext, std::string* ciphertext); 50 bool Encrypt(base::span<const uint8_t> plaintext, 51 std::vector<uint8_t>* ciphertext); 52 53 // Decrypts |ciphertext| into |plaintext|. |ciphertext| must not be empty. 54 // 55 // WARNING: In CBC mode, Decrypt() returns false if it detects the padding 56 // in the decrypted plaintext is wrong. Padding errors can result from 57 // tampered ciphertext or a wrong decryption key. But successful decryption 58 // does not imply the authenticity of the data. The caller of Decrypt() 59 // must either authenticate the ciphertext before decrypting it, or take 60 // care to not report decryption failure. Otherwise it could inadvertently 61 // be used as a padding oracle to attack the cryptosystem. 62 bool Decrypt(std::string_view ciphertext, std::string* plaintext); 63 bool Decrypt(base::span<const uint8_t> ciphertext, 64 std::vector<uint8_t>* plaintext); 65 66 // Sets the counter value when in CTR mode. Currently only 128-bits 67 // counter value is supported. 68 // 69 // Returns true only if update was successful. 70 bool SetCounter(std::string_view counter); 71 bool SetCounter(base::span<const uint8_t> counter); 72 73 // TODO(albertb): Support streaming encryption. 74 75 private: 76 raw_ptr<const SymmetricKey, DanglingUntriaged> key_; 77 Mode mode_; 78 79 bool CryptString(bool do_encrypt, 80 std::string_view input, 81 std::string* output); 82 bool CryptBytes(bool do_encrypt, 83 base::span<const uint8_t> input, 84 std::vector<uint8_t>* output); 85 86 // On success, these helper functions return the number of bytes written to 87 // |output|. 88 size_t MaxOutput(bool do_encrypt, size_t length); 89 std::optional<size_t> Crypt(bool do_encrypt, 90 base::span<const uint8_t> input, 91 base::span<uint8_t> output); 92 std::optional<size_t> CryptCTR(bool do_encrypt, 93 base::span<const uint8_t> input, 94 base::span<uint8_t> output); 95 96 // In CBC mode, the IV passed to Init(). In CTR mode, the counter value passed 97 // to SetCounter(). 98 std::vector<uint8_t> iv_; 99 }; 100 101 } // namespace crypto 102 103 #endif // CRYPTO_ENCRYPTOR_H_ 104