blob: 6dfbff2ca8960c66357198cfa1cce0094f606402 [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
17#include <stdio.h>
18#include <stdint.h>
19#include <string.h>
20#include <unistd.h>
21#include <signal.h>
22#include <errno.h>
23#include <dirent.h>
24#include <fcntl.h>
25#include <limits.h>
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <sys/stat.h>
29#include <sys/time.h>
30#include <arpa/inet.h>
31
32#include <openssl/aes.h>
33#include <openssl/evp.h>
34#include <openssl/md5.h>
35
Kenny Root70e3a862012-02-15 17:20:23 -080036#include <hardware/keymaster.h>
37
38#include <cutils/list.h>
39
40//#define LOG_NDEBUG 0
Kenny Roota91203b2012-02-15 15:00:46 -080041#define LOG_TAG "keystore"
42#include <cutils/log.h>
43#include <cutils/sockets.h>
44#include <private/android_filesystem_config.h>
45
46#include "keystore.h"
47
48/* KeyStore is a secured storage for key-value pairs. In this implementation,
49 * each file stores one key-value pair. Keys are encoded in file names, and
50 * values are encrypted with checksums. The encryption key is protected by a
51 * user-defined password. To keep things simple, buffers are always larger than
52 * the maximum space we needed, so boundary checks on buffers are omitted. */
53
54#define KEY_SIZE ((NAME_MAX - 15) / 2)
55#define VALUE_SIZE 32768
56#define PASSWORD_SIZE VALUE_SIZE
57
58struct Value {
59 int length;
60 uint8_t value[VALUE_SIZE];
61};
62
Kenny Root70e3a862012-02-15 17:20:23 -080063class ValueString {
64public:
65 ValueString(const Value* orig) {
66 length = orig->length;
67 value = new char[length + 1];
68 memcpy(value, orig->value, length);
69 value[length] = '\0';
70 }
71
72 ~ValueString() {
73 delete[] value;
74 }
75
76 const char* c_str() const {
77 return value;
78 }
79
80 char* release() {
81 char* ret = value;
82 value = NULL;
83 return ret;
84 }
85
86private:
87 char* value;
88 size_t length;
89};
90
91static 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 Roota91203b2012-02-15 15:00:46 -0800119/* Here is the encoding of keys. This is necessary in order to allow arbitrary
120 * characters in keys. Characters in [0-~] are not encoded. Others are encoded
121 * into two bytes. The first byte is one of [+-.] which represents the first
122 * two bits of the character. The second byte encodes the rest of the bits into
123 * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
124 * that Base64 cannot be used here due to the need of prefix match on keys. */
125
Kenny Root70e3a862012-02-15 17:20:23 -0800126static int encode_key(char* out, const Value* key) {
Kenny Roota91203b2012-02-15 15:00:46 -0800127 const uint8_t* in = key->value;
128 int length = key->length;
129 for (int i = length; i > 0; --i, ++in, ++out) {
130 if (*in >= '0' && *in <= '~') {
131 *out = *in;
132 } else {
133 *out = '+' + (*in >> 6);
134 *++out = '0' + (*in & 0x3F);
135 ++length;
136 }
137 }
138 *out = '\0';
Kenny Root70e3a862012-02-15 17:20:23 -0800139 return length;
140}
141
142static int encode_key_for_uid(char* out, uid_t uid, const Value* key) {
143 int n = snprintf(out, NAME_MAX, "%u_", uid);
144 out += n;
145
146 return n + encode_key(out, key);
Kenny Roota91203b2012-02-15 15:00:46 -0800147}
148
Kenny Root51878182012-03-13 12:53:19 -0700149static int decode_key(uint8_t* out, const char* in, int length) {
Kenny Roota91203b2012-02-15 15:00:46 -0800150 for (int i = 0; i < length; ++i, ++in, ++out) {
151 if (*in >= '0' && *in <= '~') {
152 *out = *in;
153 } else {
154 *out = (*in - '+') << 6;
155 *out |= (*++in - '0') & 0x3F;
156 --length;
157 }
158 }
159 *out = '\0';
160 return length;
161}
162
163static size_t readFully(int fd, uint8_t* data, size_t size) {
164 size_t remaining = size;
165 while (remaining > 0) {
166 ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size));
167 if (n == -1 || n == 0) {
168 return size-remaining;
169 }
170 data += n;
171 remaining -= n;
172 }
173 return size;
174}
175
176static size_t writeFully(int fd, uint8_t* data, size_t size) {
177 size_t remaining = size;
178 while (remaining > 0) {
179 ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size));
180 if (n == -1 || n == 0) {
181 return size-remaining;
182 }
183 data += n;
184 remaining -= n;
185 }
186 return size;
187}
188
189class Entropy {
190public:
191 Entropy() : mRandom(-1) {}
192 ~Entropy() {
193 if (mRandom != -1) {
194 close(mRandom);
195 }
196 }
197
198 bool open() {
199 const char* randomDevice = "/dev/urandom";
200 mRandom = ::open(randomDevice, O_RDONLY);
201 if (mRandom == -1) {
202 ALOGE("open: %s: %s", randomDevice, strerror(errno));
203 return false;
204 }
205 return true;
206 }
207
Kenny Root51878182012-03-13 12:53:19 -0700208 bool generate_random_data(uint8_t* data, size_t size) const {
Kenny Roota91203b2012-02-15 15:00:46 -0800209 return (readFully(mRandom, data, size) == size);
210 }
211
212private:
213 int mRandom;
214};
215
216/* Here is the file format. There are two parts in blob.value, the secret and
217 * the description. The secret is stored in ciphertext, and its original size
218 * can be found in blob.length. The description is stored after the secret in
219 * plaintext, and its size is specified in blob.info. The total size of the two
220 * parts must be no more than VALUE_SIZE bytes. The first three bytes of the
221 * file are reserved for future use and are always set to zero. Fields other
222 * than blob.info, blob.length, and blob.value are modified by encryptBlob()
223 * and decryptBlob(). Thus they should not be accessed from outside. */
224
225struct __attribute__((packed)) blob {
226 uint8_t reserved[3];
227 uint8_t info;
228 uint8_t vector[AES_BLOCK_SIZE];
229 uint8_t encrypted[0];
230 uint8_t digest[MD5_DIGEST_LENGTH];
231 uint8_t digested[0];
232 int32_t length; // in network byte order when encrypted
233 uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
234};
235
236class Blob {
237public:
238 Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength) {
239 mBlob.length = valueLength;
240 memcpy(mBlob.value, value, valueLength);
241
242 mBlob.info = infoLength;
243 memcpy(mBlob.value + valueLength, info, infoLength);
244 }
245
246 Blob(blob b) {
247 mBlob = b;
248 }
249
250 Blob() {}
251
Kenny Root51878182012-03-13 12:53:19 -0700252 const uint8_t* getValue() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800253 return mBlob.value;
254 }
255
Kenny Root51878182012-03-13 12:53:19 -0700256 int32_t getLength() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800257 return mBlob.length;
258 }
259
Kenny Root51878182012-03-13 12:53:19 -0700260 const uint8_t* getInfo() const {
261 return mBlob.value + mBlob.length;
262 }
263
264 uint8_t getInfoLength() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800265 return mBlob.info;
266 }
267
268 ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) {
269 if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
270 return SYSTEM_ERROR;
271 }
272
273 // data includes the value and the value's length
274 size_t dataLength = mBlob.length + sizeof(mBlob.length);
275 // pad data to the AES_BLOCK_SIZE
276 size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
277 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
278 // encrypted data includes the digest value
279 size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
280 // move info after space for padding
281 memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
282 // zero padding area
283 memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
284
285 mBlob.length = htonl(mBlob.length);
286 MD5(mBlob.digested, digestedLength, mBlob.digest);
287
288 uint8_t vector[AES_BLOCK_SIZE];
289 memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
290 AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
291 aes_key, vector, AES_ENCRYPT);
292
293 memset(mBlob.reserved, 0, sizeof(mBlob.reserved));
294 size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
295 size_t fileLength = encryptedLength + headerLength + mBlob.info;
296
297 const char* tmpFileName = ".tmp";
298 int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
299 if (out == -1) {
300 return SYSTEM_ERROR;
301 }
302 size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
303 if (close(out) != 0) {
304 return SYSTEM_ERROR;
305 }
306 if (writtenBytes != fileLength) {
307 unlink(tmpFileName);
308 return SYSTEM_ERROR;
309 }
310 return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR;
311 }
312
313 ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
314 int in = open(filename, O_RDONLY);
315 if (in == -1) {
316 return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
317 }
318 // fileLength may be less than sizeof(mBlob) since the in
319 // memory version has extra padding to tolerate rounding up to
320 // the AES_BLOCK_SIZE
321 size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
322 if (close(in) != 0) {
323 return SYSTEM_ERROR;
324 }
325 size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
326 if (fileLength < headerLength) {
327 return VALUE_CORRUPTED;
328 }
329
330 ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
331 if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) {
332 return VALUE_CORRUPTED;
333 }
334 AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
335 mBlob.vector, AES_DECRYPT);
336 size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
337 uint8_t computedDigest[MD5_DIGEST_LENGTH];
338 MD5(mBlob.digested, digestedLength, computedDigest);
339 if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
340 return VALUE_CORRUPTED;
341 }
342
343 ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
344 mBlob.length = ntohl(mBlob.length);
345 if (mBlob.length < 0 || mBlob.length > maxValueLength) {
346 return VALUE_CORRUPTED;
347 }
348 if (mBlob.info != 0) {
349 // move info from after padding to after data
350 memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
351 }
352 return NO_ERROR;
353 }
354
355private:
356 struct blob mBlob;
357};
358
Kenny Root70e3a862012-02-15 17:20:23 -0800359typedef struct {
360 uint32_t uid;
361 const uint8_t* keyName;
362
363 struct listnode plist;
364} grant_t;
365
Kenny Roota91203b2012-02-15 15:00:46 -0800366class KeyStore {
367public:
Kenny Root70e3a862012-02-15 17:20:23 -0800368 KeyStore(Entropy* entropy, keymaster_device_t* device)
Kenny Root51878182012-03-13 12:53:19 -0700369 : mEntropy(entropy)
Kenny Root70e3a862012-02-15 17:20:23 -0800370 , mDevice(device)
Kenny Root51878182012-03-13 12:53:19 -0700371 , mRetry(MAX_RETRY)
372 {
Kenny Roota91203b2012-02-15 15:00:46 -0800373 if (access(MASTER_KEY_FILE, R_OK) == 0) {
374 setState(STATE_LOCKED);
375 } else {
376 setState(STATE_UNINITIALIZED);
377 }
Kenny Root70e3a862012-02-15 17:20:23 -0800378
379 list_init(&mGrants);
Kenny Roota91203b2012-02-15 15:00:46 -0800380 }
381
Kenny Root51878182012-03-13 12:53:19 -0700382 State getState() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800383 return mState;
384 }
385
Kenny Root51878182012-03-13 12:53:19 -0700386 int8_t getRetry() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800387 return mRetry;
388 }
389
Kenny Root70e3a862012-02-15 17:20:23 -0800390 keymaster_device_t* getDevice() const {
391 return mDevice;
392 }
393
Kenny Roota91203b2012-02-15 15:00:46 -0800394 ResponseCode initialize(Value* pw) {
395 if (!generateMasterKey()) {
396 return SYSTEM_ERROR;
397 }
398 ResponseCode response = writeMasterKey(pw);
399 if (response != NO_ERROR) {
400 return response;
401 }
402 setupMasterKeys();
403 return NO_ERROR;
404 }
405
406 ResponseCode writeMasterKey(Value* pw) {
407 uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
408 generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
409 AES_KEY passwordAesKey;
410 AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
411 Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt));
412 return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
413 }
414
415 ResponseCode readMasterKey(Value* pw) {
416 int in = open(MASTER_KEY_FILE, O_RDONLY);
417 if (in == -1) {
418 return SYSTEM_ERROR;
419 }
420
421 // we read the raw blob to just to get the salt to generate
422 // the AES key, then we create the Blob to use with decryptBlob
423 blob rawBlob;
424 size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
425 if (close(in) != 0) {
426 return SYSTEM_ERROR;
427 }
428 // find salt at EOF if present, otherwise we have an old file
429 uint8_t* salt;
430 if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
431 salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
432 } else {
433 salt = NULL;
434 }
435 uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
436 generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
437 AES_KEY passwordAesKey;
438 AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
439 Blob masterKeyBlob(rawBlob);
440 ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
441 if (response == SYSTEM_ERROR) {
442 return SYSTEM_ERROR;
443 }
444 if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
445 // if salt was missing, generate one and write a new master key file with the salt.
446 if (salt == NULL) {
447 if (!generateSalt()) {
448 return SYSTEM_ERROR;
449 }
450 response = writeMasterKey(pw);
451 }
452 if (response == NO_ERROR) {
453 memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
454 setupMasterKeys();
455 }
456 return response;
457 }
458 if (mRetry <= 0) {
459 reset();
460 return UNINITIALIZED;
461 }
462 --mRetry;
463 switch (mRetry) {
464 case 0: return WRONG_PASSWORD_0;
465 case 1: return WRONG_PASSWORD_1;
466 case 2: return WRONG_PASSWORD_2;
467 case 3: return WRONG_PASSWORD_3;
468 default: return WRONG_PASSWORD_3;
469 }
470 }
471
472 bool reset() {
473 clearMasterKeys();
474 setState(STATE_UNINITIALIZED);
475
476 DIR* dir = opendir(".");
477 struct dirent* file;
478
479 if (!dir) {
480 return false;
481 }
482 while ((file = readdir(dir)) != NULL) {
483 unlink(file->d_name);
484 }
485 closedir(dir);
486 return true;
487 }
488
Kenny Root51878182012-03-13 12:53:19 -0700489 bool isEmpty() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800490 DIR* dir = opendir(".");
491 struct dirent* file;
492 if (!dir) {
493 return true;
494 }
495 bool result = true;
496 while ((file = readdir(dir)) != NULL) {
497 if (isKeyFile(file->d_name)) {
498 result = false;
499 break;
500 }
501 }
502 closedir(dir);
503 return result;
504 }
505
506 void lock() {
507 clearMasterKeys();
508 setState(STATE_LOCKED);
509 }
510
511 ResponseCode get(const char* filename, Blob* keyBlob) {
512 return keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
513 }
514
515 ResponseCode put(const char* filename, Blob* keyBlob) {
516 return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
517 }
518
Kenny Root70e3a862012-02-15 17:20:23 -0800519 void addGrant(const char* filename, const Value* uidValue) {
520 uid_t uid;
521 if (!convertToUid(uidValue, &uid)) {
522 return;
523 }
524
525 grant_t *grant = getGrant(filename, uid);
526 if (grant == NULL) {
527 grant = new grant_t;
528 grant->uid = uid;
529 grant->keyName = reinterpret_cast<const uint8_t*>(strdup(filename));
530 list_add_tail(&mGrants, &grant->plist);
531 }
532 }
533
534 bool removeGrant(const Value* keyValue, const Value* uidValue) {
535 uid_t uid;
536 if (!convertToUid(uidValue, &uid)) {
537 return false;
538 }
539
540 ValueString keyString(keyValue);
541
542 grant_t *grant = getGrant(keyString.c_str(), uid);
543 if (grant != NULL) {
544 list_remove(&grant->plist);
545 delete grant;
546 return true;
547 }
548
549 return false;
550 }
551
552 bool hasGrant(const Value* keyValue, const uid_t uid) const {
553 ValueString keyString(keyValue);
554 return getGrant(keyString.c_str(), uid) != NULL;
555 }
556
Kenny Roota91203b2012-02-15 15:00:46 -0800557private:
558 static const char* MASTER_KEY_FILE;
559 static const int MASTER_KEY_SIZE_BYTES = 16;
560 static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
561
562 static const int MAX_RETRY = 4;
563 static const size_t SALT_SIZE = 16;
564
565 Entropy* mEntropy;
566
Kenny Root70e3a862012-02-15 17:20:23 -0800567 keymaster_device_t* mDevice;
568
Kenny Roota91203b2012-02-15 15:00:46 -0800569 State mState;
570 int8_t mRetry;
571
572 uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
573 uint8_t mSalt[SALT_SIZE];
574
575 AES_KEY mMasterKeyEncryption;
576 AES_KEY mMasterKeyDecryption;
577
Kenny Root70e3a862012-02-15 17:20:23 -0800578 struct listnode mGrants;
579
Kenny Roota91203b2012-02-15 15:00:46 -0800580 void setState(State state) {
581 mState = state;
582 if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
583 mRetry = MAX_RETRY;
584 }
585 }
586
587 bool generateSalt() {
588 return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
589 }
590
591 bool generateMasterKey() {
592 if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
593 return false;
594 }
595 if (!generateSalt()) {
596 return false;
597 }
598 return true;
599 }
600
601 void setupMasterKeys() {
602 AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
603 AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
604 setState(STATE_NO_ERROR);
605 }
606
607 void clearMasterKeys() {
608 memset(mMasterKey, 0, sizeof(mMasterKey));
609 memset(mSalt, 0, sizeof(mSalt));
610 memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
611 memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
612 }
613
614 static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) {
615 size_t saltSize;
616 if (salt != NULL) {
617 saltSize = SALT_SIZE;
618 } else {
619 // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
620 salt = (uint8_t*) "keystore";
621 // sizeof = 9, not strlen = 8
622 saltSize = sizeof("keystore");
623 }
624 PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key);
625 }
626
627 static bool isKeyFile(const char* filename) {
628 return ((strcmp(filename, MASTER_KEY_FILE) != 0)
629 && (strcmp(filename, ".") != 0)
630 && (strcmp(filename, "..") != 0));
631 }
Kenny Root70e3a862012-02-15 17:20:23 -0800632
633 grant_t* getGrant(const char* keyName, uid_t uid) const {
634 struct listnode *node;
635 grant_t *grant;
636
637 list_for_each(node, &mGrants) {
638 grant = node_to_item(node, grant_t, plist);
639 if (grant->uid == uid
640 && !strcmp(reinterpret_cast<const char*>(grant->keyName),
641 keyName)) {
642 return grant;
643 }
644 }
645
646 return NULL;
647 }
648
649 bool convertToUid(const Value* uidValue, uid_t* uid) const {
650 ValueString uidString(uidValue);
651 char* end = NULL;
652 *uid = strtol(uidString.c_str(), &end, 10);
653 return *end == '\0';
654 }
Kenny Roota91203b2012-02-15 15:00:46 -0800655};
656
657const char* KeyStore::MASTER_KEY_FILE = ".masterkey";
658
659/* Here is the protocol used in both requests and responses:
660 * code [length_1 message_1 ... length_n message_n] end-of-file
661 * where code is one byte long and lengths are unsigned 16-bit integers in
662 * network order. Thus the maximum length of a message is 65535 bytes. */
663
664static int recv_code(int sock, int8_t* code) {
665 return recv(sock, code, 1, 0) == 1;
666}
667
668static int recv_message(int sock, uint8_t* message, int length) {
669 uint8_t bytes[2];
670 if (recv(sock, &bytes[0], 1, 0) != 1 ||
671 recv(sock, &bytes[1], 1, 0) != 1) {
672 return -1;
673 } else {
674 int offset = bytes[0] << 8 | bytes[1];
675 if (length < offset) {
676 return -1;
677 }
678 length = offset;
679 offset = 0;
680 while (offset < length) {
681 int n = recv(sock, &message[offset], length - offset, 0);
682 if (n <= 0) {
683 return -1;
684 }
685 offset += n;
686 }
687 }
688 return length;
689}
690
691static int recv_end_of_file(int sock) {
692 uint8_t byte;
693 return recv(sock, &byte, 1, 0) == 0;
694}
695
696static void send_code(int sock, int8_t code) {
697 send(sock, &code, 1, 0);
698}
699
Kenny Root51878182012-03-13 12:53:19 -0700700static void send_message(int sock, const uint8_t* message, int length) {
Kenny Roota91203b2012-02-15 15:00:46 -0800701 uint16_t bytes = htons(length);
702 send(sock, &bytes, 2, 0);
703 send(sock, message, length, 0);
704}
705
Kenny Root70e3a862012-02-15 17:20:23 -0800706static ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName,
707 const uid_t uid) {
708 char filename[NAME_MAX];
709
710 encode_key_for_uid(filename, uid, keyName);
711 ResponseCode responseCode = keyStore->get(filename, keyBlob);
712 if (responseCode == NO_ERROR) {
713 return responseCode;
714 }
715
716 // If this is the Wifi or VPN user, they actually want system
717 // UID keys.
718 if (uid == AID_WIFI || uid == AID_VPN) {
719 encode_key_for_uid(filename, AID_SYSTEM, keyName);
720 responseCode = keyStore->get(filename, keyBlob);
721 if (responseCode == NO_ERROR) {
722 return responseCode;
723 }
724 }
725
726 // They might be using a granted key.
727 if (!keyStore->hasGrant(keyName, uid)) {
728 return responseCode;
729 }
730
731 // It is a granted key. Try to load it.
732 encode_key(filename, keyName);
733 return keyStore->get(filename, keyBlob);
734}
735
Kenny Roota91203b2012-02-15 15:00:46 -0800736/* Here are the actions. Each of them is a function without arguments. All
737 * information is defined in global variables, which are set properly before
738 * performing an action. The number of parameters required by each action is
739 * fixed and defined in a table. If the return value of an action is positive,
740 * it will be treated as a response code and transmitted to the client. Note
741 * that the lengths of parameters are checked when they are received, so
742 * boundary checks on parameters are omitted. */
743
744static const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0;
745
Kenny Root51878182012-03-13 12:53:19 -0700746static ResponseCode test(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800747 return (ResponseCode) keyStore->getState();
748}
749
Kenny Root51878182012-03-13 12:53:19 -0700750static ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800751 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800752 encode_key_for_uid(filename, uid, keyName);
Kenny Roota91203b2012-02-15 15:00:46 -0800753 Blob keyBlob;
754 ResponseCode responseCode = keyStore->get(filename, &keyBlob);
755 if (responseCode != NO_ERROR) {
756 return responseCode;
757 }
758 send_code(sock, NO_ERROR);
759 send_message(sock, keyBlob.getValue(), keyBlob.getLength());
760 return NO_ERROR_RESPONSE_CODE_SENT;
761}
762
Kenny Root51878182012-03-13 12:53:19 -0700763static ResponseCode insert(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* val,
764 Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800765 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800766 encode_key_for_uid(filename, uid, keyName);
Kenny Roota91203b2012-02-15 15:00:46 -0800767 Blob keyBlob(val->value, val->length, NULL, 0);
768 return keyStore->put(filename, &keyBlob);
769}
770
Kenny Root51878182012-03-13 12:53:19 -0700771static ResponseCode del(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800772 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800773 encode_key_for_uid(filename, uid, keyName);
Kenny Roota91203b2012-02-15 15:00:46 -0800774 return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
775}
776
Kenny Root51878182012-03-13 12:53:19 -0700777static ResponseCode exist(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800778 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800779 encode_key_for_uid(filename, uid, keyName);
Kenny Roota91203b2012-02-15 15:00:46 -0800780 if (access(filename, R_OK) == -1) {
781 return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
782 }
783 return NO_ERROR;
784}
785
Kenny Root51878182012-03-13 12:53:19 -0700786static ResponseCode saw(KeyStore* keyStore, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800787 DIR* dir = opendir(".");
788 if (!dir) {
789 return SYSTEM_ERROR;
790 }
791 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800792 int n = encode_key_for_uid(filename, uid, keyPrefix);
Kenny Roota91203b2012-02-15 15:00:46 -0800793 send_code(sock, NO_ERROR);
794
795 struct dirent* file;
796 while ((file = readdir(dir)) != NULL) {
797 if (!strncmp(filename, file->d_name, n)) {
Kenny Root51878182012-03-13 12:53:19 -0700798 const char* p = &file->d_name[n];
Kenny Roota91203b2012-02-15 15:00:46 -0800799 keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p));
800 send_message(sock, keyPrefix->value, keyPrefix->length);
801 }
802 }
803 closedir(dir);
804 return NO_ERROR_RESPONSE_CODE_SENT;
805}
806
Kenny Root51878182012-03-13 12:53:19 -0700807static ResponseCode reset(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800808 return keyStore->reset() ? NO_ERROR : SYSTEM_ERROR;
809}
810
811/* Here is the history. To improve the security, the parameters to generate the
812 * master key has been changed. To make a seamless transition, we update the
813 * file using the same password when the user unlock it for the first time. If
814 * any thing goes wrong during the transition, the new file will not overwrite
815 * the old one. This avoids permanent damages of the existing data. */
816
Kenny Root51878182012-03-13 12:53:19 -0700817static ResponseCode password(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800818 switch (keyStore->getState()) {
819 case STATE_UNINITIALIZED: {
820 // generate master key, encrypt with password, write to file, initialize mMasterKey*.
821 return keyStore->initialize(pw);
822 }
823 case STATE_NO_ERROR: {
824 // rewrite master key with new password.
825 return keyStore->writeMasterKey(pw);
826 }
827 case STATE_LOCKED: {
828 // read master key, decrypt with password, initialize mMasterKey*.
829 return keyStore->readMasterKey(pw);
830 }
831 }
832 return SYSTEM_ERROR;
833}
834
Kenny Root51878182012-03-13 12:53:19 -0700835static ResponseCode lock(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800836 keyStore->lock();
837 return NO_ERROR;
838}
839
Kenny Root51878182012-03-13 12:53:19 -0700840static ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused,
841 Value* unused2) {
842 return password(keyStore, sock, uid, pw, unused, unused2);
Kenny Roota91203b2012-02-15 15:00:46 -0800843}
844
Kenny Root51878182012-03-13 12:53:19 -0700845static ResponseCode zero(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800846 return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR;
847}
848
Kenny Root70e3a862012-02-15 17:20:23 -0800849static ResponseCode generate(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*,
850 Value*) {
851 char filename[NAME_MAX];
852 uint8_t* data;
853 size_t dataLength;
854 int rc;
Kenny Roota91203b2012-02-15 15:00:46 -0800855
Kenny Root70e3a862012-02-15 17:20:23 -0800856 const keymaster_device_t* device = keyStore->getDevice();
857 if (device == NULL) {
858 return SYSTEM_ERROR;
859 }
860
861 if (device->generate_keypair == NULL) {
862 return SYSTEM_ERROR;
863 }
864
865 keymaster_rsa_keygen_params_t rsa_params;
866 rsa_params.modulus_size = 2048;
867 rsa_params.public_exponent = 0x10001;
868
869 rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
870 if (rc) {
871 return SYSTEM_ERROR;
872 }
873
874 encode_key_for_uid(filename, uid, keyName);
875
876 Blob keyBlob(data, dataLength, NULL, 0);
877 free(data);
878
879 return keyStore->put(filename, &keyBlob);
880}
881
882static ResponseCode import(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* key,
883 Value*) {
884 char filename[NAME_MAX];
885 uint8_t* data;
886 size_t dataLength;
887 int rc;
888
889 const keymaster_device_t* device = keyStore->getDevice();
890 if (device == NULL) {
891 ALOGE("No keymaster device!");
892 return SYSTEM_ERROR;
893 }
894
895 if (device->import_keypair == NULL) {
896 ALOGE("Keymaster doesn't support import!");
897 return SYSTEM_ERROR;
898 }
899
900 rc = device->import_keypair(device, key->value, key->length, &data, &dataLength);
901 if (rc) {
902 ALOGE("Error while importing keypair: %d", rc);
903 return SYSTEM_ERROR;
904 }
905
906 encode_key_for_uid(filename, uid, keyName);
907
908 Blob keyBlob(data, dataLength, NULL, 0);
909 free(data);
910
911 return keyStore->put(filename, &keyBlob);
912}
913
914/*
915 * TODO: The abstraction between things stored in hardware and regular blobs
916 * of data stored on the filesystem should be moved down to keystore itself.
917 * Unfortunately the Java code that calls this has naming conventions that it
918 * knows about. Ideally keystore shouldn't be used to store random blobs of
919 * data.
920 *
921 * Until that happens, it's necessary to have a separate "get_pubkey" and
922 * "del_key" since the Java code doesn't really communicate what it's
923 * intentions are.
924 */
925static ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
926 Blob keyBlob;
927 ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid);
928
929 ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid);
930 if (responseCode != NO_ERROR) {
931 return responseCode;
932 }
933
934 const keymaster_device_t* device = keyStore->getDevice();
935 if (device == NULL) {
936 return SYSTEM_ERROR;
937 }
938
939 if (device->get_keypair_public == NULL) {
940 ALOGE("device has no get_keypair_public implementation!");
941 return SYSTEM_ERROR;
942 }
943
944 uint8_t* data = NULL;
945 size_t dataLength;
946
947 int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data,
948 &dataLength);
949 if (rc) {
950 return SYSTEM_ERROR;
951 }
952
953 send_code(sock, NO_ERROR);
954 send_message(sock, data, dataLength);
955 free(data);
956
957 return NO_ERROR_RESPONSE_CODE_SENT;
958}
959
960static ResponseCode del_key(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*,
961 Value*) {
962 char filename[NAME_MAX];
963 encode_key_for_uid(filename, uid, keyName);
964 Blob keyBlob;
965 ResponseCode responseCode = keyStore->get(filename, &keyBlob);
966 if (responseCode != NO_ERROR) {
967 return responseCode;
968 }
969
970 const keymaster_device_t* device = keyStore->getDevice();
971 if (device == NULL) {
972 return SYSTEM_ERROR;
973 }
974
975 if (device->delete_keypair == NULL) {
976 ALOGE("device has no delete_keypair implementation!");
977 return SYSTEM_ERROR;
978 }
979
980 uint8_t* data = NULL;
981 size_t dataLength;
982
983 int rc = device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength());
984
985 return rc ? SYSTEM_ERROR : NO_ERROR;
986}
987
988static ResponseCode sign(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data,
989 Value*) {
990 ALOGV("sign %s from uid %d", ValueString(keyName).c_str(), uid);
991 Blob keyBlob;
992 int rc;
993
994 ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid);
995 if (responseCode != NO_ERROR) {
996 return responseCode;
997 }
998
999 uint8_t* signedData;
1000 size_t signedDataLength;
1001
1002 const keymaster_device_t* device = keyStore->getDevice();
1003 if (device == NULL) {
1004 return SYSTEM_ERROR;
1005 }
1006
1007 if (device->sign_data == NULL) {
1008 return SYSTEM_ERROR;
1009 }
1010
1011 keymaster_rsa_sign_params_t params;
1012 params.digest_type = DIGEST_NONE;
1013 params.padding_type = PADDING_NONE;
1014
1015 rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1016 data->value, data->length, &signedData, &signedDataLength);
1017 if (rc) {
1018 return SYSTEM_ERROR;
1019 }
1020
1021 send_code(sock, NO_ERROR);
1022 send_message(sock, signedData, signedDataLength);
1023 return NO_ERROR_RESPONSE_CODE_SENT;
1024}
1025
1026static ResponseCode verify(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data,
1027 Value* signature) {
1028 Blob keyBlob;
1029 int rc;
1030
1031 ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid);
1032 if (responseCode != NO_ERROR) {
1033 return responseCode;
1034 }
1035
1036 const keymaster_device_t* device = keyStore->getDevice();
1037 if (device == NULL) {
1038 return SYSTEM_ERROR;
1039 }
1040
1041 if (device->verify_data == NULL) {
1042 return SYSTEM_ERROR;
1043 }
1044
1045 keymaster_rsa_sign_params_t params;
1046 params.digest_type = DIGEST_NONE;
1047 params.padding_type = PADDING_NONE;
1048
1049 rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1050 data->value, data->length, signature->value, signature->length);
1051 if (rc) {
1052 return SYSTEM_ERROR;
1053 } else {
1054 return NO_ERROR;
1055 }
1056}
1057
1058static ResponseCode grant(KeyStore* keyStore, int sock, uid_t uid, Value* keyName,
1059 Value* granteeData, Value*) {
1060 char filename[NAME_MAX];
1061 encode_key_for_uid(filename, uid, keyName);
1062 if (access(filename, R_OK) == -1) {
1063 return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
1064 }
1065
1066 keyStore->addGrant(filename, granteeData);
1067 return NO_ERROR;
1068}
1069
1070static ResponseCode ungrant(KeyStore* keyStore, int sock, uid_t uid, Value* keyName,
1071 Value* granteeData, Value*) {
1072 char filename[NAME_MAX];
1073 encode_key_for_uid(filename, uid, keyName);
1074 if (access(filename, R_OK) == -1) {
1075 return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
1076 }
1077
1078 return keyStore->removeGrant(keyName, granteeData) ? NO_ERROR : KEY_NOT_FOUND;
1079}
1080
1081/* Here are the permissions, actions, users, and the main function. */
Kenny Roota91203b2012-02-15 15:00:46 -08001082enum perm {
Kenny Root51878182012-03-13 12:53:19 -07001083 P_TEST = 1 << TEST,
1084 P_GET = 1 << GET,
1085 P_INSERT = 1 << INSERT,
1086 P_DELETE = 1 << DELETE,
1087 P_EXIST = 1 << EXIST,
1088 P_SAW = 1 << SAW,
1089 P_RESET = 1 << RESET,
1090 P_PASSWORD = 1 << PASSWORD,
1091 P_LOCK = 1 << LOCK,
1092 P_UNLOCK = 1 << UNLOCK,
1093 P_ZERO = 1 << ZERO,
Kenny Root70e3a862012-02-15 17:20:23 -08001094 P_SIGN = 1 << SIGN,
1095 P_VERIFY = 1 << VERIFY,
1096 P_GRANT = 1 << GRANT,
Kenny Roota91203b2012-02-15 15:00:46 -08001097};
1098
Kenny Root51878182012-03-13 12:53:19 -07001099static const int MAX_PARAM = 3;
Kenny Roota91203b2012-02-15 15:00:46 -08001100
1101static const State STATE_ANY = (State) 0;
1102
1103static struct action {
Kenny Root51878182012-03-13 12:53:19 -07001104 ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2,
1105 Value* param3);
Kenny Roota91203b2012-02-15 15:00:46 -08001106 int8_t code;
1107 State state;
1108 uint32_t perm;
1109 int lengths[MAX_PARAM];
1110} actions[] = {
Kenny Root51878182012-03-13 12:53:19 -07001111 {test, CommandCodes[TEST], STATE_ANY, P_TEST, {0, 0, 0}},
1112 {get, CommandCodes[GET], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}},
1113 {insert, CommandCodes[INSERT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}},
1114 {del, CommandCodes[DELETE], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}},
1115 {exist, CommandCodes[EXIST], STATE_ANY, P_EXIST, {KEY_SIZE, 0, 0}},
1116 {saw, CommandCodes[SAW], STATE_ANY, P_SAW, {KEY_SIZE, 0, 0}},
1117 {reset, CommandCodes[RESET], STATE_ANY, P_RESET, {0, 0, 0}},
1118 {password, CommandCodes[PASSWORD], STATE_ANY, P_PASSWORD, {PASSWORD_SIZE, 0, 0}},
1119 {lock, CommandCodes[LOCK], STATE_NO_ERROR, P_LOCK, {0, 0, 0}},
1120 {unlock, CommandCodes[UNLOCK], STATE_LOCKED, P_UNLOCK, {PASSWORD_SIZE, 0, 0}},
1121 {zero, CommandCodes[ZERO], STATE_ANY, P_ZERO, {0, 0, 0}},
Kenny Root70e3a862012-02-15 17:20:23 -08001122 {generate, CommandCodes[GENERATE], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, 0, 0}},
1123 {import, CommandCodes[IMPORT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}},
1124 {sign, CommandCodes[SIGN], STATE_NO_ERROR, P_SIGN, {KEY_SIZE, VALUE_SIZE, 0}},
1125 {verify, CommandCodes[VERIFY], STATE_NO_ERROR, P_VERIFY, {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}},
1126 {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}},
1127 {del_key, CommandCodes[DEL_KEY], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}},
1128 {grant, CommandCodes[GRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}},
1129 {ungrant, CommandCodes[UNGRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}},
Kenny Root51878182012-03-13 12:53:19 -07001130 {NULL, 0, STATE_ANY, 0, {0, 0, 0}},
Kenny Roota91203b2012-02-15 15:00:46 -08001131};
1132
1133static struct user {
1134 uid_t uid;
1135 uid_t euid;
1136 uint32_t perms;
1137} users[] = {
1138 {AID_SYSTEM, ~0, ~0},
Kenny Root70e3a862012-02-15 17:20:23 -08001139 {AID_VPN, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
1140 {AID_WIFI, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
Kenny Root51878182012-03-13 12:53:19 -07001141 {AID_ROOT, AID_SYSTEM, P_GET},
Kenny Root70e3a862012-02-15 17:20:23 -08001142 {~0, ~0, P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW |
1143 P_SIGN | P_VERIFY},
Kenny Roota91203b2012-02-15 15:00:46 -08001144};
1145
1146static ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) {
1147 struct user* user = users;
1148 struct action* action = actions;
1149 int i;
1150
1151 while (~user->uid && user->uid != uid) {
1152 ++user;
1153 }
1154 while (action->code && action->code != code) {
1155 ++action;
1156 }
1157 if (!action->code) {
1158 return UNDEFINED_ACTION;
1159 }
1160 if (!(action->perm & user->perms)) {
1161 return PERMISSION_DENIED;
1162 }
1163 if (action->state != STATE_ANY && action->state != keyStore->getState()) {
1164 return (ResponseCode) keyStore->getState();
1165 }
1166 if (~user->euid) {
1167 uid = user->euid;
1168 }
1169 Value params[MAX_PARAM];
1170 for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) {
1171 params[i].length = recv_message(sock, params[i].value, action->lengths[i]);
1172 if (params[i].length < 0) {
1173 return PROTOCOL_ERROR;
1174 }
1175 }
1176 if (!recv_end_of_file(sock)) {
1177 return PROTOCOL_ERROR;
1178 }
Kenny Root51878182012-03-13 12:53:19 -07001179 return action->run(keyStore, sock, uid, &params[0], &params[1], &params[2]);
Kenny Roota91203b2012-02-15 15:00:46 -08001180}
1181
1182int main(int argc, char* argv[]) {
Kenny Root70e3a862012-02-15 17:20:23 -08001183 void* hardwareContext = NULL;
1184
Kenny Roota91203b2012-02-15 15:00:46 -08001185 int controlSocket = android_get_control_socket("keystore");
1186 if (argc < 2) {
1187 ALOGE("A directory must be specified!");
1188 return 1;
1189 }
1190 if (chdir(argv[1]) == -1) {
1191 ALOGE("chdir: %s: %s", argv[1], strerror(errno));
1192 return 1;
1193 }
1194
1195 Entropy entropy;
1196 if (!entropy.open()) {
1197 return 1;
1198 }
Kenny Root70e3a862012-02-15 17:20:23 -08001199
1200 keymaster_device_t* dev;
1201 if (keymaster_device_initialize(&dev)) {
1202 ALOGE("keystore keymaster could not be initialized; exiting");
1203 return 1;
1204 }
1205
Kenny Roota91203b2012-02-15 15:00:46 -08001206 if (listen(controlSocket, 3) == -1) {
1207 ALOGE("listen: %s", strerror(errno));
1208 return 1;
1209 }
1210
1211 signal(SIGPIPE, SIG_IGN);
1212
Kenny Root70e3a862012-02-15 17:20:23 -08001213 KeyStore keyStore(&entropy, dev);
Kenny Roota91203b2012-02-15 15:00:46 -08001214 int sock;
1215 while ((sock = accept(controlSocket, NULL, 0)) != -1) {
1216 struct timeval tv;
1217 tv.tv_sec = 3;
1218 setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
1219 setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
1220
1221 struct ucred cred;
1222 socklen_t size = sizeof(cred);
1223 int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size);
1224 if (credResult != 0) {
1225 ALOGW("getsockopt: %s", strerror(errno));
1226 } else {
1227 int8_t request;
1228 if (recv_code(sock, &request)) {
1229 State old_state = keyStore.getState();
1230 ResponseCode response = process(&keyStore, sock, cred.uid, request);
1231 if (response == NO_ERROR_RESPONSE_CODE_SENT) {
1232 response = NO_ERROR;
1233 } else {
1234 send_code(sock, response);
1235 }
1236 ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d",
1237 cred.uid,
1238 request, response,
1239 old_state, keyStore.getState(),
1240 keyStore.getRetry());
1241 }
1242 }
1243 close(sock);
1244 }
1245 ALOGE("accept: %s", strerror(errno));
Kenny Root70e3a862012-02-15 17:20:23 -08001246
1247 keymaster_device_release(dev);
1248
Kenny Roota91203b2012-02-15 15:00:46 -08001249 return 1;
1250}