token_encryptor.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1// Copyright 2013 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#include "chrome/browser/chromeos/settings/token_encryptor.h" 6 7#include <vector> 8 9#include "base/logging.h" 10#include "base/strings/string_number_conversions.h" 11#include "base/strings/string_util.h" 12#include "base/sys_info.h" 13#include "chromeos/cryptohome/system_salt_getter.h" 14#include "crypto/encryptor.h" 15#include "crypto/nss_util.h" 16#include "crypto/sha2.h" 17#include "crypto/symmetric_key.h" 18 19namespace chromeos { 20 21namespace { 22const size_t kNonceSize = 16; 23} // namespace 24 25CryptohomeTokenEncryptor::CryptohomeTokenEncryptor( 26 const std::string& system_salt) 27 : system_salt_(system_salt) { 28 DCHECK(!system_salt.empty()); 29 // TODO(davidroche): should this use the system salt for both the password 30 // and the salt value, or should this use a separate salt value? 31 system_salt_key_.reset(PassphraseToKey(system_salt_, system_salt_)); 32} 33 34CryptohomeTokenEncryptor::~CryptohomeTokenEncryptor() { 35} 36 37std::string CryptohomeTokenEncryptor::EncryptWithSystemSalt( 38 const std::string& token) { 39 // Don't care about token encryption while debugging. 40 if (!base::SysInfo::IsRunningOnChromeOS()) 41 return token; 42 43 if (!system_salt_key_) { 44 LOG(WARNING) << "System salt key is not available for encrypt."; 45 return std::string(); 46 } 47 return EncryptTokenWithKey(system_salt_key_.get(), 48 system_salt_, 49 token); 50} 51 52std::string CryptohomeTokenEncryptor::DecryptWithSystemSalt( 53 const std::string& encrypted_token_hex) { 54 // Don't care about token encryption while debugging. 55 if (!base::SysInfo::IsRunningOnChromeOS()) 56 return encrypted_token_hex; 57 58 if (!system_salt_key_) { 59 LOG(WARNING) << "System salt key is not available for decrypt."; 60 return std::string(); 61 } 62 return DecryptTokenWithKey(system_salt_key_.get(), 63 system_salt_, 64 encrypted_token_hex); 65} 66 67crypto::SymmetricKey* CryptohomeTokenEncryptor::PassphraseToKey( 68 const std::string& passphrase, 69 const std::string& salt) { 70 return crypto::SymmetricKey::DeriveKeyFromPassword( 71 crypto::SymmetricKey::AES, passphrase, salt, 1000, 256); 72} 73 74std::string CryptohomeTokenEncryptor::EncryptTokenWithKey( 75 crypto::SymmetricKey* key, 76 const std::string& salt, 77 const std::string& token) { 78 crypto::Encryptor encryptor; 79 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) { 80 LOG(WARNING) << "Failed to initialize Encryptor."; 81 return std::string(); 82 } 83 std::string nonce = salt.substr(0, kNonceSize); 84 std::string encoded_token; 85 CHECK(encryptor.SetCounter(nonce)); 86 if (!encryptor.Encrypt(token, &encoded_token)) { 87 LOG(WARNING) << "Failed to encrypt token."; 88 return std::string(); 89 } 90 91 return base::StringToLowerASCII(base::HexEncode( 92 reinterpret_cast<const void*>(encoded_token.data()), 93 encoded_token.size())); 94} 95 96std::string CryptohomeTokenEncryptor::DecryptTokenWithKey( 97 crypto::SymmetricKey* key, 98 const std::string& salt, 99 const std::string& encrypted_token_hex) { 100 std::vector<uint8> encrypted_token_bytes; 101 if (!base::HexStringToBytes(encrypted_token_hex, &encrypted_token_bytes)) { 102 LOG(WARNING) << "Corrupt encrypted token found."; 103 return std::string(); 104 } 105 106 std::string encrypted_token( 107 reinterpret_cast<char*>(encrypted_token_bytes.data()), 108 encrypted_token_bytes.size()); 109 crypto::Encryptor encryptor; 110 if (!encryptor.Init(key, crypto::Encryptor::CTR, std::string())) { 111 LOG(WARNING) << "Failed to initialize Encryptor."; 112 return std::string(); 113 } 114 115 std::string nonce = salt.substr(0, kNonceSize); 116 std::string token; 117 CHECK(encryptor.SetCounter(nonce)); 118 if (!encryptor.Decrypt(encrypted_token, &token)) { 119 LOG(WARNING) << "Failed to decrypt token."; 120 return std::string(); 121 } 122 return token; 123} 124 125} // namespace chromeos 126