| // 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_ |