Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / settings / token_encryptor.cc
blobdbe26c52ea90560f48ac3e233bcb5f4f10e84700
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.
5 #include "chrome/browser/chromeos/settings/token_encryptor.h"
7 #include <vector>
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"
19 namespace chromeos {
21 namespace {
22 const size_t kNonceSize = 16;
23 } // namespace
25 CryptohomeTokenEncryptor::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_));
34 CryptohomeTokenEncryptor::~CryptohomeTokenEncryptor() {
37 std::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;
43 if (!system_salt_key_) {
44 LOG(WARNING) << "System salt key is not available for encrypt.";
45 return std::string();
47 return EncryptTokenWithKey(system_salt_key_.get(),
48 system_salt_,
49 token);
52 std::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;
58 if (!system_salt_key_) {
59 LOG(WARNING) << "System salt key is not available for decrypt.";
60 return std::string();
62 return DecryptTokenWithKey(system_salt_key_.get(),
63 system_salt_,
64 encrypted_token_hex);
67 crypto::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);
74 std::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();
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();
91 return base::ToLowerASCII(
92 base::HexEncode(reinterpret_cast<const void*>(encoded_token.data()),
93 encoded_token.size()));
96 std::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();
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();
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();
122 return token;
125 } // namespace chromeos