| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CRYPTO_ENCRYPTOR_H_ |
| #define CRYPTO_ENCRYPTOR_H_ |
| |
| #include <string> |
| |
| #include "base/basictypes.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/string_piece.h" |
| #include "build/build_config.h" |
| #include "crypto/crypto_export.h" |
| |
| #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) |
| #include "crypto/scoped_nss_types.h" |
| #endif |
| |
| namespace crypto { |
| |
| class SymmetricKey; |
| |
| class CRYPTO_EXPORT Encryptor { |
| public: |
| enum Mode { |
| CBC, |
| CTR, |
| }; |
| |
| // This class implements a 128-bits counter to be used in AES-CTR encryption. |
| // Only 128-bits counter is supported in this class. |
| class CRYPTO_EXPORT Counter { |
| public: |
| explicit Counter(const base::StringPiece& counter); |
| ~Counter(); |
| |
| // Increment the counter value. |
| bool Increment(); |
| |
| // Write the content of the counter to |buf|. |buf| should have enough |
| // space for |GetLengthInBytes()|. |
| void Write(void* buf); |
| |
| // Return the length of this counter. |
| size_t GetLengthInBytes() const; |
| |
| private: |
| union { |
| uint32 components32[4]; |
| uint64 components64[2]; |
| } counter_; |
| }; |
| |
| Encryptor(); |
| virtual ~Encryptor(); |
| |
| // Initializes the encryptor using |key| and |iv|. Returns false if either the |
| // key or the initialization vector cannot be used. |
| // |
| // If |mode| is CBC, |iv| must not be empty; if it is CTR, then |iv| must be |
| // empty. |
| bool Init(SymmetricKey* key, Mode mode, const base::StringPiece& iv); |
| |
| // Encrypts |plaintext| into |ciphertext|. |plaintext| may only be empty if |
| // the mode is CBC. |
| bool Encrypt(const base::StringPiece& plaintext, std::string* ciphertext); |
| |
| // Decrypts |ciphertext| into |plaintext|. |ciphertext| must not be empty. |
| // |
| // WARNING: In CBC mode, Decrypt() returns false if it detects the padding |
| // in the decrypted plaintext is wrong. Padding errors can result from |
| // tampered ciphertext or a wrong decryption key. But successful decryption |
| // does not imply the authenticity of the data. The caller of Decrypt() |
| // must either authenticate the ciphertext before decrypting it, or take |
| // care to not report decryption failure. Otherwise it could inadvertently |
| // be used as a padding oracle to attack the cryptosystem. |
| bool Decrypt(const base::StringPiece& ciphertext, std::string* plaintext); |
| |
| // Sets the counter value when in CTR mode. Currently only 128-bits |
| // counter value is supported. |
| // |
| // Returns true only if update was successful. |
| bool SetCounter(const base::StringPiece& counter); |
| |
| // TODO(albertb): Support streaming encryption. |
| |
| private: |
| // Generates a mask using |counter_| to be used for encryption in CTR mode. |
| // Resulting mask will be written to |mask| with |mask_len| bytes. |
| // |
| // Make sure there's enough space in mask when calling this method. |
| // Reserve at least |plaintext_len| + 16 bytes for |mask|. |
| // |
| // The generated mask will always have at least |plaintext_len| bytes and |
| // will be a multiple of the counter length. |
| // |
| // This method is used only in CTR mode. |
| // |
| // Returns false if this call failed. |
| bool GenerateCounterMask(size_t plaintext_len, |
| uint8* mask, |
| size_t* mask_len); |
| |
| // Mask the |plaintext| message using |mask|. The output will be written to |
| // |ciphertext|. |ciphertext| must have at least |plaintext_len| bytes. |
| void MaskMessage(const void* plaintext, |
| size_t plaintext_len, |
| const void* mask, |
| void* ciphertext) const; |
| |
| SymmetricKey* key_; |
| Mode mode_; |
| scoped_ptr<Counter> counter_; |
| |
| #if defined(USE_OPENSSL) |
| bool Crypt(bool encrypt, // Pass true to encrypt, false to decrypt. |
| const base::StringPiece& input, |
| std::string* output); |
| std::string iv_; |
| #elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) |
| bool Crypt(PK11Context* context, |
| const base::StringPiece& input, |
| std::string* output); |
| bool CryptCTR(PK11Context* context, |
| const base::StringPiece& input, |
| std::string* output); |
| ScopedSECItem param_; |
| #endif |
| }; |
| |
| } // namespace crypto |
| |
| #endif // CRYPTO_ENCRYPTOR_H_ |