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