blob: d4032c10ee4a11d6a0f809dd9dcacc756b90c8a1 [file] [log] [blame]
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001/*
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
Janis Danisevskis011675d2016-09-01 11:41:29 +010017#define LOG_TAG "keystore"
18
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070019#include "key_store_service.h"
20
21#include <fcntl.h>
22#include <sys/stat.h>
23
Janis Danisevskis7612fd42016-09-01 11:50:02 +010024#include <algorithm>
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070025#include <sstream>
26
27#include <binder/IPCThreadState.h>
28
29#include <private/android_filesystem_config.h>
30
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010031#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070032
33#include "defaults.h"
Janis Danisevskis18f27ad2016-06-01 13:57:40 -070034#include "keystore_attestation_id.h"
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010035#include "keystore_keymaster_enforcement.h"
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070036#include "keystore_utils.h"
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010037#include <keystore/keystore_hidl_support.h>
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070038
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010039namespace keystore {
40using namespace android;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070041
42const size_t MAX_OPERATIONS = 15;
43
44struct BIGNUM_Delete {
45 void operator()(BIGNUM* p) const { BN_free(p); }
46};
47typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
48
49void KeyStoreService::binderDied(const wp<IBinder>& who) {
50 auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -070051 for (const auto& token : operations) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070052 abort(token);
53 }
54}
55
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010056KeyStoreServiceReturnCode KeyStoreService::getState(int32_t userId) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070057 if (!checkBinderPermission(P_GET_STATE)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010058 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070059 }
60
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010061 return ResponseCode(mKeyStore->getState(userId));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070062}
63
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010064KeyStoreServiceReturnCode KeyStoreService::get(const String16& name, int32_t uid,
65 hidl_vec<uint8_t>* item) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070066 uid_t targetUid = getEffectiveUid(uid);
67 if (!checkBinderPermission(P_GET, targetUid)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010068 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070069 }
70
71 String8 name8(name);
72 Blob keyBlob;
73
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010074 KeyStoreServiceReturnCode rc =
75 mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_GENERIC);
76 if (!rc.isOk()) {
77 if (item) *item = hidl_vec<uint8_t>();
78 return rc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070079 }
80
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010081 // Do not replace this with "if (item) *item = blob2hidlVec(keyBlob)"!
82 // blob2hidlVec creates a hidl_vec<uint8_t> that references, but not owns, the data in keyBlob
83 // the subsequent assignment (*item = resultBlob) makes a deep copy, so that *item will own the
84 // corresponding resources.
85 auto resultBlob = blob2hidlVec(keyBlob);
86 if (item) {
87 *item = resultBlob;
88 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070089
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010090 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070091}
92
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010093KeyStoreServiceReturnCode KeyStoreService::insert(const String16& name,
94 const hidl_vec<uint8_t>& item, int targetUid,
95 int32_t flags) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070096 targetUid = getEffectiveUid(targetUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010097 auto result =
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070098 checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010099 if (!result.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700100 return result;
101 }
102
103 String8 name8(name);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400104 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_GENERIC));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700105
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100106 Blob keyBlob(&item[0], item.size(), NULL, 0, ::TYPE_GENERIC);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700107 keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
108
109 return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid));
110}
111
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100112KeyStoreServiceReturnCode KeyStoreService::del(const String16& name, int targetUid) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700113 targetUid = getEffectiveUid(targetUid);
114 if (!checkBinderPermission(P_DELETE, targetUid)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100115 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700116 }
117 String8 name8(name);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400118 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100119 ResponseCode result = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
120 if (result != ResponseCode::NO_ERROR) {
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400121 return result;
122 }
123
124 // Also delete any characteristics files
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100125 String8 chrFilename(
126 mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400127 return mKeyStore->del(chrFilename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700128}
129
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100130KeyStoreServiceReturnCode KeyStoreService::exist(const String16& name, int targetUid) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700131 targetUid = getEffectiveUid(targetUid);
132 if (!checkBinderPermission(P_EXIST, targetUid)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100133 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700134 }
135
136 String8 name8(name);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400137 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700138
139 if (access(filename.string(), R_OK) == -1) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100140 return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700141 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100142 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700143}
144
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100145KeyStoreServiceReturnCode KeyStoreService::list(const String16& prefix, int targetUid,
146 Vector<String16>* matches) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700147 targetUid = getEffectiveUid(targetUid);
148 if (!checkBinderPermission(P_LIST, targetUid)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100149 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700150 }
151 const String8 prefix8(prefix);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400152 String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid, TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700153
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100154 if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
155 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700156 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100157 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700158}
159
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100160KeyStoreServiceReturnCode KeyStoreService::reset() {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700161 if (!checkBinderPermission(P_RESET)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100162 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700163 }
164
165 uid_t callingUid = IPCThreadState::self()->getCallingUid();
166 mKeyStore->resetUser(get_user_id(callingUid), false);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100167 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700168}
169
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100170KeyStoreServiceReturnCode KeyStoreService::onUserPasswordChanged(int32_t userId,
171 const String16& password) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700172 if (!checkBinderPermission(P_PASSWORD)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100173 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700174 }
175
176 const String8 password8(password);
177 // Flush the auth token table to prevent stale tokens from sticking
178 // around.
179 mAuthTokenTable.Clear();
180
181 if (password.size() == 0) {
182 ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
183 mKeyStore->resetUser(userId, true);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100184 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700185 } else {
186 switch (mKeyStore->getState(userId)) {
187 case ::STATE_UNINITIALIZED: {
188 // generate master key, encrypt with password, write to file,
189 // initialize mMasterKey*.
190 return mKeyStore->initializeUser(password8, userId);
191 }
192 case ::STATE_NO_ERROR: {
193 // rewrite master key with new password.
194 return mKeyStore->writeMasterKey(password8, userId);
195 }
196 case ::STATE_LOCKED: {
197 ALOGE("Changing user %d's password while locked, clearing old encryption", userId);
198 mKeyStore->resetUser(userId, true);
199 return mKeyStore->initializeUser(password8, userId);
200 }
201 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100202 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700203 }
204}
205
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100206KeyStoreServiceReturnCode KeyStoreService::onUserAdded(int32_t userId, int32_t parentId) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700207 if (!checkBinderPermission(P_USER_CHANGED)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100208 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700209 }
210
211 // Sanity check that the new user has an empty keystore.
212 if (!mKeyStore->isEmpty(userId)) {
213 ALOGW("New user %d's keystore not empty. Clearing old entries.", userId);
214 }
215 // Unconditionally clear the keystore, just to be safe.
216 mKeyStore->resetUser(userId, false);
217 if (parentId != -1) {
218 // This profile must share the same master key password as the parent profile. Because the
219 // password of the parent profile is not known here, the best we can do is copy the parent's
220 // master key and master key file. This makes this profile use the same master key as the
221 // parent profile, forever.
222 return mKeyStore->copyMasterKey(parentId, userId);
223 } else {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100224 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700225 }
226}
227
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100228KeyStoreServiceReturnCode KeyStoreService::onUserRemoved(int32_t userId) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700229 if (!checkBinderPermission(P_USER_CHANGED)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100230 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700231 }
232
233 mKeyStore->resetUser(userId, false);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100234 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700235}
236
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100237KeyStoreServiceReturnCode KeyStoreService::lock(int32_t userId) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700238 if (!checkBinderPermission(P_LOCK)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100239 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700240 }
241
242 State state = mKeyStore->getState(userId);
243 if (state != ::STATE_NO_ERROR) {
244 ALOGD("calling lock in state: %d", state);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100245 return ResponseCode(state);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700246 }
247
248 mKeyStore->lock(userId);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100249 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700250}
251
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100252KeyStoreServiceReturnCode KeyStoreService::unlock(int32_t userId, const String16& pw) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700253 if (!checkBinderPermission(P_UNLOCK)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100254 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700255 }
256
257 State state = mKeyStore->getState(userId);
258 if (state != ::STATE_LOCKED) {
259 switch (state) {
260 case ::STATE_NO_ERROR:
261 ALOGI("calling unlock when already unlocked, ignoring.");
262 break;
263 case ::STATE_UNINITIALIZED:
264 ALOGE("unlock called on uninitialized keystore.");
265 break;
266 default:
267 ALOGE("unlock called on keystore in unknown state: %d", state);
268 break;
269 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100270 return ResponseCode(state);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700271 }
272
273 const String8 password8(pw);
274 // read master key, decrypt with password, initialize mMasterKey*.
275 return mKeyStore->readMasterKey(password8, userId);
276}
277
278bool KeyStoreService::isEmpty(int32_t userId) {
279 if (!checkBinderPermission(P_IS_EMPTY)) {
280 return false;
281 }
282
283 return mKeyStore->isEmpty(userId);
284}
285
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100286KeyStoreServiceReturnCode KeyStoreService::generate(const String16& name, int32_t targetUid,
287 int32_t keyType, int32_t keySize, int32_t flags,
288 Vector<sp<KeystoreArg>>* args) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700289 targetUid = getEffectiveUid(targetUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100290 auto result =
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700291 checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100292 if (!result.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700293 return result;
294 }
295
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100296 keystore::AuthorizationSet params;
297 add_legacy_key_authorizations(keyType, &params);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700298
299 switch (keyType) {
300 case EVP_PKEY_EC: {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100301 params.push_back(TAG_ALGORITHM, Algorithm::EC);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700302 if (keySize == -1) {
303 keySize = EC_DEFAULT_KEY_SIZE;
304 } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
305 ALOGI("invalid key size %d", keySize);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100306 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700307 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100308 params.push_back(TAG_KEY_SIZE, keySize);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700309 break;
310 }
311 case EVP_PKEY_RSA: {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100312 params.push_back(TAG_ALGORITHM, Algorithm::RSA);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700313 if (keySize == -1) {
314 keySize = RSA_DEFAULT_KEY_SIZE;
315 } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
316 ALOGI("invalid key size %d", keySize);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100317 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700318 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100319 params.push_back(TAG_KEY_SIZE, keySize);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700320 unsigned long exponent = RSA_DEFAULT_EXPONENT;
321 if (args->size() > 1) {
322 ALOGI("invalid number of arguments: %zu", args->size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100323 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700324 } else if (args->size() == 1) {
Chih-Hung Hsieh24b2a392016-07-28 10:35:24 -0700325 const sp<KeystoreArg>& expArg = args->itemAt(0);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700326 if (expArg != NULL) {
327 Unique_BIGNUM pubExpBn(BN_bin2bn(
328 reinterpret_cast<const unsigned char*>(expArg->data()), expArg->size(), NULL));
329 if (pubExpBn.get() == NULL) {
330 ALOGI("Could not convert public exponent to BN");
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100331 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700332 }
333 exponent = BN_get_word(pubExpBn.get());
334 if (exponent == 0xFFFFFFFFL) {
335 ALOGW("cannot represent public exponent as a long value");
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100336 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700337 }
338 } else {
339 ALOGW("public exponent not read");
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100340 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700341 }
342 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100343 params.push_back(TAG_RSA_PUBLIC_EXPONENT, exponent);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700344 break;
345 }
346 default: {
347 ALOGW("Unsupported key type %d", keyType);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100348 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700349 }
350 }
351
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100352 auto rc = generateKey(name, params.hidl_data(), hidl_vec<uint8_t>(), targetUid, flags,
353 /*outCharacteristics*/ NULL);
354 if (!rc.isOk()) {
355 ALOGW("generate failed: %d", int32_t(rc));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700356 }
357 return translateResultToLegacyResult(rc);
358}
359
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100360KeyStoreServiceReturnCode KeyStoreService::import(const String16& name,
361 const hidl_vec<uint8_t>& data, int targetUid,
362 int32_t flags) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700363
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100364 const uint8_t* ptr = &data[0];
365
366 Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, data.size()));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700367 if (!pkcs8.get()) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100368 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700369 }
370 Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
371 if (!pkey.get()) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100372 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700373 }
374 int type = EVP_PKEY_type(pkey->type);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100375 AuthorizationSet params;
376 add_legacy_key_authorizations(type, &params);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700377 switch (type) {
378 case EVP_PKEY_RSA:
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100379 params.push_back(TAG_ALGORITHM, Algorithm::RSA);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700380 break;
381 case EVP_PKEY_EC:
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100382 params.push_back(TAG_ALGORITHM, Algorithm::EC);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700383 break;
384 default:
385 ALOGW("Unsupported key type %d", type);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100386 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700387 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100388
389 auto rc = importKey(name, params.hidl_data(), KeyFormat::PKCS8, data, targetUid, flags,
390 /*outCharacteristics*/ NULL);
391
392 if (!rc.isOk()) {
393 ALOGW("importKey failed: %d", int32_t(rc));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700394 }
395 return translateResultToLegacyResult(rc);
396}
397
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100398KeyStoreServiceReturnCode KeyStoreService::sign(const String16& name, const hidl_vec<uint8_t>& data,
399 hidl_vec<uint8_t>* out) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700400 if (!checkBinderPermission(P_SIGN)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100401 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700402 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100403 return doLegacySignVerify(name, data, out, hidl_vec<uint8_t>(), KeyPurpose::SIGN);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700404}
405
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100406KeyStoreServiceReturnCode KeyStoreService::verify(const String16& name,
407 const hidl_vec<uint8_t>& data,
408 const hidl_vec<uint8_t>& signature) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700409 if (!checkBinderPermission(P_VERIFY)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100410 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700411 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100412 return doLegacySignVerify(name, data, nullptr, signature, KeyPurpose::VERIFY);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700413}
414
415/*
416 * TODO: The abstraction between things stored in hardware and regular blobs
417 * of data stored on the filesystem should be moved down to keystore itself.
418 * Unfortunately the Java code that calls this has naming conventions that it
419 * knows about. Ideally keystore shouldn't be used to store random blobs of
420 * data.
421 *
422 * Until that happens, it's necessary to have a separate "get_pubkey" and
423 * "del_key" since the Java code doesn't really communicate what it's
424 * intentions are.
425 */
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100426KeyStoreServiceReturnCode KeyStoreService::get_pubkey(const String16& name,
427 hidl_vec<uint8_t>* pubKey) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700428 ExportResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100429 exportKey(name, KeyFormat::X509, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF, &result);
430 if (!result.resultCode.isOk()) {
431 ALOGW("export failed: %d", int32_t(result.resultCode));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700432 return translateResultToLegacyResult(result.resultCode);
433 }
434
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100435 if (pubKey) *pubKey = std::move(result.exportData);
436 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700437}
438
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100439KeyStoreServiceReturnCode KeyStoreService::grant(const String16& name, int32_t granteeUid) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700440 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100441 auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
442 if (!result.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700443 return result;
444 }
445
446 String8 name8(name);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400447 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700448
449 if (access(filename.string(), R_OK) == -1) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100450 return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700451 }
452
453 mKeyStore->addGrant(filename.string(), granteeUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100454 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700455}
456
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100457KeyStoreServiceReturnCode KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700458 uid_t callingUid = IPCThreadState::self()->getCallingUid();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100459 auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
460 if (!result.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700461 return result;
462 }
463
464 String8 name8(name);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400465 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700466
467 if (access(filename.string(), R_OK) == -1) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100468 return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700469 }
470
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100471 return mKeyStore->removeGrant(filename.string(), granteeUid) ? ResponseCode::NO_ERROR
472 : ResponseCode::KEY_NOT_FOUND;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700473}
474
475int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
476 uid_t targetUid = getEffectiveUid(uid);
477 if (!checkBinderPermission(P_GET, targetUid)) {
478 ALOGW("permission denied for %d: getmtime", targetUid);
479 return -1L;
480 }
481
482 String8 name8(name);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400483 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700484
485 if (access(filename.string(), R_OK) == -1) {
486 ALOGW("could not access %s for getmtime", filename.string());
487 return -1L;
488 }
489
490 int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY));
491 if (fd < 0) {
492 ALOGW("could not open %s for getmtime", filename.string());
493 return -1L;
494 }
495
496 struct stat s;
497 int ret = fstat(fd, &s);
498 close(fd);
499 if (ret == -1) {
500 ALOGW("could not stat %s for getmtime", filename.string());
501 return -1L;
502 }
503
504 return static_cast<int64_t>(s.st_mtime);
505}
506
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400507// TODO(tuckeris): This is dead code, remove it. Don't bother copying over key characteristics here
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100508KeyStoreServiceReturnCode KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid,
509 const String16& destKey, int32_t destUid) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700510 uid_t callingUid = IPCThreadState::self()->getCallingUid();
511 pid_t spid = IPCThreadState::self()->getCallingPid();
512 if (!has_permission(callingUid, P_DUPLICATE, spid)) {
513 ALOGW("permission denied for %d: duplicate", callingUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100514 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700515 }
516
517 State state = mKeyStore->getState(get_user_id(callingUid));
518 if (!isKeystoreUnlocked(state)) {
519 ALOGD("calling duplicate in state: %d", state);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100520 return ResponseCode(state);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700521 }
522
523 if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) {
524 srcUid = callingUid;
525 } else if (!is_granted_to(callingUid, srcUid)) {
526 ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100527 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700528 }
529
530 if (destUid == -1) {
531 destUid = callingUid;
532 }
533
534 if (srcUid != destUid) {
535 if (static_cast<uid_t>(srcUid) != callingUid) {
536 ALOGD("can only duplicate from caller to other or to same uid: "
537 "calling=%d, srcUid=%d, destUid=%d",
538 callingUid, srcUid, destUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100539 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700540 }
541
542 if (!is_granted_to(callingUid, destUid)) {
543 ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100544 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700545 }
546 }
547
548 String8 source8(srcKey);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400549 String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid, ::TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700550
551 String8 target8(destKey);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400552 String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid, ::TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700553
554 if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
555 ALOGD("destination already exists: %s", targetFile.string());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100556 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700557 }
558
559 Blob keyBlob;
560 ResponseCode responseCode =
561 mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, get_user_id(srcUid));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100562 if (responseCode != ResponseCode::NO_ERROR) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700563 return responseCode;
564 }
565
566 return mKeyStore->put(targetFile.string(), &keyBlob, get_user_id(destUid));
567}
568
569int32_t KeyStoreService::is_hardware_backed(const String16& keyType) {
570 return mKeyStore->isHardwareBacked(keyType) ? 1 : 0;
571}
572
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100573KeyStoreServiceReturnCode KeyStoreService::clear_uid(int64_t targetUid64) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700574 uid_t targetUid = getEffectiveUid(targetUid64);
575 if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100576 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700577 }
578
579 String8 prefix = String8::format("%u_", targetUid);
580 Vector<String16> aliases;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100581 if (mKeyStore->list(prefix, &aliases, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
582 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700583 }
584
585 for (uint32_t i = 0; i < aliases.size(); i++) {
586 String8 name8(aliases[i]);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400587 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700588 mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400589
590 // del() will fail silently if no cached characteristics are present for this alias.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100591 String8 chr_filename(
592 mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400593 mKeyStore->del(chr_filename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700594 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100595 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700596}
597
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100598KeyStoreServiceReturnCode KeyStoreService::addRngEntropy(const hidl_vec<uint8_t>& entropy) {
599 const auto& device = mKeyStore->getDevice();
600 return KS_HANDLE_HIDL_ERROR(device->addRngEntropy(entropy));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700601}
602
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100603KeyStoreServiceReturnCode KeyStoreService::generateKey(const String16& name,
604 const hidl_vec<KeyParameter>& params,
605 const hidl_vec<uint8_t>& entropy, int uid,
606 int flags,
607 KeyCharacteristics* outCharacteristics) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700608 uid = getEffectiveUid(uid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100609 KeyStoreServiceReturnCode rc =
610 checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
611 if (!rc.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700612 return rc;
613 }
614
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100615 bool usingFallback = false;
616 auto& dev = mKeyStore->getDevice();
617 AuthorizationSet keyCharacteristics = params;
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400618
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700619 // TODO: Seed from Linux RNG before this.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100620 rc = addRngEntropy(entropy);
621 if (!rc.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700622 return rc;
623 }
624
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100625 KeyStoreServiceReturnCode error;
626 auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
627 const KeyCharacteristics& keyCharacteristics) {
628 error = ret;
629 if (!error.isOk()) {
630 return;
631 }
632 if (outCharacteristics) *outCharacteristics = keyCharacteristics;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700633
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100634 // Write the key
635 String8 name8(name);
636 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700637
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100638 Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
639 keyBlob.setFallback(usingFallback);
640 keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700641
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100642 error = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
643 };
644
645 rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(params, hidl_cb));
646 if (!rc.isOk()) {
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400647 return rc;
648 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100649 if (!error.isOk()) {
650 ALOGE("Failed to generate key -> falling back to software keymaster");
651 usingFallback = true;
652 auto& fallback = mKeyStore->getFallbackDevice();
653 rc = KS_HANDLE_HIDL_ERROR(fallback->generateKey(params, hidl_cb));
654 if (!rc.isOk()) {
655 return rc;
656 }
657 if (!error.isOk()) {
658 return error;
659 }
660 }
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400661
662 // Write the characteristics:
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100663 String8 name8(name);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400664 String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
665
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100666 std::stringstream kc_stream;
667 keyCharacteristics.Serialize(&kc_stream);
668 if (kc_stream.bad()) {
669 return ResponseCode::SYSTEM_ERROR;
670 }
671 auto kc_buf = kc_stream.str();
672 Blob charBlob(reinterpret_cast<const uint8_t*>(kc_buf.data()), kc_buf.size(), NULL, 0,
673 ::TYPE_KEY_CHARACTERISTICS);
674 charBlob.setFallback(usingFallback);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400675 charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
676
677 return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700678}
679
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100680KeyStoreServiceReturnCode
681KeyStoreService::getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId,
682 const hidl_vec<uint8_t>& appData, int32_t uid,
683 KeyCharacteristics* outCharacteristics) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700684 if (!outCharacteristics) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100685 return ErrorCode::UNEXPECTED_NULL_POINTER;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700686 }
687
688 uid_t targetUid = getEffectiveUid(uid);
689 uid_t callingUid = IPCThreadState::self()->getCallingUid();
690 if (!is_granted_to(callingUid, targetUid)) {
691 ALOGW("uid %d not permitted to act for uid %d in getKeyCharacteristics", callingUid,
692 targetUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100693 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700694 }
695
696 Blob keyBlob;
697 String8 name8(name);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700698
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100699 KeyStoreServiceReturnCode rc =
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700700 mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100701 if (!rc.isOk()) {
702 return rc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700703 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100704
705 auto hidlKeyBlob = blob2hidlVec(keyBlob);
706 auto& dev = mKeyStore->getDevice(keyBlob);
707
708 KeyStoreServiceReturnCode error;
709
710 auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
711 error = ret;
712 if (!error.isOk()) {
713 return;
Shawn Willden98c59162016-03-20 09:10:18 -0600714 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100715 *outCharacteristics = keyCharacteristics;
716 };
717
718 rc = KS_HANDLE_HIDL_ERROR(dev->getKeyCharacteristics(hidlKeyBlob, clientId, appData, hidlCb));
719 if (!rc.isOk()) {
720 return rc;
721 }
722
723 if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
724 AuthorizationSet upgradeParams;
725 if (clientId.size()) {
726 upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
727 }
728 if (appData.size()) {
729 upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
Shawn Willden98c59162016-03-20 09:10:18 -0600730 }
731 rc = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100732 if (!rc.isOk()) {
Shawn Willden98c59162016-03-20 09:10:18 -0600733 return rc;
734 }
Shawn Willden715d0232016-01-21 00:45:13 -0700735
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100736 auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
737
738 rc = KS_HANDLE_HIDL_ERROR(
739 dev->getKeyCharacteristics(upgradedHidlKeyBlob, clientId, appData, hidlCb));
740 if (!rc.isOk()) {
741 return rc;
742 }
743 // Note that, on success, "error" will have been updated by the hidlCB callback.
744 // So it is fine to return "error" below.
745 }
746 return error;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700747}
748
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100749KeyStoreServiceReturnCode
750KeyStoreService::importKey(const String16& name, const hidl_vec<KeyParameter>& params,
751 KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid, int flags,
752 KeyCharacteristics* outCharacteristics) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700753 uid = getEffectiveUid(uid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100754 KeyStoreServiceReturnCode rc =
755 checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
756 if (!rc.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700757 return rc;
758 }
759
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100760 bool usingFallback = false;
761 auto& dev = mKeyStore->getDevice();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700762
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700763 String8 name8(name);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700764
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100765 KeyStoreServiceReturnCode error;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700766
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100767 auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
768 const KeyCharacteristics& keyCharacteristics) {
769 error = ret;
770 if (!error.isOk()) {
771 return;
772 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700773
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100774 if (outCharacteristics) *outCharacteristics = keyCharacteristics;
775
776 // Write the key:
777 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
778
779 Blob ksBlob(&keyBlob[0], keyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
780 ksBlob.setFallback(usingFallback);
781 ksBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
782
783 error = mKeyStore->put(filename.string(), &ksBlob, get_user_id(uid));
784 };
785
786 rc = KS_HANDLE_HIDL_ERROR(dev->importKey(params, format, keyData, hidlCb));
787 // possible hidl error
788 if (!rc.isOk()) {
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400789 return rc;
790 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100791 // now check error from callback
792 if (!error.isOk()) {
793 ALOGE("Failed to import key -> falling back to software keymaster");
794 usingFallback = true;
795 auto& fallback = mKeyStore->getFallbackDevice();
796 rc = KS_HANDLE_HIDL_ERROR(fallback->importKey(params, format, keyData, hidlCb));
797 // possible hidl error
798 if (!rc.isOk()) {
799 return rc;
800 }
801 // now check error from callback
802 if (!error.isOk()) {
803 return error;
804 }
805 }
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400806
807 // Write the characteristics:
808 String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
809
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100810 AuthorizationSet opParams = params;
811 std::stringstream kcStream;
812 opParams.Serialize(&kcStream);
813 if (kcStream.bad()) return ResponseCode::SYSTEM_ERROR;
814 auto kcBuf = kcStream.str();
815
816 Blob charBlob(reinterpret_cast<const uint8_t*>(kcBuf.data()), kcBuf.size(), NULL, 0,
817 ::TYPE_KEY_CHARACTERISTICS);
818 charBlob.setFallback(usingFallback);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400819 charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
820
821 return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700822}
823
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100824void KeyStoreService::exportKey(const String16& name, KeyFormat format,
825 const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700826 int32_t uid, ExportResult* result) {
827
828 uid_t targetUid = getEffectiveUid(uid);
829 uid_t callingUid = IPCThreadState::self()->getCallingUid();
830 if (!is_granted_to(callingUid, targetUid)) {
831 ALOGW("uid %d not permitted to act for uid %d in exportKey", callingUid, targetUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100832 result->resultCode = ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700833 return;
834 }
835
836 Blob keyBlob;
837 String8 name8(name);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700838
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100839 result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
840 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700841 return;
842 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100843
844 auto key = blob2hidlVec(keyBlob);
845 auto& dev = mKeyStore->getDevice(keyBlob);
846
847 auto hidlCb = [&](ErrorCode ret, const ::android::hardware::hidl_vec<uint8_t>& keyMaterial) {
848 result->resultCode = ret;
849 if (!result->resultCode.isOk()) {
Ji Wang2c142312016-10-14 17:21:10 +0800850 return;
851 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100852 result->exportData = keyMaterial;
853 };
854 KeyStoreServiceReturnCode rc =
855 KS_HANDLE_HIDL_ERROR(dev->exportKey(format, key, clientId, appData, hidlCb));
856 // Overwrite result->resultCode only on HIDL error. Otherwise we want the result set in the
857 // callback hidlCb.
858 if (!rc.isOk()) {
859 result->resultCode = rc;
Ji Wang2c142312016-10-14 17:21:10 +0800860 }
861
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100862 if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
863 AuthorizationSet upgradeParams;
864 if (clientId.size()) {
865 upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
866 }
867 if (appData.size()) {
868 upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
869 }
870 result->resultCode = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
871 if (!result->resultCode.isOk()) {
872 return;
873 }
874
875 auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
876
877 result->resultCode = KS_HANDLE_HIDL_ERROR(
878 dev->exportKey(format, upgradedHidlKeyBlob, clientId, appData, hidlCb));
879 if (!result->resultCode.isOk()) {
880 return;
881 }
882 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700883}
884
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100885static inline void addAuthTokenToParams(AuthorizationSet* params, const HardwareAuthToken* token) {
886 if (token) {
887 params->push_back(TAG_AUTH_TOKEN, authToken2HidlVec(*token));
888 }
889}
890
891void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose,
892 bool pruneable, const hidl_vec<KeyParameter>& params,
893 const hidl_vec<uint8_t>& entropy, int32_t uid,
894 OperationResult* result) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700895 uid_t callingUid = IPCThreadState::self()->getCallingUid();
896 uid_t targetUid = getEffectiveUid(uid);
897 if (!is_granted_to(callingUid, targetUid)) {
898 ALOGW("uid %d not permitted to act for uid %d in begin", callingUid, targetUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100899 result->resultCode = ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700900 return;
901 }
902 if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
903 ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100904 result->resultCode = ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700905 return;
906 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100907 if (!checkAllowedOperationParams(params)) {
908 result->resultCode = ErrorCode::INVALID_ARGUMENT;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700909 return;
910 }
911 Blob keyBlob;
912 String8 name8(name);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100913 result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
914 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700915 return;
916 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100917
918 auto key = blob2hidlVec(keyBlob);
919 auto& dev = mKeyStore->getDevice(keyBlob);
920 AuthorizationSet opParams = params;
921 KeyCharacteristics characteristics;
922 result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
923
924 if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
925 result->resultCode = upgradeKeyBlob(name, targetUid, opParams, &keyBlob);
926 if (!result->resultCode.isOk()) {
Shawn Willden98c59162016-03-20 09:10:18 -0600927 return;
928 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100929 key = blob2hidlVec(keyBlob);
930 result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
Shawn Willden98c59162016-03-20 09:10:18 -0600931 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100932 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700933 return;
934 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100935
936 const HardwareAuthToken* authToken = NULL;
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400937
938 // Merge these characteristics with the ones cached when the key was generated or imported
939 Blob charBlob;
940 AuthorizationSet persistedCharacteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100941 result->resultCode =
942 mKeyStore->getKeyForName(&charBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
943 if (result->resultCode.isOk()) {
944 // TODO write one shot stream buffer to avoid copying (twice here)
945 std::string charBuffer(reinterpret_cast<const char*>(charBlob.getValue()),
946 charBlob.getLength());
947 std::stringstream charStream(charBuffer);
948 persistedCharacteristics.Deserialize(&charStream);
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400949 } else {
950 ALOGD("Unable to read cached characteristics for key");
951 }
952
953 // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100954 AuthorizationSet softwareEnforced = characteristics.softwareEnforced;
955 AuthorizationSet teeEnforced = characteristics.teeEnforced;
956 persistedCharacteristics.Union(softwareEnforced);
957 persistedCharacteristics.Subtract(teeEnforced);
958 characteristics.softwareEnforced = persistedCharacteristics.hidl_data();
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -0400959
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100960 result->resultCode = getAuthToken(characteristics, 0, purpose, &authToken,
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700961 /*failOnTokenMissing*/ false);
962 // If per-operation auth is needed we need to begin the operation and
963 // the client will need to authorize that operation before calling
964 // update. Any other auth issues stop here.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100965 if (!result->resultCode.isOk() && result->resultCode != ResponseCode::OP_AUTH_NEEDED) return;
966
967 addAuthTokenToParams(&opParams, authToken);
968
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700969 // Add entropy to the device first.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100970 if (entropy.size()) {
971 result->resultCode = addRngEntropy(entropy);
972 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700973 return;
974 }
975 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700976
977 // Create a keyid for this key.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100978 km_id_t keyid;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700979 if (!enforcement_policy.CreateKeyId(key, &keyid)) {
980 ALOGE("Failed to create a key ID for authorization checking.");
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100981 result->resultCode = ErrorCode::UNKNOWN_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700982 return;
983 }
984
985 // Check that all key authorization policy requirements are met.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100986 AuthorizationSet key_auths = characteristics.teeEnforced;
987 key_auths.append(&characteristics.softwareEnforced[0],
988 &characteristics.softwareEnforced[characteristics.softwareEnforced.size()]);
989
990 result->resultCode = enforcement_policy.AuthorizeOperation(
991 purpose, keyid, key_auths, opParams, 0 /* op_handle */, true /* is_begin_operation */);
992 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700993 return;
994 }
995
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700996 // If there are more than MAX_OPERATIONS, abort the oldest operation that was started as
997 // pruneable.
998 while (mOperationMap.getOperationCount() >= MAX_OPERATIONS) {
999 ALOGD("Reached or exceeded concurrent operations limit");
1000 if (!pruneOperation()) {
1001 break;
1002 }
1003 }
1004
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001005 auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
1006 uint64_t operationHandle) {
1007 result->resultCode = ret;
1008 if (!result->resultCode.isOk()) {
1009 return;
1010 }
1011 result->handle = operationHandle;
1012 result->outParams = outParams;
1013 };
1014
1015 ErrorCode rc = KS_HANDLE_HIDL_ERROR(dev->begin(purpose, key, opParams.hidl_data(), hidlCb));
1016 if (rc != ErrorCode::OK) {
1017 ALOGW("Got error %d from begin()", rc);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001018 }
1019
1020 // If there are too many operations abort the oldest operation that was
1021 // started as pruneable and try again.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001022 while (rc == ErrorCode::TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) {
1023 ALOGW("Ran out of operation handles");
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001024 if (!pruneOperation()) {
1025 break;
1026 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001027 rc = KS_HANDLE_HIDL_ERROR(dev->begin(purpose, key, opParams.hidl_data(), hidlCb));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001028 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001029 if (rc != ErrorCode::OK) {
1030 result->resultCode = rc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001031 return;
1032 }
1033
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001034 // Note: The operation map takes possession of the contents of "characteristics".
1035 // It is safe to use characteristics after the following line but it will be empty.
1036 sp<IBinder> operationToken = mOperationMap.addOperation(
1037 result->handle, keyid, purpose, dev, appToken, std::move(characteristics), pruneable);
1038 assert(characteristics.teeEnforced.size() == 0);
1039 assert(characteristics.softwareEnforced.size() == 0);
1040
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001041 if (authToken) {
1042 mOperationMap.setOperationAuthToken(operationToken, authToken);
1043 }
1044 // Return the authentication lookup result. If this is a per operation
1045 // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the
1046 // application should get an auth token using the handle before the
1047 // first call to update, which will fail if keystore hasn't received the
1048 // auth token.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001049 // All fields but "token" were set in the begin operation's callback.
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001050 result->token = operationToken;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001051}
1052
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001053void KeyStoreService::update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
1054 const hidl_vec<uint8_t>& data, OperationResult* result) {
1055 if (!checkAllowedOperationParams(params)) {
1056 result->resultCode = ErrorCode::INVALID_ARGUMENT;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001057 return;
1058 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001059 km_device_t dev;
1060 uint64_t handle;
1061 KeyPurpose purpose;
1062 km_id_t keyid;
1063 const KeyCharacteristics* characteristics;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001064 if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001065 result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001066 return;
1067 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001068 AuthorizationSet opParams = params;
1069 result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
1070 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001071 return;
1072 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001073
1074 // Check that all key authorization policy requirements are met.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001075 AuthorizationSet key_auths(characteristics->teeEnforced);
1076 key_auths.append(&characteristics->softwareEnforced[0],
1077 &characteristics->softwareEnforced[characteristics->softwareEnforced.size()]);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001078 result->resultCode = enforcement_policy.AuthorizeOperation(
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001079 purpose, keyid, key_auths, opParams, handle, false /* is_begin_operation */);
1080 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001081 return;
1082 }
1083
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001084 auto hidlCb = [&](ErrorCode ret, uint32_t inputConsumed,
1085 const hidl_vec<KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
1086 result->resultCode = ret;
1087 if (!result->resultCode.isOk()) {
1088 return;
1089 }
1090 result->inputConsumed = inputConsumed;
1091 result->outParams = outParams;
1092 result->data = output;
1093 };
1094
1095 KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(dev->update(handle, params, data, hidlCb));
1096 // just a reminder: on success result->resultCode was set in the callback. So we only overwrite
1097 // it if there was a communication error indicated by the ErrorCode.
1098 if (!rc.isOk()) {
1099 result->resultCode = rc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001100 }
1101}
1102
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001103void KeyStoreService::finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
1104 const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001105 OperationResult* result) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001106 if (!checkAllowedOperationParams(params)) {
1107 result->resultCode = ErrorCode::INVALID_ARGUMENT;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001108 return;
1109 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001110 km_device_t dev;
1111 uint64_t handle;
1112 KeyPurpose purpose;
1113 km_id_t keyid;
1114 const KeyCharacteristics* characteristics;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001115 if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001116 result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001117 return;
1118 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001119 AuthorizationSet opParams = params;
1120 result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
1121 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001122 return;
1123 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001124
1125 if (entropy.size()) {
1126 result->resultCode = addRngEntropy(entropy);
1127 if (!result->resultCode.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001128 return;
1129 }
1130 }
1131
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001132 // Check that all key authorization policy requirements are met.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001133 AuthorizationSet key_auths(characteristics->teeEnforced);
1134 key_auths.append(&characteristics->softwareEnforced[0],
1135 &characteristics->softwareEnforced[characteristics->softwareEnforced.size()]);
1136 result->resultCode = enforcement_policy.AuthorizeOperation(
1137 purpose, keyid, key_auths, opParams, handle, false /* is_begin_operation */);
1138 if (!result->resultCode.isOk()) return;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001139
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001140 auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
1141 const hidl_vec<uint8_t>& output) {
1142 result->resultCode = ret;
1143 if (!result->resultCode.isOk()) {
1144 return;
1145 }
1146 result->outParams = outParams;
1147 result->data = output;
1148 };
1149
1150 KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(dev->finish(
1151 handle, opParams.hidl_data(),
1152 hidl_vec<uint8_t>() /* TODO(swillden): wire up input to finish() */, signature, hidlCb));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001153 // Remove the operation regardless of the result
1154 mOperationMap.removeOperation(token);
1155 mAuthTokenTable.MarkCompleted(handle);
1156
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001157 // just a reminder: on success result->resultCode was set in the callback. So we only overwrite
1158 // it if there was a communication error indicated by the ErrorCode.
1159 if (!rc.isOk()) {
1160 result->resultCode = rc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001161 }
1162}
1163
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001164KeyStoreServiceReturnCode KeyStoreService::abort(const sp<IBinder>& token) {
1165 km_device_t dev;
1166 uint64_t handle;
1167 KeyPurpose purpose;
1168 km_id_t keyid;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001169 if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, NULL)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001170 return ErrorCode::INVALID_OPERATION_HANDLE;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001171 }
1172 mOperationMap.removeOperation(token);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001173
1174 ErrorCode rc = KS_HANDLE_HIDL_ERROR(dev->abort(handle));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001175 mAuthTokenTable.MarkCompleted(handle);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001176 return rc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001177}
1178
1179bool KeyStoreService::isOperationAuthorized(const sp<IBinder>& token) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001180 km_device_t dev;
1181 uint64_t handle;
1182 const KeyCharacteristics* characteristics;
1183 KeyPurpose purpose;
1184 km_id_t keyid;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001185 if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
1186 return false;
1187 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001188 const HardwareAuthToken* authToken = NULL;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001189 mOperationMap.getOperationAuthToken(token, &authToken);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001190 AuthorizationSet ignored;
1191 auto authResult = addOperationAuthTokenIfNeeded(token, &ignored);
1192 return authResult.isOk();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001193}
1194
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001195KeyStoreServiceReturnCode KeyStoreService::addAuthToken(const uint8_t* token, size_t length) {
1196 // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
1197 // receive a HardwareAuthToken, rather than an opaque byte array.
1198
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001199 if (!checkBinderPermission(P_ADD_AUTH)) {
1200 ALOGW("addAuthToken: permission denied for %d", IPCThreadState::self()->getCallingUid());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001201 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001202 }
1203 if (length != sizeof(hw_auth_token_t)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001204 return ErrorCode::INVALID_ARGUMENT;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001205 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001206
1207 hw_auth_token_t authToken;
1208 memcpy(reinterpret_cast<void*>(&authToken), token, sizeof(hw_auth_token_t));
1209 if (authToken.version != 0) {
1210 return ErrorCode::INVALID_ARGUMENT;
1211 }
1212
1213 std::unique_ptr<HardwareAuthToken> hidlAuthToken(new HardwareAuthToken);
1214 hidlAuthToken->challenge = authToken.challenge;
1215 hidlAuthToken->userId = authToken.user_id;
1216 hidlAuthToken->authenticatorId = authToken.authenticator_id;
1217 hidlAuthToken->authenticatorType = authToken.authenticator_type;
1218 hidlAuthToken->timestamp = authToken.timestamp;
1219 static_assert(
1220 std::is_same<decltype(hidlAuthToken->hmac),
1221 ::android::hardware::hidl_array<uint8_t, sizeof(authToken.hmac)>>::value,
1222 "This function assumes token HMAC is 32 bytes, but it might not be.");
1223 std::copy(authToken.hmac, authToken.hmac + sizeof(authToken.hmac), hidlAuthToken->hmac.data());
1224
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001225 // The table takes ownership of authToken.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001226 mAuthTokenTable.AddAuthenticationToken(hidlAuthToken.release());
1227 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001228}
1229
Janis Danisevskis7612fd42016-09-01 11:50:02 +01001230constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
1231
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001232KeyStoreServiceReturnCode KeyStoreService::attestKey(const String16& name,
1233 const hidl_vec<KeyParameter>& params,
1234 hidl_vec<hidl_vec<uint8_t>>* outChain) {
1235 if (!outChain) {
1236 return ErrorCode::OUTPUT_PARAMETER_NULL;
1237 }
Shawn Willden50eb1b22016-01-21 12:41:23 -07001238
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001239 if (!checkAllowedOperationParams(params)) {
1240 return ErrorCode::INVALID_ARGUMENT;
Shawn Willden50eb1b22016-01-21 12:41:23 -07001241 }
1242
1243 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1244
1245 Blob keyBlob;
1246 String8 name8(name);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001247 KeyStoreServiceReturnCode responseCode =
Shawn Willden50eb1b22016-01-21 12:41:23 -07001248 mKeyStore->getKeyForName(&keyBlob, name8, callingUid, TYPE_KEYMASTER_10);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001249 if (!responseCode.isOk()) {
Shawn Willden50eb1b22016-01-21 12:41:23 -07001250 return responseCode;
1251 }
1252
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001253 auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
Janis Danisevskis011675d2016-09-01 11:41:29 +01001254 if (!asn1_attestation_id_result.isOk()) {
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001255 ALOGE("failed to gather attestation_id");
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001256 return ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001257 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001258 std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001259
1260 /*
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001261 * The attestation application ID cannot be longer than
1262 * KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE, so we truncate if too long.
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001263 */
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001264 if (asn1_attestation_id.size() > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE)
1265 asn1_attestation_id.resize(KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001266
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001267 AuthorizationSet mutableParams = params;
Shawn Willden50eb1b22016-01-21 12:41:23 -07001268
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001269 mutableParams.push_back(TAG_ATTESTATION_APPLICATION_ID, blob2hidlVec(asn1_attestation_id));
1270
1271 KeyStoreServiceReturnCode error;
1272 auto hidlCb = [&](ErrorCode ret, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
1273 error = ret;
1274 if (!error.isOk()) {
1275 return;
1276 }
1277 if (outChain) *outChain = certChain;
1278 };
1279
1280 auto hidlKey = blob2hidlVec(keyBlob);
1281 auto& dev = mKeyStore->getDevice(keyBlob);
1282 KeyStoreServiceReturnCode rc =
1283 KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), hidlCb));
1284 if (!rc.isOk()) {
1285 return rc;
1286 }
1287 return error;
Shawn Willden50eb1b22016-01-21 12:41:23 -07001288}
1289
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001290KeyStoreServiceReturnCode KeyStoreService::onDeviceOffBody() {
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -04001291 // TODO(tuckeris): add permission check. This should be callable from ClockworkHome only.
1292 mAuthTokenTable.onDeviceOffBody();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001293 return ResponseCode::NO_ERROR;
Tucker Sylvestro0ab28b72016-08-05 18:02:47 -04001294}
1295
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001296/**
1297 * Prune the oldest pruneable operation.
1298 */
1299bool KeyStoreService::pruneOperation() {
1300 sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation();
1301 ALOGD("Trying to prune operation %p", oldest.get());
1302 size_t op_count_before_abort = mOperationMap.getOperationCount();
1303 // We mostly ignore errors from abort() because all we care about is whether at least
1304 // one operation has been removed.
1305 int abort_error = abort(oldest);
1306 if (mOperationMap.getOperationCount() >= op_count_before_abort) {
1307 ALOGE("Failed to abort pruneable operation %p, error: %d", oldest.get(), abort_error);
1308 return false;
1309 }
1310 return true;
1311}
1312
1313/**
1314 * Get the effective target uid for a binder operation that takes an
1315 * optional uid as the target.
1316 */
1317uid_t KeyStoreService::getEffectiveUid(int32_t targetUid) {
1318 if (targetUid == UID_SELF) {
1319 return IPCThreadState::self()->getCallingUid();
1320 }
1321 return static_cast<uid_t>(targetUid);
1322}
1323
1324/**
1325 * Check if the caller of the current binder method has the required
1326 * permission and if acting on other uids the grants to do so.
1327 */
1328bool KeyStoreService::checkBinderPermission(perm_t permission, int32_t targetUid) {
1329 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1330 pid_t spid = IPCThreadState::self()->getCallingPid();
1331 if (!has_permission(callingUid, permission, spid)) {
1332 ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
1333 return false;
1334 }
1335 if (!is_granted_to(callingUid, getEffectiveUid(targetUid))) {
1336 ALOGW("uid %d not granted to act for %d", callingUid, targetUid);
1337 return false;
1338 }
1339 return true;
1340}
1341
1342/**
1343 * Check if the caller of the current binder method has the required
1344 * permission and the target uid is the caller or the caller is system.
1345 */
1346bool KeyStoreService::checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid) {
1347 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1348 pid_t spid = IPCThreadState::self()->getCallingPid();
1349 if (!has_permission(callingUid, permission, spid)) {
1350 ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
1351 return false;
1352 }
1353 return getEffectiveUid(targetUid) == callingUid || callingUid == AID_SYSTEM;
1354}
1355
1356/**
1357 * Check if the caller of the current binder method has the required
1358 * permission or the target of the operation is the caller's uid. This is
1359 * for operation where the permission is only for cross-uid activity and all
1360 * uids are allowed to act on their own (ie: clearing all entries for a
1361 * given uid).
1362 */
1363bool KeyStoreService::checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid) {
1364 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1365 if (getEffectiveUid(targetUid) == callingUid) {
1366 return true;
1367 } else {
1368 return checkBinderPermission(permission, targetUid);
1369 }
1370}
1371
1372/**
1373 * Helper method to check that the caller has the required permission as
1374 * well as the keystore is in the unlocked state if checkUnlocked is true.
1375 *
1376 * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and
1377 * otherwise the state of keystore when not unlocked and checkUnlocked is
1378 * true.
1379 */
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001380KeyStoreServiceReturnCode
1381KeyStoreService::checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid,
1382 bool checkUnlocked) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001383 if (!checkBinderPermission(permission, targetUid)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001384 return ResponseCode::PERMISSION_DENIED;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001385 }
1386 State state = mKeyStore->getState(get_user_id(getEffectiveUid(targetUid)));
1387 if (checkUnlocked && !isKeystoreUnlocked(state)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001388 // All State values coincide with ResponseCodes
1389 return static_cast<ResponseCode>(state);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001390 }
1391
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001392 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001393}
1394
1395bool KeyStoreService::isKeystoreUnlocked(State state) {
1396 switch (state) {
1397 case ::STATE_NO_ERROR:
1398 return true;
1399 case ::STATE_UNINITIALIZED:
1400 case ::STATE_LOCKED:
1401 return false;
1402 }
1403 return false;
1404}
1405
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001406/**
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001407 * Check that all KeyParameter's provided by the application are
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001408 * allowed. Any parameter that keystore adds itself should be disallowed here.
1409 */
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001410bool KeyStoreService::checkAllowedOperationParams(const hidl_vec<KeyParameter>& params) {
1411 for (size_t i = 0; i < params.size(); ++i) {
1412 switch (params[i].tag) {
1413 case Tag::AUTH_TOKEN:
Janis Danisevskis18f27ad2016-06-01 13:57:40 -07001414 // fall through intended
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001415 case Tag::ATTESTATION_APPLICATION_ID:
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001416 return false;
1417 default:
1418 break;
1419 }
1420 }
1421 return true;
1422}
1423
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001424ErrorCode KeyStoreService::getOperationCharacteristics(const hidl_vec<uint8_t>& key,
1425 km_device_t* dev,
1426 const AuthorizationSet& params,
1427 KeyCharacteristics* out) {
1428 hidl_vec<uint8_t> appId;
1429 hidl_vec<uint8_t> appData;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001430 for (auto param : params) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001431 if (param.tag == Tag::APPLICATION_ID) {
1432 appId = authorizationValue(TAG_APPLICATION_ID, param).value();
1433 } else if (param.tag == Tag::APPLICATION_DATA) {
1434 appData = authorizationValue(TAG_APPLICATION_DATA, param).value();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001435 }
1436 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001437 ErrorCode error = ErrorCode::OK;
1438
1439 auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
1440 error = ret;
1441 if (error != ErrorCode::OK) {
1442 return;
1443 }
1444 if (out) *out = keyCharacteristics;
1445 };
1446
1447 ErrorCode rc = KS_HANDLE_HIDL_ERROR((*dev)->getKeyCharacteristics(key, appId, appData, hidlCb));
1448 if (rc != ErrorCode::OK) {
1449 return rc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001450 }
1451 return error;
1452}
1453
1454/**
1455 * Get the auth token for this operation from the auth token table.
1456 *
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001457 * Returns ResponseCode::NO_ERROR if the auth token was set or none was required.
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001458 * ::OP_AUTH_NEEDED if it is a per op authorization, no
1459 * authorization token exists for that operation and
1460 * failOnTokenMissing is false.
1461 * KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
1462 * token for the operation
1463 */
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001464KeyStoreServiceReturnCode KeyStoreService::getAuthToken(const KeyCharacteristics& characteristics,
1465 uint64_t handle, KeyPurpose purpose,
1466 const HardwareAuthToken** authToken,
1467 bool failOnTokenMissing) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001468
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001469 AuthorizationSet allCharacteristics;
1470 for (size_t i = 0; i < characteristics.softwareEnforced.size(); i++) {
1471 allCharacteristics.push_back(characteristics.softwareEnforced[i]);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001472 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001473 for (size_t i = 0; i < characteristics.teeEnforced.size(); i++) {
1474 allCharacteristics.push_back(characteristics.teeEnforced[i]);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001475 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001476 AuthTokenTable::Error err =
1477 mAuthTokenTable.FindAuthorization(allCharacteristics, purpose, handle, authToken);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001478 switch (err) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001479 case AuthTokenTable::OK:
1480 case AuthTokenTable::AUTH_NOT_REQUIRED:
1481 return ResponseCode::NO_ERROR;
1482 case AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
1483 case AuthTokenTable::AUTH_TOKEN_EXPIRED:
1484 case AuthTokenTable::AUTH_TOKEN_WRONG_SID:
1485 return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
1486 case AuthTokenTable::OP_HANDLE_REQUIRED:
1487 return failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
1488 : KeyStoreServiceReturnCode(ResponseCode::OP_AUTH_NEEDED);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001489 default:
1490 ALOGE("Unexpected FindAuthorization return value %d", err);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001491 return ErrorCode::INVALID_ARGUMENT;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001492 }
1493}
1494
1495/**
1496 * Add the auth token for the operation to the param list if the operation
1497 * requires authorization. Uses the cached result in the OperationMap if available
1498 * otherwise gets the token from the AuthTokenTable and caches the result.
1499 *
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001500 * Returns ResponseCode::NO_ERROR if the auth token was added or not needed.
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001501 * KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not
1502 * authenticated.
1503 * KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
1504 * operation token.
1505 */
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001506KeyStoreServiceReturnCode KeyStoreService::addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
1507 AuthorizationSet* params) {
1508 const HardwareAuthToken* authToken = nullptr;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001509 mOperationMap.getOperationAuthToken(token, &authToken);
1510 if (!authToken) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001511 km_device_t dev;
1512 uint64_t handle;
1513 const KeyCharacteristics* characteristics = nullptr;
1514 KeyPurpose purpose;
1515 km_id_t keyid;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001516 if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001517 return ErrorCode::INVALID_OPERATION_HANDLE;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001518 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001519 auto result = getAuthToken(*characteristics, handle, purpose, &authToken);
1520 if (!result.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001521 return result;
1522 }
1523 if (authToken) {
1524 mOperationMap.setOperationAuthToken(token, authToken);
1525 }
1526 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001527 addAuthTokenToParams(params, authToken);
1528 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001529}
1530
1531/**
1532 * Translate a result value to a legacy return value. All keystore errors are
1533 * preserved and keymaster errors become SYSTEM_ERRORs
1534 */
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001535KeyStoreServiceReturnCode KeyStoreService::translateResultToLegacyResult(int32_t result) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001536 if (result > 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001537 return static_cast<ResponseCode>(result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001538 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001539 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001540}
1541
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001542static NullOr<const Algorithm&>
1543getKeyAlgoritmFromKeyCharacteristics(const KeyCharacteristics& characteristics) {
1544 for (size_t i = 0; i < characteristics.teeEnforced.size(); ++i) {
1545 auto algo = authorizationValue(TAG_ALGORITHM, characteristics.teeEnforced[i]);
1546 if (algo.isOk()) return algo.value();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001547 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001548 for (size_t i = 0; i < characteristics.softwareEnforced.size(); ++i) {
1549 auto algo = authorizationValue(TAG_ALGORITHM, characteristics.softwareEnforced[i]);
1550 if (algo.isOk()) return algo.value();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001551 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001552 return {};
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001553}
1554
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001555void KeyStoreService::addLegacyBeginParams(const String16& name, AuthorizationSet* params) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001556 // All legacy keys are DIGEST_NONE/PAD_NONE.
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001557 params->push_back(TAG_DIGEST, Digest::NONE);
1558 params->push_back(TAG_PADDING, PaddingMode::NONE);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001559
1560 // Look up the algorithm of the key.
1561 KeyCharacteristics characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001562 auto rc = getKeyCharacteristics(name, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF,
1563 &characteristics);
1564 if (!rc.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001565 ALOGE("Failed to get key characteristics");
1566 return;
1567 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001568 auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
1569 if (!algorithm.isOk()) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001570 ALOGE("getKeyCharacteristics did not include KM_TAG_ALGORITHM");
1571 return;
1572 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001573 params->push_back(TAG_ALGORITHM, algorithm.value());
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001574}
1575
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001576KeyStoreServiceReturnCode KeyStoreService::doLegacySignVerify(const String16& name,
1577 const hidl_vec<uint8_t>& data,
1578 hidl_vec<uint8_t>* out,
1579 const hidl_vec<uint8_t>& signature,
1580 KeyPurpose purpose) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001581
1582 std::basic_stringstream<uint8_t> outBuffer;
1583 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001584 AuthorizationSet inArgs;
1585 addLegacyBeginParams(name, &inArgs);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001586 sp<IBinder> appToken(new BBinder);
1587 sp<IBinder> token;
1588
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001589 begin(appToken, name, purpose, true, inArgs.hidl_data(), hidl_vec<uint8_t>(), UID_SELF,
1590 &result);
1591 if (!result.resultCode.isOk()) {
1592 if (result.resultCode == ResponseCode::KEY_NOT_FOUND) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001593 ALOGW("Key not found");
1594 } else {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001595 ALOGW("Error in begin: %d", int32_t(result.resultCode));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001596 }
1597 return translateResultToLegacyResult(result.resultCode);
1598 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001599 inArgs.Clear();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001600 token = result.token;
1601 size_t consumed = 0;
1602 size_t lastConsumed = 0;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001603 hidl_vec<uint8_t> data_view;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001604 do {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001605 data_view.setToExternal(const_cast<uint8_t*>(&data[consumed]), data.size() - consumed);
1606 update(token, inArgs.hidl_data(), data_view, &result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001607 if (result.resultCode != ResponseCode::NO_ERROR) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001608 ALOGW("Error in update: %d", int32_t(result.resultCode));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001609 return translateResultToLegacyResult(result.resultCode);
1610 }
1611 if (out) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001612 outBuffer.write(&result.data[0], result.data.size());
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001613 }
1614 lastConsumed = result.inputConsumed;
1615 consumed += lastConsumed;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001616 } while (consumed < data.size() && lastConsumed > 0);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001617
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001618 if (consumed != data.size()) {
1619 ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, data.size());
1620 return ResponseCode::SYSTEM_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001621 }
1622
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001623 finish(token, inArgs.hidl_data(), signature, hidl_vec<uint8_t>(), &result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001624 if (result.resultCode != ResponseCode::NO_ERROR) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001625 ALOGW("Error in finish: %d", int32_t(result.resultCode));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001626 return translateResultToLegacyResult(result.resultCode);
1627 }
1628 if (out) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001629 outBuffer.write(&result.data[0], result.data.size());
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001630 }
1631
1632 if (out) {
1633 auto buf = outBuffer.str();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001634 out->resize(buf.size());
1635 memcpy(&(*out)[0], buf.data(), out->size());
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001636 }
1637
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001638 return ResponseCode::NO_ERROR;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001639}
1640
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001641KeyStoreServiceReturnCode KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
1642 const AuthorizationSet& params,
1643 Blob* blob) {
Shawn Willden98c59162016-03-20 09:10:18 -06001644 // Read the blob rather than assuming the caller provided the right name/uid/blob triplet.
1645 String8 name8(name);
1646 ResponseCode responseCode = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001647 if (responseCode != ResponseCode::NO_ERROR) {
Shawn Willden98c59162016-03-20 09:10:18 -06001648 return responseCode;
1649 }
1650
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001651 auto hidlKey = blob2hidlVec(*blob);
1652 auto& dev = mKeyStore->getDevice(*blob);
Shawn Willden98c59162016-03-20 09:10:18 -06001653
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001654 KeyStoreServiceReturnCode error;
1655 auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
1656 error = ret;
1657 if (!error.isOk()) {
1658 return;
1659 }
1660
1661 String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
1662 error = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(uid));
1663 if (!error.isOk()) {
1664 return;
1665 }
1666
1667 Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
1668 0 /* infoLength */, ::TYPE_KEYMASTER_10);
1669 newBlob.setFallback(blob->isFallback());
1670 newBlob.setEncrypted(blob->isEncrypted());
1671
1672 error = mKeyStore->put(filename.string(), &newBlob, get_user_id(uid));
1673 if (!error.isOk()) {
1674 return;
1675 }
1676
1677 // Re-read blob for caller. We can't use newBlob because writing it modified it.
1678 error = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
1679 };
1680
1681 KeyStoreServiceReturnCode rc =
1682 KS_HANDLE_HIDL_ERROR(dev->upgradeKey(hidlKey, params.hidl_data(), hidlCb));
1683 if (!rc.isOk()) {
Shawn Willden98c59162016-03-20 09:10:18 -06001684 return rc;
1685 }
1686
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +01001687 return error;
Shawn Willden98c59162016-03-20 09:10:18 -06001688}
1689
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07001690} // namespace android