OSDN Git Service

vold: Accept Linux GPT partitions on external SD cards
[android-x86/system-vold.git] / Keymaster.cpp
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "Keymaster.h"
18
19 #include <android-base/logging.h>
20 #include <keymasterV4_0/authorization_set.h>
21 #include <keymasterV4_0/keymaster_utils.h>
22
23 namespace android {
24 namespace vold {
25
26 using ::android::hardware::hidl_string;
27 using ::android::hardware::hidl_vec;
28 using ::android::hardware::keymaster::V4_0::SecurityLevel;
29
30 KeymasterOperation::~KeymasterOperation() {
31     if (mDevice) mDevice->abort(mOpHandle);
32 }
33
34 bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
35                                           const std::function<void(const char*, size_t)> consumer) {
36     uint32_t inputConsumed = 0;
37
38     km::ErrorCode km_error;
39     auto hidlCB = [&](km::ErrorCode ret, uint32_t inputConsumedDelta,
40                       const hidl_vec<km::KeyParameter>& /*ignored*/,
41                       const hidl_vec<uint8_t>& _output) {
42         km_error = ret;
43         if (km_error != km::ErrorCode::OK) return;
44         inputConsumed += inputConsumedDelta;
45         consumer(reinterpret_cast<const char*>(&_output[0]), _output.size());
46     };
47
48     while (inputConsumed != inputLen) {
49         size_t toRead = static_cast<size_t>(inputLen - inputConsumed);
50         auto inputBlob = km::support::blob2hidlVec(
51             reinterpret_cast<const uint8_t*>(&input[inputConsumed]), toRead);
52         auto error = mDevice->update(mOpHandle, hidl_vec<km::KeyParameter>(), inputBlob,
53                                      km::HardwareAuthToken(), km::VerificationToken(), hidlCB);
54         if (!error.isOk()) {
55             LOG(ERROR) << "update failed: " << error.description();
56             mDevice = nullptr;
57             return false;
58         }
59         if (km_error != km::ErrorCode::OK) {
60             LOG(ERROR) << "update failed, code " << int32_t(km_error);
61             mDevice = nullptr;
62             return false;
63         }
64         if (inputConsumed > inputLen) {
65             LOG(ERROR) << "update reported too much input consumed";
66             mDevice = nullptr;
67             return false;
68         }
69     }
70     return true;
71 }
72
73 bool KeymasterOperation::finish(std::string* output) {
74     km::ErrorCode km_error;
75     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& /*ignored*/,
76                       const hidl_vec<uint8_t>& _output) {
77         km_error = ret;
78         if (km_error != km::ErrorCode::OK) return;
79         if (output) output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
80     };
81     auto error = mDevice->finish(mOpHandle, hidl_vec<km::KeyParameter>(), hidl_vec<uint8_t>(),
82                                  hidl_vec<uint8_t>(), km::HardwareAuthToken(),
83                                  km::VerificationToken(), hidlCb);
84     mDevice = nullptr;
85     if (!error.isOk()) {
86         LOG(ERROR) << "finish failed: " << error.description();
87         return false;
88     }
89     if (km_error != km::ErrorCode::OK) {
90         LOG(ERROR) << "finish failed, code " << int32_t(km_error);
91         return false;
92     }
93     return true;
94 }
95
96 /* static */ bool Keymaster::hmacKeyGenerated = false;
97
98 Keymaster::Keymaster() {
99     auto devices = KmDevice::enumerateAvailableDevices();
100     if (!hmacKeyGenerated) {
101         KmDevice::performHmacKeyAgreement(devices);
102         hmacKeyGenerated = true;
103     }
104     for (auto& dev : devices) {
105         // Do not use StrongBox for device encryption / credential encryption.  If a security chip
106         // is present it will have Weaver, which already strengthens CE.  We get no additional
107         // benefit from using StrongBox here, so skip it.
108         if (dev->halVersion().securityLevel != SecurityLevel::STRONGBOX) {
109             mDevice = std::move(dev);
110             break;
111         }
112     }
113     if (!mDevice) return;
114     auto& version = mDevice->halVersion();
115     LOG(INFO) << "Using " << version.keymasterName << " from " << version.authorName
116               << " for encryption.  Security level: " << toString(version.securityLevel)
117               << ", HAL: " << mDevice->descriptor() << "/" << mDevice->instanceName();
118 }
119
120 bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
121     km::ErrorCode km_error;
122     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
123                       const km::KeyCharacteristics& /*ignored*/) {
124         km_error = ret;
125         if (km_error != km::ErrorCode::OK) return;
126         if (key) key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
127     };
128
129     auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
130     if (!error.isOk()) {
131         LOG(ERROR) << "generate_key failed: " << error.description();
132         return false;
133     }
134     if (km_error != km::ErrorCode::OK) {
135         LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
136         return false;
137     }
138     return true;
139 }
140
141 bool Keymaster::deleteKey(const std::string& key) {
142     auto keyBlob = km::support::blob2hidlVec(key);
143     auto error = mDevice->deleteKey(keyBlob);
144     if (!error.isOk()) {
145         LOG(ERROR) << "delete_key failed: " << error.description();
146         return false;
147     }
148     if (error != km::ErrorCode::OK) {
149         LOG(ERROR) << "delete_key failed, code " << int32_t(km::ErrorCode(error));
150         return false;
151     }
152     return true;
153 }
154
155 bool Keymaster::upgradeKey(const std::string& oldKey, const km::AuthorizationSet& inParams,
156                            std::string* newKey) {
157     auto oldKeyBlob = km::support::blob2hidlVec(oldKey);
158     km::ErrorCode km_error;
159     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
160         km_error = ret;
161         if (km_error != km::ErrorCode::OK) return;
162         if (newKey)
163             newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
164                            upgradedKeyBlob.size());
165     };
166     auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
167     if (!error.isOk()) {
168         LOG(ERROR) << "upgrade_key failed: " << error.description();
169         return false;
170     }
171     if (km_error != km::ErrorCode::OK) {
172         LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
173         return false;
174     }
175     return true;
176 }
177
178 KeymasterOperation Keymaster::begin(km::KeyPurpose purpose, const std::string& key,
179                                     const km::AuthorizationSet& inParams,
180                                     const km::HardwareAuthToken& authToken,
181                                     km::AuthorizationSet* outParams) {
182     auto keyBlob = km::support::blob2hidlVec(key);
183     uint64_t mOpHandle;
184     km::ErrorCode km_error;
185
186     auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& _outParams,
187                       uint64_t operationHandle) {
188         km_error = ret;
189         if (km_error != km::ErrorCode::OK) return;
190         if (outParams) *outParams = _outParams;
191         mOpHandle = operationHandle;
192     };
193
194     auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), authToken, hidlCb);
195     if (!error.isOk()) {
196         LOG(ERROR) << "begin failed: " << error.description();
197         return KeymasterOperation(km::ErrorCode::UNKNOWN_ERROR);
198     }
199     if (km_error != km::ErrorCode::OK) {
200         LOG(ERROR) << "begin failed, code " << int32_t(km_error);
201         return KeymasterOperation(km_error);
202     }
203     return KeymasterOperation(mDevice.get(), mOpHandle);
204 }
205
206 bool Keymaster::isSecure() {
207     return mDevice->halVersion().securityLevel != km::SecurityLevel::SOFTWARE;
208 }
209
210 }  // namespace vold
211 }  // namespace android
212
213 using namespace ::android::vold;
214
215 int keymaster_compatibility_cryptfs_scrypt() {
216     Keymaster dev;
217     if (!dev) {
218         LOG(ERROR) << "Failed to initiate keymaster session";
219         return -1;
220     }
221     return dev.isSecure();
222 }
223
224 static bool write_string_to_buf(const std::string& towrite, uint8_t* buffer, uint32_t buffer_size,
225                                 uint32_t* out_size) {
226     if (!buffer || !out_size) {
227         LOG(ERROR) << "Missing target pointers";
228         return false;
229     }
230     *out_size = towrite.size();
231     if (buffer_size < towrite.size()) {
232         LOG(ERROR) << "Buffer too small " << buffer_size << " < " << towrite.size();
233         return false;
234     }
235     memset(buffer, '\0', buffer_size);
236     std::copy(towrite.begin(), towrite.end(), buffer);
237     return true;
238 }
239
240 static km::AuthorizationSet keyParams(uint32_t rsa_key_size, uint64_t rsa_exponent,
241                                       uint32_t ratelimit) {
242     return km::AuthorizationSetBuilder()
243         .RsaSigningKey(rsa_key_size, rsa_exponent)
244         .NoDigestOrPadding()
245         .Authorization(km::TAG_BLOB_USAGE_REQUIREMENTS, km::KeyBlobUsageRequirements::STANDALONE)
246         .Authorization(km::TAG_NO_AUTH_REQUIRED)
247         .Authorization(km::TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
248 }
249
250 int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
251                                             uint32_t ratelimit, uint8_t* key_buffer,
252                                             uint32_t key_buffer_size, uint32_t* key_out_size) {
253     if (key_out_size) {
254         *key_out_size = 0;
255     }
256     Keymaster dev;
257     if (!dev) {
258         LOG(ERROR) << "Failed to initiate keymaster session";
259         return -1;
260     }
261     std::string key;
262     if (!dev.generateKey(keyParams(rsa_key_size, rsa_exponent, ratelimit), &key)) return -1;
263     if (!write_string_to_buf(key, key_buffer, key_buffer_size, key_out_size)) return -1;
264     return 0;
265 }
266
267 int keymaster_upgrade_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
268                                              uint32_t ratelimit, const uint8_t* key_blob,
269                                              size_t key_blob_size, uint8_t* key_buffer,
270                                              uint32_t key_buffer_size, uint32_t* key_out_size) {
271     if (key_out_size) {
272         *key_out_size = 0;
273     }
274     Keymaster dev;
275     if (!dev) {
276         LOG(ERROR) << "Failed to initiate keymaster session";
277         return -1;
278     }
279     std::string old_key(reinterpret_cast<const char*>(key_blob), key_blob_size);
280     std::string new_key;
281     if (!dev.upgradeKey(old_key, keyParams(rsa_key_size, rsa_exponent, ratelimit), &new_key))
282         return -1;
283     if (!write_string_to_buf(new_key, key_buffer, key_buffer_size, key_out_size)) return -1;
284     return 0;
285 }
286
287 KeymasterSignResult keymaster_sign_object_for_cryptfs_scrypt(
288     const uint8_t* key_blob, size_t key_blob_size, uint32_t ratelimit, const uint8_t* object,
289     const size_t object_size, uint8_t** signature_buffer, size_t* signature_buffer_size) {
290     Keymaster dev;
291     if (!dev) {
292         LOG(ERROR) << "Failed to initiate keymaster session";
293         return KeymasterSignResult::error;
294     }
295     if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
296         LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
297         return KeymasterSignResult::error;
298     }
299
300     km::AuthorizationSet outParams;
301     std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size);
302     std::string input(reinterpret_cast<const char*>(object), object_size);
303     std::string output;
304     KeymasterOperation op;
305
306     auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding();
307     while (true) {
308         op = dev.begin(km::KeyPurpose::SIGN, key, paramBuilder, km::HardwareAuthToken(), &outParams);
309         if (op.errorCode() == km::ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
310             sleep(ratelimit);
311             continue;
312         } else
313             break;
314     }
315
316     if (op.errorCode() == km::ErrorCode::KEY_REQUIRES_UPGRADE) {
317         LOG(ERROR) << "Keymaster key requires upgrade";
318         return KeymasterSignResult::upgrade;
319     }
320
321     if (op.errorCode() != km::ErrorCode::OK) {
322         LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
323         return KeymasterSignResult::error;
324     }
325
326     if (!op.updateCompletely(input, &output)) {
327         LOG(ERROR) << "Error sending data to keymaster signature transaction: "
328                    << uint32_t(op.errorCode());
329         return KeymasterSignResult::error;
330     }
331
332     if (!op.finish(&output)) {
333         LOG(ERROR) << "Error finalizing keymaster signature transaction: "
334                    << int32_t(op.errorCode());
335         return KeymasterSignResult::error;
336     }
337
338     *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
339     if (*signature_buffer == nullptr) {
340         LOG(ERROR) << "Error allocation buffer for keymaster signature";
341         return KeymasterSignResult::error;
342     }
343     *signature_buffer_size = output.size();
344     std::copy(output.data(), output.data() + output.size(), *signature_buffer);
345     return KeymasterSignResult::ok;
346 }