blob: ef64f332efb45c75308909d8719b6a13b0d8598d [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 Root07438c82012-11-02 15:41:02 -0700981 int32_t insert(const String16& name, const uint8_t* item, size_t itemLength) {
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
989 State state = checkState();
990 if (state != STATE_NO_ERROR) {
991 ALOGD("calling insert in state: %d", state);
992 return state;
993 }
994
995 String8 name8(name);
996 char filename[NAME_MAX];
997
Kenny Rootd38a0b02013-02-13 12:59:14 -0800998 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -0700999
1000 Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
1001 return mKeyStore->put(filename, &keyBlob);
Kenny Root70e3a862012-02-15 17:20:23 -08001002 }
1003
Kenny Root07438c82012-11-02 15:41:02 -07001004 int32_t del(const String16& name) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001005 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1006 if (!has_permission(callingUid, P_DELETE)) {
1007 ALOGW("permission denied for %d: del", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001008 return ::PERMISSION_DENIED;
1009 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001010 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001011
Kenny Root07438c82012-11-02 15:41:02 -07001012 String8 name8(name);
1013 char filename[NAME_MAX];
1014
Kenny Rootd38a0b02013-02-13 12:59:14 -08001015 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001016
1017 Blob keyBlob;
1018 ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
1019 if (responseCode != ::NO_ERROR) {
1020 return responseCode;
1021 }
1022 return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001023 }
1024
Kenny Root07438c82012-11-02 15:41:02 -07001025 int32_t exist(const String16& name) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001026 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1027 if (!has_permission(callingUid, P_EXIST)) {
1028 ALOGW("permission denied for %d: exist", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001029 return ::PERMISSION_DENIED;
1030 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001031 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001032
Kenny Root07438c82012-11-02 15:41:02 -07001033 String8 name8(name);
1034 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -08001035
Kenny Rootd38a0b02013-02-13 12:59:14 -08001036 encode_key_for_uid(filename, callingUid, name8);
Kenny Root70e3a862012-02-15 17:20:23 -08001037
Kenny Root07438c82012-11-02 15:41:02 -07001038 if (access(filename, R_OK) == -1) {
1039 return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
1040 }
1041 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001042 }
1043
Kenny Root07438c82012-11-02 15:41:02 -07001044 int32_t saw(const String16& prefix, Vector<String16>* matches) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001045 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1046 if (!has_permission(callingUid, P_SAW)) {
1047 ALOGW("permission denied for %d: saw", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001048 return ::PERMISSION_DENIED;
1049 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001050 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001051
Kenny Root07438c82012-11-02 15:41:02 -07001052 DIR* dir = opendir(".");
1053 if (!dir) {
1054 return ::SYSTEM_ERROR;
1055 }
Kenny Root70e3a862012-02-15 17:20:23 -08001056
Kenny Root07438c82012-11-02 15:41:02 -07001057 const String8 prefix8(prefix);
1058 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -08001059
Kenny Rootd38a0b02013-02-13 12:59:14 -08001060 int n = encode_key_for_uid(filename, callingUid, prefix8);
Kenny Root70e3a862012-02-15 17:20:23 -08001061
Kenny Root07438c82012-11-02 15:41:02 -07001062 struct dirent* file;
1063 while ((file = readdir(dir)) != NULL) {
1064 if (!strncmp(filename, file->d_name, n)) {
1065 const char* p = &file->d_name[n];
1066 size_t plen = strlen(p);
Kenny Root70e3a862012-02-15 17:20:23 -08001067
Kenny Root07438c82012-11-02 15:41:02 -07001068 size_t extra = decode_key_length(p, plen);
1069 char *match = (char*) malloc(extra + 1);
1070 if (match != NULL) {
1071 decode_key(match, p, plen);
1072 matches->push(String16(match, extra));
1073 free(match);
1074 } else {
1075 ALOGW("could not allocate match of size %zd", extra);
1076 }
Kenny Root9a53d3e2012-08-14 10:47:54 -07001077 }
1078 }
Kenny Root07438c82012-11-02 15:41:02 -07001079 closedir(dir);
1080
1081 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001082 }
1083
Kenny Root07438c82012-11-02 15:41:02 -07001084 int32_t reset() {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001085 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1086 if (!has_permission(callingUid, P_RESET)) {
1087 ALOGW("permission denied for %d: reset", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001088 return ::PERMISSION_DENIED;
1089 }
1090
1091 ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR;
1092
1093 const keymaster_device_t* device = mKeyStore->getDevice();
1094 if (device == NULL) {
1095 ALOGE("No keymaster device!");
1096 return ::SYSTEM_ERROR;
1097 }
1098
1099 if (device->delete_all == NULL) {
1100 ALOGV("keymaster device doesn't implement delete_all");
1101 return rc;
1102 }
1103
1104 if (device->delete_all(device)) {
1105 ALOGE("Problem calling keymaster's delete_all");
1106 return ::SYSTEM_ERROR;
1107 }
1108
Kenny Root9a53d3e2012-08-14 10:47:54 -07001109 return rc;
Kenny Root70e3a862012-02-15 17:20:23 -08001110 }
1111
Kenny Root07438c82012-11-02 15:41:02 -07001112 /*
1113 * Here is the history. To improve the security, the parameters to generate the
1114 * master key has been changed. To make a seamless transition, we update the
1115 * file using the same password when the user unlock it for the first time. If
1116 * any thing goes wrong during the transition, the new file will not overwrite
1117 * the old one. This avoids permanent damages of the existing data.
1118 */
1119 int32_t password(const String16& password) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001120 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1121 if (!has_permission(callingUid, P_PASSWORD)) {
1122 ALOGW("permission denied for %d: password", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001123 return ::PERMISSION_DENIED;
1124 }
Kenny Root70e3a862012-02-15 17:20:23 -08001125
Kenny Root07438c82012-11-02 15:41:02 -07001126 const String8 password8(password);
Kenny Root70e3a862012-02-15 17:20:23 -08001127
Kenny Root07438c82012-11-02 15:41:02 -07001128 switch (mKeyStore->getState()) {
1129 case ::STATE_UNINITIALIZED: {
1130 // generate master key, encrypt with password, write to file, initialize mMasterKey*.
1131 return mKeyStore->initialize(password8);
1132 }
1133 case ::STATE_NO_ERROR: {
1134 // rewrite master key with new password.
1135 return mKeyStore->writeMasterKey(password8);
1136 }
1137 case ::STATE_LOCKED: {
1138 // read master key, decrypt with password, initialize mMasterKey*.
1139 return mKeyStore->readMasterKey(password8);
1140 }
1141 }
1142 return ::SYSTEM_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001143 }
1144
Kenny Root07438c82012-11-02 15:41:02 -07001145 int32_t lock() {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001146 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1147 if (!has_permission(callingUid, P_LOCK)) {
1148 ALOGW("permission denied for %d: lock", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001149 return ::PERMISSION_DENIED;
1150 }
Kenny Root70e3a862012-02-15 17:20:23 -08001151
Kenny Root07438c82012-11-02 15:41:02 -07001152 State state = checkState();
1153 if (state != STATE_NO_ERROR) {
1154 ALOGD("calling lock in state: %d", state);
1155 return state;
1156 }
1157
1158 mKeyStore->lock();
1159 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001160 }
1161
Kenny Root07438c82012-11-02 15:41:02 -07001162 int32_t unlock(const String16& pw) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001163 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1164 if (!has_permission(callingUid, P_UNLOCK)) {
1165 ALOGW("permission denied for %d: unlock", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001166 return ::PERMISSION_DENIED;
1167 }
1168
1169 State state = checkState();
1170 if (state != STATE_LOCKED) {
1171 ALOGD("calling unlock when not locked");
1172 return state;
1173 }
1174
1175 const String8 password8(pw);
1176 return password(pw);
Kenny Root70e3a862012-02-15 17:20:23 -08001177 }
1178
Kenny Root07438c82012-11-02 15:41:02 -07001179 int32_t zero() {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001180 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1181 if (!has_permission(callingUid, P_ZERO)) {
1182 ALOGW("permission denied for %d: zero", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001183 return -1;
1184 }
Kenny Root70e3a862012-02-15 17:20:23 -08001185
Kenny Root07438c82012-11-02 15:41:02 -07001186 return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001187 }
1188
Kenny Root07438c82012-11-02 15:41:02 -07001189 int32_t generate(const String16& name) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001190 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1191 if (!has_permission(callingUid, P_INSERT)) {
1192 ALOGW("permission denied for %d: generate", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001193 return ::PERMISSION_DENIED;
1194 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001195 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001196
Kenny Root07438c82012-11-02 15:41:02 -07001197 State state = checkState();
1198 if (state != STATE_NO_ERROR) {
1199 ALOGD("calling generate in state: %d", state);
1200 return state;
1201 }
Kenny Root70e3a862012-02-15 17:20:23 -08001202
Kenny Root07438c82012-11-02 15:41:02 -07001203 String8 name8(name);
1204 char filename[NAME_MAX];
1205
1206 uint8_t* data;
1207 size_t dataLength;
1208 int rc;
1209
1210 const keymaster_device_t* device = mKeyStore->getDevice();
1211 if (device == NULL) {
1212 return ::SYSTEM_ERROR;
1213 }
1214
1215 if (device->generate_keypair == NULL) {
1216 return ::SYSTEM_ERROR;
1217 }
1218
1219 keymaster_rsa_keygen_params_t rsa_params;
1220 rsa_params.modulus_size = 2048;
1221 rsa_params.public_exponent = 0x10001;
1222
1223 rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
1224 if (rc) {
1225 return ::SYSTEM_ERROR;
1226 }
1227
Kenny Rootd38a0b02013-02-13 12:59:14 -08001228 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001229
1230 Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
1231 free(data);
1232
1233 return mKeyStore->put(filename, &keyBlob);
Kenny Root70e3a862012-02-15 17:20:23 -08001234 }
1235
Kenny Root07438c82012-11-02 15:41:02 -07001236 int32_t import(const String16& name, const uint8_t* data, size_t length) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001237 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1238 if (!has_permission(callingUid, P_INSERT)) {
1239 ALOGW("permission denied for %d: import", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001240 return ::PERMISSION_DENIED;
1241 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001242 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001243
1244 State state = checkState();
1245 if (state != STATE_NO_ERROR) {
1246 ALOGD("calling import in state: %d", state);
1247 return state;
1248 }
1249
1250 String8 name8(name);
1251 char filename[NAME_MAX];
1252
Kenny Rootd38a0b02013-02-13 12:59:14 -08001253 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001254
1255 return mKeyStore->importKey(data, length, filename);
Kenny Root70e3a862012-02-15 17:20:23 -08001256 }
1257
Kenny Root07438c82012-11-02 15:41:02 -07001258 int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
1259 size_t* outLength) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001260 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1261 if (!has_permission(callingUid, P_SIGN)) {
1262 ALOGW("permission denied for %d: saw", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001263 return ::PERMISSION_DENIED;
1264 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001265 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001266
1267 State state = checkState();
1268 if (state != STATE_NO_ERROR) {
1269 ALOGD("calling sign in state: %d", state);
1270 return state;
1271 }
1272
1273 Blob keyBlob;
1274 String8 name8(name);
1275
Kenny Rootd38a0b02013-02-13 12:59:14 -08001276 ALOGV("sign %s from uid %d", name8.string(), callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001277 int rc;
1278
Kenny Rootd38a0b02013-02-13 12:59:14 -08001279 ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
1280 ::TYPE_KEY_PAIR);
Kenny Root07438c82012-11-02 15:41:02 -07001281 if (responseCode != ::NO_ERROR) {
1282 return responseCode;
1283 }
1284
1285 const keymaster_device_t* device = mKeyStore->getDevice();
1286 if (device == NULL) {
1287 ALOGE("no keymaster device; cannot sign");
1288 return ::SYSTEM_ERROR;
1289 }
1290
1291 if (device->sign_data == NULL) {
1292 ALOGE("device doesn't implement signing");
1293 return ::SYSTEM_ERROR;
1294 }
1295
1296 keymaster_rsa_sign_params_t params;
1297 params.digest_type = DIGEST_NONE;
1298 params.padding_type = PADDING_NONE;
1299
1300 rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1301 data, length, out, outLength);
1302 if (rc) {
1303 ALOGW("device couldn't sign data");
1304 return ::SYSTEM_ERROR;
1305 }
1306
1307 return ::NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001308 }
1309
Kenny Root07438c82012-11-02 15:41:02 -07001310 int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
1311 const uint8_t* signature, size_t signatureLength) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001312 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1313 if (!has_permission(callingUid, P_VERIFY)) {
1314 ALOGW("permission denied for %d: verify", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001315 return ::PERMISSION_DENIED;
1316 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001317 callingUid = get_keystore_euid(callingUid);
Kenny Root70e3a862012-02-15 17:20:23 -08001318
Kenny Root07438c82012-11-02 15:41:02 -07001319 State state = checkState();
1320 if (state != STATE_NO_ERROR) {
1321 ALOGD("calling verify in state: %d", state);
1322 return state;
1323 }
Kenny Root70e3a862012-02-15 17:20:23 -08001324
Kenny Root07438c82012-11-02 15:41:02 -07001325 Blob keyBlob;
1326 String8 name8(name);
1327 int rc;
Kenny Root70e3a862012-02-15 17:20:23 -08001328
Kenny Rootd38a0b02013-02-13 12:59:14 -08001329 ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, TYPE_KEY_PAIR);
Kenny Root07438c82012-11-02 15:41:02 -07001330 if (responseCode != ::NO_ERROR) {
1331 return responseCode;
1332 }
Kenny Root70e3a862012-02-15 17:20:23 -08001333
Kenny Root07438c82012-11-02 15:41:02 -07001334 const keymaster_device_t* device = mKeyStore->getDevice();
1335 if (device == NULL) {
1336 return ::SYSTEM_ERROR;
1337 }
Kenny Root70e3a862012-02-15 17:20:23 -08001338
Kenny Root07438c82012-11-02 15:41:02 -07001339 if (device->verify_data == NULL) {
1340 return ::SYSTEM_ERROR;
1341 }
Kenny Root70e3a862012-02-15 17:20:23 -08001342
Kenny Root07438c82012-11-02 15:41:02 -07001343 keymaster_rsa_sign_params_t params;
1344 params.digest_type = DIGEST_NONE;
1345 params.padding_type = PADDING_NONE;
Kenny Root344e0bc2012-08-15 10:44:03 -07001346
Kenny Root07438c82012-11-02 15:41:02 -07001347 rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1348 data, dataLength, signature, signatureLength);
1349 if (rc) {
1350 return ::SYSTEM_ERROR;
1351 } else {
1352 return ::NO_ERROR;
Kenny Roota91203b2012-02-15 15:00:46 -08001353 }
1354 }
Kenny Root07438c82012-11-02 15:41:02 -07001355
1356 /*
1357 * TODO: The abstraction between things stored in hardware and regular blobs
1358 * of data stored on the filesystem should be moved down to keystore itself.
1359 * Unfortunately the Java code that calls this has naming conventions that it
1360 * knows about. Ideally keystore shouldn't be used to store random blobs of
1361 * data.
1362 *
1363 * Until that happens, it's necessary to have a separate "get_pubkey" and
1364 * "del_key" since the Java code doesn't really communicate what it's
1365 * intentions are.
1366 */
1367 int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001368 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1369 if (!has_permission(callingUid, P_GET)) {
1370 ALOGW("permission denied for %d: get_pubkey", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001371 return ::PERMISSION_DENIED;
1372 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001373 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001374
1375 State state = checkState();
1376 if (state != STATE_NO_ERROR) {
1377 ALOGD("calling get_pubkey in state: %d", state);
1378 return state;
1379 }
1380
1381 Blob keyBlob;
1382 String8 name8(name);
1383
Kenny Rootd38a0b02013-02-13 12:59:14 -08001384 ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001385
Kenny Rootd38a0b02013-02-13 12:59:14 -08001386 ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
Kenny Root07438c82012-11-02 15:41:02 -07001387 TYPE_KEY_PAIR);
1388 if (responseCode != ::NO_ERROR) {
1389 return responseCode;
1390 }
1391
1392 const keymaster_device_t* device = mKeyStore->getDevice();
1393 if (device == NULL) {
1394 return ::SYSTEM_ERROR;
1395 }
1396
1397 if (device->get_keypair_public == NULL) {
1398 ALOGE("device has no get_keypair_public implementation!");
1399 return ::SYSTEM_ERROR;
1400 }
1401
1402 int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
1403 pubkeyLength);
1404 if (rc) {
1405 return ::SYSTEM_ERROR;
1406 }
1407
1408 return ::NO_ERROR;
Kenny Roota91203b2012-02-15 15:00:46 -08001409 }
Kenny Root07438c82012-11-02 15:41:02 -07001410
1411 int32_t del_key(const String16& name) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001412 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1413 if (!has_permission(callingUid, P_DELETE)) {
1414 ALOGW("permission denied for %d: del_key", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001415 return ::PERMISSION_DENIED;
1416 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001417 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001418
1419 String8 name8(name);
1420 char filename[NAME_MAX];
1421
Kenny Rootd38a0b02013-02-13 12:59:14 -08001422 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001423
1424 Blob keyBlob;
1425 ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR);
1426 if (responseCode != ::NO_ERROR) {
1427 return responseCode;
1428 }
1429
1430 ResponseCode rc = ::NO_ERROR;
1431
1432 const keymaster_device_t* device = mKeyStore->getDevice();
1433 if (device == NULL) {
1434 rc = ::SYSTEM_ERROR;
1435 } else {
1436 // A device doesn't have to implement delete_keypair.
1437 if (device->delete_keypair != NULL) {
1438 if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
1439 rc = ::SYSTEM_ERROR;
1440 }
1441 }
1442 }
1443
1444 if (rc != ::NO_ERROR) {
1445 return rc;
1446 }
1447
1448 return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
1449 }
1450
1451 int32_t grant(const String16& name, int32_t granteeUid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001452 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1453 if (!has_permission(callingUid, P_GRANT)) {
1454 ALOGW("permission denied for %d: grant", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001455 return ::PERMISSION_DENIED;
1456 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001457 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001458
1459 State state = checkState();
1460 if (state != STATE_NO_ERROR) {
1461 ALOGD("calling grant in state: %d", state);
1462 return state;
1463 }
1464
1465 String8 name8(name);
1466 char filename[NAME_MAX];
1467
Kenny Rootd38a0b02013-02-13 12:59:14 -08001468 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001469
1470 if (access(filename, R_OK) == -1) {
1471 return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
1472 }
1473
1474 mKeyStore->addGrant(filename, granteeUid);
1475 return ::NO_ERROR;
1476 }
1477
1478 int32_t ungrant(const String16& name, int32_t granteeUid) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001479 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1480 if (!has_permission(callingUid, P_GRANT)) {
1481 ALOGW("permission denied for %d: ungrant", callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001482 return ::PERMISSION_DENIED;
1483 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001484 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001485
1486 State state = checkState();
1487 if (state != STATE_NO_ERROR) {
1488 ALOGD("calling ungrant in state: %d", state);
1489 return state;
1490 }
1491
1492 String8 name8(name);
1493 char filename[NAME_MAX];
1494
Kenny Rootd38a0b02013-02-13 12:59:14 -08001495 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001496
1497 if (access(filename, R_OK) == -1) {
1498 return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
1499 }
1500
1501 return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
1502 }
1503
1504 int64_t getmtime(const String16& name) {
Kenny Rootd38a0b02013-02-13 12:59:14 -08001505 uid_t callingUid = IPCThreadState::self()->getCallingUid();
1506 if (!has_permission(callingUid, P_GET)) {
1507 ALOGW("permission denied for %d: getmtime", callingUid);
Kenny Root36a9e232013-02-04 14:24:15 -08001508 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001509 }
Kenny Rootd38a0b02013-02-13 12:59:14 -08001510 callingUid = get_keystore_euid(callingUid);
Kenny Root07438c82012-11-02 15:41:02 -07001511
1512 String8 name8(name);
1513 char filename[NAME_MAX];
1514
Kenny Rootd38a0b02013-02-13 12:59:14 -08001515 encode_key_for_uid(filename, callingUid, name8);
Kenny Root07438c82012-11-02 15:41:02 -07001516
1517 if (access(filename, R_OK) == -1) {
Kenny Root36a9e232013-02-04 14:24:15 -08001518 ALOGW("could not access %s for getmtime", filename);
1519 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001520 }
1521
Kenny Root150ca932012-11-14 14:29:02 -08001522 int fd = TEMP_FAILURE_RETRY(open(filename, O_NOFOLLOW, O_RDONLY));
Kenny Root07438c82012-11-02 15:41:02 -07001523 if (fd < 0) {
Kenny Root36a9e232013-02-04 14:24:15 -08001524 ALOGW("could not open %s for getmtime", filename);
1525 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001526 }
1527
1528 struct stat s;
1529 int ret = fstat(fd, &s);
1530 close(fd);
1531 if (ret == -1) {
Kenny Root36a9e232013-02-04 14:24:15 -08001532 ALOGW("could not stat %s for getmtime", filename);
1533 return -1L;
Kenny Root07438c82012-11-02 15:41:02 -07001534 }
1535
Kenny Root36a9e232013-02-04 14:24:15 -08001536 return static_cast<int64_t>(s.st_mtime);
Kenny Root07438c82012-11-02 15:41:02 -07001537 }
1538
1539private:
1540 inline State checkState() {
1541 return mKeyStore->getState();
1542 }
1543
1544 ::KeyStore* mKeyStore;
1545};
1546
1547}; // namespace android
Kenny Roota91203b2012-02-15 15:00:46 -08001548
1549int main(int argc, char* argv[]) {
Kenny Roota91203b2012-02-15 15:00:46 -08001550 if (argc < 2) {
1551 ALOGE("A directory must be specified!");
1552 return 1;
1553 }
1554 if (chdir(argv[1]) == -1) {
1555 ALOGE("chdir: %s: %s", argv[1], strerror(errno));
1556 return 1;
1557 }
1558
1559 Entropy entropy;
1560 if (!entropy.open()) {
1561 return 1;
1562 }
Kenny Root70e3a862012-02-15 17:20:23 -08001563
1564 keymaster_device_t* dev;
1565 if (keymaster_device_initialize(&dev)) {
1566 ALOGE("keystore keymaster could not be initialized; exiting");
1567 return 1;
1568 }
1569
Kenny Root70e3a862012-02-15 17:20:23 -08001570 KeyStore keyStore(&entropy, dev);
Kenny Root07438c82012-11-02 15:41:02 -07001571 android::sp<android::IServiceManager> sm = android::defaultServiceManager();
1572 android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
1573 android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy);
1574 if (ret != android::OK) {
1575 ALOGE("Couldn't register binder service!");
1576 return -1;
Kenny Roota91203b2012-02-15 15:00:46 -08001577 }
Kenny Root07438c82012-11-02 15:41:02 -07001578
1579 /*
1580 * We're the only thread in existence, so we're just going to process
1581 * Binder transaction as a single-threaded program.
1582 */
1583 android::IPCThreadState::self()->joinThreadPool();
Kenny Root70e3a862012-02-15 17:20:23 -08001584
1585 keymaster_device_release(dev);
Kenny Roota91203b2012-02-15 15:00:46 -08001586 return 1;
1587}