Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(580)

Side by Side Diff: base/crypto/symmetric_key_mac.cc

Issue 1347002: Add Mac implementations of new SymmetricKey and Encryptor classes. (Closed)
Patch Set: Responding to feedback Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/crypto/symmetric_key.h" 5 #include "base/crypto/symmetric_key.h"
6 6
7 #include <CommonCrypto/CommonCryptor.h>
8 #include <CoreFoundation/CFString.h>
9 #include <Security/cssm.h>
10
11 #include "base/crypto/cssm_init.h"
12 #include "base/logging.h"
13 #include "base/rand_util.h"
14
15 namespace {
16
17 CSSM_KEY_TYPE CheckKeyParams(base::SymmetricKey::Algorithm algorithm,
18 size_t key_size_in_bits) {
19 if (algorithm == base::SymmetricKey::AES) {
20 CHECK(key_size_in_bits == 128 ||
21 key_size_in_bits == 192 ||
22 key_size_in_bits == 256)
23 << "Invalid key size " << key_size_in_bits << " bits";
24 return CSSM_ALGID_AES;
25 } else {
26 CHECK(algorithm == base::SymmetricKey::HMAC_SHA1);
27 CHECK(key_size_in_bits >= 80 && (key_size_in_bits % 8) == 0)
28 << "Invalid key size " << key_size_in_bits << " bits";
29 return CSSM_ALGID_SHA1HMAC_LEGACY;
wtc 2010/03/26 21:14:30 Just curious: why does this ALGID say "LEGACY"?
Jens Alfke 2010/03/29 18:34:17 I don't know -- the header comment says "HMAC/SHA1
30 }
31 }
32
33 void* CreateRandomBytes(size_t size) {
wtc 2010/03/26 21:14:30 It seems better to take a result buffer as an inpu
Jens Alfke 2010/03/29 18:34:17 It would be possible, but not any more efficient,
34 CSSM_RETURN err;
35 CSSM_CC_HANDLE ctx;
36 err = CSSM_CSP_CreateRandomGenContext(base::GetSharedCSPHandle(),
37 CSSM_ALGID_APPLE_YARROW,
38 NULL,
39 size, &ctx);
40 if (err) {
41 base::LogCSSMError("CSSM_CSP_CreateRandomGenContext", err);
42 return NULL;
43 }
44 CSSM_DATA random_data = {};
45 err = CSSM_GenerateRandom(ctx, &random_data);
46 if (err) {
47 base::LogCSSMError("CSSM_GenerateRandom", err);
48 random_data.Data = NULL;
49 }
50 CSSM_DeleteContext(ctx);
51 return random_data.Data; // Caller responsible for freeing this
wtc 2010/03/26 21:14:30 Nit: could you move this comment to the beginning
52 }
53
54 inline CSSM_DATA StringToData(const std::string& str) {
55 CSSM_DATA data = {
56 str.size(),
57 reinterpret_cast<uint8_t*>(const_cast<char*>(str.data()))
58 };
59 return data;
60 }
61
62 } // namespace
63
7 namespace base { 64 namespace base {
8 65
9 // TODO(albertb): Implement on Mac.
10
11 // static 66 // static
12 SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, size_t key_si ze) { 67 SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm,
13 return NULL; 68 size_t key_size_in_bits) {
69 CheckKeyParams(algorithm, key_size_in_bits);
70 void* random_bytes = CreateRandomBytes((key_size_in_bits + 7) / 8);
71 if (!random_bytes)
72 return NULL;
73 SymmetricKey *key = new SymmetricKey(random_bytes, key_size_in_bits);
74 free(random_bytes);
75 return key;
14 } 76 }
15 77
16 // static 78 // static
17 SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm, 79 SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
18 const std::string& password, 80 const std::string& password,
19 const std::string& salt, 81 const std::string& salt,
20 size_t iterations, 82 size_t iterations,
21 size_t key_size) { 83 size_t key_size_in_bits) {
22 return NULL; 84 // Derived (haha) from cdsaDeriveKey() in Apple's CryptoSample.
85 CSSM_KEY_TYPE key_type = CheckKeyParams(algorithm, key_size_in_bits);
86 SymmetricKey* derived_key = NULL;
87 CSSM_KEY cssm_key = {};
88
89 CSSM_CC_HANDLE ctx = 0;
90 CSSM_ACCESS_CREDENTIALS credentials = {};
91 CSSM_RETURN err;
92 CSSM_DATA salt_data = StringToData(salt);
93 err = CSSM_CSP_CreateDeriveKeyContext(GetSharedCSPHandle(),
94 CSSM_ALGID_PKCS5_PBKDF2,
95 key_type, key_size_in_bits,
96 &credentials,
97 NULL,
98 iterations,
99 &salt_data,
100 NULL,
101 &ctx);
102 if (err) {
103 LogCSSMError("CSSM_CSP_CreateDeriveKeyContext", err);
104 return NULL;
105 }
106
107 CSSM_PKCS5_PBKDF2_PARAMS params = {};
108 params.Passphrase = StringToData(password);
109 params.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
110 CSSM_DATA param_data = {sizeof(params), reinterpret_cast<uint8_t*>(&params)};
111 err = CSSM_DeriveKey(ctx,
112 &param_data,
113 CSSM_KEYUSE_ANY,
114 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE,
115 NULL,
116 NULL,
117 &cssm_key);
118 if (err) {
119 LogCSSMError("CSSM_DeriveKey", err);
120 goto exit;
121 }
122
123 DCHECK_EQ(cssm_key.KeyData.Length, key_size_in_bits / 8);
124 derived_key = new SymmetricKey(cssm_key.KeyData.Data, key_size_in_bits);
125
126 exit:
127 CSSM_DeleteContext(ctx);
128 CSSM_FreeKey(GetSharedCSPHandle(), &credentials, &cssm_key, false);
129 return derived_key;
23 } 130 }
24 131
132 SymmetricKey::SymmetricKey(const void *key_data, size_t key_size_in_bits)
133 : key_(reinterpret_cast<const char*>(key_data),
134 key_size_in_bits / 8) {}
135
25 bool SymmetricKey::GetRawKey(std::string* raw_key) { 136 bool SymmetricKey::GetRawKey(std::string* raw_key) {
26 return false; 137 *raw_key = key_;
138 return true;
139 }
140
141 CSSM_DATA SymmetricKey::cssm_data() const {
142 return StringToData(key_);
27 } 143 }
28 144
29 } // namespace base 145 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698