blob: 7d061bba9d926afd23687b1b298ede33bea6a7db [file] [log] [blame]
Paul Crowley1ef25582016-01-21 20:26:12 +00001/*
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>
Shawn Willden35351812018-01-22 09:08:32 -070020#include <keymasterV4_0/authorization_set.h>
21#include <keymasterV4_0/keymaster_utils.h>
Paul Crowley1ef25582016-01-21 20:26:12 +000022
23namespace android {
24namespace vold {
25
Shawn Willden35351812018-01-22 09:08:32 -070026using ::android::hardware::hidl_string;
27using ::android::hardware::hidl_vec;
28
Paul Crowley0323afd2016-03-15 17:04:39 -070029KeymasterOperation::~KeymasterOperation() {
Shawn Willden35351812018-01-22 09:08:32 -070030 if (mDevice) mDevice->abort(mOpHandle);
Paul Crowley0323afd2016-03-15 17:04:39 -070031}
32
Pavel Grafove2e2d302017-08-01 17:15:53 +010033bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
Shawn Willden785365b2018-01-20 09:37:36 -070034 const std::function<void(const char*, size_t)> consumer) {
Pavel Grafove2e2d302017-08-01 17:15:53 +010035 uint32_t inputConsumed = 0;
Janis Danisevskis8e537b82016-10-26 14:27:10 +010036
Shawn Willden35351812018-01-22 09:08:32 -070037 km::ErrorCode km_error;
38 auto hidlCB = [&](km::ErrorCode ret, uint32_t inputConsumedDelta,
39 const hidl_vec<km::KeyParameter>& /*ignored*/,
40 const hidl_vec<uint8_t>& _output) {
Janis Danisevskis8e537b82016-10-26 14:27:10 +010041 km_error = ret;
Shawn Willden35351812018-01-22 09:08:32 -070042 if (km_error != km::ErrorCode::OK) return;
Pavel Grafove2e2d302017-08-01 17:15:53 +010043 inputConsumed += inputConsumedDelta;
44 consumer(reinterpret_cast<const char*>(&_output[0]), _output.size());
Janis Danisevskis8e537b82016-10-26 14:27:10 +010045 };
46
Pavel Grafove2e2d302017-08-01 17:15:53 +010047 while (inputConsumed != inputLen) {
48 size_t toRead = static_cast<size_t>(inputLen - inputConsumed);
Shawn Willden35351812018-01-22 09:08:32 -070049 auto inputBlob = km::support::blob2hidlVec(
50 reinterpret_cast<const uint8_t*>(&input[inputConsumed]), toRead);
51 // TODO(swillden): Need to handle getting a VerificationToken from the TEE if mDevice is
52 // StrongBox, so we can provide it here. The VerificationToken will need to be
53 // requested/retrieved during Keymaster::begin().
54 auto error = mDevice->update(mOpHandle, hidl_vec<km::KeyParameter>(), inputBlob,
55 km::HardwareAuthToken(), km::VerificationToken(), hidlCB);
Janis Danisevskis8e537b82016-10-26 14:27:10 +010056 if (!error.isOk()) {
57 LOG(ERROR) << "update failed: " << error.description();
Paul Crowley13ffd8e2016-01-27 14:30:22 +000058 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +000059 return false;
60 }
Shawn Willden35351812018-01-22 09:08:32 -070061 if (km_error != km::ErrorCode::OK) {
Janis Danisevskis015ec302017-01-31 11:31:08 +000062 LOG(ERROR) << "update failed, code " << int32_t(km_error);
Janis Danisevskis8e537b82016-10-26 14:27:10 +010063 mDevice = nullptr;
64 return false;
65 }
Pavel Grafove2e2d302017-08-01 17:15:53 +010066 if (inputConsumed > inputLen) {
Paul Crowley1ef25582016-01-21 20:26:12 +000067 LOG(ERROR) << "update reported too much input consumed";
Paul Crowley13ffd8e2016-01-27 14:30:22 +000068 mDevice = nullptr;
Paul Crowley1ef25582016-01-21 20:26:12 +000069 return false;
70 }
Paul Crowley1ef25582016-01-21 20:26:12 +000071 }
72 return true;
73}
74
Paul Crowleydff8c722016-05-16 08:14:56 -070075bool KeymasterOperation::finish(std::string* output) {
Shawn Willden35351812018-01-22 09:08:32 -070076 km::ErrorCode km_error;
77 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& /*ignored*/,
Shawn Willden785365b2018-01-20 09:37:36 -070078 const hidl_vec<uint8_t>& _output) {
Janis Danisevskis8e537b82016-10-26 14:27:10 +010079 km_error = ret;
Shawn Willden35351812018-01-22 09:08:32 -070080 if (km_error != km::ErrorCode::OK) return;
Shawn Willden785365b2018-01-20 09:37:36 -070081 if (output) output->assign(reinterpret_cast<const char*>(&_output[0]), _output.size());
Janis Danisevskis8e537b82016-10-26 14:27:10 +010082 };
Shawn Willden35351812018-01-22 09:08:32 -070083 auto error = mDevice->finish(mOpHandle, hidl_vec<km::KeyParameter>(), hidl_vec<uint8_t>(),
84 hidl_vec<uint8_t>(), km::HardwareAuthToken(),
85 km::VerificationToken(), hidlCb);
Paul Crowley13ffd8e2016-01-27 14:30:22 +000086 mDevice = nullptr;
Janis Danisevskis8e537b82016-10-26 14:27:10 +010087 if (!error.isOk()) {
88 LOG(ERROR) << "finish failed: " << error.description();
Paul Crowley1ef25582016-01-21 20:26:12 +000089 return false;
90 }
Shawn Willden35351812018-01-22 09:08:32 -070091 if (km_error != km::ErrorCode::OK) {
Janis Danisevskis015ec302017-01-31 11:31:08 +000092 LOG(ERROR) << "finish failed, code " << int32_t(km_error);
Janis Danisevskis8e537b82016-10-26 14:27:10 +010093 return false;
Paul Crowleydff8c722016-05-16 08:14:56 -070094 }
Paul Crowley1ef25582016-01-21 20:26:12 +000095 return true;
96}
97
98Keymaster::Keymaster() {
Shawn Willden35351812018-01-22 09:08:32 -070099 auto devices = KmDevice::enumerateAvailableDevices();
100 if (devices.empty()) return;
101 mDevice = std::move(devices[0]);
102 auto& version = mDevice->halVersion();
103 LOG(INFO) << "Using " << version.keymasterName << " from " << version.authorName
104 << " for encryption. Security level: " << toString(version.securityLevel)
105 << ", HAL: " << mDevice->descriptor() << "/" << mDevice->instanceName();
Paul Crowley1ef25582016-01-21 20:26:12 +0000106}
107
Shawn Willden35351812018-01-22 09:08:32 -0700108bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
109 km::ErrorCode km_error;
110 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
111 const km::KeyCharacteristics& /*ignored*/) {
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100112 km_error = ret;
Shawn Willden35351812018-01-22 09:08:32 -0700113 if (km_error != km::ErrorCode::OK) return;
Shawn Willden785365b2018-01-20 09:37:36 -0700114 if (key) key->assign(reinterpret_cast<const char*>(&keyBlob[0]), keyBlob.size());
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100115 };
116
117 auto error = mDevice->generateKey(inParams.hidl_data(), hidlCb);
118 if (!error.isOk()) {
119 LOG(ERROR) << "generate_key failed: " << error.description();
Paul Crowley1ef25582016-01-21 20:26:12 +0000120 return false;
121 }
Shawn Willden35351812018-01-22 09:08:32 -0700122 if (km_error != km::ErrorCode::OK) {
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100123 LOG(ERROR) << "generate_key failed, code " << int32_t(km_error);
124 return false;
125 }
Paul Crowley1ef25582016-01-21 20:26:12 +0000126 return true;
127}
128
Paul Crowleydf528a72016-03-09 09:31:37 -0800129bool Keymaster::deleteKey(const std::string& key) {
Shawn Willden35351812018-01-22 09:08:32 -0700130 auto keyBlob = km::support::blob2hidlVec(key);
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100131 auto error = mDevice->deleteKey(keyBlob);
132 if (!error.isOk()) {
133 LOG(ERROR) << "delete_key failed: " << error.description();
134 return false;
135 }
Shawn Willden35351812018-01-22 09:08:32 -0700136 if (error != km::ErrorCode::OK) {
137 LOG(ERROR) << "delete_key failed, code " << int32_t(km::ErrorCode(error));
Paul Crowley1ef25582016-01-21 20:26:12 +0000138 return false;
139 }
140 return true;
141}
142
Shawn Willden35351812018-01-22 09:08:32 -0700143bool Keymaster::upgradeKey(const std::string& oldKey, const km::AuthorizationSet& inParams,
Paul Crowleydff8c722016-05-16 08:14:56 -0700144 std::string* newKey) {
Shawn Willden35351812018-01-22 09:08:32 -0700145 auto oldKeyBlob = km::support::blob2hidlVec(oldKey);
146 km::ErrorCode km_error;
147 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100148 km_error = ret;
Shawn Willden35351812018-01-22 09:08:32 -0700149 if (km_error != km::ErrorCode::OK) return;
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100150 if (newKey)
151 newKey->assign(reinterpret_cast<const char*>(&upgradedKeyBlob[0]),
Shawn Willden785365b2018-01-20 09:37:36 -0700152 upgradedKeyBlob.size());
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100153 };
154 auto error = mDevice->upgradeKey(oldKeyBlob, inParams.hidl_data(), hidlCb);
155 if (!error.isOk()) {
156 LOG(ERROR) << "upgrade_key failed: " << error.description();
Paul Crowleydff8c722016-05-16 08:14:56 -0700157 return false;
158 }
Shawn Willden35351812018-01-22 09:08:32 -0700159 if (km_error != km::ErrorCode::OK) {
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100160 LOG(ERROR) << "upgrade_key failed, code " << int32_t(km_error);
161 return false;
162 }
Paul Crowleydff8c722016-05-16 08:14:56 -0700163 return true;
164}
165
Shawn Willden35351812018-01-22 09:08:32 -0700166KeymasterOperation Keymaster::begin(km::KeyPurpose purpose, const std::string& key,
167 const km::AuthorizationSet& inParams,
168 const km::HardwareAuthToken& authToken,
169 km::AuthorizationSet* outParams) {
170 auto keyBlob = km::support::blob2hidlVec(key);
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100171 uint64_t mOpHandle;
Shawn Willden35351812018-01-22 09:08:32 -0700172 km::ErrorCode km_error;
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100173
Shawn Willden35351812018-01-22 09:08:32 -0700174 auto hidlCb = [&](km::ErrorCode ret, const hidl_vec<km::KeyParameter>& _outParams,
Shawn Willden785365b2018-01-20 09:37:36 -0700175 uint64_t operationHandle) {
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100176 km_error = ret;
Shawn Willden35351812018-01-22 09:08:32 -0700177 if (km_error != km::ErrorCode::OK) return;
Shawn Willden785365b2018-01-20 09:37:36 -0700178 if (outParams) *outParams = _outParams;
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100179 mOpHandle = operationHandle;
180 };
181
Shawn Willden35351812018-01-22 09:08:32 -0700182 auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), authToken, hidlCb);
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100183 if (!error.isOk()) {
184 LOG(ERROR) << "begin failed: " << error.description();
Shawn Willden35351812018-01-22 09:08:32 -0700185 return KeymasterOperation(km::ErrorCode::UNKNOWN_ERROR);
Paul Crowley1ef25582016-01-21 20:26:12 +0000186 }
Shawn Willden35351812018-01-22 09:08:32 -0700187 if (km_error != km::ErrorCode::OK) {
Janis Danisevskis015ec302017-01-31 11:31:08 +0000188 LOG(ERROR) << "begin failed, code " << int32_t(km_error);
Janis Danisevskis8e537b82016-10-26 14:27:10 +0100189 return KeymasterOperation(km_error);
Paul Crowley1ef25582016-01-21 20:26:12 +0000190 }
Shawn Willden35351812018-01-22 09:08:32 -0700191 return KeymasterOperation(mDevice.get(), mOpHandle);
Paul Crowley1ef25582016-01-21 20:26:12 +0000192}
Shawn Willden35351812018-01-22 09:08:32 -0700193
Janis Danisevskis015ec302017-01-31 11:31:08 +0000194bool Keymaster::isSecure() {
Shawn Willden35351812018-01-22 09:08:32 -0700195 return mDevice->halVersion().securityLevel != km::SecurityLevel::SOFTWARE;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000196}
Paul Crowley1ef25582016-01-21 20:26:12 +0000197
198} // namespace vold
199} // namespace android
Janis Danisevskis015ec302017-01-31 11:31:08 +0000200
201using namespace ::android::vold;
202
203int keymaster_compatibility_cryptfs_scrypt() {
Janis Danisevskise7152c32017-03-08 11:02:30 -0800204 Keymaster dev;
205 if (!dev) {
206 LOG(ERROR) << "Failed to initiate keymaster session";
207 return -1;
208 }
209 return dev.isSecure();
Janis Danisevskis015ec302017-01-31 11:31:08 +0000210}
211
Paul Crowley73473332017-11-21 15:43:51 -0800212static bool write_string_to_buf(const std::string& towrite, uint8_t* buffer, uint32_t buffer_size,
213 uint32_t* out_size) {
214 if (!buffer || !out_size) {
215 LOG(ERROR) << "Missing target pointers";
216 return false;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000217 }
Paul Crowley73473332017-11-21 15:43:51 -0800218 *out_size = towrite.size();
219 if (buffer_size < towrite.size()) {
220 LOG(ERROR) << "Buffer too small " << buffer_size << " < " << towrite.size();
221 return false;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000222 }
Paul Crowley73473332017-11-21 15:43:51 -0800223 memset(buffer, '\0', buffer_size);
224 std::copy(towrite.begin(), towrite.end(), buffer);
225 return true;
226}
227
Shawn Willden35351812018-01-22 09:08:32 -0700228static km::AuthorizationSet keyParams(uint32_t rsa_key_size, uint64_t rsa_exponent,
229 uint32_t ratelimit) {
230 return km::AuthorizationSetBuilder()
231 .RsaSigningKey(rsa_key_size, rsa_exponent)
232 .NoDigestOrPadding()
233 .Authorization(km::TAG_BLOB_USAGE_REQUIREMENTS, km::KeyBlobUsageRequirements::STANDALONE)
234 .Authorization(km::TAG_NO_AUTH_REQUIRED)
235 .Authorization(km::TAG_MIN_SECONDS_BETWEEN_OPS, ratelimit);
Paul Crowley73473332017-11-21 15:43:51 -0800236}
237
238int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
239 uint32_t ratelimit, uint8_t* key_buffer,
240 uint32_t key_buffer_size, uint32_t* key_out_size) {
Janis Danisevskis015ec302017-01-31 11:31:08 +0000241 if (key_out_size) {
242 *key_out_size = 0;
243 }
Janis Danisevskis015ec302017-01-31 11:31:08 +0000244 Keymaster dev;
245 if (!dev) {
246 LOG(ERROR) << "Failed to initiate keymaster session";
247 return -1;
248 }
Paul Crowley73473332017-11-21 15:43:51 -0800249 std::string key;
250 if (!dev.generateKey(keyParams(rsa_key_size, rsa_exponent, ratelimit), &key)) return -1;
251 if (!write_string_to_buf(key, key_buffer, key_buffer_size, key_out_size)) return -1;
252 return 0;
253}
254
255int keymaster_upgrade_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64_t rsa_exponent,
256 uint32_t ratelimit, const uint8_t* key_blob,
257 size_t key_blob_size, uint8_t* key_buffer,
258 uint32_t key_buffer_size, uint32_t* key_out_size) {
259 if (key_out_size) {
260 *key_out_size = 0;
261 }
262 Keymaster dev;
263 if (!dev) {
264 LOG(ERROR) << "Failed to initiate keymaster session";
265 return -1;
266 }
267 std::string old_key(reinterpret_cast<const char*>(key_blob), key_blob_size);
268 std::string new_key;
269 if (!dev.upgradeKey(old_key, keyParams(rsa_key_size, rsa_exponent, ratelimit), &new_key))
270 return -1;
271 if (!write_string_to_buf(new_key, key_buffer, key_buffer_size, key_out_size)) return -1;
272 return 0;
273}
274
275KeymasterSignResult keymaster_sign_object_for_cryptfs_scrypt(
276 const uint8_t* key_blob, size_t key_blob_size, uint32_t ratelimit, const uint8_t* object,
277 const size_t object_size, uint8_t** signature_buffer, size_t* signature_buffer_size) {
278 Keymaster dev;
279 if (!dev) {
280 LOG(ERROR) << "Failed to initiate keymaster session";
281 return KeymasterSignResult::error;
282 }
Janis Danisevskis015ec302017-01-31 11:31:08 +0000283 if (!key_blob || !object || !signature_buffer || !signature_buffer_size) {
284 LOG(ERROR) << __FILE__ << ":" << __LINE__ << ":Invalid argument";
Paul Crowley73473332017-11-21 15:43:51 -0800285 return KeymasterSignResult::error;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000286 }
287
Shawn Willden35351812018-01-22 09:08:32 -0700288 km::AuthorizationSet outParams;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000289 std::string key(reinterpret_cast<const char*>(key_blob), key_blob_size);
290 std::string input(reinterpret_cast<const char*>(object), object_size);
291 std::string output;
292 KeymasterOperation op;
293
Shawn Willden35351812018-01-22 09:08:32 -0700294 auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding();
Janis Danisevskis015ec302017-01-31 11:31:08 +0000295 while (true) {
Shawn Willden35351812018-01-22 09:08:32 -0700296 op = dev.begin(km::KeyPurpose::SIGN, key, paramBuilder, km::HardwareAuthToken(), &outParams);
297 if (op.errorCode() == km::ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
Janis Danisevskis015ec302017-01-31 11:31:08 +0000298 sleep(ratelimit);
299 continue;
Shawn Willden785365b2018-01-20 09:37:36 -0700300 } else
301 break;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000302 }
303
Shawn Willden35351812018-01-22 09:08:32 -0700304 if (op.errorCode() == km::ErrorCode::KEY_REQUIRES_UPGRADE) {
Paul Crowley73473332017-11-21 15:43:51 -0800305 LOG(ERROR) << "Keymaster key requires upgrade";
306 return KeymasterSignResult::upgrade;
307 }
308
Shawn Willden35351812018-01-22 09:08:32 -0700309 if (op.errorCode() != km::ErrorCode::OK) {
Wei Wang4375f1b2017-02-24 17:43:01 -0800310 LOG(ERROR) << "Error starting keymaster signature transaction: " << int32_t(op.errorCode());
Paul Crowley73473332017-11-21 15:43:51 -0800311 return KeymasterSignResult::error;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000312 }
313
314 if (!op.updateCompletely(input, &output)) {
315 LOG(ERROR) << "Error sending data to keymaster signature transaction: "
Wei Wang4375f1b2017-02-24 17:43:01 -0800316 << uint32_t(op.errorCode());
Paul Crowley73473332017-11-21 15:43:51 -0800317 return KeymasterSignResult::error;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000318 }
319
320 if (!op.finish(&output)) {
Shawn Willden785365b2018-01-20 09:37:36 -0700321 LOG(ERROR) << "Error finalizing keymaster signature transaction: "
322 << int32_t(op.errorCode());
Paul Crowley73473332017-11-21 15:43:51 -0800323 return KeymasterSignResult::error;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000324 }
325
326 *signature_buffer = reinterpret_cast<uint8_t*>(malloc(output.size()));
327 if (*signature_buffer == nullptr) {
328 LOG(ERROR) << "Error allocation buffer for keymaster signature";
Paul Crowley73473332017-11-21 15:43:51 -0800329 return KeymasterSignResult::error;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000330 }
331 *signature_buffer_size = output.size();
332 std::copy(output.data(), output.data() + output.size(), *signature_buffer);
Paul Crowley73473332017-11-21 15:43:51 -0800333 return KeymasterSignResult::ok;
Janis Danisevskis015ec302017-01-31 11:31:08 +0000334}