blob: bd4e564ef5800bff9f7846c818f4279a2178c827 [file] [log] [blame]
Kenny Roota91203b2012-02-15 15:00:46 -08001/*
2 * Copyright (C) 2009 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
Kenny Root07438c82012-11-02 15:41:02 -070017//#define LOG_NDEBUG 0
18#define LOG_TAG "keystore"
19
Kenny Roota91203b2012-02-15 15:00:46 -080020#include <stdio.h>
21#include <stdint.h>
22#include <string.h>
23#include <unistd.h>
24#include <signal.h>
25#include <errno.h>
26#include <dirent.h>
27#include <fcntl.h>
28#include <limits.h>
Kenny Root822c3a92012-03-23 16:34:39 -070029#include <assert.h>
Kenny Roota91203b2012-02-15 15:00:46 -080030#include <sys/types.h>
31#include <sys/socket.h>
32#include <sys/stat.h>
33#include <sys/time.h>
34#include <arpa/inet.h>
35
36#include <openssl/aes.h>
Kenny Root822c3a92012-03-23 16:34:39 -070037#include <openssl/bio.h>
Kenny Roota91203b2012-02-15 15:00:46 -080038#include <openssl/evp.h>
39#include <openssl/md5.h>
Kenny Root822c3a92012-03-23 16:34:39 -070040#include <openssl/pem.h>
Kenny Roota91203b2012-02-15 15:00:46 -080041
Kenny Root70e3a862012-02-15 17:20:23 -080042#include <hardware/keymaster.h>
43
Kenny Root822c3a92012-03-23 16:34:39 -070044#include <utils/UniquePtr.h>
45
Kenny Root70e3a862012-02-15 17:20:23 -080046#include <cutils/list.h>
47
Kenny Root07438c82012-11-02 15:41:02 -070048#include <keystore/IKeystoreService.h>
49#include <binder/IPCThreadState.h>
50#include <binder/IServiceManager.h>
51
Kenny Roota91203b2012-02-15 15:00:46 -080052#include <cutils/log.h>
53#include <cutils/sockets.h>
54#include <private/android_filesystem_config.h>
55
Kenny Root07438c82012-11-02 15:41:02 -070056#include <keystore/keystore.h>
Kenny Roota91203b2012-02-15 15:00:46 -080057
58/* KeyStore is a secured storage for key-value pairs. In this implementation,
59 * each file stores one key-value pair. Keys are encoded in file names, and
60 * values are encrypted with checksums. The encryption key is protected by a
61 * user-defined password. To keep things simple, buffers are always larger than
62 * the maximum space we needed, so boundary checks on buffers are omitted. */
63
64#define KEY_SIZE ((NAME_MAX - 15) / 2)
65#define VALUE_SIZE 32768
66#define PASSWORD_SIZE VALUE_SIZE
67
Kenny Root822c3a92012-03-23 16:34:39 -070068
69struct BIO_Delete {
70 void operator()(BIO* p) const {
71 BIO_free(p);
72 }
73};
74typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
75
76struct EVP_PKEY_Delete {
77 void operator()(EVP_PKEY* p) const {
78 EVP_PKEY_free(p);
79 }
80};
81typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
82
83struct PKCS8_PRIV_KEY_INFO_Delete {
84 void operator()(PKCS8_PRIV_KEY_INFO* p) const {
85 PKCS8_PRIV_KEY_INFO_free(p);
86 }
87};
88typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
89
90
Kenny Root70e3a862012-02-15 17:20:23 -080091static int keymaster_device_initialize(keymaster_device_t** dev) {
92 int rc;
93
94 const hw_module_t* mod;
95 rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
96 if (rc) {
97 ALOGE("could not find any keystore module");
98 goto out;
99 }
100
101 rc = keymaster_open(mod, dev);
102 if (rc) {
103 ALOGE("could not open keymaster device in %s (%s)",
104 KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
105 goto out;
106 }
107
108 return 0;
109
110out:
111 *dev = NULL;
112 return rc;
113}
114
115static void keymaster_device_release(keymaster_device_t* dev) {
116 keymaster_close(dev);
117}
118
Kenny Root07438c82012-11-02 15:41:02 -0700119/***************
120 * PERMISSIONS *
121 ***************/
122
123/* Here are the permissions, actions, users, and the main function. */
124typedef enum {
125 P_TEST = 1 << 0,
126 P_GET = 1 << 1,
127 P_INSERT = 1 << 2,
128 P_DELETE = 1 << 3,
129 P_EXIST = 1 << 4,
130 P_SAW = 1 << 5,
131 P_RESET = 1 << 6,
132 P_PASSWORD = 1 << 7,
133 P_LOCK = 1 << 8,
134 P_UNLOCK = 1 << 9,
135 P_ZERO = 1 << 10,
136 P_SIGN = 1 << 11,
137 P_VERIFY = 1 << 12,
138 P_GRANT = 1 << 13,
139} perm_t;
140
141static struct user_euid {
142 uid_t uid;
143 uid_t euid;
144} user_euids[] = {
145 {AID_VPN, AID_SYSTEM},
146 {AID_WIFI, AID_SYSTEM},
147 {AID_ROOT, AID_SYSTEM},
148};
149
150static struct user_perm {
151 uid_t uid;
152 perm_t perms;
153} user_perms[] = {
154 {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) },
155 {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
156 {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
157 {AID_ROOT, static_cast<perm_t>(P_GET) },
158};
159
160static const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN
161 | P_VERIFY);
162
163static bool has_permission(uid_t uid, perm_t perm) {
164 for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) {
165 struct user_perm user = user_perms[i];
166 if (user.uid == uid) {
167 return user.perms & perm;
168 }
169 }
170
171 return DEFAULT_PERMS & perm;
172}
173
174static uid_t get_keystore_euid(uid_t uid) {
175 for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
176 struct user_euid user = user_euids[i];
177 if (user.uid == uid) {
178 return user.euid;
179 }
180 }
181
182 return uid;
183}
184
Kenny Roota91203b2012-02-15 15:00:46 -0800185/* Here is the encoding of keys. This is necessary in order to allow arbitrary
186 * characters in keys. Characters in [0-~] are not encoded. Others are encoded
187 * into two bytes. The first byte is one of [+-.] which represents the first
188 * two bits of the character. The second byte encodes the rest of the bits into
189 * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
190 * that Base64 cannot be used here due to the need of prefix match on keys. */
191
Kenny Root07438c82012-11-02 15:41:02 -0700192static int encode_key(char* out, const android::String8& keyName) {
193 const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
194 size_t length = keyName.length();
Kenny Roota91203b2012-02-15 15:00:46 -0800195 for (int i = length; i > 0; --i, ++in, ++out) {
196 if (*in >= '0' && *in <= '~') {
197 *out = *in;
198 } else {
199 *out = '+' + (*in >> 6);
200 *++out = '0' + (*in & 0x3F);
201 ++length;
202 }
203 }
204 *out = '\0';
Kenny Root70e3a862012-02-15 17:20:23 -0800205 return length;
206}
207
Kenny Root07438c82012-11-02 15:41:02 -0700208static int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) {
Kenny Root70e3a862012-02-15 17:20:23 -0800209 int n = snprintf(out, NAME_MAX, "%u_", uid);
210 out += n;
211
Kenny Root07438c82012-11-02 15:41:02 -0700212 return n + encode_key(out, keyName);
Kenny Roota91203b2012-02-15 15:00:46 -0800213}
214
Kenny Root07438c82012-11-02 15:41:02 -0700215/*
216 * Converts from the "escaped" format on disk to actual name.
217 * This will be smaller than the input string.
218 *
219 * Characters that should combine with the next at the end will be truncated.
220 */
221static size_t decode_key_length(const char* in, size_t length) {
222 size_t outLength = 0;
223
224 for (const char* end = in + length; in < end; in++) {
225 /* This combines with the next character. */
226 if (*in < '0' || *in > '~') {
227 continue;
228 }
229
230 outLength++;
231 }
232 return outLength;
233}
234
235static void decode_key(char* out, const char* in, size_t length) {
236 for (const char* end = in + length; in < end; in++) {
237 if (*in < '0' || *in > '~') {
238 /* Truncate combining characters at the end. */
239 if (in + 1 >= end) {
240 break;
241 }
242
243 *out = (*in++ - '+') << 6;
244 *out++ |= (*in - '0') & 0x3F;
Kenny Roota91203b2012-02-15 15:00:46 -0800245 } else {
Kenny Root07438c82012-11-02 15:41:02 -0700246 *out++ = *in;
Kenny Roota91203b2012-02-15 15:00:46 -0800247 }
248 }
249 *out = '\0';
Kenny Roota91203b2012-02-15 15:00:46 -0800250}
251
252static size_t readFully(int fd, uint8_t* data, size_t size) {
253 size_t remaining = size;
254 while (remaining > 0) {
Kenny Root150ca932012-11-14 14:29:02 -0800255 ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining));
Kenny Root5281edb2012-11-21 15:14:04 -0800256 if (n <= 0) {
Kenny Root150ca932012-11-14 14:29:02 -0800257 return size - remaining;
Kenny Roota91203b2012-02-15 15:00:46 -0800258 }
259 data += n;
260 remaining -= n;
261 }
262 return size;
263}
264
265static size_t writeFully(int fd, uint8_t* data, size_t size) {
266 size_t remaining = size;
267 while (remaining > 0) {
Kenny Root150ca932012-11-14 14:29:02 -0800268 ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining));
269 if (n < 0) {
270 ALOGW("write failed: %s", strerror(errno));
271 return size - remaining;
Kenny Roota91203b2012-02-15 15:00:46 -0800272 }
273 data += n;
274 remaining -= n;
275 }
276 return size;
277}
278
279class Entropy {
280public:
281 Entropy() : mRandom(-1) {}
282 ~Entropy() {
Kenny Root150ca932012-11-14 14:29:02 -0800283 if (mRandom >= 0) {
Kenny Roota91203b2012-02-15 15:00:46 -0800284 close(mRandom);
285 }
286 }
287
288 bool open() {
289 const char* randomDevice = "/dev/urandom";
Kenny Root150ca932012-11-14 14:29:02 -0800290 mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY));
291 if (mRandom < 0) {
Kenny Roota91203b2012-02-15 15:00:46 -0800292 ALOGE("open: %s: %s", randomDevice, strerror(errno));
293 return false;
294 }
295 return true;
296 }
297
Kenny Root51878182012-03-13 12:53:19 -0700298 bool generate_random_data(uint8_t* data, size_t size) const {
Kenny Roota91203b2012-02-15 15:00:46 -0800299 return (readFully(mRandom, data, size) == size);
300 }
301
302private:
303 int mRandom;
304};
305
306/* Here is the file format. There are two parts in blob.value, the secret and
307 * the description. The secret is stored in ciphertext, and its original size
308 * can be found in blob.length. The description is stored after the secret in
309 * plaintext, and its size is specified in blob.info. The total size of the two
Kenny Root822c3a92012-03-23 16:34:39 -0700310 * parts must be no more than VALUE_SIZE bytes. The first field is the version,
311 * the second is the blob's type, and the third byte is reserved. Fields other
Kenny Roota91203b2012-02-15 15:00:46 -0800312 * than blob.info, blob.length, and blob.value are modified by encryptBlob()
313 * and decryptBlob(). Thus they should not be accessed from outside. */
314
Kenny Root822c3a92012-03-23 16:34:39 -0700315/* ** Note to future implementors of encryption: **
316 * Currently this is the construction:
317 * metadata || Enc(MD5(data) || data)
318 *
319 * This should be the construction used for encrypting if re-implementing:
320 *
321 * Derive independent keys for encryption and MAC:
322 * Kenc = AES_encrypt(masterKey, "Encrypt")
323 * Kmac = AES_encrypt(masterKey, "MAC")
324 *
325 * Store this:
326 * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
327 * HMAC(Kmac, metadata || Enc(data))
328 */
Kenny Roota91203b2012-02-15 15:00:46 -0800329struct __attribute__((packed)) blob {
Kenny Root822c3a92012-03-23 16:34:39 -0700330 uint8_t version;
331 uint8_t type;
332 uint8_t reserved;
Kenny Roota91203b2012-02-15 15:00:46 -0800333 uint8_t info;
334 uint8_t vector[AES_BLOCK_SIZE];
Kenny Root822c3a92012-03-23 16:34:39 -0700335 uint8_t encrypted[0]; // Marks offset to encrypted data.
Kenny Roota91203b2012-02-15 15:00:46 -0800336 uint8_t digest[MD5_DIGEST_LENGTH];
Kenny Root822c3a92012-03-23 16:34:39 -0700337 uint8_t digested[0]; // Marks offset to digested data.
Kenny Roota91203b2012-02-15 15:00:46 -0800338 int32_t length; // in network byte order when encrypted
339 uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
340};
341
Kenny Root822c3a92012-03-23 16:34:39 -0700342typedef enum {
343 TYPE_GENERIC = 1,
344 TYPE_MASTER_KEY = 2,
345 TYPE_KEY_PAIR = 3,
346} BlobType;
347
Kenny Root07438c82012-11-02 15:41:02 -0700348static const uint8_t CURRENT_BLOB_VERSION = 1;
Kenny Root822c3a92012-03-23 16:34:39 -0700349
Kenny Roota91203b2012-02-15 15:00:46 -0800350class Blob {
351public:
Kenny Root07438c82012-11-02 15:41:02 -0700352 Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength,
353 BlobType type) {
Kenny Roota91203b2012-02-15 15:00:46 -0800354 mBlob.length = valueLength;
355 memcpy(mBlob.value, value, valueLength);
356
357 mBlob.info = infoLength;
358 memcpy(mBlob.value + valueLength, info, infoLength);
Kenny Root822c3a92012-03-23 16:34:39 -0700359
Kenny Root07438c82012-11-02 15:41:02 -0700360 mBlob.version = CURRENT_BLOB_VERSION;
Kenny Root822c3a92012-03-23 16:34:39 -0700361 mBlob.type = uint8_t(type);
Kenny Roota91203b2012-02-15 15:00:46 -0800362 }
363
364 Blob(blob b) {
365 mBlob = b;
366 }
367
368 Blob() {}
369
Kenny Root51878182012-03-13 12:53:19 -0700370 const uint8_t* getValue() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800371 return mBlob.value;
372 }
373
Kenny Root51878182012-03-13 12:53:19 -0700374 int32_t getLength() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800375 return mBlob.length;
376 }
377
Kenny Root51878182012-03-13 12:53:19 -0700378 const uint8_t* getInfo() const {
379 return mBlob.value + mBlob.length;
380 }
381
382 uint8_t getInfoLength() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800383 return mBlob.info;
384 }
385
Kenny Root822c3a92012-03-23 16:34:39 -0700386 uint8_t getVersion() const {
387 return mBlob.version;
388 }
389
390 void setVersion(uint8_t version) {
391 mBlob.version = version;
392 }
393
394 BlobType getType() const {
395 return BlobType(mBlob.type);
396 }
397
398 void setType(BlobType type) {
399 mBlob.type = uint8_t(type);
400 }
401
Kenny Roota91203b2012-02-15 15:00:46 -0800402 ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) {
403 if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
Kenny Root150ca932012-11-14 14:29:02 -0800404 ALOGW("Could not read random data for: %s", filename);
Kenny Roota91203b2012-02-15 15:00:46 -0800405 return SYSTEM_ERROR;
406 }
407
408 // data includes the value and the value's length
409 size_t dataLength = mBlob.length + sizeof(mBlob.length);
410 // pad data to the AES_BLOCK_SIZE
411 size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
412 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
413 // encrypted data includes the digest value
414 size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
415 // move info after space for padding
416 memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
417 // zero padding area
418 memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
419
420 mBlob.length = htonl(mBlob.length);
421 MD5(mBlob.digested, digestedLength, mBlob.digest);
422
423 uint8_t vector[AES_BLOCK_SIZE];
424 memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
425 AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
426 aes_key, vector, AES_ENCRYPT);
427
Kenny Root822c3a92012-03-23 16:34:39 -0700428 mBlob.reserved = 0;
Kenny Roota91203b2012-02-15 15:00:46 -0800429 size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
430 size_t fileLength = encryptedLength + headerLength + mBlob.info;
431
432 const char* tmpFileName = ".tmp";
Kenny Root150ca932012-11-14 14:29:02 -0800433 int out = TEMP_FAILURE_RETRY(open(tmpFileName,
434 O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
435 if (out < 0) {
436 ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno));
Kenny Roota91203b2012-02-15 15:00:46 -0800437 return SYSTEM_ERROR;
438 }
439 size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
440 if (close(out) != 0) {
441 return SYSTEM_ERROR;
442 }
443 if (writtenBytes != fileLength) {
Kenny Root150ca932012-11-14 14:29:02 -0800444 ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
Kenny Roota91203b2012-02-15 15:00:46 -0800445 unlink(tmpFileName);
446 return SYSTEM_ERROR;
447 }
Kenny Root150ca932012-11-14 14:29:02 -0800448 if (rename(tmpFileName, filename) == -1) {
449 ALOGW("could not rename blob to %s: %s", filename, strerror(errno));
450 return SYSTEM_ERROR;
451 }
452 return NO_ERROR;
Kenny Roota91203b2012-02-15 15:00:46 -0800453 }
454
455 ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
Kenny Root150ca932012-11-14 14:29:02 -0800456 int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
457 if (in < 0) {
Kenny Roota91203b2012-02-15 15:00:46 -0800458 return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
459 }
460 // fileLength may be less than sizeof(mBlob) since the in
461 // memory version has extra padding to tolerate rounding up to
462 // the AES_BLOCK_SIZE
463 size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
464 if (close(in) != 0) {
465 return SYSTEM_ERROR;
466 }
467 size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
468 if (fileLength < headerLength) {
469 return VALUE_CORRUPTED;
470 }
471
472 ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
473 if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) {
474 return VALUE_CORRUPTED;
475 }
476 AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
477 mBlob.vector, AES_DECRYPT);
478 size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
479 uint8_t computedDigest[MD5_DIGEST_LENGTH];
480 MD5(mBlob.digested, digestedLength, computedDigest);
481 if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
482 return VALUE_CORRUPTED;
483 }
484
485 ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
486 mBlob.length = ntohl(mBlob.length);
487 if (mBlob.length < 0 || mBlob.length > maxValueLength) {
488 return VALUE_CORRUPTED;
489 }
490 if (mBlob.info != 0) {
491 // move info from after padding to after data
492 memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
493 }
Kenny Root07438c82012-11-02 15:41:02 -0700494 return ::NO_ERROR;
Kenny Roota91203b2012-02-15 15:00:46 -0800495 }
496
497private:
498 struct blob mBlob;
499};
500
Kenny Root70e3a862012-02-15 17:20:23 -0800501typedef struct {
502 uint32_t uid;
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700503 const uint8_t* filename;
Kenny Root70e3a862012-02-15 17:20:23 -0800504
505 struct listnode plist;
506} grant_t;
507
Kenny Roota91203b2012-02-15 15:00:46 -0800508class KeyStore {
509public:
Kenny Root70e3a862012-02-15 17:20:23 -0800510 KeyStore(Entropy* entropy, keymaster_device_t* device)
Kenny Root51878182012-03-13 12:53:19 -0700511 : mEntropy(entropy)
Kenny Root70e3a862012-02-15 17:20:23 -0800512 , mDevice(device)
Kenny Root51878182012-03-13 12:53:19 -0700513 , mRetry(MAX_RETRY)
514 {
Kenny Roota91203b2012-02-15 15:00:46 -0800515 if (access(MASTER_KEY_FILE, R_OK) == 0) {
516 setState(STATE_LOCKED);
517 } else {
518 setState(STATE_UNINITIALIZED);
519 }
Kenny Root70e3a862012-02-15 17:20:23 -0800520
521 list_init(&mGrants);
Kenny Roota91203b2012-02-15 15:00:46 -0800522 }
523
Kenny Root51878182012-03-13 12:53:19 -0700524 State getState() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800525 return mState;
526 }
527
Kenny Root51878182012-03-13 12:53:19 -0700528 int8_t getRetry() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800529 return mRetry;
530 }
531
Kenny Root70e3a862012-02-15 17:20:23 -0800532 keymaster_device_t* getDevice() const {
533 return mDevice;
534 }
535
Kenny Root07438c82012-11-02 15:41:02 -0700536 ResponseCode initialize(const android::String8& pw) {
Kenny Roota91203b2012-02-15 15:00:46 -0800537 if (!generateMasterKey()) {
538 return SYSTEM_ERROR;
539 }
540 ResponseCode response = writeMasterKey(pw);
541 if (response != NO_ERROR) {
542 return response;
543 }
544 setupMasterKeys();
Kenny Root07438c82012-11-02 15:41:02 -0700545 return ::NO_ERROR;
Kenny Roota91203b2012-02-15 15:00:46 -0800546 }
547
Kenny Root07438c82012-11-02 15:41:02 -0700548 ResponseCode writeMasterKey(const android::String8& pw) {
Kenny Roota91203b2012-02-15 15:00:46 -0800549 uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
550 generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
551 AES_KEY passwordAesKey;
552 AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
Kenny Root822c3a92012-03-23 16:34:39 -0700553 Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
Kenny Roota91203b2012-02-15 15:00:46 -0800554 return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
555 }
556
Kenny Root07438c82012-11-02 15:41:02 -0700557 ResponseCode readMasterKey(const android::String8& pw) {
Kenny Root150ca932012-11-14 14:29:02 -0800558 int in = TEMP_FAILURE_RETRY(open(MASTER_KEY_FILE, O_RDONLY));
559 if (in < 0) {
Kenny Roota91203b2012-02-15 15:00:46 -0800560 return SYSTEM_ERROR;
561 }
562
563 // we read the raw blob to just to get the salt to generate
564 // the AES key, then we create the Blob to use with decryptBlob
565 blob rawBlob;
566 size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
567 if (close(in) != 0) {
568 return SYSTEM_ERROR;
569 }
570 // find salt at EOF if present, otherwise we have an old file
571 uint8_t* salt;
572 if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
573 salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
574 } else {
575 salt = NULL;
576 }
577 uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
578 generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
579 AES_KEY passwordAesKey;
580 AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
581 Blob masterKeyBlob(rawBlob);
582 ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
583 if (response == SYSTEM_ERROR) {
584 return SYSTEM_ERROR;
585 }
586 if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
587 // if salt was missing, generate one and write a new master key file with the salt.
588 if (salt == NULL) {
589 if (!generateSalt()) {
590 return SYSTEM_ERROR;
591 }
592 response = writeMasterKey(pw);
593 }
594 if (response == NO_ERROR) {
595 memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
596 setupMasterKeys();
597 }
598 return response;
599 }
600 if (mRetry <= 0) {
601 reset();
602 return UNINITIALIZED;
603 }
604 --mRetry;
605 switch (mRetry) {
606 case 0: return WRONG_PASSWORD_0;
607 case 1: return WRONG_PASSWORD_1;
608 case 2: return WRONG_PASSWORD_2;
609 case 3: return WRONG_PASSWORD_3;
610 default: return WRONG_PASSWORD_3;
611 }
612 }
613
614 bool reset() {
615 clearMasterKeys();
616 setState(STATE_UNINITIALIZED);
617
618 DIR* dir = opendir(".");
619 struct dirent* file;
620
621 if (!dir) {
622 return false;
623 }
624 while ((file = readdir(dir)) != NULL) {
625 unlink(file->d_name);
626 }
627 closedir(dir);
628 return true;
629 }
630
Kenny Root51878182012-03-13 12:53:19 -0700631 bool isEmpty() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800632 DIR* dir = opendir(".");
633 struct dirent* file;
634 if (!dir) {
635 return true;
636 }
637 bool result = true;
638 while ((file = readdir(dir)) != NULL) {
639 if (isKeyFile(file->d_name)) {
640 result = false;
641 break;
642 }
643 }
644 closedir(dir);
645 return result;
646 }
647
648 void lock() {
649 clearMasterKeys();
650 setState(STATE_LOCKED);
651 }
652
Kenny Root822c3a92012-03-23 16:34:39 -0700653 ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) {
654 ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
655 if (rc != NO_ERROR) {
656 return rc;
657 }
658
659 const uint8_t version = keyBlob->getVersion();
Kenny Root07438c82012-11-02 15:41:02 -0700660 if (version < CURRENT_BLOB_VERSION) {
Kenny Root822c3a92012-03-23 16:34:39 -0700661 upgrade(filename, keyBlob, version, type);
662 }
663
664 if (keyBlob->getType() != type) {
665 ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
666 return KEY_NOT_FOUND;
667 }
668
669 return rc;
Kenny Roota91203b2012-02-15 15:00:46 -0800670 }
671
672 ResponseCode put(const char* filename, Blob* keyBlob) {
673 return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
674 }
675
Kenny Root07438c82012-11-02 15:41:02 -0700676 void addGrant(const char* filename, uid_t granteeUid) {
677 grant_t *grant = getGrant(filename, granteeUid);
Kenny Root70e3a862012-02-15 17:20:23 -0800678 if (grant == NULL) {
679 grant = new grant_t;
Kenny Root07438c82012-11-02 15:41:02 -0700680 grant->uid = granteeUid;
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700681 grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
Kenny Root70e3a862012-02-15 17:20:23 -0800682 list_add_tail(&mGrants, &grant->plist);
683 }
684 }
685
Kenny Root07438c82012-11-02 15:41:02 -0700686 bool removeGrant(const char* filename, uid_t granteeUid) {
687 grant_t *grant = getGrant(filename, granteeUid);
Kenny Root70e3a862012-02-15 17:20:23 -0800688 if (grant != NULL) {
689 list_remove(&grant->plist);
690 delete grant;
691 return true;
692 }
693
694 return false;
695 }
696
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700697 bool hasGrant(const char* filename, const uid_t uid) const {
698 return getGrant(filename, uid) != NULL;
Kenny Root70e3a862012-02-15 17:20:23 -0800699 }
700
Kenny Root07438c82012-11-02 15:41:02 -0700701 ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename) {
Kenny Root822c3a92012-03-23 16:34:39 -0700702 uint8_t* data;
703 size_t dataLength;
704 int rc;
705
706 if (mDevice->import_keypair == NULL) {
707 ALOGE("Keymaster doesn't support import!");
708 return SYSTEM_ERROR;
709 }
710
Kenny Root07438c82012-11-02 15:41:02 -0700711 rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength);
Kenny Root822c3a92012-03-23 16:34:39 -0700712 if (rc) {
713 ALOGE("Error while importing keypair: %d", rc);
714 return SYSTEM_ERROR;
715 }
716
717 Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
718 free(data);
719
720 return put(filename, &keyBlob);
721 }
722
Kenny Roota91203b2012-02-15 15:00:46 -0800723private:
724 static const char* MASTER_KEY_FILE;
725 static const int MASTER_KEY_SIZE_BYTES = 16;
726 static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
727
728 static const int MAX_RETRY = 4;
729 static const size_t SALT_SIZE = 16;
730
731 Entropy* mEntropy;
732
Kenny Root70e3a862012-02-15 17:20:23 -0800733 keymaster_device_t* mDevice;
734
Kenny Roota91203b2012-02-15 15:00:46 -0800735 State mState;
736 int8_t mRetry;
737
738 uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
739 uint8_t mSalt[SALT_SIZE];
740
741 AES_KEY mMasterKeyEncryption;
742 AES_KEY mMasterKeyDecryption;
743
Kenny Root70e3a862012-02-15 17:20:23 -0800744 struct listnode mGrants;
745
Kenny Roota91203b2012-02-15 15:00:46 -0800746 void setState(State state) {
747 mState = state;
748 if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
749 mRetry = MAX_RETRY;
750 }
751 }
752
753 bool generateSalt() {
754 return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
755 }
756
757 bool generateMasterKey() {
758 if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
759 return false;
760 }
761 if (!generateSalt()) {
762 return false;
763 }
764 return true;
765 }
766
767 void setupMasterKeys() {
768 AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
769 AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
770 setState(STATE_NO_ERROR);
771 }
772
773 void clearMasterKeys() {
774 memset(mMasterKey, 0, sizeof(mMasterKey));
775 memset(mSalt, 0, sizeof(mSalt));
776 memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
777 memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
778 }
779
Kenny Root07438c82012-11-02 15:41:02 -0700780 static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
781 uint8_t* salt) {
Kenny Roota91203b2012-02-15 15:00:46 -0800782 size_t saltSize;
783 if (salt != NULL) {
784 saltSize = SALT_SIZE;
785 } else {
786 // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
787 salt = (uint8_t*) "keystore";
788 // sizeof = 9, not strlen = 8
789 saltSize = sizeof("keystore");
790 }
Kenny Root07438c82012-11-02 15:41:02 -0700791
792 PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt,
793 saltSize, 8192, keySize, key);
Kenny Roota91203b2012-02-15 15:00:46 -0800794 }
795
796 static bool isKeyFile(const char* filename) {
797 return ((strcmp(filename, MASTER_KEY_FILE) != 0)
798 && (strcmp(filename, ".") != 0)
799 && (strcmp(filename, "..") != 0));
800 }
Kenny Root70e3a862012-02-15 17:20:23 -0800801
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700802 grant_t* getGrant(const char* filename, uid_t uid) const {
Kenny Root70e3a862012-02-15 17:20:23 -0800803 struct listnode *node;
804 grant_t *grant;
805
806 list_for_each(node, &mGrants) {
807 grant = node_to_item(node, grant_t, plist);
808 if (grant->uid == uid
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700809 && !strcmp(reinterpret_cast<const char*>(grant->filename),
810 filename)) {
Kenny Root70e3a862012-02-15 17:20:23 -0800811 return grant;
812 }
813 }
814
815 return NULL;
816 }
817
Kenny Root822c3a92012-03-23 16:34:39 -0700818 /**
819 * Upgrade code. This will upgrade the key from the current version
820 * to whatever is newest.
821 */
822 void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) {
823 bool updated = false;
824 uint8_t version = oldVersion;
825
826 /* From V0 -> V1: All old types were unknown */
827 if (version == 0) {
828 ALOGV("upgrading to version 1 and setting type %d", type);
829
830 blob->setType(type);
831 if (type == TYPE_KEY_PAIR) {
832 importBlobAsKey(blob, filename);
833 }
834 version = 1;
835 updated = true;
836 }
837
838 /*
839 * If we've updated, set the key blob to the right version
840 * and write it.
841 * */
842 if (updated) {
843 ALOGV("updated and writing file %s", filename);
844 blob->setVersion(version);
845 this->put(filename, blob);
846 }
847 }
848
849 /**
850 * Takes a blob that is an PEM-encoded RSA key as a byte array and
851 * converts it to a DER-encoded PKCS#8 for import into a keymaster.
852 * Then it overwrites the original blob with the new blob
853 * format that is returned from the keymaster.
854 */
855 ResponseCode importBlobAsKey(Blob* blob, const char* filename) {
856 // We won't even write to the blob directly with this BIO, so const_cast is okay.
857 Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
858 if (b.get() == NULL) {
859 ALOGE("Problem instantiating BIO");
860 return SYSTEM_ERROR;
861 }
862
863 Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
864 if (pkey.get() == NULL) {
865 ALOGE("Couldn't read old PEM file");
866 return SYSTEM_ERROR;
867 }
868
869 Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
870 int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
871 if (len < 0) {
872 ALOGE("Couldn't measure PKCS#8 length");
873 return SYSTEM_ERROR;
874 }
875
Kenny Root70c98892013-02-07 09:10:36 -0800876 UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]);
877 uint8_t* tmp = pkcs8key.get();
Kenny Root822c3a92012-03-23 16:34:39 -0700878 if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
879 ALOGE("Couldn't convert to PKCS#8");
880 return SYSTEM_ERROR;
881 }
882
Kenny Root70c98892013-02-07 09:10:36 -0800883 ResponseCode rc = importKey(pkcs8key.get(), len, filename);
Kenny Root822c3a92012-03-23 16:34:39 -0700884 if (rc != NO_ERROR) {
885 return rc;
886 }
887
888 return get(filename, blob, TYPE_KEY_PAIR);
889 }
Kenny Roota91203b2012-02-15 15:00:46 -0800890};
891
892const char* KeyStore::MASTER_KEY_FILE = ".masterkey";
893
Kenny Root07438c82012-11-02 15:41:02 -0700894static ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob,
895 const android::String8& keyName, const uid_t uid, const BlobType type) {
Kenny Root70e3a862012-02-15 17:20:23 -0800896 char filename[NAME_MAX];
897
898 encode_key_for_uid(filename, uid, keyName);
Kenny Root822c3a92012-03-23 16:34:39 -0700899 ResponseCode responseCode = keyStore->get(filename, keyBlob, type);
Kenny Root70e3a862012-02-15 17:20:23 -0800900 if (responseCode == NO_ERROR) {
901 return responseCode;
902 }
903
904 // If this is the Wifi or VPN user, they actually want system
905 // UID keys.
906 if (uid == AID_WIFI || uid == AID_VPN) {
907 encode_key_for_uid(filename, AID_SYSTEM, keyName);
Kenny Root822c3a92012-03-23 16:34:39 -0700908 responseCode = keyStore->get(filename, keyBlob, type);
Kenny Root70e3a862012-02-15 17:20:23 -0800909 if (responseCode == NO_ERROR) {
910 return responseCode;
911 }
912 }
913
914 // They might be using a granted key.
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700915 encode_key(filename, keyName);
916 if (!keyStore->hasGrant(filename, uid)) {
Kenny Root70e3a862012-02-15 17:20:23 -0800917 return responseCode;
918 }
919
920 // It is a granted key. Try to load it.
Kenny Root822c3a92012-03-23 16:34:39 -0700921 return keyStore->get(filename, keyBlob, type);
Kenny Root70e3a862012-02-15 17:20:23 -0800922}
923
Kenny Root07438c82012-11-02 15:41:02 -0700924namespace android {
925class KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient {
926public:
927 KeyStoreProxy(KeyStore* keyStore)
928 : mKeyStore(keyStore)
929 {
Kenny Roota91203b2012-02-15 15:00:46 -0800930 }
Kenny Roota91203b2012-02-15 15:00:46 -0800931
Kenny Root07438c82012-11-02 15:41:02 -0700932 void binderDied(const wp<IBinder>&) {
933 ALOGE("binder death detected");
Kenny Root822c3a92012-03-23 16:34:39 -0700934 }
Kenny Roota91203b2012-02-15 15:00:46 -0800935
Kenny Root07438c82012-11-02 15:41:02 -0700936 int32_t test() {
Kenny Rootd38a0b02013-02-13 12:59:14 -0800937 uid_t callingUid = IPCThreadState::self()->getCallingUid();
938 if (!has_permission(callingUid, P_TEST)) {
939 ALOGW("permission denied for %d: test", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -0700940 return ::PERMISSION_DENIED;
Kenny Roota91203b2012-02-15 15:00:46 -0800941 }
Kenny Roota91203b2012-02-15 15:00:46 -0800942
Kenny Root07438c82012-11-02 15:41:02 -0700943 return mKeyStore->getState();
Kenny Root298e7b12012-03-26 13:54:44 -0700944 }
945
Kenny Root07438c82012-11-02 15:41:02 -0700946 int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
Kenny Rootd38a0b02013-02-13 12:59:14 -0800947 uid_t callingUid = IPCThreadState::self()->getCallingUid();
948 if (!has_permission(callingUid, P_GET)) {
949 ALOGW("permission denied for %d: get", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -0700950 return ::PERMISSION_DENIED;
Kenny Roota91203b2012-02-15 15:00:46 -0800951 }
Kenny Rootd38a0b02013-02-13 12:59:14 -0800952 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -0700953
954 State state = checkState();
955 if (state != STATE_NO_ERROR) {
956 ALOGD("calling get in state: %d", state);
957 return state;
Kenny Roota91203b2012-02-15 15:00:46 -0800958 }
Kenny Root07438c82012-11-02 15:41:02 -0700959
960 String8 name8(name);
961 char filename[NAME_MAX];
962
Kenny Rootd38a0b02013-02-13 12:59:14 -0800963 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -0700964
965 Blob keyBlob;
966 ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
967 if (responseCode != ::NO_ERROR) {
Kenny Root150ca932012-11-14 14:29:02 -0800968 ALOGW("Could not read %s", filename);
Kenny Root07438c82012-11-02 15:41:02 -0700969 *item = NULL;
970 *itemLength = 0;
971 return responseCode;
Kenny Roota91203b2012-02-15 15:00:46 -0800972 }
Kenny Roota91203b2012-02-15 15:00:46 -0800973
Kenny Root07438c82012-11-02 15:41:02 -0700974 *item = (uint8_t*) malloc(keyBlob.getLength());
975 memcpy(*item, keyBlob.getValue(), keyBlob.getLength());
976 *itemLength = keyBlob.getLength();
Kenny Roota91203b2012-02-15 15:00:46 -0800977
Kenny Root07438c82012-11-02 15:41:02 -0700978 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -0800979 }
980
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800981 int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -0800982 uid_t callingUid = IPCThreadState::self()->getCallingUid();
983 if (!has_permission(callingUid, P_INSERT)) {
984 ALOGW("permission denied for %d: insert", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -0700985 return ::PERMISSION_DENIED;
986 }
Kenny Rootd38a0b02013-02-13 12:59:14 -0800987 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -0700988
Kenny Rootb88c3eb2013-02-13 14:43:43 -0800989 if (uid != -1) {
990 return ::PERMISSION_DENIED;
991 }
992
Kenny Root07438c82012-11-02 15:41:02 -0700993 State state = checkState();
994 if (state != STATE_NO_ERROR) {
995 ALOGD("calling insert in state: %d", state);
996 return state;
997 }
998
999 String8 name8(name);
1000 char filename[NAME_MAX];
1001
Kenny Rootd38a0b02013-02-13 12:59:14 -08001002 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001003
1004 Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
1005 return mKeyStore->put(filename, &keyBlob);
Kenny Root70e3a862012-02-15 17:20:23 -08001006 }
1007
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001008 int32_t del(const String16& name, int uid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001009 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1010 if (!has_permission(callingUid, P_DELETE)) {
1011 ALOGW("permission denied for %d: del", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001012 return ::PERMISSION_DENIED;
1013 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001014 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001015
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001016 if (uid != -1) {
1017 return ::PERMISSION_DENIED;
1018 }
1019
Kenny Root07438c82012-11-02 15:41:02 -07001020 String8 name8(name);
1021 char filename[NAME_MAX];
1022
Kenny Rootd38a0b02013-02-13 12:59:14 -08001023 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001024
1025 Blob keyBlob;
1026 ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
1027 if (responseCode != ::NO_ERROR) {
1028 return responseCode;
1029 }
1030 return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001031 }
1032
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001033 int32_t exist(const String16& name, int uid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001034 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1035 if (!has_permission(callingUid, P_EXIST)) {
1036 ALOGW("permission denied for %d: exist", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001037 return ::PERMISSION_DENIED;
1038 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001039 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001040
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001041 if (uid != -1) {
1042 return ::PERMISSION_DENIED;
1043 }
1044
Kenny Root07438c82012-11-02 15:41:02 -07001045 String8 name8(name);
1046 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -08001047
Kenny Rootd38a0b02013-02-13 12:59:14 -08001048 encode_key_for_uid(filename, callingUid, name8);
Kenny Root70e3a862012-02-15 17:20:23 -08001049
Kenny Root07438c82012-11-02 15:41:02 -07001050 if (access(filename, R_OK) == -1) {
1051 return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
1052 }
1053 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001054 }
1055
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001056 int32_t saw(const String16& prefix, int uid, Vector<String16>* matches) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001057 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1058 if (!has_permission(callingUid, P_SAW)) {
1059 ALOGW("permission denied for %d: saw", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001060 return ::PERMISSION_DENIED;
1061 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001062 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001063
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001064 if (uid != -1) {
1065 return ::PERMISSION_DENIED;
1066 }
1067
Kenny Root07438c82012-11-02 15:41:02 -07001068 DIR* dir = opendir(".");
1069 if (!dir) {
1070 return ::SYSTEM_ERROR;
1071 }
Kenny Root70e3a862012-02-15 17:20:23 -08001072
Kenny Root07438c82012-11-02 15:41:02 -07001073 const String8 prefix8(prefix);
1074 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -08001075
Kenny Rootd38a0b02013-02-13 12:59:14 -08001076 int n = encode_key_for_uid(filename, callingUid, prefix8);
Kenny Root70e3a862012-02-15 17:20:23 -08001077
Kenny Root07438c82012-11-02 15:41:02 -07001078 struct dirent* file;
1079 while ((file = readdir(dir)) != NULL) {
1080 if (!strncmp(filename, file->d_name, n)) {
1081 const char* p = &file->d_name[n];
1082 size_t plen = strlen(p);
Kenny Root70e3a862012-02-15 17:20:23 -08001083
Kenny Root07438c82012-11-02 15:41:02 -07001084 size_t extra = decode_key_length(p, plen);
1085 char *match = (char*) malloc(extra + 1);
1086 if (match != NULL) {
1087 decode_key(match, p, plen);
1088 matches->push(String16(match, extra));
1089 free(match);
1090 } else {
1091 ALOGW("could not allocate match of size %zd", extra);
1092 }
Kenny Root9a53d3e2012-08-14 10:47:54 -07001093 }
1094 }
Kenny Root07438c82012-11-02 15:41:02 -07001095 closedir(dir);
1096
1097 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001098 }
1099
Kenny Root07438c82012-11-02 15:41:02 -07001100 int32_t reset() {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001101 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1102 if (!has_permission(callingUid, P_RESET)) {
1103 ALOGW("permission denied for %d: reset", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001104 return ::PERMISSION_DENIED;
1105 }
1106
1107 ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR;
1108
1109 const keymaster_device_t* device = mKeyStore->getDevice();
1110 if (device == NULL) {
1111 ALOGE("No keymaster device!");
1112 return ::SYSTEM_ERROR;
1113 }
1114
1115 if (device->delete_all == NULL) {
1116 ALOGV("keymaster device doesn't implement delete_all");
1117 return rc;
1118 }
1119
1120 if (device->delete_all(device)) {
1121 ALOGE("Problem calling keymaster's delete_all");
1122 return ::SYSTEM_ERROR;
1123 }
1124
Kenny Root9a53d3e2012-08-14 10:47:54 -07001125 return rc;
Kenny Root70e3a862012-02-15 17:20:23 -08001126 }
1127
Kenny Root07438c82012-11-02 15:41:02 -07001128 /*
1129 * Here is the history. To improve the security, the parameters to generate the
1130 * master key has been changed. To make a seamless transition, we update the
1131 * file using the same password when the user unlock it for the first time. If
1132 * any thing goes wrong during the transition, the new file will not overwrite
1133 * the old one. This avoids permanent damages of the existing data.
1134 */
1135 int32_t password(const String16& password) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001136 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1137 if (!has_permission(callingUid, P_PASSWORD)) {
1138 ALOGW("permission denied for %d: password", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001139 return ::PERMISSION_DENIED;
1140 }
Kenny Root70e3a862012-02-15 17:20:23 -08001141
Kenny Root07438c82012-11-02 15:41:02 -07001142 const String8 password8(password);
Kenny Root70e3a862012-02-15 17:20:23 -08001143
Kenny Root07438c82012-11-02 15:41:02 -07001144 switch (mKeyStore->getState()) {
1145 case ::STATE_UNINITIALIZED: {
1146 // generate master key, encrypt with password, write to file, initialize mMasterKey*.
1147 return mKeyStore->initialize(password8);
1148 }
1149 case ::STATE_NO_ERROR: {
1150 // rewrite master key with new password.
1151 return mKeyStore->writeMasterKey(password8);
1152 }
1153 case ::STATE_LOCKED: {
1154 // read master key, decrypt with password, initialize mMasterKey*.
1155 return mKeyStore->readMasterKey(password8);
1156 }
1157 }
1158 return ::SYSTEM_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001159 }
1160
Kenny Root07438c82012-11-02 15:41:02 -07001161 int32_t lock() {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001162 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1163 if (!has_permission(callingUid, P_LOCK)) {
1164 ALOGW("permission denied for %d: lock", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001165 return ::PERMISSION_DENIED;
1166 }
Kenny Root70e3a862012-02-15 17:20:23 -08001167
Kenny Root07438c82012-11-02 15:41:02 -07001168 State state = checkState();
1169 if (state != STATE_NO_ERROR) {
1170 ALOGD("calling lock in state: %d", state);
1171 return state;
1172 }
1173
1174 mKeyStore->lock();
1175 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001176 }
1177
Kenny Root07438c82012-11-02 15:41:02 -07001178 int32_t unlock(const String16& pw) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001179 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1180 if (!has_permission(callingUid, P_UNLOCK)) {
1181 ALOGW("permission denied for %d: unlock", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001182 return ::PERMISSION_DENIED;
1183 }
1184
1185 State state = checkState();
1186 if (state != STATE_LOCKED) {
1187 ALOGD("calling unlock when not locked");
1188 return state;
1189 }
1190
1191 const String8 password8(pw);
1192 return password(pw);
Kenny Root70e3a862012-02-15 17:20:23 -08001193 }
1194
Kenny Root07438c82012-11-02 15:41:02 -07001195 int32_t zero() {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001196 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1197 if (!has_permission(callingUid, P_ZERO)) {
1198 ALOGW("permission denied for %d: zero", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001199 return -1;
1200 }
Kenny Root70e3a862012-02-15 17:20:23 -08001201
Kenny Root07438c82012-11-02 15:41:02 -07001202 return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001203 }
1204
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001205 int32_t generate(const String16& name, int uid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001206 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1207 if (!has_permission(callingUid, P_INSERT)) {
1208 ALOGW("permission denied for %d: generate", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001209 return ::PERMISSION_DENIED;
1210 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001211 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001212
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001213 if (uid != -1) {
1214 return ::PERMISSION_DENIED;
1215 }
1216
Kenny Root07438c82012-11-02 15:41:02 -07001217 State state = checkState();
1218 if (state != STATE_NO_ERROR) {
1219 ALOGD("calling generate in state: %d", state);
1220 return state;
1221 }
Kenny Root70e3a862012-02-15 17:20:23 -08001222
Kenny Root07438c82012-11-02 15:41:02 -07001223 String8 name8(name);
1224 char filename[NAME_MAX];
1225
1226 uint8_t* data;
1227 size_t dataLength;
1228 int rc;
1229
1230 const keymaster_device_t* device = mKeyStore->getDevice();
1231 if (device == NULL) {
1232 return ::SYSTEM_ERROR;
1233 }
1234
1235 if (device->generate_keypair == NULL) {
1236 return ::SYSTEM_ERROR;
1237 }
1238
1239 keymaster_rsa_keygen_params_t rsa_params;
1240 rsa_params.modulus_size = 2048;
1241 rsa_params.public_exponent = 0x10001;
1242
1243 rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
1244 if (rc) {
1245 return ::SYSTEM_ERROR;
1246 }
1247
Kenny Rootd38a0b02013-02-13 12:59:14 -08001248 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001249
1250 Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
1251 free(data);
1252
1253 return mKeyStore->put(filename, &keyBlob);
Kenny Root70e3a862012-02-15 17:20:23 -08001254 }
1255
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001256 int32_t import(const String16& name, const uint8_t* data, size_t length, int uid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001257 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1258 if (!has_permission(callingUid, P_INSERT)) {
1259 ALOGW("permission denied for %d: import", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001260 return ::PERMISSION_DENIED;
1261 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001262 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001263
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001264 if (uid != -1) {
1265 return ::PERMISSION_DENIED;
1266 }
1267
Kenny Root07438c82012-11-02 15:41:02 -07001268 State state = checkState();
1269 if (state != STATE_NO_ERROR) {
1270 ALOGD("calling import in state: %d", state);
1271 return state;
1272 }
1273
1274 String8 name8(name);
1275 char filename[NAME_MAX];
1276
Kenny Rootd38a0b02013-02-13 12:59:14 -08001277 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001278
1279 return mKeyStore->importKey(data, length, filename);
Kenny Root70e3a862012-02-15 17:20:23 -08001280 }
1281
Kenny Root07438c82012-11-02 15:41:02 -07001282 int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
1283 size_t* outLength) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001284 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1285 if (!has_permission(callingUid, P_SIGN)) {
1286 ALOGW("permission denied for %d: saw", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001287 return ::PERMISSION_DENIED;
1288 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001289 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001290
1291 State state = checkState();
1292 if (state != STATE_NO_ERROR) {
1293 ALOGD("calling sign in state: %d", state);
1294 return state;
1295 }
1296
1297 Blob keyBlob;
1298 String8 name8(name);
1299
Kenny Rootd38a0b02013-02-13 12:59:14 -08001300 ALOGV("sign %s from uid %d", name8.string(), callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001301 int rc;
1302
Kenny Rootd38a0b02013-02-13 12:59:14 -08001303 ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
1304 ::TYPE_KEY_PAIR);
Kenny Root07438c82012-11-02 15:41:02 -07001305 if (responseCode != ::NO_ERROR) {
1306 return responseCode;
1307 }
1308
1309 const keymaster_device_t* device = mKeyStore->getDevice();
1310 if (device == NULL) {
1311 ALOGE("no keymaster device; cannot sign");
1312 return ::SYSTEM_ERROR;
1313 }
1314
1315 if (device->sign_data == NULL) {
1316 ALOGE("device doesn't implement signing");
1317 return ::SYSTEM_ERROR;
1318 }
1319
1320 keymaster_rsa_sign_params_t params;
1321 params.digest_type = DIGEST_NONE;
1322 params.padding_type = PADDING_NONE;
1323
1324 rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1325 data, length, out, outLength);
1326 if (rc) {
1327 ALOGW("device couldn't sign data");
1328 return ::SYSTEM_ERROR;
1329 }
1330
1331 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001332 }
1333
Kenny Root07438c82012-11-02 15:41:02 -07001334 int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
1335 const uint8_t* signature, size_t signatureLength) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001336 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1337 if (!has_permission(callingUid, P_VERIFY)) {
1338 ALOGW("permission denied for %d: verify", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001339 return ::PERMISSION_DENIED;
1340 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001341 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001342
Kenny Root07438c82012-11-02 15:41:02 -07001343 State state = checkState();
1344 if (state != STATE_NO_ERROR) {
1345 ALOGD("calling verify in state: %d", state);
1346 return state;
1347 }
Kenny Root70e3a862012-02-15 17:20:23 -08001348
Kenny Root07438c82012-11-02 15:41:02 -07001349 Blob keyBlob;
1350 String8 name8(name);
1351 int rc;
Kenny Root70e3a862012-02-15 17:20:23 -08001352
Kenny Rootd38a0b02013-02-13 12:59:14 -08001353 ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, TYPE_KEY_PAIR);
Kenny Root07438c82012-11-02 15:41:02 -07001354 if (responseCode != ::NO_ERROR) {
1355 return responseCode;
1356 }
Kenny Root70e3a862012-02-15 17:20:23 -08001357
Kenny Root07438c82012-11-02 15:41:02 -07001358 const keymaster_device_t* device = mKeyStore->getDevice();
1359 if (device == NULL) {
1360 return ::SYSTEM_ERROR;
1361 }
Kenny Root70e3a862012-02-15 17:20:23 -08001362
Kenny Root07438c82012-11-02 15:41:02 -07001363 if (device->verify_data == NULL) {
1364 return ::SYSTEM_ERROR;
1365 }
Kenny Root70e3a862012-02-15 17:20:23 -08001366
Kenny Root07438c82012-11-02 15:41:02 -07001367 keymaster_rsa_sign_params_t params;
1368 params.digest_type = DIGEST_NONE;
1369 params.padding_type = PADDING_NONE;
Kenny Root344e0bc2012-08-15 10:44:03 -07001370
Kenny Root07438c82012-11-02 15:41:02 -07001371 rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1372 data, dataLength, signature, signatureLength);
1373 if (rc) {
1374 return ::SYSTEM_ERROR;
1375 } else {
1376 return ::NO_ERROR;
Kenny Roota91203b2012-02-15 15:00:46 -08001377 }
1378 }
Kenny Root07438c82012-11-02 15:41:02 -07001379
1380 /*
1381 * TODO: The abstraction between things stored in hardware and regular blobs
1382 * of data stored on the filesystem should be moved down to keystore itself.
1383 * Unfortunately the Java code that calls this has naming conventions that it
1384 * knows about. Ideally keystore shouldn't be used to store random blobs of
1385 * data.
1386 *
1387 * Until that happens, it's necessary to have a separate "get_pubkey" and
1388 * "del_key" since the Java code doesn't really communicate what it's
1389 * intentions are.
1390 */
1391 int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001392 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1393 if (!has_permission(callingUid, P_GET)) {
1394 ALOGW("permission denied for %d: get_pubkey", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001395 return ::PERMISSION_DENIED;
1396 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001397 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001398
1399 State state = checkState();
1400 if (state != STATE_NO_ERROR) {
1401 ALOGD("calling get_pubkey in state: %d", state);
1402 return state;
1403 }
1404
1405 Blob keyBlob;
1406 String8 name8(name);
1407
Kenny Rootd38a0b02013-02-13 12:59:14 -08001408 ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001409
Kenny Rootd38a0b02013-02-13 12:59:14 -08001410 ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
Kenny Root07438c82012-11-02 15:41:02 -07001411 TYPE_KEY_PAIR);
1412 if (responseCode != ::NO_ERROR) {
1413 return responseCode;
1414 }
1415
1416 const keymaster_device_t* device = mKeyStore->getDevice();
1417 if (device == NULL) {
1418 return ::SYSTEM_ERROR;
1419 }
1420
1421 if (device->get_keypair_public == NULL) {
1422 ALOGE("device has no get_keypair_public implementation!");
1423 return ::SYSTEM_ERROR;
1424 }
1425
1426 int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
1427 pubkeyLength);
1428 if (rc) {
1429 return ::SYSTEM_ERROR;
1430 }
1431
1432 return ::NO_ERROR;
Kenny Roota91203b2012-02-15 15:00:46 -08001433 }
Kenny Root07438c82012-11-02 15:41:02 -07001434
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001435 int32_t del_key(const String16& name, int uid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001436 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1437 if (!has_permission(callingUid, P_DELETE)) {
1438 ALOGW("permission denied for %d: del_key", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001439 return ::PERMISSION_DENIED;
1440 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001441 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001442
Kenny Rootb88c3eb2013-02-13 14:43:43 -08001443 if (uid != -1) {
1444 return ::PERMISSION_DENIED;
1445 }
1446
Kenny Root07438c82012-11-02 15:41:02 -07001447 String8 name8(name);
1448 char filename[NAME_MAX];
1449
Kenny Rootd38a0b02013-02-13 12:59:14 -08001450 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001451
1452 Blob keyBlob;
1453 ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR);
1454 if (responseCode != ::NO_ERROR) {
1455 return responseCode;
1456 }
1457
1458 ResponseCode rc = ::NO_ERROR;
1459
1460 const keymaster_device_t* device = mKeyStore->getDevice();
1461 if (device == NULL) {
1462 rc = ::SYSTEM_ERROR;
1463 } else {
1464 // A device doesn't have to implement delete_keypair.
1465 if (device->delete_keypair != NULL) {
1466 if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
1467 rc = ::SYSTEM_ERROR;
1468 }
1469 }
1470 }
1471
1472 if (rc != ::NO_ERROR) {
1473 return rc;
1474 }
1475
1476 return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
1477 }
1478
1479 int32_t grant(const String16& name, int32_t granteeUid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001480 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1481 if (!has_permission(callingUid, P_GRANT)) {
1482 ALOGW("permission denied for %d: grant", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001483 return ::PERMISSION_DENIED;
1484 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001485 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001486
1487 State state = checkState();
1488 if (state != STATE_NO_ERROR) {
1489 ALOGD("calling grant in state: %d", state);
1490 return state;
1491 }
1492
1493 String8 name8(name);
1494 char filename[NAME_MAX];
1495
Kenny Rootd38a0b02013-02-13 12:59:14 -08001496 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001497
1498 if (access(filename, R_OK) == -1) {
1499 return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
1500 }
1501
1502 mKeyStore->addGrant(filename, granteeUid);
1503 return ::NO_ERROR;
1504 }
1505
1506 int32_t ungrant(const String16& name, int32_t granteeUid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001507 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1508 if (!has_permission(callingUid, P_GRANT)) {
1509 ALOGW("permission denied for %d: ungrant", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001510 return ::PERMISSION_DENIED;
1511 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001512 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001513
1514 State state = checkState();
1515 if (state != STATE_NO_ERROR) {
1516 ALOGD("calling ungrant in state: %d", state);
1517 return state;
1518 }
1519
1520 String8 name8(name);
1521 char filename[NAME_MAX];
1522
Kenny Rootd38a0b02013-02-13 12:59:14 -08001523 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001524
1525 if (access(filename, R_OK) == -1) {
1526 return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
1527 }
1528
1529 return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
1530 }
1531
1532 int64_t getmtime(const String16& name) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001533 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1534 if (!has_permission(callingUid, P_GET)) {
1535 ALOGW("permission denied for %d: getmtime", callingUid);
Kenny Root36a9e232013-02-04 14:24:15 -08001536 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001537 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001538 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001539
1540 String8 name8(name);
1541 char filename[NAME_MAX];
1542
Kenny Rootd38a0b02013-02-13 12:59:14 -08001543 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001544
1545 if (access(filename, R_OK) == -1) {
Kenny Root36a9e232013-02-04 14:24:15 -08001546 ALOGW("could not access %s for getmtime", filename);
1547 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001548 }
1549
Kenny Root150ca932012-11-14 14:29:02 -08001550 int fd = TEMP_FAILURE_RETRY(open(filename, O_NOFOLLOW, O_RDONLY));
Kenny Root07438c82012-11-02 15:41:02 -07001551 if (fd < 0) {
Kenny Root36a9e232013-02-04 14:24:15 -08001552 ALOGW("could not open %s for getmtime", filename);
1553 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001554 }
1555
1556 struct stat s;
1557 int ret = fstat(fd, &s);
1558 close(fd);
1559 if (ret == -1) {
Kenny Root36a9e232013-02-04 14:24:15 -08001560 ALOGW("could not stat %s for getmtime", filename);
1561 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001562 }
1563
Kenny Root36a9e232013-02-04 14:24:15 -08001564 return static_cast<int64_t>(s.st_mtime);
Kenny Root07438c82012-11-02 15:41:02 -07001565 }
1566
1567private:
1568 inline State checkState() {
1569 return mKeyStore->getState();
1570 }
1571
1572 ::KeyStore* mKeyStore;
1573};
1574
1575}; // namespace android
Kenny Roota91203b2012-02-15 15:00:46 -08001576
1577int main(int argc, char* argv[]) {
Kenny Roota91203b2012-02-15 15:00:46 -08001578 if (argc < 2) {
1579 ALOGE("A directory must be specified!");
1580 return 1;
1581 }
1582 if (chdir(argv[1]) == -1) {
1583 ALOGE("chdir: %s: %s", argv[1], strerror(errno));
1584 return 1;
1585 }
1586
1587 Entropy entropy;
1588 if (!entropy.open()) {
1589 return 1;
1590 }
Kenny Root70e3a862012-02-15 17:20:23 -08001591
1592 keymaster_device_t* dev;
1593 if (keymaster_device_initialize(&dev)) {
1594 ALOGE("keystore keymaster could not be initialized; exiting");
1595 return 1;
1596 }
1597
Kenny Root70e3a862012-02-15 17:20:23 -08001598 KeyStore keyStore(&entropy, dev);
Kenny Root07438c82012-11-02 15:41:02 -07001599 android::sp<android::IServiceManager> sm = android::defaultServiceManager();
1600 android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
1601 android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy);
1602 if (ret != android::OK) {
1603 ALOGE("Couldn't register binder service!");
1604 return -1;
Kenny Roota91203b2012-02-15 15:00:46 -08001605 }
Kenny Root07438c82012-11-02 15:41:02 -07001606
1607 /*
1608 * We're the only thread in existence, so we're just going to process
1609 * Binder transaction as a single-threaded program.
1610 */
1611 android::IPCThreadState::self()->joinThreadPool();
Kenny Root70e3a862012-02-15 17:20:23 -08001612
1613 keymaster_device_release(dev);
Kenny Roota91203b2012-02-15 15:00:46 -08001614 return 1;
1615}