1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 <string> 9 10 #include "base/basictypes.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/strings/string_piece.h" 13 #include "build/build_config.h" 14 #include "crypto/crypto_export.h" 15 16 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) 17 #include "crypto/scoped_nss_types.h" 18 #endif 19 20 namespace crypto { 21 22 class SymmetricKey; 23 24 class CRYPTO_EXPORT Encryptor { 25 public: 26 enum Mode { 27 CBC, 28 CTR, 29 }; 30 31 // This class implements a 128-bits counter to be used in AES-CTR encryption. 32 // Only 128-bits counter is supported in this class. 33 class CRYPTO_EXPORT Counter { 34 public: 35 explicit Counter(const base::StringPiece& counter); 36 ~Counter(); 37 38 // Increment the counter value. 39 bool Increment(); 40 41 // Write the content of the counter to |buf|. |buf| should have enough 42 // space for |GetLengthInBytes()|. 43 void Write(void* buf); 44 45 // Return the length of this counter. 46 size_t GetLengthInBytes() const; 47 48 private: 49 union { 50 uint32 components32[4]; 51 uint64 components64[2]; 52 } counter_; 53 }; 54 55 Encryptor(); 56 virtual ~Encryptor(); 57 58 // Initializes the encryptor using |key| and |iv|. Returns false if either the 59 // key or the initialization vector cannot be used. 60 // 61 // If |mode| is CBC, |iv| must not be empty; if it is CTR, then |iv| must be 62 // empty. 63 bool Init(SymmetricKey* key, Mode mode, const base::StringPiece& iv); 64 65 // Encrypts |plaintext| into |ciphertext|. |plaintext| may only be empty if 66 // the mode is CBC. 67 bool Encrypt(const base::StringPiece& plaintext, std::string* ciphertext); 68 69 // Decrypts |ciphertext| into |plaintext|. |ciphertext| must not be empty. 70 // 71 // WARNING: In CBC mode, Decrypt() returns false if it detects the padding 72 // in the decrypted plaintext is wrong. Padding errors can result from 73 // tampered ciphertext or a wrong decryption key. But successful decryption 74 // does not imply the authenticity of the data. The caller of Decrypt() 75 // must either authenticate the ciphertext before decrypting it, or take 76 // care to not report decryption failure. Otherwise it could inadvertently 77 // be used as a padding oracle to attack the cryptosystem. 78 bool Decrypt(const base::StringPiece& ciphertext, std::string* plaintext); 79 80 // Sets the counter value when in CTR mode. Currently only 128-bits 81 // counter value is supported. 82 // 83 // Returns true only if update was successful. 84 bool SetCounter(const base::StringPiece& counter); 85 86 // TODO(albertb): Support streaming encryption. 87 88 private: 89 // Generates a mask using |counter_| to be used for encryption in CTR mode. 90 // Resulting mask will be written to |mask| with |mask_len| bytes. 91 // 92 // Make sure there's enough space in mask when calling this method. 93 // Reserve at least |plaintext_len| + 16 bytes for |mask|. 94 // 95 // The generated mask will always have at least |plaintext_len| bytes and 96 // will be a multiple of the counter length. 97 // 98 // This method is used only in CTR mode. 99 // 100 // Returns false if this call failed. 101 bool GenerateCounterMask(size_t plaintext_len, 102 uint8* mask, 103 size_t* mask_len); 104 105 // Mask the |plaintext| message using |mask|. The output will be written to 106 // |ciphertext|. |ciphertext| must have at least |plaintext_len| bytes. 107 void MaskMessage(const void* plaintext, 108 size_t plaintext_len, 109 const void* mask, 110 void* ciphertext) const; 111 112 SymmetricKey* key_; 113 Mode mode_; 114 scoped_ptr<Counter> counter_; 115 116 #if defined(USE_OPENSSL) 117 bool Crypt(bool do_encrypt, // Pass true to encrypt, false to decrypt. 118 const base::StringPiece& input, 119 std::string* output); 120 bool CryptCTR(bool do_encrypt, 121 const base::StringPiece& input, 122 std::string* output); 123 std::string iv_; 124 #elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) 125 bool Crypt(PK11Context* context, 126 const base::StringPiece& input, 127 std::string* output); 128 bool CryptCTR(PK11Context* context, 129 const base::StringPiece& input, 130 std::string* output); 131 ScopedSECItem param_; 132 #endif 133 }; 134 135 } // namespace crypto 136 137 #endif // CRYPTO_ENCRYPTOR_H_ 138