blob: ea58ad609aae7c9eb5363f744c2a22bbeb61eeb3 [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>
Kenny Root822c3a92012-03-23 16:34:39 -070026#include <assert.h>
Kenny Roota91203b2012-02-15 15:00:46 -080027#include <sys/types.h>
28#include <sys/socket.h>
29#include <sys/stat.h>
30#include <sys/time.h>
31#include <arpa/inet.h>
32
33#include <openssl/aes.h>
Kenny Root822c3a92012-03-23 16:34:39 -070034#include <openssl/bio.h>
Kenny Roota91203b2012-02-15 15:00:46 -080035#include <openssl/evp.h>
36#include <openssl/md5.h>
Kenny Root822c3a92012-03-23 16:34:39 -070037#include <openssl/pem.h>
Kenny Roota91203b2012-02-15 15:00:46 -080038
Kenny Root70e3a862012-02-15 17:20:23 -080039#include <hardware/keymaster.h>
40
Kenny Root822c3a92012-03-23 16:34:39 -070041#include <utils/UniquePtr.h>
42
Kenny Root70e3a862012-02-15 17:20:23 -080043#include <cutils/list.h>
44
45//#define LOG_NDEBUG 0
Kenny Roota91203b2012-02-15 15:00:46 -080046#define LOG_TAG "keystore"
47#include <cutils/log.h>
48#include <cutils/sockets.h>
49#include <private/android_filesystem_config.h>
50
51#include "keystore.h"
52
53/* KeyStore is a secured storage for key-value pairs. In this implementation,
54 * each file stores one key-value pair. Keys are encoded in file names, and
55 * values are encrypted with checksums. The encryption key is protected by a
56 * user-defined password. To keep things simple, buffers are always larger than
57 * the maximum space we needed, so boundary checks on buffers are omitted. */
58
59#define KEY_SIZE ((NAME_MAX - 15) / 2)
60#define VALUE_SIZE 32768
61#define PASSWORD_SIZE VALUE_SIZE
62
Kenny Root822c3a92012-03-23 16:34:39 -070063
64struct BIO_Delete {
65 void operator()(BIO* p) const {
66 BIO_free(p);
67 }
68};
69typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
70
71struct EVP_PKEY_Delete {
72 void operator()(EVP_PKEY* p) const {
73 EVP_PKEY_free(p);
74 }
75};
76typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
77
78struct PKCS8_PRIV_KEY_INFO_Delete {
79 void operator()(PKCS8_PRIV_KEY_INFO* p) const {
80 PKCS8_PRIV_KEY_INFO_free(p);
81 }
82};
83typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
84
85
Kenny Roota91203b2012-02-15 15:00:46 -080086struct Value {
Kenny Root822c3a92012-03-23 16:34:39 -070087 Value(const uint8_t* orig, int origLen) {
88 assert(origLen <= VALUE_SIZE);
89 memcpy(value, orig, origLen);
90 length = origLen;
91 }
92
93 Value() {
94 }
95
Kenny Roota91203b2012-02-15 15:00:46 -080096 int length;
97 uint8_t value[VALUE_SIZE];
98};
99
Kenny Root70e3a862012-02-15 17:20:23 -0800100class ValueString {
101public:
102 ValueString(const Value* orig) {
Kenny Root822c3a92012-03-23 16:34:39 -0700103 assert(length <= VALUE_SIZE);
Kenny Root70e3a862012-02-15 17:20:23 -0800104 length = orig->length;
105 value = new char[length + 1];
106 memcpy(value, orig->value, length);
107 value[length] = '\0';
108 }
109
110 ~ValueString() {
111 delete[] value;
112 }
113
114 const char* c_str() const {
115 return value;
116 }
117
118 char* release() {
119 char* ret = value;
120 value = NULL;
121 return ret;
122 }
123
124private:
125 char* value;
126 size_t length;
127};
128
129static int keymaster_device_initialize(keymaster_device_t** dev) {
130 int rc;
131
132 const hw_module_t* mod;
133 rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
134 if (rc) {
135 ALOGE("could not find any keystore module");
136 goto out;
137 }
138
139 rc = keymaster_open(mod, dev);
140 if (rc) {
141 ALOGE("could not open keymaster device in %s (%s)",
142 KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
143 goto out;
144 }
145
146 return 0;
147
148out:
149 *dev = NULL;
150 return rc;
151}
152
153static void keymaster_device_release(keymaster_device_t* dev) {
154 keymaster_close(dev);
155}
156
Kenny Roota91203b2012-02-15 15:00:46 -0800157/* Here is the encoding of keys. This is necessary in order to allow arbitrary
158 * characters in keys. Characters in [0-~] are not encoded. Others are encoded
159 * into two bytes. The first byte is one of [+-.] which represents the first
160 * two bits of the character. The second byte encodes the rest of the bits into
161 * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
162 * that Base64 cannot be used here due to the need of prefix match on keys. */
163
Kenny Root70e3a862012-02-15 17:20:23 -0800164static int encode_key(char* out, const Value* key) {
Kenny Roota91203b2012-02-15 15:00:46 -0800165 const uint8_t* in = key->value;
166 int length = key->length;
167 for (int i = length; i > 0; --i, ++in, ++out) {
168 if (*in >= '0' && *in <= '~') {
169 *out = *in;
170 } else {
171 *out = '+' + (*in >> 6);
172 *++out = '0' + (*in & 0x3F);
173 ++length;
174 }
175 }
176 *out = '\0';
Kenny Root70e3a862012-02-15 17:20:23 -0800177 return length;
178}
179
180static int encode_key_for_uid(char* out, uid_t uid, const Value* key) {
181 int n = snprintf(out, NAME_MAX, "%u_", uid);
182 out += n;
183
184 return n + encode_key(out, key);
Kenny Roota91203b2012-02-15 15:00:46 -0800185}
186
Kenny Root51878182012-03-13 12:53:19 -0700187static int decode_key(uint8_t* out, const char* in, int length) {
Kenny Roota91203b2012-02-15 15:00:46 -0800188 for (int i = 0; i < length; ++i, ++in, ++out) {
189 if (*in >= '0' && *in <= '~') {
190 *out = *in;
191 } else {
192 *out = (*in - '+') << 6;
193 *out |= (*++in - '0') & 0x3F;
194 --length;
195 }
196 }
197 *out = '\0';
198 return length;
199}
200
201static size_t readFully(int fd, uint8_t* data, size_t size) {
202 size_t remaining = size;
203 while (remaining > 0) {
204 ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size));
205 if (n == -1 || n == 0) {
206 return size-remaining;
207 }
208 data += n;
209 remaining -= n;
210 }
211 return size;
212}
213
214static size_t writeFully(int fd, uint8_t* data, size_t size) {
215 size_t remaining = size;
216 while (remaining > 0) {
217 ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size));
218 if (n == -1 || n == 0) {
219 return size-remaining;
220 }
221 data += n;
222 remaining -= n;
223 }
224 return size;
225}
226
227class Entropy {
228public:
229 Entropy() : mRandom(-1) {}
230 ~Entropy() {
231 if (mRandom != -1) {
232 close(mRandom);
233 }
234 }
235
236 bool open() {
237 const char* randomDevice = "/dev/urandom";
238 mRandom = ::open(randomDevice, O_RDONLY);
239 if (mRandom == -1) {
240 ALOGE("open: %s: %s", randomDevice, strerror(errno));
241 return false;
242 }
243 return true;
244 }
245
Kenny Root51878182012-03-13 12:53:19 -0700246 bool generate_random_data(uint8_t* data, size_t size) const {
Kenny Roota91203b2012-02-15 15:00:46 -0800247 return (readFully(mRandom, data, size) == size);
248 }
249
250private:
251 int mRandom;
252};
253
254/* Here is the file format. There are two parts in blob.value, the secret and
255 * the description. The secret is stored in ciphertext, and its original size
256 * can be found in blob.length. The description is stored after the secret in
257 * plaintext, and its size is specified in blob.info. The total size of the two
Kenny Root822c3a92012-03-23 16:34:39 -0700258 * parts must be no more than VALUE_SIZE bytes. The first field is the version,
259 * the second is the blob's type, and the third byte is reserved. Fields other
Kenny Roota91203b2012-02-15 15:00:46 -0800260 * than blob.info, blob.length, and blob.value are modified by encryptBlob()
261 * and decryptBlob(). Thus they should not be accessed from outside. */
262
Kenny Root822c3a92012-03-23 16:34:39 -0700263/* ** Note to future implementors of encryption: **
264 * Currently this is the construction:
265 * metadata || Enc(MD5(data) || data)
266 *
267 * This should be the construction used for encrypting if re-implementing:
268 *
269 * Derive independent keys for encryption and MAC:
270 * Kenc = AES_encrypt(masterKey, "Encrypt")
271 * Kmac = AES_encrypt(masterKey, "MAC")
272 *
273 * Store this:
274 * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
275 * HMAC(Kmac, metadata || Enc(data))
276 */
Kenny Roota91203b2012-02-15 15:00:46 -0800277struct __attribute__((packed)) blob {
Kenny Root822c3a92012-03-23 16:34:39 -0700278 uint8_t version;
279 uint8_t type;
280 uint8_t reserved;
Kenny Roota91203b2012-02-15 15:00:46 -0800281 uint8_t info;
282 uint8_t vector[AES_BLOCK_SIZE];
Kenny Root822c3a92012-03-23 16:34:39 -0700283 uint8_t encrypted[0]; // Marks offset to encrypted data.
Kenny Roota91203b2012-02-15 15:00:46 -0800284 uint8_t digest[MD5_DIGEST_LENGTH];
Kenny Root822c3a92012-03-23 16:34:39 -0700285 uint8_t digested[0]; // Marks offset to digested data.
Kenny Roota91203b2012-02-15 15:00:46 -0800286 int32_t length; // in network byte order when encrypted
287 uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
288};
289
Kenny Root822c3a92012-03-23 16:34:39 -0700290typedef enum {
291 TYPE_GENERIC = 1,
292 TYPE_MASTER_KEY = 2,
293 TYPE_KEY_PAIR = 3,
294} BlobType;
295
296static const uint8_t CurrentBlobVersion = 1;
297
Kenny Roota91203b2012-02-15 15:00:46 -0800298class Blob {
299public:
Kenny Root822c3a92012-03-23 16:34:39 -0700300 Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength, BlobType type) {
Kenny Roota91203b2012-02-15 15:00:46 -0800301 mBlob.length = valueLength;
302 memcpy(mBlob.value, value, valueLength);
303
304 mBlob.info = infoLength;
305 memcpy(mBlob.value + valueLength, info, infoLength);
Kenny Root822c3a92012-03-23 16:34:39 -0700306
307 mBlob.version = CurrentBlobVersion;
308 mBlob.type = uint8_t(type);
Kenny Roota91203b2012-02-15 15:00:46 -0800309 }
310
311 Blob(blob b) {
312 mBlob = b;
313 }
314
315 Blob() {}
316
Kenny Root51878182012-03-13 12:53:19 -0700317 const uint8_t* getValue() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800318 return mBlob.value;
319 }
320
Kenny Root51878182012-03-13 12:53:19 -0700321 int32_t getLength() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800322 return mBlob.length;
323 }
324
Kenny Root51878182012-03-13 12:53:19 -0700325 const uint8_t* getInfo() const {
326 return mBlob.value + mBlob.length;
327 }
328
329 uint8_t getInfoLength() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800330 return mBlob.info;
331 }
332
Kenny Root822c3a92012-03-23 16:34:39 -0700333 uint8_t getVersion() const {
334 return mBlob.version;
335 }
336
337 void setVersion(uint8_t version) {
338 mBlob.version = version;
339 }
340
341 BlobType getType() const {
342 return BlobType(mBlob.type);
343 }
344
345 void setType(BlobType type) {
346 mBlob.type = uint8_t(type);
347 }
348
Kenny Roota91203b2012-02-15 15:00:46 -0800349 ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) {
350 if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
351 return SYSTEM_ERROR;
352 }
353
354 // data includes the value and the value's length
355 size_t dataLength = mBlob.length + sizeof(mBlob.length);
356 // pad data to the AES_BLOCK_SIZE
357 size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
358 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
359 // encrypted data includes the digest value
360 size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
361 // move info after space for padding
362 memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
363 // zero padding area
364 memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
365
366 mBlob.length = htonl(mBlob.length);
367 MD5(mBlob.digested, digestedLength, mBlob.digest);
368
369 uint8_t vector[AES_BLOCK_SIZE];
370 memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
371 AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
372 aes_key, vector, AES_ENCRYPT);
373
Kenny Root822c3a92012-03-23 16:34:39 -0700374 mBlob.reserved = 0;
Kenny Roota91203b2012-02-15 15:00:46 -0800375 size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
376 size_t fileLength = encryptedLength + headerLength + mBlob.info;
377
378 const char* tmpFileName = ".tmp";
379 int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
380 if (out == -1) {
381 return SYSTEM_ERROR;
382 }
383 size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
384 if (close(out) != 0) {
385 return SYSTEM_ERROR;
386 }
387 if (writtenBytes != fileLength) {
388 unlink(tmpFileName);
389 return SYSTEM_ERROR;
390 }
391 return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR;
392 }
393
394 ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
395 int in = open(filename, O_RDONLY);
396 if (in == -1) {
397 return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
398 }
399 // fileLength may be less than sizeof(mBlob) since the in
400 // memory version has extra padding to tolerate rounding up to
401 // the AES_BLOCK_SIZE
402 size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
403 if (close(in) != 0) {
404 return SYSTEM_ERROR;
405 }
406 size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
407 if (fileLength < headerLength) {
408 return VALUE_CORRUPTED;
409 }
410
411 ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
412 if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) {
413 return VALUE_CORRUPTED;
414 }
415 AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
416 mBlob.vector, AES_DECRYPT);
417 size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
418 uint8_t computedDigest[MD5_DIGEST_LENGTH];
419 MD5(mBlob.digested, digestedLength, computedDigest);
420 if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
421 return VALUE_CORRUPTED;
422 }
423
424 ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
425 mBlob.length = ntohl(mBlob.length);
426 if (mBlob.length < 0 || mBlob.length > maxValueLength) {
427 return VALUE_CORRUPTED;
428 }
429 if (mBlob.info != 0) {
430 // move info from after padding to after data
431 memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
432 }
433 return NO_ERROR;
434 }
435
436private:
437 struct blob mBlob;
438};
439
Kenny Root70e3a862012-02-15 17:20:23 -0800440typedef struct {
441 uint32_t uid;
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700442 const uint8_t* filename;
Kenny Root70e3a862012-02-15 17:20:23 -0800443
444 struct listnode plist;
445} grant_t;
446
Kenny Roota91203b2012-02-15 15:00:46 -0800447class KeyStore {
448public:
Kenny Root70e3a862012-02-15 17:20:23 -0800449 KeyStore(Entropy* entropy, keymaster_device_t* device)
Kenny Root51878182012-03-13 12:53:19 -0700450 : mEntropy(entropy)
Kenny Root70e3a862012-02-15 17:20:23 -0800451 , mDevice(device)
Kenny Root51878182012-03-13 12:53:19 -0700452 , mRetry(MAX_RETRY)
453 {
Kenny Roota91203b2012-02-15 15:00:46 -0800454 if (access(MASTER_KEY_FILE, R_OK) == 0) {
455 setState(STATE_LOCKED);
456 } else {
457 setState(STATE_UNINITIALIZED);
458 }
Kenny Root70e3a862012-02-15 17:20:23 -0800459
460 list_init(&mGrants);
Kenny Roota91203b2012-02-15 15:00:46 -0800461 }
462
Kenny Root51878182012-03-13 12:53:19 -0700463 State getState() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800464 return mState;
465 }
466
Kenny Root51878182012-03-13 12:53:19 -0700467 int8_t getRetry() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800468 return mRetry;
469 }
470
Kenny Root70e3a862012-02-15 17:20:23 -0800471 keymaster_device_t* getDevice() const {
472 return mDevice;
473 }
474
Kenny Roota91203b2012-02-15 15:00:46 -0800475 ResponseCode initialize(Value* pw) {
476 if (!generateMasterKey()) {
477 return SYSTEM_ERROR;
478 }
479 ResponseCode response = writeMasterKey(pw);
480 if (response != NO_ERROR) {
481 return response;
482 }
483 setupMasterKeys();
484 return NO_ERROR;
485 }
486
487 ResponseCode writeMasterKey(Value* pw) {
488 uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
489 generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
490 AES_KEY passwordAesKey;
491 AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
Kenny Root822c3a92012-03-23 16:34:39 -0700492 Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
Kenny Roota91203b2012-02-15 15:00:46 -0800493 return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
494 }
495
496 ResponseCode readMasterKey(Value* pw) {
497 int in = open(MASTER_KEY_FILE, O_RDONLY);
498 if (in == -1) {
499 return SYSTEM_ERROR;
500 }
501
502 // we read the raw blob to just to get the salt to generate
503 // the AES key, then we create the Blob to use with decryptBlob
504 blob rawBlob;
505 size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
506 if (close(in) != 0) {
507 return SYSTEM_ERROR;
508 }
509 // find salt at EOF if present, otherwise we have an old file
510 uint8_t* salt;
511 if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
512 salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
513 } else {
514 salt = NULL;
515 }
516 uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
517 generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
518 AES_KEY passwordAesKey;
519 AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
520 Blob masterKeyBlob(rawBlob);
521 ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
522 if (response == SYSTEM_ERROR) {
523 return SYSTEM_ERROR;
524 }
525 if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
526 // if salt was missing, generate one and write a new master key file with the salt.
527 if (salt == NULL) {
528 if (!generateSalt()) {
529 return SYSTEM_ERROR;
530 }
531 response = writeMasterKey(pw);
532 }
533 if (response == NO_ERROR) {
534 memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
535 setupMasterKeys();
536 }
537 return response;
538 }
539 if (mRetry <= 0) {
540 reset();
541 return UNINITIALIZED;
542 }
543 --mRetry;
544 switch (mRetry) {
545 case 0: return WRONG_PASSWORD_0;
546 case 1: return WRONG_PASSWORD_1;
547 case 2: return WRONG_PASSWORD_2;
548 case 3: return WRONG_PASSWORD_3;
549 default: return WRONG_PASSWORD_3;
550 }
551 }
552
553 bool reset() {
554 clearMasterKeys();
555 setState(STATE_UNINITIALIZED);
556
557 DIR* dir = opendir(".");
558 struct dirent* file;
559
560 if (!dir) {
561 return false;
562 }
563 while ((file = readdir(dir)) != NULL) {
564 unlink(file->d_name);
565 }
566 closedir(dir);
567 return true;
568 }
569
Kenny Root51878182012-03-13 12:53:19 -0700570 bool isEmpty() const {
Kenny Roota91203b2012-02-15 15:00:46 -0800571 DIR* dir = opendir(".");
572 struct dirent* file;
573 if (!dir) {
574 return true;
575 }
576 bool result = true;
577 while ((file = readdir(dir)) != NULL) {
578 if (isKeyFile(file->d_name)) {
579 result = false;
580 break;
581 }
582 }
583 closedir(dir);
584 return result;
585 }
586
587 void lock() {
588 clearMasterKeys();
589 setState(STATE_LOCKED);
590 }
591
Kenny Root822c3a92012-03-23 16:34:39 -0700592 ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) {
593 ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
594 if (rc != NO_ERROR) {
595 return rc;
596 }
597
598 const uint8_t version = keyBlob->getVersion();
599 if (version < CurrentBlobVersion) {
600 upgrade(filename, keyBlob, version, type);
601 }
602
603 if (keyBlob->getType() != type) {
604 ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
605 return KEY_NOT_FOUND;
606 }
607
608 return rc;
Kenny Roota91203b2012-02-15 15:00:46 -0800609 }
610
611 ResponseCode put(const char* filename, Blob* keyBlob) {
612 return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
613 }
614
Kenny Root70e3a862012-02-15 17:20:23 -0800615 void addGrant(const char* filename, const Value* uidValue) {
616 uid_t uid;
617 if (!convertToUid(uidValue, &uid)) {
618 return;
619 }
620
621 grant_t *grant = getGrant(filename, uid);
622 if (grant == NULL) {
623 grant = new grant_t;
624 grant->uid = uid;
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700625 grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
Kenny Root70e3a862012-02-15 17:20:23 -0800626 list_add_tail(&mGrants, &grant->plist);
627 }
628 }
629
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700630 bool removeGrant(const char* filename, const Value* uidValue) {
Kenny Root70e3a862012-02-15 17:20:23 -0800631 uid_t uid;
632 if (!convertToUid(uidValue, &uid)) {
633 return false;
634 }
635
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700636 grant_t *grant = getGrant(filename, uid);
Kenny Root70e3a862012-02-15 17:20:23 -0800637 if (grant != NULL) {
638 list_remove(&grant->plist);
639 delete grant;
640 return true;
641 }
642
643 return false;
644 }
645
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700646 bool hasGrant(const char* filename, const uid_t uid) const {
647 return getGrant(filename, uid) != NULL;
Kenny Root70e3a862012-02-15 17:20:23 -0800648 }
649
Kenny Root822c3a92012-03-23 16:34:39 -0700650 ResponseCode importKey(const Value* key, const char* filename) {
651 uint8_t* data;
652 size_t dataLength;
653 int rc;
654
655 if (mDevice->import_keypair == NULL) {
656 ALOGE("Keymaster doesn't support import!");
657 return SYSTEM_ERROR;
658 }
659
660 rc = mDevice->import_keypair(mDevice, key->value, key->length, &data, &dataLength);
661 if (rc) {
662 ALOGE("Error while importing keypair: %d", rc);
663 return SYSTEM_ERROR;
664 }
665
666 Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
667 free(data);
668
669 return put(filename, &keyBlob);
670 }
671
Kenny Roota91203b2012-02-15 15:00:46 -0800672private:
673 static const char* MASTER_KEY_FILE;
674 static const int MASTER_KEY_SIZE_BYTES = 16;
675 static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
676
677 static const int MAX_RETRY = 4;
678 static const size_t SALT_SIZE = 16;
679
680 Entropy* mEntropy;
681
Kenny Root70e3a862012-02-15 17:20:23 -0800682 keymaster_device_t* mDevice;
683
Kenny Roota91203b2012-02-15 15:00:46 -0800684 State mState;
685 int8_t mRetry;
686
687 uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
688 uint8_t mSalt[SALT_SIZE];
689
690 AES_KEY mMasterKeyEncryption;
691 AES_KEY mMasterKeyDecryption;
692
Kenny Root70e3a862012-02-15 17:20:23 -0800693 struct listnode mGrants;
694
Kenny Roota91203b2012-02-15 15:00:46 -0800695 void setState(State state) {
696 mState = state;
697 if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
698 mRetry = MAX_RETRY;
699 }
700 }
701
702 bool generateSalt() {
703 return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
704 }
705
706 bool generateMasterKey() {
707 if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
708 return false;
709 }
710 if (!generateSalt()) {
711 return false;
712 }
713 return true;
714 }
715
716 void setupMasterKeys() {
717 AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
718 AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
719 setState(STATE_NO_ERROR);
720 }
721
722 void clearMasterKeys() {
723 memset(mMasterKey, 0, sizeof(mMasterKey));
724 memset(mSalt, 0, sizeof(mSalt));
725 memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
726 memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
727 }
728
729 static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) {
730 size_t saltSize;
731 if (salt != NULL) {
732 saltSize = SALT_SIZE;
733 } else {
734 // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
735 salt = (uint8_t*) "keystore";
736 // sizeof = 9, not strlen = 8
737 saltSize = sizeof("keystore");
738 }
739 PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key);
740 }
741
742 static bool isKeyFile(const char* filename) {
743 return ((strcmp(filename, MASTER_KEY_FILE) != 0)
744 && (strcmp(filename, ".") != 0)
745 && (strcmp(filename, "..") != 0));
746 }
Kenny Root70e3a862012-02-15 17:20:23 -0800747
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700748 grant_t* getGrant(const char* filename, uid_t uid) const {
Kenny Root70e3a862012-02-15 17:20:23 -0800749 struct listnode *node;
750 grant_t *grant;
751
752 list_for_each(node, &mGrants) {
753 grant = node_to_item(node, grant_t, plist);
754 if (grant->uid == uid
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700755 && !strcmp(reinterpret_cast<const char*>(grant->filename),
756 filename)) {
Kenny Root70e3a862012-02-15 17:20:23 -0800757 return grant;
758 }
759 }
760
761 return NULL;
762 }
763
764 bool convertToUid(const Value* uidValue, uid_t* uid) const {
765 ValueString uidString(uidValue);
766 char* end = NULL;
767 *uid = strtol(uidString.c_str(), &end, 10);
768 return *end == '\0';
769 }
Kenny Root822c3a92012-03-23 16:34:39 -0700770
771 /**
772 * Upgrade code. This will upgrade the key from the current version
773 * to whatever is newest.
774 */
775 void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) {
776 bool updated = false;
777 uint8_t version = oldVersion;
778
779 /* From V0 -> V1: All old types were unknown */
780 if (version == 0) {
781 ALOGV("upgrading to version 1 and setting type %d", type);
782
783 blob->setType(type);
784 if (type == TYPE_KEY_PAIR) {
785 importBlobAsKey(blob, filename);
786 }
787 version = 1;
788 updated = true;
789 }
790
791 /*
792 * If we've updated, set the key blob to the right version
793 * and write it.
794 * */
795 if (updated) {
796 ALOGV("updated and writing file %s", filename);
797 blob->setVersion(version);
798 this->put(filename, blob);
799 }
800 }
801
802 /**
803 * Takes a blob that is an PEM-encoded RSA key as a byte array and
804 * converts it to a DER-encoded PKCS#8 for import into a keymaster.
805 * Then it overwrites the original blob with the new blob
806 * format that is returned from the keymaster.
807 */
808 ResponseCode importBlobAsKey(Blob* blob, const char* filename) {
809 // We won't even write to the blob directly with this BIO, so const_cast is okay.
810 Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
811 if (b.get() == NULL) {
812 ALOGE("Problem instantiating BIO");
813 return SYSTEM_ERROR;
814 }
815
816 Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
817 if (pkey.get() == NULL) {
818 ALOGE("Couldn't read old PEM file");
819 return SYSTEM_ERROR;
820 }
821
822 Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
823 int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
824 if (len < 0) {
825 ALOGE("Couldn't measure PKCS#8 length");
826 return SYSTEM_ERROR;
827 }
828
829 Value pkcs8key;
830 pkcs8key.length = len;
831 uint8_t* tmp = pkcs8key.value;
832 if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
833 ALOGE("Couldn't convert to PKCS#8");
834 return SYSTEM_ERROR;
835 }
836
837 ResponseCode rc = importKey(&pkcs8key, filename);
838 if (rc != NO_ERROR) {
839 return rc;
840 }
841
842 return get(filename, blob, TYPE_KEY_PAIR);
843 }
Kenny Roota91203b2012-02-15 15:00:46 -0800844};
845
846const char* KeyStore::MASTER_KEY_FILE = ".masterkey";
847
848/* Here is the protocol used in both requests and responses:
849 * code [length_1 message_1 ... length_n message_n] end-of-file
850 * where code is one byte long and lengths are unsigned 16-bit integers in
851 * network order. Thus the maximum length of a message is 65535 bytes. */
852
853static int recv_code(int sock, int8_t* code) {
854 return recv(sock, code, 1, 0) == 1;
855}
856
857static int recv_message(int sock, uint8_t* message, int length) {
858 uint8_t bytes[2];
859 if (recv(sock, &bytes[0], 1, 0) != 1 ||
860 recv(sock, &bytes[1], 1, 0) != 1) {
861 return -1;
862 } else {
863 int offset = bytes[0] << 8 | bytes[1];
864 if (length < offset) {
865 return -1;
866 }
867 length = offset;
868 offset = 0;
869 while (offset < length) {
870 int n = recv(sock, &message[offset], length - offset, 0);
871 if (n <= 0) {
872 return -1;
873 }
874 offset += n;
875 }
876 }
877 return length;
878}
879
880static int recv_end_of_file(int sock) {
881 uint8_t byte;
882 return recv(sock, &byte, 1, 0) == 0;
883}
884
885static void send_code(int sock, int8_t code) {
886 send(sock, &code, 1, 0);
887}
888
Kenny Root51878182012-03-13 12:53:19 -0700889static void send_message(int sock, const uint8_t* message, int length) {
Kenny Roota91203b2012-02-15 15:00:46 -0800890 uint16_t bytes = htons(length);
891 send(sock, &bytes, 2, 0);
892 send(sock, message, length, 0);
893}
894
Kenny Root70e3a862012-02-15 17:20:23 -0800895static ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName,
Kenny Root822c3a92012-03-23 16:34:39 -0700896 const uid_t uid, const BlobType type) {
Kenny Root70e3a862012-02-15 17:20:23 -0800897 char filename[NAME_MAX];
898
899 encode_key_for_uid(filename, uid, keyName);
Kenny Root822c3a92012-03-23 16:34:39 -0700900 ResponseCode responseCode = keyStore->get(filename, keyBlob, type);
Kenny Root70e3a862012-02-15 17:20:23 -0800901 if (responseCode == NO_ERROR) {
902 return responseCode;
903 }
904
905 // If this is the Wifi or VPN user, they actually want system
906 // UID keys.
907 if (uid == AID_WIFI || uid == AID_VPN) {
908 encode_key_for_uid(filename, AID_SYSTEM, keyName);
Kenny Root822c3a92012-03-23 16:34:39 -0700909 responseCode = keyStore->get(filename, keyBlob, type);
Kenny Root70e3a862012-02-15 17:20:23 -0800910 if (responseCode == NO_ERROR) {
911 return responseCode;
912 }
913 }
914
915 // They might be using a granted key.
Brian Carlstroma8c703d2012-07-17 14:43:46 -0700916 encode_key(filename, keyName);
917 if (!keyStore->hasGrant(filename, uid)) {
Kenny Root70e3a862012-02-15 17:20:23 -0800918 return responseCode;
919 }
920
921 // It is a granted key. Try to load it.
Kenny Root822c3a92012-03-23 16:34:39 -0700922 return keyStore->get(filename, keyBlob, type);
Kenny Root70e3a862012-02-15 17:20:23 -0800923}
924
Kenny Roota91203b2012-02-15 15:00:46 -0800925/* Here are the actions. Each of them is a function without arguments. All
926 * information is defined in global variables, which are set properly before
927 * performing an action. The number of parameters required by each action is
928 * fixed and defined in a table. If the return value of an action is positive,
929 * it will be treated as a response code and transmitted to the client. Note
930 * that the lengths of parameters are checked when they are received, so
931 * boundary checks on parameters are omitted. */
932
933static const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0;
934
Kenny Rootda1ed9a2012-04-10 12:34:07 -0700935static ResponseCode test(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800936 return (ResponseCode) keyStore->getState();
937}
938
Kenny Root51878182012-03-13 12:53:19 -0700939static ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800940 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800941 encode_key_for_uid(filename, uid, keyName);
Kenny Roota91203b2012-02-15 15:00:46 -0800942 Blob keyBlob;
Kenny Root822c3a92012-03-23 16:34:39 -0700943 ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC);
Kenny Roota91203b2012-02-15 15:00:46 -0800944 if (responseCode != NO_ERROR) {
945 return responseCode;
946 }
947 send_code(sock, NO_ERROR);
948 send_message(sock, keyBlob.getValue(), keyBlob.getLength());
949 return NO_ERROR_RESPONSE_CODE_SENT;
950}
951
Kenny Rootda1ed9a2012-04-10 12:34:07 -0700952static ResponseCode insert(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* val,
Kenny Root51878182012-03-13 12:53:19 -0700953 Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800954 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800955 encode_key_for_uid(filename, uid, keyName);
Kenny Root822c3a92012-03-23 16:34:39 -0700956 Blob keyBlob(val->value, val->length, NULL, 0, TYPE_GENERIC);
Kenny Roota91203b2012-02-15 15:00:46 -0800957 return keyStore->put(filename, &keyBlob);
958}
959
Kenny Rootda1ed9a2012-04-10 12:34:07 -0700960static ResponseCode del(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800961 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800962 encode_key_for_uid(filename, uid, keyName);
Kenny Root822c3a92012-03-23 16:34:39 -0700963 Blob keyBlob;
964 ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC);
965 if (responseCode != NO_ERROR) {
966 return responseCode;
967 }
Kenny Roota91203b2012-02-15 15:00:46 -0800968 return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
969}
970
Kenny Rootda1ed9a2012-04-10 12:34:07 -0700971static ResponseCode exist(KeyStore*, int, uid_t uid, Value* keyName, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800972 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800973 encode_key_for_uid(filename, uid, keyName);
Kenny Roota91203b2012-02-15 15:00:46 -0800974 if (access(filename, R_OK) == -1) {
975 return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
976 }
977 return NO_ERROR;
978}
979
Kenny Rootda1ed9a2012-04-10 12:34:07 -0700980static ResponseCode saw(KeyStore*, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -0800981 DIR* dir = opendir(".");
982 if (!dir) {
983 return SYSTEM_ERROR;
984 }
985 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -0800986 int n = encode_key_for_uid(filename, uid, keyPrefix);
Kenny Roota91203b2012-02-15 15:00:46 -0800987 send_code(sock, NO_ERROR);
988
989 struct dirent* file;
990 while ((file = readdir(dir)) != NULL) {
991 if (!strncmp(filename, file->d_name, n)) {
Kenny Root51878182012-03-13 12:53:19 -0700992 const char* p = &file->d_name[n];
Kenny Roota91203b2012-02-15 15:00:46 -0800993 keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p));
994 send_message(sock, keyPrefix->value, keyPrefix->length);
995 }
996 }
997 closedir(dir);
998 return NO_ERROR_RESPONSE_CODE_SENT;
999}
1000
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001001static ResponseCode reset(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
Kenny Root298e7b12012-03-26 13:54:44 -07001002 ResponseCode rc = keyStore->reset() ? NO_ERROR : SYSTEM_ERROR;
1003
1004 const keymaster_device_t* device = keyStore->getDevice();
1005 if (device == NULL) {
1006 ALOGE("No keymaster device!");
1007 return SYSTEM_ERROR;
1008 }
1009
1010 if (device->delete_all == NULL) {
1011 ALOGV("keymaster device doesn't implement delete_all");
1012 return rc;
1013 }
1014
1015 if (device->delete_all(device)) {
1016 ALOGE("Problem calling keymaster's delete_all");
1017 return SYSTEM_ERROR;
1018 }
1019
1020 return rc;
Kenny Roota91203b2012-02-15 15:00:46 -08001021}
1022
1023/* Here is the history. To improve the security, the parameters to generate the
1024 * master key has been changed. To make a seamless transition, we update the
1025 * file using the same password when the user unlock it for the first time. If
1026 * any thing goes wrong during the transition, the new file will not overwrite
1027 * the old one. This avoids permanent damages of the existing data. */
1028
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001029static ResponseCode password(KeyStore* keyStore, int, uid_t, Value* pw, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -08001030 switch (keyStore->getState()) {
1031 case STATE_UNINITIALIZED: {
1032 // generate master key, encrypt with password, write to file, initialize mMasterKey*.
1033 return keyStore->initialize(pw);
1034 }
1035 case STATE_NO_ERROR: {
1036 // rewrite master key with new password.
1037 return keyStore->writeMasterKey(pw);
1038 }
1039 case STATE_LOCKED: {
1040 // read master key, decrypt with password, initialize mMasterKey*.
1041 return keyStore->readMasterKey(pw);
1042 }
1043 }
1044 return SYSTEM_ERROR;
1045}
1046
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001047static ResponseCode lock(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -08001048 keyStore->lock();
1049 return NO_ERROR;
1050}
1051
Kenny Root51878182012-03-13 12:53:19 -07001052static ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused,
1053 Value* unused2) {
1054 return password(keyStore, sock, uid, pw, unused, unused2);
Kenny Roota91203b2012-02-15 15:00:46 -08001055}
1056
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001057static ResponseCode zero(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
Kenny Roota91203b2012-02-15 15:00:46 -08001058 return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR;
1059}
1060
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001061static ResponseCode generate(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*,
Kenny Root70e3a862012-02-15 17:20:23 -08001062 Value*) {
1063 char filename[NAME_MAX];
1064 uint8_t* data;
1065 size_t dataLength;
1066 int rc;
Kenny Roota91203b2012-02-15 15:00:46 -08001067
Kenny Root70e3a862012-02-15 17:20:23 -08001068 const keymaster_device_t* device = keyStore->getDevice();
1069 if (device == NULL) {
1070 return SYSTEM_ERROR;
1071 }
1072
1073 if (device->generate_keypair == NULL) {
1074 return SYSTEM_ERROR;
1075 }
1076
1077 keymaster_rsa_keygen_params_t rsa_params;
1078 rsa_params.modulus_size = 2048;
1079 rsa_params.public_exponent = 0x10001;
1080
1081 rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
1082 if (rc) {
1083 return SYSTEM_ERROR;
1084 }
1085
1086 encode_key_for_uid(filename, uid, keyName);
1087
Kenny Root822c3a92012-03-23 16:34:39 -07001088 Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
Kenny Root70e3a862012-02-15 17:20:23 -08001089 free(data);
1090
1091 return keyStore->put(filename, &keyBlob);
1092}
1093
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001094static ResponseCode import(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* key,
Kenny Root70e3a862012-02-15 17:20:23 -08001095 Value*) {
1096 char filename[NAME_MAX];
Kenny Root70e3a862012-02-15 17:20:23 -08001097
1098 encode_key_for_uid(filename, uid, keyName);
1099
Kenny Root822c3a92012-03-23 16:34:39 -07001100 return keyStore->importKey(key, filename);
Kenny Root70e3a862012-02-15 17:20:23 -08001101}
1102
1103/*
1104 * TODO: The abstraction between things stored in hardware and regular blobs
1105 * of data stored on the filesystem should be moved down to keystore itself.
1106 * Unfortunately the Java code that calls this has naming conventions that it
1107 * knows about. Ideally keystore shouldn't be used to store random blobs of
1108 * data.
1109 *
1110 * Until that happens, it's necessary to have a separate "get_pubkey" and
1111 * "del_key" since the Java code doesn't really communicate what it's
1112 * intentions are.
1113 */
1114static ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
1115 Blob keyBlob;
1116 ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid);
1117
Kenny Root822c3a92012-03-23 16:34:39 -07001118 ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
Kenny Root70e3a862012-02-15 17:20:23 -08001119 if (responseCode != NO_ERROR) {
1120 return responseCode;
1121 }
1122
1123 const keymaster_device_t* device = keyStore->getDevice();
1124 if (device == NULL) {
1125 return SYSTEM_ERROR;
1126 }
1127
1128 if (device->get_keypair_public == NULL) {
1129 ALOGE("device has no get_keypair_public implementation!");
1130 return SYSTEM_ERROR;
1131 }
1132
1133 uint8_t* data = NULL;
1134 size_t dataLength;
1135
1136 int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data,
1137 &dataLength);
1138 if (rc) {
1139 return SYSTEM_ERROR;
1140 }
1141
1142 send_code(sock, NO_ERROR);
1143 send_message(sock, data, dataLength);
1144 free(data);
1145
1146 return NO_ERROR_RESPONSE_CODE_SENT;
1147}
1148
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001149static ResponseCode del_key(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*,
Kenny Root70e3a862012-02-15 17:20:23 -08001150 Value*) {
1151 char filename[NAME_MAX];
1152 encode_key_for_uid(filename, uid, keyName);
1153 Blob keyBlob;
Kenny Root822c3a92012-03-23 16:34:39 -07001154 ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_KEY_PAIR);
Kenny Root70e3a862012-02-15 17:20:23 -08001155 if (responseCode != NO_ERROR) {
1156 return responseCode;
1157 }
1158
Kenny Root9a53d3e2012-08-14 10:47:54 -07001159 ResponseCode rc = NO_ERROR;
1160
Kenny Root70e3a862012-02-15 17:20:23 -08001161 const keymaster_device_t* device = keyStore->getDevice();
1162 if (device == NULL) {
Kenny Root9a53d3e2012-08-14 10:47:54 -07001163 rc = SYSTEM_ERROR;
1164 } else {
1165 // A device doesn't have to implement delete_keypair.
1166 if (device->delete_keypair != NULL) {
1167 if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
1168 rc = SYSTEM_ERROR;
1169 }
1170 }
Kenny Root70e3a862012-02-15 17:20:23 -08001171 }
1172
Kenny Root9a53d3e2012-08-14 10:47:54 -07001173 if (rc != NO_ERROR) {
1174 return rc;
Kenny Root70e3a862012-02-15 17:20:23 -08001175 }
1176
Kenny Root9a53d3e2012-08-14 10:47:54 -07001177 return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
Kenny Root70e3a862012-02-15 17:20:23 -08001178}
1179
1180static ResponseCode sign(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data,
1181 Value*) {
1182 ALOGV("sign %s from uid %d", ValueString(keyName).c_str(), uid);
1183 Blob keyBlob;
1184 int rc;
1185
Kenny Root822c3a92012-03-23 16:34:39 -07001186 ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
Kenny Root70e3a862012-02-15 17:20:23 -08001187 if (responseCode != NO_ERROR) {
1188 return responseCode;
1189 }
1190
1191 uint8_t* signedData;
1192 size_t signedDataLength;
1193
1194 const keymaster_device_t* device = keyStore->getDevice();
1195 if (device == NULL) {
Kenny Root822c3a92012-03-23 16:34:39 -07001196 ALOGE("no keymaster device; cannot sign");
Kenny Root70e3a862012-02-15 17:20:23 -08001197 return SYSTEM_ERROR;
1198 }
1199
1200 if (device->sign_data == NULL) {
Kenny Root822c3a92012-03-23 16:34:39 -07001201 ALOGE("device doesn't implement signing");
Kenny Root70e3a862012-02-15 17:20:23 -08001202 return SYSTEM_ERROR;
1203 }
1204
1205 keymaster_rsa_sign_params_t params;
1206 params.digest_type = DIGEST_NONE;
1207 params.padding_type = PADDING_NONE;
1208
1209 rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1210 data->value, data->length, &signedData, &signedDataLength);
1211 if (rc) {
Kenny Root822c3a92012-03-23 16:34:39 -07001212 ALOGW("device couldn't sign data");
Kenny Root70e3a862012-02-15 17:20:23 -08001213 return SYSTEM_ERROR;
1214 }
1215
1216 send_code(sock, NO_ERROR);
1217 send_message(sock, signedData, signedDataLength);
1218 return NO_ERROR_RESPONSE_CODE_SENT;
1219}
1220
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001221static ResponseCode verify(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* data,
Kenny Root70e3a862012-02-15 17:20:23 -08001222 Value* signature) {
1223 Blob keyBlob;
1224 int rc;
1225
Kenny Root822c3a92012-03-23 16:34:39 -07001226 ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
Kenny Root70e3a862012-02-15 17:20:23 -08001227 if (responseCode != NO_ERROR) {
1228 return responseCode;
1229 }
1230
1231 const keymaster_device_t* device = keyStore->getDevice();
1232 if (device == NULL) {
1233 return SYSTEM_ERROR;
1234 }
1235
1236 if (device->verify_data == NULL) {
1237 return SYSTEM_ERROR;
1238 }
1239
1240 keymaster_rsa_sign_params_t params;
1241 params.digest_type = DIGEST_NONE;
1242 params.padding_type = PADDING_NONE;
1243
1244 rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
1245 data->value, data->length, signature->value, signature->length);
1246 if (rc) {
1247 return SYSTEM_ERROR;
1248 } else {
1249 return NO_ERROR;
1250 }
1251}
1252
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001253static ResponseCode grant(KeyStore* keyStore, int, uid_t uid, Value* keyName,
Kenny Root70e3a862012-02-15 17:20:23 -08001254 Value* granteeData, Value*) {
1255 char filename[NAME_MAX];
1256 encode_key_for_uid(filename, uid, keyName);
1257 if (access(filename, R_OK) == -1) {
1258 return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
1259 }
1260
1261 keyStore->addGrant(filename, granteeData);
1262 return NO_ERROR;
1263}
1264
Kenny Rootda1ed9a2012-04-10 12:34:07 -07001265static ResponseCode ungrant(KeyStore* keyStore, int, uid_t uid, Value* keyName,
Kenny Root70e3a862012-02-15 17:20:23 -08001266 Value* granteeData, Value*) {
1267 char filename[NAME_MAX];
1268 encode_key_for_uid(filename, uid, keyName);
1269 if (access(filename, R_OK) == -1) {
1270 return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
1271 }
1272
Brian Carlstroma8c703d2012-07-17 14:43:46 -07001273 return keyStore->removeGrant(filename, granteeData) ? NO_ERROR : KEY_NOT_FOUND;
Kenny Root70e3a862012-02-15 17:20:23 -08001274}
1275
Kenny Root344e0bc2012-08-15 10:44:03 -07001276static ResponseCode getmtime(KeyStore*, int sock, uid_t uid, Value* keyName,
1277 Value*, Value*) {
1278 char filename[NAME_MAX];
1279 encode_key_for_uid(filename, uid, keyName);
1280 if (access(filename, R_OK) == -1) {
1281 return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
1282 }
1283
1284 int fd = open(filename, O_NOFOLLOW, O_RDONLY);
1285 if (fd < 0) {
1286 return SYSTEM_ERROR;
1287 }
1288
1289 struct stat s;
1290 int ret = fstat(fd, &s);
1291 close(fd);
1292 if (ret == -1) {
1293 return SYSTEM_ERROR;
1294 }
1295
1296 uint8_t *data;
1297 int dataLength = asprintf(reinterpret_cast<char**>(&data), "%lu", s.st_mtime);
1298 if (dataLength < 0) {
1299 return SYSTEM_ERROR;
1300 }
1301
1302 send_code(sock, NO_ERROR);
1303 send_message(sock, data, dataLength);
1304 free(data);
1305
1306 return NO_ERROR_RESPONSE_CODE_SENT;
1307}
1308
Kenny Root70e3a862012-02-15 17:20:23 -08001309/* Here are the permissions, actions, users, and the main function. */
Kenny Roota91203b2012-02-15 15:00:46 -08001310enum perm {
Kenny Root51878182012-03-13 12:53:19 -07001311 P_TEST = 1 << TEST,
1312 P_GET = 1 << GET,
1313 P_INSERT = 1 << INSERT,
1314 P_DELETE = 1 << DELETE,
1315 P_EXIST = 1 << EXIST,
1316 P_SAW = 1 << SAW,
1317 P_RESET = 1 << RESET,
1318 P_PASSWORD = 1 << PASSWORD,
1319 P_LOCK = 1 << LOCK,
1320 P_UNLOCK = 1 << UNLOCK,
1321 P_ZERO = 1 << ZERO,
Kenny Root70e3a862012-02-15 17:20:23 -08001322 P_SIGN = 1 << SIGN,
1323 P_VERIFY = 1 << VERIFY,
1324 P_GRANT = 1 << GRANT,
Kenny Roota91203b2012-02-15 15:00:46 -08001325};
1326
Kenny Root51878182012-03-13 12:53:19 -07001327static const int MAX_PARAM = 3;
Kenny Roota91203b2012-02-15 15:00:46 -08001328
1329static const State STATE_ANY = (State) 0;
1330
1331static struct action {
Kenny Root51878182012-03-13 12:53:19 -07001332 ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2,
1333 Value* param3);
Pavel Chupinc3cb8512012-09-14 10:47:46 +04001334 uint8_t code;
Kenny Roota91203b2012-02-15 15:00:46 -08001335 State state;
1336 uint32_t perm;
1337 int lengths[MAX_PARAM];
1338} actions[] = {
Kenny Root51878182012-03-13 12:53:19 -07001339 {test, CommandCodes[TEST], STATE_ANY, P_TEST, {0, 0, 0}},
1340 {get, CommandCodes[GET], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}},
1341 {insert, CommandCodes[INSERT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}},
1342 {del, CommandCodes[DELETE], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}},
1343 {exist, CommandCodes[EXIST], STATE_ANY, P_EXIST, {KEY_SIZE, 0, 0}},
1344 {saw, CommandCodes[SAW], STATE_ANY, P_SAW, {KEY_SIZE, 0, 0}},
1345 {reset, CommandCodes[RESET], STATE_ANY, P_RESET, {0, 0, 0}},
1346 {password, CommandCodes[PASSWORD], STATE_ANY, P_PASSWORD, {PASSWORD_SIZE, 0, 0}},
1347 {lock, CommandCodes[LOCK], STATE_NO_ERROR, P_LOCK, {0, 0, 0}},
1348 {unlock, CommandCodes[UNLOCK], STATE_LOCKED, P_UNLOCK, {PASSWORD_SIZE, 0, 0}},
1349 {zero, CommandCodes[ZERO], STATE_ANY, P_ZERO, {0, 0, 0}},
Kenny Root70e3a862012-02-15 17:20:23 -08001350 {generate, CommandCodes[GENERATE], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, 0, 0}},
1351 {import, CommandCodes[IMPORT], STATE_NO_ERROR, P_INSERT, {KEY_SIZE, VALUE_SIZE, 0}},
1352 {sign, CommandCodes[SIGN], STATE_NO_ERROR, P_SIGN, {KEY_SIZE, VALUE_SIZE, 0}},
1353 {verify, CommandCodes[VERIFY], STATE_NO_ERROR, P_VERIFY, {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}},
1354 {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET, {KEY_SIZE, 0, 0}},
1355 {del_key, CommandCodes[DEL_KEY], STATE_ANY, P_DELETE, {KEY_SIZE, 0, 0}},
1356 {grant, CommandCodes[GRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}},
1357 {ungrant, CommandCodes[UNGRANT], STATE_NO_ERROR, P_GRANT, {KEY_SIZE, KEY_SIZE, 0}},
Kenny Root344e0bc2012-08-15 10:44:03 -07001358 {getmtime, CommandCodes[GETMTIME], STATE_ANY, P_SAW, {KEY_SIZE, 0, 0}},
Kenny Root51878182012-03-13 12:53:19 -07001359 {NULL, 0, STATE_ANY, 0, {0, 0, 0}},
Kenny Roota91203b2012-02-15 15:00:46 -08001360};
1361
1362static struct user {
1363 uid_t uid;
1364 uid_t euid;
1365 uint32_t perms;
1366} users[] = {
Pavel Chupinc3cb8512012-09-14 10:47:46 +04001367 {AID_SYSTEM, (uid_t)(~0), (uint32_t)(~0)},
1368 {AID_VPN, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
1369 {AID_WIFI, AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
1370 {AID_ROOT, AID_SYSTEM, P_GET},
1371 {(uid_t)(~0), (uid_t)(~0), P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW |
Kenny Root70e3a862012-02-15 17:20:23 -08001372 P_SIGN | P_VERIFY},
Kenny Roota91203b2012-02-15 15:00:46 -08001373};
1374
1375static ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) {
1376 struct user* user = users;
1377 struct action* action = actions;
1378 int i;
1379
Amith Yamasanie95ce352012-04-06 18:35:36 -07001380 while (~user->uid && user->uid != (uid % AID_USER)) {
Kenny Roota91203b2012-02-15 15:00:46 -08001381 ++user;
1382 }
1383 while (action->code && action->code != code) {
1384 ++action;
1385 }
1386 if (!action->code) {
1387 return UNDEFINED_ACTION;
1388 }
1389 if (!(action->perm & user->perms)) {
1390 return PERMISSION_DENIED;
1391 }
1392 if (action->state != STATE_ANY && action->state != keyStore->getState()) {
1393 return (ResponseCode) keyStore->getState();
1394 }
1395 if (~user->euid) {
1396 uid = user->euid;
1397 }
1398 Value params[MAX_PARAM];
1399 for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) {
1400 params[i].length = recv_message(sock, params[i].value, action->lengths[i]);
1401 if (params[i].length < 0) {
1402 return PROTOCOL_ERROR;
1403 }
1404 }
1405 if (!recv_end_of_file(sock)) {
1406 return PROTOCOL_ERROR;
1407 }
Kenny Root51878182012-03-13 12:53:19 -07001408 return action->run(keyStore, sock, uid, &params[0], &params[1], &params[2]);
Kenny Roota91203b2012-02-15 15:00:46 -08001409}
1410
1411int main(int argc, char* argv[]) {
1412 int controlSocket = android_get_control_socket("keystore");
1413 if (argc < 2) {
1414 ALOGE("A directory must be specified!");
1415 return 1;
1416 }
1417 if (chdir(argv[1]) == -1) {
1418 ALOGE("chdir: %s: %s", argv[1], strerror(errno));
1419 return 1;
1420 }
1421
1422 Entropy entropy;
1423 if (!entropy.open()) {
1424 return 1;
1425 }
Kenny Root70e3a862012-02-15 17:20:23 -08001426
1427 keymaster_device_t* dev;
1428 if (keymaster_device_initialize(&dev)) {
1429 ALOGE("keystore keymaster could not be initialized; exiting");
1430 return 1;
1431 }
1432
Kenny Roota91203b2012-02-15 15:00:46 -08001433 if (listen(controlSocket, 3) == -1) {
1434 ALOGE("listen: %s", strerror(errno));
1435 return 1;
1436 }
1437
1438 signal(SIGPIPE, SIG_IGN);
1439
Kenny Root70e3a862012-02-15 17:20:23 -08001440 KeyStore keyStore(&entropy, dev);
Kenny Roota91203b2012-02-15 15:00:46 -08001441 int sock;
1442 while ((sock = accept(controlSocket, NULL, 0)) != -1) {
1443 struct timeval tv;
1444 tv.tv_sec = 3;
1445 setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
1446 setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
1447
1448 struct ucred cred;
1449 socklen_t size = sizeof(cred);
1450 int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size);
1451 if (credResult != 0) {
1452 ALOGW("getsockopt: %s", strerror(errno));
1453 } else {
1454 int8_t request;
1455 if (recv_code(sock, &request)) {
1456 State old_state = keyStore.getState();
1457 ResponseCode response = process(&keyStore, sock, cred.uid, request);
1458 if (response == NO_ERROR_RESPONSE_CODE_SENT) {
1459 response = NO_ERROR;
1460 } else {
1461 send_code(sock, response);
1462 }
1463 ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d",
1464 cred.uid,
1465 request, response,
1466 old_state, keyStore.getState(),
1467 keyStore.getRetry());
1468 }
1469 }
1470 close(sock);
1471 }
1472 ALOGE("accept: %s", strerror(errno));
Kenny Root70e3a862012-02-15 17:20:23 -08001473
1474 keymaster_device_release(dev);
1475
Kenny Roota91203b2012-02-15 15:00:46 -08001476 return 1;
1477}