encryptor.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CRYPTO_ENCRYPTOR_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CRYPTO_ENCRYPTOR_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_piece.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/crypto_export.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/scoped_nss_types.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SymmetricKey; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CRYPTO_EXPORT Encryptor { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Mode { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CBC, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CTR, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This class implements a 128-bits counter to be used in AES-CTR encryption. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only 128-bits counter is supported in this class. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class CRYPTO_EXPORT Counter { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit Counter(const base::StringPiece& counter); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Counter(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Increment the counter value. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Increment(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write the content of the counter to |buf|. |buf| should have enough 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // space for |GetLengthInBytes()|. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Write(void* buf); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return the length of this counter. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t GetLengthInBytes() const; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) union { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 components32[4]; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint64 components64[2]; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } counter_; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Encryptor(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Encryptor(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes the encryptor using |key| and |iv|. Returns false if either the 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // key or the initialization vector cannot be used. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |mode| is CBC, |iv| must not be empty; if it is CTR, then |iv| must be 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // empty. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(SymmetricKey* key, Mode mode, const base::StringPiece& iv); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Encrypts |plaintext| into |ciphertext|. |plaintext| may only be empty if 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the mode is CBC. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Encrypt(const base::StringPiece& plaintext, std::string* ciphertext); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decrypts |ciphertext| into |plaintext|. |ciphertext| must not be empty. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WARNING: In CBC mode, Decrypt() returns false if it detects the padding 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the decrypted plaintext is wrong. Padding errors can result from 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tampered ciphertext or a wrong decryption key. But successful decryption 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // does not imply the authenticity of the data. The caller of Decrypt() 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // must either authenticate the ciphertext before decrypting it, or take 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // care to not report decryption failure. Otherwise it could inadvertently 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be used as a padding oracle to attack the cryptosystem. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Decrypt(const base::StringPiece& ciphertext, std::string* plaintext); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sets the counter value when in CTR mode. Currently only 128-bits 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // counter value is supported. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true only if update was successful. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SetCounter(const base::StringPiece& counter); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(albertb): Support streaming encryption. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generates a mask using |counter_| to be used for encryption in CTR mode. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resulting mask will be written to |mask| with |mask_len| bytes. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure there's enough space in mask when calling this method. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reserve at least |plaintext_len| + 16 bytes for |mask|. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The generated mask will always have at least |plaintext_len| bytes and 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be a multiple of the counter length. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method is used only in CTR mode. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns false if this call failed. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GenerateCounterMask(size_t plaintext_len, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* mask, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t* mask_len); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mask the |plaintext| message using |mask|. The output will be written to 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |ciphertext|. |ciphertext| must have at least |plaintext_len| bytes. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MaskMessage(const void* plaintext, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t plaintext_len, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* mask, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* ciphertext) const; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SymmetricKey* key_; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Mode mode_; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Counter> counter_; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_OPENSSL) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Crypt(bool encrypt, // Pass true to encrypt, false to decrypt. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& input, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* output); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string iv_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Crypt(PK11Context* context, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& input, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* output); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CryptCTR(PK11Context* context, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece& input, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* output); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedSECItem param_; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace crypto 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CRYPTO_ENCRYPTOR_H_ 135