blob: c5b7bc3c5eaaddf08fe310a16387275c6b9a0ea5 [file] [log] [blame]
bigbiff7ba75002020-04-11 20:47:09 -04001/*
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.
bigbiffa957f072021-03-07 18:20:29 -05006 * You may obtain a copy of the License at
bigbiff7ba75002020-04-11 20:47:09 -04007 *
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>
bigbiffa957f072021-03-07 18:20:29 -050020#include <keymasterV4_1/authorization_set.h>
21#include <keymasterV4_1/keymaster_utils.h>
bigbiff7ba75002020-04-11 20:47:09 -040022
bigbiff7ba75002020-04-11 20:47:09 -040023
24using ::android::hardware::hidl_string;
25using ::android::hardware::hidl_vec;
26using ::android::hardware::keymaster::V4_0::SecurityLevel;
27
28KeymasterOperation::~KeymasterOperation() {
29 if (mDevice) mDevice->abort(mOpHandle);
30}
31
32bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
33 const std::function<void(const char*, size_t)> consumer) {
34 uint32_t inputConsumed = 0;
35
36 km::ErrorCode km_error;
37 auto hidlCB = [&](km::ErrorCode ret, uint32_t inputConsumedDelta,
38 const hidl_vec<km::KeyParameter>& /*ignored*/,
39 const hidl_vec<uint8_t>& _output) {
40 km_error = ret;
41 if (km_error != km::ErrorCode::OK) return;
42 inputConsumed += inputConsumedDelta;
43 consumer(reinterpret_cast<const char*>(&_output[0]), _output.size());
44 };
45
46 while (inputConsumed != inputLen) {
47 size_t toRead = static_cast<size_t>(inputLen - inputConsumed);
48 auto inputBlob = km::support::blob2hidlVec(
49 reinterpret_cast<const uint8_t*>(&input[inputConsumed]), toRead);
50 auto error = mDevice->update(mOpHandle, hidl_vec<km::KeyParameter>(), inputBlob,
51 km::HardwareAuthToken(), km::VerificationToken(), hidlCB);
52 if (!error.isOk()) {
53 LOG(ERROR) << "update failed: " << error.description();
54 mDevice = nullptr;
55 return false;
56 }
57 if (km_error != km::ErrorCode::OK) {
58 LOG(ERROR) << "update failed, code " << int32_t(km_error);
59 mDevice = nullptr;
60 return false;
61 }
62 if (inputConsumed > inputLen) {
63 LOG(ERROR) << "update reported too much input consumed";
64 mDevice = nullptr;
65 return false;
66 }
67 }
68 return true;
69}
70
71bool KeymasterOperation::finish(std::string* output) {
72 km::ErrorCode km_error;
73 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& /*ignored*/,
74 const hidl_vec<uint8_t>& _output) {
75 km_error = ret;
76 if (km_error != km::ErrorCode::OK) return;
77 if (output) output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
78 };
79 auto error = mDevice->finish(mOpHandle, hidl_vec<km::KeyParameter>(), hidl_vec<uint8_t>(),
80 hidl_vec<uint8_t>(), km::HardwareAuthToken(),
81 km::VerificationToken(), hidlCb);
82 mDevice = nullptr;
83 if (!error.isOk()) {
84 LOG(ERROR) << "finish failed: " << error.description();
85 return false;
86 }
87 if (km_error != km::ErrorCode::OK) {
88 LOG(ERROR) << "finish failed, code " << int32_t(km_error);
89 return false;
90 }
91 return true;
92}
93
94/* static */ bool Keymaster::hmacKeyGenerated = false;
95
96Keymaster::Keymaster() {
97 auto devices = KmDevice::enumerateAvailableDevices();
98 if (!hmacKeyGenerated) {
99 KmDevice::performHmacKeyAgreement(devices);
100 hmacKeyGenerated = true;
101 }
102 for (auto& dev : devices) {
103 // Do not use StrongBox for device encryption / credential encryption. If a security chip
104 // is present it will have Weaver, which already strengthens CE. We get no additional
105 // benefit from using StrongBox here, so skip it.
106 if (dev->halVersion().securityLevel != SecurityLevel::STRONGBOX) {
107 mDevice = std::move(dev);
108 break;
109 }
110 }
111 if (!mDevice) return;
112 auto& version = mDevice->halVersion();
113 LOG(INFO) << "Using " << version.keymasterName << " from " << version.authorName
114 << " for encryption. Security level: " << toString(version.securityLevel)
115 << ", HAL: " << mDevice->descriptor() << "/" << mDevice->instanceName();
116}
117
118bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
119 km::ErrorCode km_error;
120 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
121 const km::KeyCharacteristics& /*ignored*/) {
122 km_error = ret;
123 if (km_error != km::ErrorCode::OK) return;
124 if (key) key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
125 };
126
127 auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
128 if (!error.isOk()) {
129 LOG(ERROR) << "generate_key failed: " << error.description();
130 return false;
131 }
132 if (km_error != km::ErrorCode::OK) {
133 LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
134 return false;
135 }
136 return true;
137}
138
bigbiffbbbfe172021-05-30 15:52:41 -0400139km::ErrorCode Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {
mauronofrio matarrese79820322020-05-25 19:48:56 +0200140 auto kmKeyBlob = km::support::blob2hidlVec(std::string(kmKey.data(), kmKey.size()));
mauronofrio matarrese79820322020-05-25 19:48:56 +0200141 km::ErrorCode km_error;
142 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& exportedKeyBlob) {
143 km_error = ret;
144 if (km_error != km::ErrorCode::OK) return;
bigbiffa957f072021-03-07 18:20:29 -0500145 if (key)
146 key->assign(reinterpret_cast<const char*>(&exportedKeyBlob[0]), exportedKeyBlob.size());
mauronofrio matarrese79820322020-05-25 19:48:56 +0200147 };
bigbiffa957f072021-03-07 18:20:29 -0500148 auto error = mDevice->exportKey(km::KeyFormat::RAW, kmKeyBlob, {}, {}, hidlCb);
mauronofrio matarrese79820322020-05-25 19:48:56 +0200149 if (!error.isOk()) {
150 LOG(ERROR) << "export_key failed: " << error.description();
bigbiffbbbfe172021-05-30 15:52:41 -0400151 return km::ErrorCode::UNKNOWN_ERROR;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200152 }
153 if (km_error != km::ErrorCode::OK) {
154 LOG(ERROR) << "export_key failed, code " << int32_t(km_error);
bigbiffbbbfe172021-05-30 15:52:41 -0400155 return km_error;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200156 }
bigbiffbbbfe172021-05-30 15:52:41 -0400157 return km::ErrorCode::OK;
mauronofrio matarrese79820322020-05-25 19:48:56 +0200158}
159
bigbiff7ba75002020-04-11 20:47:09 -0400160bool Keymaster::deleteKey(const std::string& key) {
161 auto keyBlob = km::support::blob2hidlVec(key);
162 auto error = mDevice->deleteKey(keyBlob);
163 if (!error.isOk()) {
164 LOG(ERROR) << "delete_key failed: " << error.description();
165 return false;
166 }
167 if (error != km::ErrorCode::OK) {
168 LOG(ERROR) << "delete_key failed, code " << int32_t(km::ErrorCode(error));
169 return false;
170 }
171 return true;
172}
173
174bool Keymaster::upgradeKey(const std::string& oldKey, const km::AuthorizationSet& inParams,
175 std::string* newKey) {
176 auto oldKeyBlob = km::support::blob2hidlVec(oldKey);
177 km::ErrorCode km_error;
178 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
179 km_error = ret;
180 if (km_error != km::ErrorCode::OK) return;
181 if (newKey)
182 newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
183 upgradedKeyBlob.size());
184 };
185 auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
186 if (!error.isOk()) {
187 LOG(ERROR) << "upgrade_key failed: " << error.description();
188 return false;
189 }
190 if (km_error != km::ErrorCode::OK) {
191 LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
192 return false;
193 }
194 return true;
195}
196
197KeymasterOperation Keymaster::begin(km::KeyPurpose purpose, const std::string& key,
198 const km::AuthorizationSet& inParams,
199 const km::HardwareAuthToken& authToken,
200 km::AuthorizationSet* outParams) {
201 auto keyBlob = km::support::blob2hidlVec(key);
202 uint64_t mOpHandle;
203 km::ErrorCode km_error;
204
205 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& _outParams,
206 uint64_t operationHandle) {
207 km_error = ret;
208 if (km_error != km::ErrorCode::OK) return;
209 if (outParams) *outParams = _outParams;
210 mOpHandle = operationHandle;
211 };
212
213 auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), authToken, hidlCb);
214 if (!error.isOk()) {
215 LOG(ERROR) << "begin failed: " << error.description();
216 return KeymasterOperation(km::ErrorCode::UNKNOWN_ERROR);
217 }
218 if (km_error != km::ErrorCode::OK) {
219 LOG(ERROR) << "begin failed, code " << int32_t(km_error);
220 return KeymasterOperation(km_error);
221 }
222 return KeymasterOperation(mDevice.get(), mOpHandle);
223}
224
225bool Keymaster::isSecure() {
226 return mDevice->halVersion().securityLevel != km::SecurityLevel::SOFTWARE;
227}
228
bigbiffa957f072021-03-07 18:20:29 -0500229void Keymaster::earlyBootEnded() {
230 auto devices = KmDevice::enumerateAvailableDevices();
231 for (auto& dev : devices) {
232 auto error = dev->earlyBootEnded();
233 if (!error.isOk()) {
234 LOG(ERROR) << "earlyBootEnded call failed: " << error.description() << " for "
235 << dev->halVersion().keymasterName;
236 }
237 km::V4_1_ErrorCode km_error = error;
238 if (km_error != km::V4_1_ErrorCode::OK && km_error != km::V4_1_ErrorCode::UNIMPLEMENTED) {
239 LOG(ERROR) << "Error reporting early boot ending to keymaster: "
240 << static_cast<int32_t>(km_error) << " for "
241 << dev->halVersion().keymasterName;
242 }
243 }
244}
bigbiff7ba75002020-04-11 20:47:09 -0400245
246int keymaster_compatibility_cryptfs_scrypt() {
247 Keymaster dev;
248 if (!dev) {
249 LOG(ERROR) << "Failed to initiate keymaster session";
250 return -1;
251 }
252 return dev.isSecure();
253}
254
255static bool write_string_to_buf(const std::string& towrite, uint8_t* buffer, uint32_t buffer_size,
256 uint32_t* out_size) {
257 if (!buffer || !out_size) {
258 LOG(ERROR) << "Missing target pointers";
259 return false;
260 }
261 *out_size = towrite.size();
262 if (buffer_size < towrite.size()) {
263 LOG(ERROR) << "Buffer too small " << buffer_size << " < " << towrite.size();
264 return false;
265 }
266 memset(buffer, '\0', buffer_size);
267 std::copy(towrite.begin(), towrite.end(), buffer);
268 return true;
269}
270
271static km::AuthorizationSet keyParams(uint32_t rsa_key_size, uint64_t rsa_exponent,
272 uint32_t ratelimit) {
273 return km::AuthorizationSetBuilder()
274 .RsaSigningKey(rsa_key_size, rsa_exponent)
275 .NoDigestOrPadding()
276 .Authorization(km::TAG_BLOB_USAGE_REQUIREMENTS, km::KeyBlobUsageRequirements::STANDALONE)
277 .Authorization(km::TAG_NO_AUTH_REQUIRED)
278 .Authorization(km::TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
279}
280
281int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
282 uint32_t ratelimit, uint8_t* key_buffer,
283 uint32_t key_buffer_size, uint32_t* key_out_size) {
284 if (key_out_size) {
285 *key_out_size = 0;
286 }
287 Keymaster dev;
288 if (!dev) {
289 LOG(ERROR) << "Failed to initiate keymaster session";
290 return -1;
291 }
292 std::string key;
293 if (!dev.generateKey(keyParams(rsa_key_size, rsa_exponent, ratelimit), &key)) return -1;
294 if (!write_string_to_buf(key, key_buffer, key_buffer_size, key_out_size)) return -1;
295 return 0;
296}
297
298int keymaster_upgrade_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
299 uint32_t ratelimit, const uint8_t* key_blob,
300 size_t key_blob_size, uint8_t* key_buffer,
301 uint32_t key_buffer_size, uint32_t* key_out_size) {
302 if (key_out_size) {
303 *key_out_size = 0;
304 }
305 Keymaster dev;
306 if (!dev) {
307 LOG(ERROR) << "Failed to initiate keymaster session";
308 return -1;
309 }
310 std::string old_key(reinterpret_cast<const char*>(key_blob), key_blob_size);
311 std::string new_key;
312 if (!dev.upgradeKey(old_key, keyParams(rsa_key_size, rsa_exponent, ratelimit), &new_key))
313 return -1;
314 if (!write_string_to_buf(new_key, key_buffer, key_buffer_size, key_out_size)) return -1;
315 return 0;
316}
317
318KeymasterSignResult keymaster_sign_object_for_cryptfs_scrypt(
319 const uint8_t* key_blob, size_t key_blob_size, uint32_t ratelimit, const uint8_t* object,
320 const size_t object_size, uint8_t** signature_buffer, size_t* signature_buffer_size) {
321 Keymaster dev;
322 if (!dev) {
323 LOG(ERROR) << "Failed to initiate keymaster session";
324 return KeymasterSignResult::error;
325 }
326 if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
327 LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
328 return KeymasterSignResult::error;
329 }
330
331 km::AuthorizationSet outParams;
332 std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size);
333 std::string input(reinterpret_cast<const char*>(object), object_size);
334 std::string output;
335 KeymasterOperation op;
336
337 auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding();
338 while (true) {
339 op = dev.begin(km::KeyPurpose::SIGN, key, paramBuilder, km::HardwareAuthToken(), &outParams);
340 if (op.errorCode() == km::ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
341 sleep(ratelimit);
342 continue;
343 } else
344 break;
345 }
346
347 if (op.errorCode() == km::ErrorCode::KEY_REQUIRES_UPGRADE) {
348 LOG(ERROR) << "Keymaster key requires upgrade";
349 return KeymasterSignResult::upgrade;
350 }
351
352 if (op.errorCode() != km::ErrorCode::OK) {
353 LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
354 return KeymasterSignResult::error;
355 }
356
357 if (!op.updateCompletely(input, &output)) {
358 LOG(ERROR) << "Error sending data to keymaster signature transaction: "
359 << uint32_t(op.errorCode());
360 return KeymasterSignResult::error;
361 }
362
363 if (!op.finish(&output)) {
364 LOG(ERROR) << "Error finalizing keymaster signature transaction: "
365 << int32_t(op.errorCode());
366 return KeymasterSignResult::error;
367 }
368
369 *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
370 if (*signature_buffer == nullptr) {
371 LOG(ERROR) << "Error allocation buffer for keymaster signature";
372 return KeymasterSignResult::error;
373 }
374 *signature_buffer_size = output.size();
375 std::copy(output.data(), output.data() + output.size(), *signature_buffer);
376 return KeymasterSignResult::ok;
377}