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"
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"
22 const size_t kNonceSize
= 16;
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())
43 if (!system_salt_key_
) {
44 LOG(WARNING
) << "System salt key is not available for encrypt.";
47 return EncryptTokenWithKey(system_salt_key_
.get(),
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.";
62 return DecryptTokenWithKey(system_salt_key_
.get(),
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.";
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.";
91 return base::StringToLowerASCII(base::HexEncode(
92 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
);
117 CHECK(encryptor
.SetCounter(nonce
));
118 if (!encryptor
.Decrypt(encrypted_token
, &token
)) {
119 LOG(WARNING
) << "Failed to decrypt token.";
120 return std::string();
125 } // namespace chromeos