1 // Copyright 2014 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 "chromeos/login/auth/key.h"
7 #include "base/base64.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h"
12 #include "crypto/sha2.h"
13 #include "crypto/symmetric_key.h"
19 // Parameters for the transformation to KEY_TYPE_SALTED_AES256_1234.
20 const int kNumIterations
= 1234;
21 const int kKeySizeInBits
= 256;
25 Key::Key() : key_type_(KEY_TYPE_PASSWORD_PLAIN
) {
28 Key::Key(const Key
& other
)
29 : key_type_(other
.key_type_
),
31 secret_(other
.secret_
),
32 label_(other
.label_
) {
35 Key::Key(const std::string
& plain_text_password
)
36 : key_type_(KEY_TYPE_PASSWORD_PLAIN
), secret_(plain_text_password
) {
39 Key::Key(KeyType key_type
, const std::string
& salt
, const std::string
& secret
)
40 : key_type_(key_type
), salt_(salt
), secret_(secret
) {
46 bool Key::operator==(const Key
& other
) const {
47 return other
.key_type_
== key_type_
&& other
.salt_
== salt_
&&
48 other
.secret_
== secret_
&& other
.label_
== label_
;
51 Key::KeyType
Key::GetKeyType() const {
55 const std::string
& Key::GetSecret() const {
59 const std::string
& Key::GetLabel() const {
63 void Key::SetLabel(const std::string
& label
) {
67 void Key::ClearSecret() {
71 void Key::Transform(KeyType target_key_type
, const std::string
& salt
) {
72 if (key_type_
!= KEY_TYPE_PASSWORD_PLAIN
) {
77 switch (target_key_type
) {
78 case KEY_TYPE_SALTED_SHA256_TOP_HALF
: {
79 // TODO(stevenjb/nkostylev): Handle empty salt gracefully.
81 char hash
[crypto::kSHA256Length
];
82 crypto::SHA256HashString(salt
+ secret_
, &hash
, sizeof(hash
));
84 // Keep only the first half of the hash for 'weak' hashing so that the
85 // plain text secret cannot be reconstructed even if the hashing is
87 secret_
= base::ToLowerASCII(base::HexEncode(
88 reinterpret_cast<const void*>(hash
), sizeof(hash
) / 2));
91 case KEY_TYPE_SALTED_PBKDF2_AES256_1234
: {
92 scoped_ptr
<crypto::SymmetricKey
> key(
93 crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES
,
98 std::string raw_secret
;
99 key
->GetRawKey(&raw_secret
);
100 base::Base64Encode(raw_secret
, &secret_
);
103 case KEY_TYPE_SALTED_SHA256
:
104 base::Base64Encode(crypto::SHA256HashString(salt
+ secret_
), &secret_
);
108 // The resulting key will be sent to cryptohomed. It should always be
109 // hashed. If hashing fails, crash instead of sending a plain-text key.
114 key_type_
= target_key_type
;
118 } // namespace chromeos