keystore.cpp 75.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

Kenny Root's avatar
Kenny Root committed
17 18 19
//#define LOG_NDEBUG 0
#define LOG_TAG "keystore"

20 21 22 23 24 25 26
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <dirent.h>
Kenny Root's avatar
Kenny Root committed
27
#include <errno.h>
28 29
#include <fcntl.h>
#include <limits.h>
30
#include <assert.h>
31 32 33 34 35 36 37
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <arpa/inet.h>

#include <openssl/aes.h>
38
#include <openssl/bio.h>
39 40
#include <openssl/evp.h>
#include <openssl/md5.h>
41
#include <openssl/pem.h>
42

43 44
#include <hardware/keymaster.h>

45 46
#include <keymaster/softkeymaster.h>

Kenny Root's avatar
Kenny Root committed
47
#include <UniquePtr.h>
Kenny Root's avatar
Kenny Root committed
48 49
#include <utils/String8.h>
#include <utils/Vector.h>
50

Kenny Root's avatar
Kenny Root committed
51 52 53 54
#include <keystore/IKeystoreService.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>

55 56 57 58
#include <cutils/log.h>
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>

Kenny Root's avatar
Kenny Root committed
59
#include <keystore/keystore.h>
60

61 62
#include "defaults.h"

63 64 65 66 67 68 69 70 71 72
/* KeyStore is a secured storage for key-value pairs. In this implementation,
 * each file stores one key-value pair. Keys are encoded in file names, and
 * values are encrypted with checksums. The encryption key is protected by a
 * user-defined password. To keep things simple, buffers are always larger than
 * the maximum space we needed, so boundary checks on buffers are omitted. */

#define KEY_SIZE        ((NAME_MAX - 15) / 2)
#define VALUE_SIZE      32768
#define PASSWORD_SIZE   VALUE_SIZE

73

74 75 76 77 78 79 80
struct BIGNUM_Delete {
    void operator()(BIGNUM* p) const {
        BN_free(p);
    }
};
typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;

81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
struct BIO_Delete {
    void operator()(BIO* p) const {
        BIO_free(p);
    }
};
typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;

struct EVP_PKEY_Delete {
    void operator()(EVP_PKEY* p) const {
        EVP_PKEY_free(p);
    }
};
typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;

struct PKCS8_PRIV_KEY_INFO_Delete {
    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
        PKCS8_PRIV_KEY_INFO_free(p);
    }
};
typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;


103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
static int keymaster_device_initialize(keymaster_device_t** dev) {
    int rc;

    const hw_module_t* mod;
    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
    if (rc) {
        ALOGE("could not find any keystore module");
        goto out;
    }

    rc = keymaster_open(mod, dev);
    if (rc) {
        ALOGE("could not open keymaster device in %s (%s)",
            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
        goto out;
    }

    return 0;

out:
    *dev = NULL;
    return rc;
}

static void keymaster_device_release(keymaster_device_t* dev) {
    keymaster_close(dev);
}

Kenny Root's avatar
Kenny Root committed
131 132 133 134 135 136
/***************
 * PERMISSIONS *
 ***************/

/* Here are the permissions, actions, users, and the main function. */
typedef enum {
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
    P_TEST      = 1 << 0,
    P_GET       = 1 << 1,
    P_INSERT    = 1 << 2,
    P_DELETE    = 1 << 3,
    P_EXIST     = 1 << 4,
    P_SAW       = 1 << 5,
    P_RESET     = 1 << 6,
    P_PASSWORD  = 1 << 7,
    P_LOCK      = 1 << 8,
    P_UNLOCK    = 1 << 9,
    P_ZERO      = 1 << 10,
    P_SIGN      = 1 << 11,
    P_VERIFY    = 1 << 12,
    P_GRANT     = 1 << 13,
    P_DUPLICATE = 1 << 14,
152
    P_CLEAR_UID = 1 << 15,
Kenny Root's avatar
Kenny Root committed
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
} perm_t;

static struct user_euid {
    uid_t uid;
    uid_t euid;
} user_euids[] = {
    {AID_VPN, AID_SYSTEM},
    {AID_WIFI, AID_SYSTEM},
    {AID_ROOT, AID_SYSTEM},
};

static struct user_perm {
    uid_t uid;
    perm_t perms;
} user_perms[] = {
    {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) },
    {AID_VPN,    static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
    {AID_WIFI,   static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
    {AID_ROOT,   static_cast<perm_t>(P_GET) },
};

static const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN
        | P_VERIFY);

Kenny Root's avatar
Kenny Root committed
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
/**
 * Returns the app ID (in the Android multi-user sense) for the current
 * UNIX UID.
 */
static uid_t get_app_id(uid_t uid) {
    return uid % AID_USER;
}

/**
 * Returns the user ID (in the Android multi-user sense) for the current
 * UNIX UID.
 */
static uid_t get_user_id(uid_t uid) {
    return uid / AID_USER;
}


Kenny Root's avatar
Kenny Root committed
194
static bool has_permission(uid_t uid, perm_t perm) {
Kenny Root's avatar
Kenny Root committed
195 196 197 198 199
    // All system users are equivalent for multi-user support.
    if (get_app_id(uid) == AID_SYSTEM) {
        uid = AID_SYSTEM;
    }

Kenny Root's avatar
Kenny Root committed
200 201 202 203 204 205 206 207 208 209
    for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) {
        struct user_perm user = user_perms[i];
        if (user.uid == uid) {
            return user.perms & perm;
        }
    }

    return DEFAULT_PERMS & perm;
}

210 211 212 213 214
/**
 * Returns the UID that the callingUid should act as. This is here for
 * legacy support of the WiFi and VPN systems and should be removed
 * when WiFi can operate in its own namespace.
 */
Kenny Root's avatar
Kenny Root committed
215 216 217 218 219 220 221 222 223 224 225
static uid_t get_keystore_euid(uid_t uid) {
    for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
        struct user_euid user = user_euids[i];
        if (user.uid == uid) {
            return user.euid;
        }
    }

    return uid;
}

226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
/**
 * Returns true if the callingUid is allowed to interact in the targetUid's
 * namespace.
 */
static bool is_granted_to(uid_t callingUid, uid_t targetUid) {
    for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
        struct user_euid user = user_euids[i];
        if (user.euid == callingUid && user.uid == targetUid) {
            return true;
        }
    }

    return false;
}

241 242 243 244 245 246 247
/* Here is the encoding of keys. This is necessary in order to allow arbitrary
 * characters in keys. Characters in [0-~] are not encoded. Others are encoded
 * into two bytes. The first byte is one of [+-.] which represents the first
 * two bits of the character. The second byte encodes the rest of the bits into
 * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
 * that Base64 cannot be used here due to the need of prefix match on keys. */

Kenny Root's avatar
Kenny Root committed
248 249 250 251 252 253 254 255 256 257 258
static size_t encode_key_length(const android::String8& keyName) {
    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
    size_t length = keyName.length();
    for (int i = length; i > 0; --i, ++in) {
        if (*in < '0' || *in > '~') {
            ++length;
        }
    }
    return length;
}

Kenny Root's avatar
Kenny Root committed
259 260 261
static int encode_key(char* out, const android::String8& keyName) {
    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
    size_t length = keyName.length();
262
    for (int i = length; i > 0; --i, ++in, ++out) {
Kenny Root's avatar
Kenny Root committed
263
        if (*in < '0' || *in > '~') {
264 265 266
            *out = '+' + (*in >> 6);
            *++out = '0' + (*in & 0x3F);
            ++length;
Kenny Root's avatar
Kenny Root committed
267 268
        } else {
            *out = *in;
269 270 271
        }
    }
    *out = '\0';
272 273 274
    return length;
}

Kenny Root's avatar
Kenny Root committed
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
/*
 * Converts from the "escaped" format on disk to actual name.
 * This will be smaller than the input string.
 *
 * Characters that should combine with the next at the end will be truncated.
 */
static size_t decode_key_length(const char* in, size_t length) {
    size_t outLength = 0;

    for (const char* end = in + length; in < end; in++) {
        /* This combines with the next character. */
        if (*in < '0' || *in > '~') {
            continue;
        }

        outLength++;
    }
    return outLength;
}

static void decode_key(char* out, const char* in, size_t length) {
    for (const char* end = in + length; in < end; in++) {
        if (*in < '0' || *in > '~') {
            /* Truncate combining characters at the end. */
            if (in + 1 >= end) {
                break;
            }

            *out = (*in++ - '+') << 6;
            *out++ |= (*in - '0') & 0x3F;
305
        } else {
Kenny Root's avatar
Kenny Root committed
306
            *out++ = *in;
307 308 309 310 311 312 313 314
        }
    }
    *out = '\0';
}

static size_t readFully(int fd, uint8_t* data, size_t size) {
    size_t remaining = size;
    while (remaining > 0) {
315
        ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining));
Kenny Root's avatar
Kenny Root committed
316
        if (n <= 0) {
317
            return size - remaining;
318 319 320 321 322 323 324 325 326 327
        }
        data += n;
        remaining -= n;
    }
    return size;
}

static size_t writeFully(int fd, uint8_t* data, size_t size) {
    size_t remaining = size;
    while (remaining > 0) {
328 329 330 331
        ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining));
        if (n < 0) {
            ALOGW("write failed: %s", strerror(errno));
            return size - remaining;
332 333 334 335 336 337 338 339 340 341 342
        }
        data += n;
        remaining -= n;
    }
    return size;
}

class Entropy {
public:
    Entropy() : mRandom(-1) {}
    ~Entropy() {
343
        if (mRandom >= 0) {
344 345 346 347 348 349
            close(mRandom);
        }
    }

    bool open() {
        const char* randomDevice = "/dev/urandom";
350 351
        mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY));
        if (mRandom < 0) {
352 353 354 355 356 357
            ALOGE("open: %s: %s", randomDevice, strerror(errno));
            return false;
        }
        return true;
    }

Kenny Root's avatar
Kenny Root committed
358
    bool generate_random_data(uint8_t* data, size_t size) const {
359 360 361 362 363 364 365 366 367 368 369
        return (readFully(mRandom, data, size) == size);
    }

private:
    int mRandom;
};

/* Here is the file format. There are two parts in blob.value, the secret and
 * the description. The secret is stored in ciphertext, and its original size
 * can be found in blob.length. The description is stored after the secret in
 * plaintext, and its size is specified in blob.info. The total size of the two
370
 * parts must be no more than VALUE_SIZE bytes. The first field is the version,
371
 * the second is the blob's type, and the third byte is flags. Fields other
372 373 374
 * than blob.info, blob.length, and blob.value are modified by encryptBlob()
 * and decryptBlob(). Thus they should not be accessed from outside. */

375 376 377 378 379 380 381 382 383 384 385 386 387 388
/* ** Note to future implementors of encryption: **
 * Currently this is the construction:
 *   metadata || Enc(MD5(data) || data)
 *
 * This should be the construction used for encrypting if re-implementing:
 *
 *   Derive independent keys for encryption and MAC:
 *     Kenc = AES_encrypt(masterKey, "Encrypt")
 *     Kmac = AES_encrypt(masterKey, "MAC")
 *
 *   Store this:
 *     metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
 *             HMAC(Kmac, metadata || Enc(data))
 */
389
struct __attribute__((packed)) blob {
390 391
    uint8_t version;
    uint8_t type;
392
    uint8_t flags;
393 394
    uint8_t info;
    uint8_t vector[AES_BLOCK_SIZE];
395
    uint8_t encrypted[0]; // Marks offset to encrypted data.
396
    uint8_t digest[MD5_DIGEST_LENGTH];
397
    uint8_t digested[0]; // Marks offset to digested data.
398 399 400 401
    int32_t length; // in network byte order when encrypted
    uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
};

402
typedef enum {
403
    TYPE_ANY = 0, // meta type that matches anything
404 405 406 407 408
    TYPE_GENERIC = 1,
    TYPE_MASTER_KEY = 2,
    TYPE_KEY_PAIR = 3,
} BlobType;

409
static const uint8_t CURRENT_BLOB_VERSION = 2;
410

411 412
class Blob {
public:
Kenny Root's avatar
Kenny Root committed
413 414
    Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength,
            BlobType type) {
415 416 417 418 419
        mBlob.length = valueLength;
        memcpy(mBlob.value, value, valueLength);

        mBlob.info = infoLength;
        memcpy(mBlob.value + valueLength, info, infoLength);
420

Kenny Root's avatar
Kenny Root committed
421
        mBlob.version = CURRENT_BLOB_VERSION;
422
        mBlob.type = uint8_t(type);
423

424 425 426 427 428
        if (type == TYPE_MASTER_KEY) {
            mBlob.flags = KEYSTORE_FLAG_ENCRYPTED;
        } else {
            mBlob.flags = KEYSTORE_FLAG_NONE;
        }
429 430 431 432 433 434 435 436
    }

    Blob(blob b) {
        mBlob = b;
    }

    Blob() {}

Kenny Root's avatar
Kenny Root committed
437
    const uint8_t* getValue() const {
438 439 440
        return mBlob.value;
    }

Kenny Root's avatar
Kenny Root committed
441
    int32_t getLength() const {
442 443 444
        return mBlob.length;
    }

Kenny Root's avatar
Kenny Root committed
445 446 447 448 449
    const uint8_t* getInfo() const {
        return mBlob.value + mBlob.length;
    }

    uint8_t getInfoLength() const {
450 451 452
        return mBlob.info;
    }

453 454 455 456
    uint8_t getVersion() const {
        return mBlob.version;
    }

457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
    bool isEncrypted() const {
        if (mBlob.version < 2) {
            return true;
        }

        return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED;
    }

    void setEncrypted(bool encrypted) {
        if (encrypted) {
            mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED;
        } else {
            mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED;
        }
    }

473 474 475 476 477 478 479 480 481 482 483 484
    bool isFallback() const {
        return mBlob.flags & KEYSTORE_FLAG_FALLBACK;
    }

    void setFallback(bool fallback) {
        if (fallback) {
            mBlob.flags |= KEYSTORE_FLAG_FALLBACK;
        } else {
            mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK;
        }
    }

485 486 487 488 489 490 491 492 493 494 495 496
    void setVersion(uint8_t version) {
        mBlob.version = version;
    }

    BlobType getType() const {
        return BlobType(mBlob.type);
    }

    void setType(BlobType type) {
        mBlob.type = uint8_t(type);
    }

497 498 499 500 501 502 503 504 505 506 507 508
    ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) {
        ALOGV("writing blob %s", filename);
        if (isEncrypted()) {
            if (state != STATE_NO_ERROR) {
                ALOGD("couldn't insert encrypted blob while not unlocked");
                return LOCKED;
            }

            if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
                ALOGW("Could not read random data for: %s", filename);
                return SYSTEM_ERROR;
            }
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
        }

        // data includes the value and the value's length
        size_t dataLength = mBlob.length + sizeof(mBlob.length);
        // pad data to the AES_BLOCK_SIZE
        size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
                                 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
        // encrypted data includes the digest value
        size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
        // move info after space for padding
        memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
        // zero padding area
        memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);

        mBlob.length = htonl(mBlob.length);

525 526 527 528 529 530 531 532
        if (isEncrypted()) {
            MD5(mBlob.digested, digestedLength, mBlob.digest);

            uint8_t vector[AES_BLOCK_SIZE];
            memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
            AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
                            aes_key, vector, AES_ENCRYPT);
        }
533 534 535 536 537

        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
        size_t fileLength = encryptedLength + headerLength + mBlob.info;

        const char* tmpFileName = ".tmp";
538 539 540 541
        int out = TEMP_FAILURE_RETRY(open(tmpFileName,
                O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
        if (out < 0) {
            ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno));
542 543 544 545 546 547 548
            return SYSTEM_ERROR;
        }
        size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
        if (close(out) != 0) {
            return SYSTEM_ERROR;
        }
        if (writtenBytes != fileLength) {
549
            ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
550 551 552
            unlink(tmpFileName);
            return SYSTEM_ERROR;
        }
553 554 555 556 557
        if (rename(tmpFileName, filename) == -1) {
            ALOGW("could not rename blob to %s: %s", filename, strerror(errno));
            return SYSTEM_ERROR;
        }
        return NO_ERROR;
558 559
    }

560 561
    ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) {
        ALOGV("reading blob %s", filename);
562 563
        int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
        if (in < 0) {
564 565 566 567 568 569 570 571 572
            return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
        }
        // fileLength may be less than sizeof(mBlob) since the in
        // memory version has extra padding to tolerate rounding up to
        // the AES_BLOCK_SIZE
        size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
        if (close(in) != 0) {
            return SYSTEM_ERROR;
        }
573 574 575 576 577

        if (isEncrypted() && (state != STATE_NO_ERROR)) {
            return LOCKED;
        }

578 579 580 581 582 583
        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
        if (fileLength < headerLength) {
            return VALUE_CORRUPTED;
        }

        ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
584
        if (encryptedLength < 0) {
585 586
            return VALUE_CORRUPTED;
        }
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603

        ssize_t digestedLength;
        if (isEncrypted()) {
            if (encryptedLength % AES_BLOCK_SIZE != 0) {
                return VALUE_CORRUPTED;
            }

            AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
                            mBlob.vector, AES_DECRYPT);
            digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
            uint8_t computedDigest[MD5_DIGEST_LENGTH];
            MD5(mBlob.digested, digestedLength, computedDigest);
            if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
                return VALUE_CORRUPTED;
            }
        } else {
            digestedLength = encryptedLength;
604 605 606 607 608 609 610 611 612 613 614
        }

        ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
        mBlob.length = ntohl(mBlob.length);
        if (mBlob.length < 0 || mBlob.length > maxValueLength) {
            return VALUE_CORRUPTED;
        }
        if (mBlob.info != 0) {
            // move info from after padding to after data
            memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
        }
Kenny Root's avatar
Kenny Root committed
615
        return ::NO_ERROR;
616 617 618 619 620 621
    }

private:
    struct blob mBlob;
};

Kenny Root's avatar
Kenny Root committed
622 623 624 625 626 627
class UserState {
public:
    UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) {
        asprintf(&mUserDir, "user_%u", mUserId);
        asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir);
    }
628

Kenny Root's avatar
Kenny Root committed
629 630 631 632
    ~UserState() {
        free(mUserDir);
        free(mMasterKeyFile);
    }
633

Kenny Root's avatar
Kenny Root committed
634 635 636 637 638 639 640
    bool initialize() {
        if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) {
            ALOGE("Could not create directory '%s'", mUserDir);
            return false;
        }

        if (access(mMasterKeyFile, R_OK) == 0) {
641 642 643 644
            setState(STATE_LOCKED);
        } else {
            setState(STATE_UNINITIALIZED);
        }
645

Kenny Root's avatar
Kenny Root committed
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
        return true;
    }

    uid_t getUserId() const {
        return mUserId;
    }

    const char* getUserDirName() const {
        return mUserDir;
    }

    const char* getMasterKeyFileName() const {
        return mMasterKeyFile;
    }

    void setState(State state) {
        mState = state;
        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
            mRetry = MAX_RETRY;
        }
666 667
    }

Kenny Root's avatar
Kenny Root committed
668
    State getState() const {
669 670 671
        return mState;
    }

Kenny Root's avatar
Kenny Root committed
672
    int8_t getRetry() const {
673 674 675
        return mRetry;
    }

Kenny Root's avatar
Kenny Root committed
676 677 678 679 680
    void zeroizeMasterKeysInMemory() {
        memset(mMasterKey, 0, sizeof(mMasterKey));
        memset(mSalt, 0, sizeof(mSalt));
        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
681 682
    }

Kenny Root's avatar
Kenny Root committed
683 684
    ResponseCode initialize(const android::String8& pw, Entropy* entropy) {
        if (!generateMasterKey(entropy)) {
685 686
            return SYSTEM_ERROR;
        }
Kenny Root's avatar
Kenny Root committed
687
        ResponseCode response = writeMasterKey(pw, entropy);
688 689 690 691
        if (response != NO_ERROR) {
            return response;
        }
        setupMasterKeys();
Kenny Root's avatar
Kenny Root committed
692
        return ::NO_ERROR;
693 694
    }

Kenny Root's avatar
Kenny Root committed
695
    ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) {
696 697 698 699
        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
        AES_KEY passwordAesKey;
        AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
700
        Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
701
        return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy);
702 703
    }

Kenny Root's avatar
Kenny Root committed
704 705
    ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) {
        int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
706
        if (in < 0) {
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
            return SYSTEM_ERROR;
        }

        // we read the raw blob to just to get the salt to generate
        // the AES key, then we create the Blob to use with decryptBlob
        blob rawBlob;
        size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
        if (close(in) != 0) {
            return SYSTEM_ERROR;
        }
        // find salt at EOF if present, otherwise we have an old file
        uint8_t* salt;
        if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
            salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
        } else {
            salt = NULL;
        }
        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
        AES_KEY passwordAesKey;
        AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
        Blob masterKeyBlob(rawBlob);
729 730
        ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey,
                STATE_NO_ERROR);
731
        if (response == SYSTEM_ERROR) {
732
            return response;
733 734 735 736
        }
        if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
            // if salt was missing, generate one and write a new master key file with the salt.
            if (salt == NULL) {
Kenny Root's avatar
Kenny Root committed
737
                if (!generateSalt(entropy)) {
738 739
                    return SYSTEM_ERROR;
                }
Kenny Root's avatar
Kenny Root committed
740
                response = writeMasterKey(pw, entropy);
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
            }
            if (response == NO_ERROR) {
                memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
                setupMasterKeys();
            }
            return response;
        }
        if (mRetry <= 0) {
            reset();
            return UNINITIALIZED;
        }
        --mRetry;
        switch (mRetry) {
            case 0: return WRONG_PASSWORD_0;
            case 1: return WRONG_PASSWORD_1;
            case 2: return WRONG_PASSWORD_2;
            case 3: return WRONG_PASSWORD_3;
            default: return WRONG_PASSWORD_3;
        }
    }

Kenny Root's avatar
Kenny Root committed
762 763 764
    AES_KEY* getEncryptionKey() {
        return &mMasterKeyEncryption;
    }
765

Kenny Root's avatar
Kenny Root committed
766 767 768
    AES_KEY* getDecryptionKey() {
        return &mMasterKeyDecryption;
    }
769

Kenny Root's avatar
Kenny Root committed
770 771
    bool reset() {
        DIR* dir = opendir(getUserDirName());
772
        if (!dir) {
Kenny Root's avatar
Kenny Root committed
773
            ALOGW("couldn't open user directory: %s", strerror(errno));
774 775
            return false;
        }
Kenny Root's avatar
Kenny Root committed
776 777

        struct dirent* file;
778
        while ((file = readdir(dir)) != NULL) {
Kenny Root's avatar
Kenny Root committed
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
            // We only care about files.
            if (file->d_type != DT_REG) {
                continue;
            }

            // Skip anything that starts with a "."
            if (file->d_name[0] == '.') {
                continue;
            }

            // Find the current file's UID.
            char* end;
            unsigned long thisUid = strtoul(file->d_name, &end, 10);
            if (end[0] != '_' || end[1] == 0) {
                continue;
            }

            // Skip if this is not our user.
            if (get_user_id(thisUid) != mUserId) {
                continue;
            }

            unlinkat(dirfd(dir), file->d_name, 0);
802 803 804 805 806
        }
        closedir(dir);
        return true;
    }

Kenny Root's avatar
Kenny Root committed
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927
private:
    static const int MASTER_KEY_SIZE_BYTES = 16;
    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;

    static const int MAX_RETRY = 4;
    static const size_t SALT_SIZE = 16;

    void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
            uint8_t* salt) {
        size_t saltSize;
        if (salt != NULL) {
            saltSize = SALT_SIZE;
        } else {
            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
            salt = (uint8_t*) "keystore";
            // sizeof = 9, not strlen = 8
            saltSize = sizeof("keystore");
        }

        PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt,
                saltSize, 8192, keySize, key);
    }

    bool generateSalt(Entropy* entropy) {
        return entropy->generate_random_data(mSalt, sizeof(mSalt));
    }

    bool generateMasterKey(Entropy* entropy) {
        if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
            return false;
        }
        if (!generateSalt(entropy)) {
            return false;
        }
        return true;
    }

    void setupMasterKeys() {
        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
        setState(STATE_NO_ERROR);
    }

    uid_t mUserId;

    char* mUserDir;
    char* mMasterKeyFile;

    State mState;
    int8_t mRetry;

    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
    uint8_t mSalt[SALT_SIZE];

    AES_KEY mMasterKeyEncryption;
    AES_KEY mMasterKeyDecryption;
};

typedef struct {
    uint32_t uid;
    const uint8_t* filename;
} grant_t;

class KeyStore {
public:
    KeyStore(Entropy* entropy, keymaster_device_t* device)
        : mEntropy(entropy)
        , mDevice(device)
    {
        memset(&mMetaData, '\0', sizeof(mMetaData));
    }

    ~KeyStore() {
        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
                it != mGrants.end(); it++) {
            delete *it;
            mGrants.erase(it);
        }

        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
                it != mMasterKeys.end(); it++) {
            delete *it;
            mMasterKeys.erase(it);
        }
    }

    keymaster_device_t* getDevice() const {
        return mDevice;
    }

    ResponseCode initialize() {
        readMetaData();
        if (upgradeKeystore()) {
            writeMetaData();
        }

        return ::NO_ERROR;
    }

    State getState(uid_t uid) {
        return getUserState(uid)->getState();
    }

    ResponseCode initializeUser(const android::String8& pw, uid_t uid) {
        UserState* userState = getUserState(uid);
        return userState->initialize(pw, mEntropy);
    }

    ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) {
        uid_t user_id = get_user_id(uid);
        UserState* userState = getUserState(user_id);
        return userState->writeMasterKey(pw, mEntropy);
    }

    ResponseCode readMasterKey(const android::String8& pw, uid_t uid) {
        uid_t user_id = get_user_id(uid);
        UserState* userState = getUserState(user_id);
        return userState->readMasterKey(pw, mEntropy);
    }

    android::String8 getKeyName(const android::String8& keyName) {
928
        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
Kenny Root's avatar
Kenny Root committed
929 930 931 932 933
        encode_key(encoded, keyName);
        return android::String8(encoded);
    }

    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) {
934
        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
Kenny Root's avatar
Kenny Root committed
935 936 937 938 939
        encode_key(encoded, keyName);
        return android::String8::format("%u_%s", uid, encoded);
    }

    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) {
940
        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
Kenny Root's avatar
Kenny Root committed
941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959
        encode_key(encoded, keyName);
        return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid,
                encoded);
    }

    bool reset(uid_t uid) {
        UserState* userState = getUserState(uid);
        userState->zeroizeMasterKeysInMemory();
        userState->setState(STATE_UNINITIALIZED);
        return userState->reset();
    }

    bool isEmpty(uid_t uid) const {
        const UserState* userState = getUserState(uid);
        if (userState == NULL) {
            return true;
        }

        DIR* dir = opendir(userState->getUserDirName());
960 961 962 963 964
        struct dirent* file;
        if (!dir) {
            return true;
        }
        bool result = true;
Kenny Root's avatar
Kenny Root committed
965 966 967 968

        char filename[NAME_MAX];
        int n = snprintf(filename, sizeof(filename), "%u_", uid);

969
        while ((file = readdir(dir)) != NULL) {
Kenny Root's avatar
Kenny Root committed
970 971 972 973 974 975 976 977 978 979 980
            // We only care about files.
            if (file->d_type != DT_REG) {
                continue;
            }

            // Skip anything that starts with a "."
            if (file->d_name[0] == '.') {
                continue;
            }

            if (!strncmp(file->d_name, filename, n)) {
981 982 983 984 985 986 987 988
                result = false;
                break;
            }
        }
        closedir(dir);
        return result;
    }

Kenny Root's avatar
Kenny Root committed
989 990 991 992
    void lock(uid_t uid) {
        UserState* userState = getUserState(uid);
        userState->zeroizeMasterKeysInMemory();
        userState->setState(STATE_LOCKED);
993 994
    }

Kenny Root's avatar
Kenny Root committed
995 996
    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) {
        UserState* userState = getUserState(uid);
997 998
        ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
                userState->getState());
999 1000 1001 1002 1003
        if (rc != NO_ERROR) {
            return rc;
        }

        const uint8_t version = keyBlob->getVersion();
Kenny Root's avatar
Kenny Root committed
1004
        if (version < CURRENT_BLOB_VERSION) {
Kenny Root's avatar
Kenny Root committed
1005 1006 1007 1008
            /* If we upgrade the key, we need to write it to disk again. Then
             * it must be read it again since the blob is encrypted each time
             * it's written.
             */
Kenny Root's avatar
Kenny Root committed
1009 1010
            if (upgradeBlob(filename, keyBlob, version, type, uid)) {
                if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR
1011 1012
                        || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
                                userState->getState())) != NO_ERROR) {
Kenny Root's avatar
Kenny Root committed
1013 1014 1015
                    return rc;
                }
            }
1016 1017
        }

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
        /*
         * This will upgrade software-backed keys to hardware-backed keys when
         * the HAL for the device supports the newer key types.
         */
        if (rc == NO_ERROR && type == TYPE_KEY_PAIR
                && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2
                && keyBlob->isFallback()) {
            ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename,
                    uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);

            // The HAL allowed the import, reget the key to have the "fresh"
            // version.
            if (imported == NO_ERROR) {
                rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid);
            }
        }

1035
        if (type != TYPE_ANY && keyBlob->getType() != type) {
1036 1037 1038 1039 1040
            ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
            return KEY_NOT_FOUND;
        }

        return rc;
1041 1042
    }

Kenny Root's avatar
Kenny Root committed
1043 1044
    ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) {
        UserState* userState = getUserState(uid);
1045 1046
        return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(),
                mEntropy);
1047 1048
    }

Kenny Root's avatar
Kenny Root committed
1049
    void addGrant(const char* filename, uid_t granteeUid) {
Kenny Root's avatar
Kenny Root committed
1050 1051 1052
        const grant_t* existing = getGrant(filename, granteeUid);
        if (existing == NULL) {
            grant_t* grant = new grant_t;
Kenny Root's avatar
Kenny Root committed
1053
            grant->uid = granteeUid;
1054
            grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
Kenny Root's avatar
Kenny Root committed
1055
            mGrants.add(grant);
1056 1057 1058
        }
    }

Kenny Root's avatar
Kenny Root committed
1059
    bool removeGrant(const char* filename, uid_t granteeUid) {
Kenny Root's avatar
Kenny Root committed
1060 1061 1062 1063 1064 1065 1066 1067
        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
                it != mGrants.end(); it++) {
            grant_t* grant = *it;
            if (grant->uid == granteeUid
                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
                mGrants.erase(it);
                return true;
            }
1068 1069 1070 1071
        }
        return false;
    }

1072 1073
    bool hasGrant(const char* filename, const uid_t uid) const {
        return getGrant(filename, uid) != NULL;
1074 1075
    }

1076 1077
    ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid,
            int32_t flags) {
1078 1079 1080 1081 1082 1083 1084 1085 1086
        uint8_t* data;
        size_t dataLength;
        int rc;

        if (mDevice->import_keypair == NULL) {
            ALOGE("Keymaster doesn't support import!");
            return SYSTEM_ERROR;
        }

1087
        bool isFallback = false;
Kenny Root's avatar
Kenny Root committed
1088
        rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength);
1089
        if (rc) {
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
            // If this is an old device HAL, try to fall back to an old version
            if (mDevice->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_2) {
                rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength);
                isFallback = true;
            }

            if (rc) {
                ALOGE("Error while importing keypair: %d", rc);
                return SYSTEM_ERROR;
            }
1100 1101 1102 1103 1104
        }

        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
        free(data);

1105
        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
1106
        keyBlob.setFallback(isFallback);
1107

Kenny Root's avatar
Kenny Root committed
1108
        return put(filename, &keyBlob, uid);
1109 1110
    }

1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
    bool isHardwareBacked(const android::String16& keyType) const {
        if (mDevice == NULL) {
            ALOGW("can't get keymaster device");
            return false;
        }

        if (sRSAKeyType == keyType) {
            return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0;
        } else {
            return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0
                    && (mDevice->common.module->module_api_version
                            >= KEYMASTER_MODULE_API_VERSION_0_2);
        }
1124 1125
    }

Kenny Root's avatar
Kenny Root committed
1126 1127
    ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid,
            const BlobType type) {
1128
        android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid));
1129

Kenny Root's avatar
Kenny Root committed
1130 1131 1132 1133
        ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid);
        if (responseCode == NO_ERROR) {
            return responseCode;
        }
1134

Kenny Root's avatar
Kenny Root committed
1135 1136 1137
        // If this is one of the legacy UID->UID mappings, use it.
        uid_t euid = get_keystore_euid(uid);
        if (euid != uid) {
1138
            filepath8 = getKeyNameForUidWithDir(keyName, euid);
Kenny Root's avatar
Kenny Root committed
1139 1140 1141 1142 1143
            responseCode = get(filepath8.string(), keyBlob, type, uid);
            if (responseCode == NO_ERROR) {
                return responseCode;
            }
        }
1144

Kenny Root's avatar
Kenny Root committed
1145
        // They might be using a granted key.
1146
        android::String8 filename8 = getKeyName(keyName);
Kenny Root's avatar
Kenny Root committed
1147
        char* end;
1148
        strtoul(filename8.string(), &end, 10);
Kenny Root's avatar
Kenny Root committed
1149 1150 1151
        if (end[0] != '_' || end[1] == 0) {
            return KEY_NOT_FOUND;
        }
1152 1153
        filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(),
                filename8.string());
Kenny Root's avatar
Kenny Root committed
1154 1155
        if (!hasGrant(filepath8.string(), uid)) {
            return responseCode;
1156 1157
        }

Kenny Root's avatar
Kenny Root committed
1158 1159
        // It is a granted key. Try to load it.
        return get(filepath8.string(), keyBlob, type, uid);
1160 1161
    }

Kenny Root's avatar
Kenny Root committed
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
    /**
     * Returns any existing UserState or creates it if it doesn't exist.
     */
    UserState* getUserState(uid_t uid) {
        uid_t userId = get_user_id(uid);

        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
                it != mMasterKeys.end(); it++) {
            UserState* state = *it;
            if (state->getUserId() == userId) {
                return state;
            }
1174
        }
Kenny Root's avatar
Kenny Root committed
1175 1176 1177 1178 1179 1180 1181 1182

        UserState* userState = new UserState(userId);
        if (!userState->initialize()) {
            /* There's not much we can do if initialization fails. Trying to
             * unlock the keystore for that user will fail as well, so any
             * subsequent request for this user will just return SYSTEM_ERROR.
             */
            ALOGE("User initialization failed for %u; subsuquent operations will fail", userId);
1183
        }
Kenny Root's avatar
Kenny Root committed
1184 1185
        mMasterKeys.add(userState);
        return userState;
1186 1187
    }

Kenny Root's avatar
Kenny Root committed
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
    /**
     * Returns NULL if the UserState doesn't already exist.
     */
    const UserState* getUserState(uid_t uid) const {
        uid_t userId = get_user_id(uid);

        for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin());
                it != mMasterKeys.end(); it++) {
            UserState* state = *it;
            if (state->getUserId() == userId) {
                return state;
            }
        }
1201

Kenny Root's avatar
Kenny Root committed
1202
        return NULL;
1203 1204
    }

Kenny Root's avatar
Kenny Root committed
1205 1206 1207
private:
    static const char* sOldMasterKey;
    static const char* sMetaDataFile;
1208
    static const android::String16 sRSAKeyType;
Kenny Root's avatar
Kenny Root committed
1209
    Entropy* mEntropy;
Kenny Root's avatar
Kenny Root committed
1210

Kenny Root's avatar
Kenny Root committed
1211
    keymaster_device_t* mDevice;
1212

Kenny Root's avatar
Kenny Root committed
1213 1214 1215
    android::Vector<UserState*> mMasterKeys;

    android::Vector<grant_t*> mGrants;
1216

Kenny Root's avatar
Kenny Root committed
1217 1218 1219
    typedef struct {
        uint32_t version;
    } keystore_metadata_t;
1220

Kenny Root's avatar
Kenny Root committed
1221 1222 1223 1224 1225 1226
    keystore_metadata_t mMetaData;

    const grant_t* getGrant(const char* filename, uid_t uid) const {
        for (android::Vector<grant_t*>::const_iterator it(mGrants.begin());
                it != mGrants.end(); it++) {
            grant_t* grant = *it;
1227
            if (grant->uid == uid
Kenny Root's avatar
Kenny Root committed
1228
                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
1229 1230 1231 1232 1233 1234
                return grant;
            }
        }
        return NULL;
    }

1235 1236 1237 1238
    /**
     * Upgrade code. This will upgrade the key from the current version
     * to whatever is newest.
     */
Kenny Root's avatar
Kenny Root committed
1239 1240
    bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
            const BlobType type, uid_t uid) {
1241 1242 1243 1244 1245 1246 1247 1248 1249
        bool updated = false;
        uint8_t version = oldVersion;

        /* From V0 -> V1: All old types were unknown */
        if (version == 0) {
            ALOGV("upgrading to version 1 and setting type %d", type);

            blob->setType(type);
            if (type == TYPE_KEY_PAIR) {
Kenny Root's avatar
Kenny Root committed
1250
                importBlobAsKey(blob, filename, uid);
1251 1252 1253 1254 1255
            }
            version = 1;
            updated = true;
        }

1256 1257 1258 1259 1260 1261 1262 1263 1264
        /* From V1 -> V2: All old keys were encrypted */
        if (version == 1) {
            ALOGV("upgrading to version 2");

            blob->setEncrypted(true);
            version = 2;
            updated = true;
        }

1265 1266 1267
        /*
         * If we've updated, set the key blob to the right version
         * and write it.
Kenny Root's avatar
Kenny Root committed
1268
         */
1269 1270 1271 1272
        if (updated) {
            ALOGV("updated and writing file %s", filename);
            blob->setVersion(version);
        }
Kenny Root's avatar
Kenny Root committed
1273 1274

        return updated;
1275 1276 1277 1278 1279 1280 1281 1282
    }

    /**
     * Takes a blob that is an PEM-encoded RSA key as a byte array and
     * converts it to a DER-encoded PKCS#8 for import into a keymaster.
     * Then it overwrites the original blob with the new blob
     * format that is returned from the keymaster.
     */
Kenny Root's avatar
Kenny Root committed
1283
    ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) {
1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303
        // We won't even write to the blob directly with this BIO, so const_cast is okay.
        Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
        if (b.get() == NULL) {
            ALOGE("Problem instantiating BIO");
            return SYSTEM_ERROR;
        }

        Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
        if (pkey.get() == NULL) {
            ALOGE("Couldn't read old PEM file");
            return SYSTEM_ERROR;
        }

        Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
        int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
        if (len < 0) {
            ALOGE("Couldn't measure PKCS#8 length");
            return SYSTEM_ERROR;
        }

1304 1305
        UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]);
        uint8_t* tmp = pkcs8key.get();
1306 1307 1308 1309 1310
        if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
            ALOGE("Couldn't convert to PKCS#8");
            return SYSTEM_ERROR;
        }

1311 1312
        ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid,
                blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
1313 1314 1315 1316
        if (rc != NO_ERROR) {
            return rc;
        }

Kenny Root's avatar
Kenny Root committed
1317
        return get(filename, blob, TYPE_KEY_PAIR, uid);
1318
    }
1319

Kenny Root's avatar
Kenny Root committed
1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330
    void readMetaData() {
        int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY));
        if (in < 0) {
            return;
        }
        size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData));
        if (fileLength != sizeof(mMetaData)) {
            ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength,
                    sizeof(mMetaData));
        }
        close(in);
1331 1332
    }

Kenny Root's avatar
Kenny Root committed
1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
    void writeMetaData() {
        const char* tmpFileName = ".metadata.tmp";
        int out = TEMP_FAILURE_RETRY(open(tmpFileName,
                O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
        if (out < 0) {
            ALOGE("couldn't write metadata file: %s", strerror(errno));
            return;
        }
        size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData));
        if (fileLength != sizeof(mMetaData)) {
            ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
                    sizeof(mMetaData));
1345
        }
Kenny Root's avatar
Kenny Root committed
1346 1347
        close(out);
        rename(tmpFileName, sMetaDataFile);
1348 1349
    }

Kenny Root's avatar
Kenny Root committed
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
    bool upgradeKeystore() {
        bool upgraded = false;

        if (mMetaData.version == 0) {
            UserState* userState = getUserState(0);

            // Initialize first so the directory is made.
            userState->initialize();

            // Migrate the old .masterkey file to user 0.
            if (access(sOldMasterKey, R_OK) == 0) {
                if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) {
                    ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
                    return false;
                }
            }

            // Initialize again in case we had a key.
            userState->initialize();

            // Try to migrate existing keys.
            DIR* dir = opendir(".");
            if (!dir) {
                // Give up now; maybe we can upgrade later.
                ALOGE("couldn't open keystore's directory; something is wrong");
                return false;
            }

            struct dirent* file;
            while ((file = readdir(dir)) != NULL) {
                // We only care about files.
                if (file->d_type != DT_REG) {
                    continue;
                }

                // Skip anything that starts with a "."
                if (file->d_name[0] == '.') {
                    continue;
                }

                // Find the current file's user.
                char* end;
                unsigned long thisUid = strtoul(file->d_name, &end, 10);
                if (end[0] != '_' || end[1] == 0) {
                    continue;
                }
                UserState* otherUser = getUserState(thisUid);
                if (otherUser->getUserId() != 0) {
                    unlinkat(dirfd(dir), file->d_name, 0);
                }

                // Rename the file into user directory.
                DIR* otherdir = opendir(otherUser->getUserDirName());
                if (otherdir == NULL) {
                    ALOGW("couldn't open user directory for rename");
                    continue;
                }
                if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
                    ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
                }
                closedir(otherdir);
            }
            closedir(dir);

            mMetaData.version = 1;
            upgraded = true;
        }

        return upgraded;
1419
    }
Kenny Root's avatar
Kenny Root committed
1420
};
1421

Kenny Root's avatar
Kenny Root committed
1422 1423
const char* KeyStore::sOldMasterKey = ".masterkey";
const char* KeyStore::sMetaDataFile = ".metadata";
1424

1425 1426
const android::String16 KeyStore::sRSAKeyType("RSA");

Kenny Root's avatar
Kenny Root committed
1427 1428 1429 1430 1431 1432 1433
namespace android {
class KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient {
public:
    KeyStoreProxy(KeyStore* keyStore)
        : mKeyStore(keyStore)
    {
    }
1434

Kenny Root's avatar
Kenny Root committed
1435 1436 1437
    void binderDied(const wp<IBinder>&) {
        ALOGE("binder death detected");
    }
1438

Kenny Root's avatar
Kenny Root committed
1439
    int32_t test() {
1440 1441 1442
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_TEST)) {
            ALOGW("permission denied for %d: test", callingUid);
Kenny Root's avatar
Kenny Root committed
1443 1444
            return ::PERMISSION_DENIED;
        }
1445

Kenny Root's avatar
Kenny Root committed
1446
        return mKeyStore->getState(callingUid);
1447 1448
    }

Kenny Root's avatar
Kenny Root committed
1449
    int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
1450 1451 1452
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_GET)) {
            ALOGW("permission denied for %d: get", callingUid);
Kenny Root's avatar
Kenny Root committed
1453 1454
            return ::PERMISSION_DENIED;
        }
1455

Kenny Root's avatar
Kenny Root committed
1456 1457
        String8 name8(name);
        Blob keyBlob;
1458

Kenny Root's avatar
Kenny Root committed
1459
        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
1460
                TYPE_GENERIC);
Kenny Root's avatar
Kenny Root committed
1461
        if (responseCode != ::NO_ERROR) {
Kenny Root's avatar
Kenny Root committed
1462
            ALOGW("Could not read %s", name8.string());
Kenny Root's avatar
Kenny Root committed
1463 1464 1465 1466 1467 1468 1469 1470 1471 1472
            *item = NULL;
            *itemLength = 0;
            return responseCode;
        }

        *item = (uint8_t*) malloc(keyBlob.getLength());
        memcpy(*item, keyBlob.getValue(), keyBlob.getLength());
        *itemLength = keyBlob.getLength();

        return ::NO_ERROR;
1473 1474
    }

1475 1476
    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid,
            int32_t flags) {
1477 1478 1479
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_INSERT)) {
            ALOGW("permission denied for %d: insert", callingUid);
Kenny Root's avatar
Kenny Root committed
1480 1481 1482
            return ::PERMISSION_DENIED;
        }

1483 1484 1485 1486 1487 1488
        State state = mKeyStore->getState(callingUid);
        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
            ALOGD("calling get in state: %d", state);
            return state;
        }

1489 1490 1491
        if (targetUid == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
Kenny Root's avatar
Kenny Root committed
1492 1493 1494
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
1495
        String8 name8(name);
Kenny Root's avatar
Kenny Root committed
1496
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
Kenny Root's avatar
Kenny Root committed
1497 1498

        Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
1499 1500
        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);

1501
        return mKeyStore->put(filename.string(), &keyBlob, targetUid);
1502 1503
    }

1504
    int32_t del(const String16& name, int targetUid) {
1505 1506 1507
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_DELETE)) {
            ALOGW("permission denied for %d: del", callingUid);
Kenny Root's avatar
Kenny Root committed
1508 1509 1510
            return ::PERMISSION_DENIED;
        }

1511 1512 1513
        if (targetUid == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
Kenny Root's avatar
Kenny Root committed
1514 1515 1516
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
1517
        String8 name8(name);
Kenny Root's avatar
Kenny Root committed
1518
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
1519

Kenny Root's avatar
Kenny Root committed
1520
        Blob keyBlob;
Kenny Root's avatar
Kenny Root committed
1521
        ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC,
1522
                targetUid);
Kenny Root's avatar
Kenny Root committed
1523 1524 1525 1526
        if (responseCode != ::NO_ERROR) {
            return responseCode;
        }
        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
1527 1528
    }

1529
    int32_t exist(const String16& name, int targetUid) {
1530 1531 1532
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_EXIST)) {
            ALOGW("permission denied for %d: exist", callingUid);
Kenny Root's avatar
Kenny Root committed
1533 1534 1535
            return ::PERMISSION_DENIED;
        }

1536 1537 1538
        if (targetUid == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
Kenny Root's avatar
Kenny Root committed
1539 1540 1541
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
1542
        String8 name8(name);
Kenny Root's avatar
Kenny Root committed
1543
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
Kenny Root's avatar
Kenny Root committed
1544

Kenny Root's avatar
Kenny Root committed
1545
        if (access(filename.string(), R_OK) == -1) {
Kenny Root's avatar
Kenny Root committed
1546 1547 1548
            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
        }
        return ::NO_ERROR;
1549 1550
    }

1551
    int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) {
1552 1553 1554
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_SAW)) {
            ALOGW("permission denied for %d: saw", callingUid);
Kenny Root's avatar
Kenny Root committed
1555 1556 1557
            return ::PERMISSION_DENIED;
        }

1558 1559 1560
        if (targetUid == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
Kenny Root's avatar
Kenny Root committed
1561 1562 1563
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
1564 1565
        UserState* userState = mKeyStore->getUserState(targetUid);
        DIR* dir = opendir(userState->getUserDirName());
Kenny Root's avatar
Kenny Root committed
1566
        if (!dir) {
Kenny Root's avatar
Kenny Root committed
1567
            ALOGW("can't open directory for user: %s", strerror(errno));
Kenny Root's avatar
Kenny Root committed
1568 1569 1570 1571
            return ::SYSTEM_ERROR;
        }

        const String8 prefix8(prefix);
Kenny Root's avatar
Kenny Root committed
1572 1573
        String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
        size_t n = filename.length();
Kenny Root's avatar
Kenny Root committed
1574 1575 1576

        struct dirent* file;
        while ((file = readdir(dir)) != NULL) {
Kenny Root's avatar
Kenny Root committed
1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587
            // We only care about files.
            if (file->d_type != DT_REG) {
                continue;
            }

            // Skip anything that starts with a "."
            if (file->d_name[0] == '.') {
                continue;
            }

            if (!strncmp(filename.string(), file->d_name, n)) {
Kenny Root's avatar
Kenny Root committed
1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604
                const char* p = &file->d_name[n];
                size_t plen = strlen(p);

                size_t extra = decode_key_length(p, plen);
                char *match = (char*) malloc(extra + 1);
                if (match != NULL) {
                    decode_key(match, p, plen);
                    matches->push(String16(match, extra));
                    free(match);
                } else {
                    ALOGW("could not allocate match of size %zd", extra);
                }
            }
        }
        closedir(dir);

        return ::NO_ERROR;
1605 1606
    }

Kenny Root's avatar
Kenny Root committed
1607
    int32_t reset() {
1608 1609 1610
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_RESET)) {
            ALOGW("permission denied for %d: reset", callingUid);
Kenny Root's avatar
Kenny Root committed
1611 1612
            return ::PERMISSION_DENIED;
        }
1613

Kenny Root's avatar
Kenny Root committed
1614
        ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
1615

Kenny Root's avatar
Kenny Root committed
1616 1617 1618 1619
        const keymaster_device_t* device = mKeyStore->getDevice();
        if (device == NULL) {
            ALOGE("No keymaster device!");
            return ::SYSTEM_ERROR;
1620
        }
Kenny Root's avatar
Kenny Root committed
1621 1622 1623 1624

        if (device->delete_all == NULL) {
            ALOGV("keymaster device doesn't implement delete_all");
            return rc;
1625
        }
Kenny Root's avatar
Kenny Root committed
1626 1627 1628 1629

        if (device->delete_all(device)) {
            ALOGE("Problem calling keymaster's delete_all");
            return ::SYSTEM_ERROR;
1630
        }
Kenny Root's avatar
Kenny Root committed
1631 1632

        return rc;
1633 1634
    }

Kenny Root's avatar
Kenny Root committed
1635 1636 1637 1638 1639 1640 1641 1642
    /*
     * Here is the history. To improve the security, the parameters to generate the
     * master key has been changed. To make a seamless transition, we update the
     * file using the same password when the user unlock it for the first time. If
     * any thing goes wrong during the transition, the new file will not overwrite
     * the old one. This avoids permanent damages of the existing data.
     */
    int32_t password(const String16& password) {
1643 1644 1645
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_PASSWORD)) {
            ALOGW("permission denied for %d: password", callingUid);
Kenny Root's avatar
Kenny Root committed
1646 1647
            return ::PERMISSION_DENIED;
        }
1648

Kenny Root's avatar
Kenny Root committed
1649
        const String8 password8(password);
1650

Kenny Root's avatar
Kenny Root committed
1651
        switch (mKeyStore->getState(callingUid)) {
Kenny Root's avatar
Kenny Root committed
1652 1653
            case ::STATE_UNINITIALIZED: {
                // generate master key, encrypt with password, write to file, initialize mMasterKey*.
Kenny Root's avatar
Kenny Root committed
1654
                return mKeyStore->initializeUser(password8, callingUid);
Kenny Root's avatar
Kenny Root committed
1655 1656 1657
            }
            case ::STATE_NO_ERROR: {
                // rewrite master key with new password.
Kenny Root's avatar
Kenny Root committed
1658
                return mKeyStore->writeMasterKey(password8, callingUid);
Kenny Root's avatar
Kenny Root committed
1659 1660 1661
            }
            case ::STATE_LOCKED: {
                // read master key, decrypt with password, initialize mMasterKey*.
Kenny Root's avatar
Kenny Root committed
1662
                return mKeyStore->readMasterKey(password8, callingUid);
Kenny Root's avatar
Kenny Root committed
1663 1664 1665 1666
            }
        }
        return ::SYSTEM_ERROR;
    }
1667

Kenny Root's avatar
Kenny Root committed
1668
    int32_t lock() {
1669 1670 1671
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_LOCK)) {
            ALOGW("permission denied for %d: lock", callingUid);
Kenny Root's avatar
Kenny Root committed
1672 1673 1674
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
1675
        State state = mKeyStore->getState(callingUid);
1676
        if (state != ::STATE_NO_ERROR) {
Kenny Root's avatar
Kenny Root committed
1677 1678 1679
            ALOGD("calling lock in state: %d", state);
            return state;
        }
1680

Kenny Root's avatar
Kenny Root committed
1681
        mKeyStore->lock(callingUid);
Kenny Root's avatar
Kenny Root committed
1682
        return ::NO_ERROR;
1683
    }
1684

Kenny Root's avatar
Kenny Root committed
1685
    int32_t unlock(const String16& pw) {
1686 1687 1688
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_UNLOCK)) {
            ALOGW("permission denied for %d: unlock", callingUid);
Kenny Root's avatar
Kenny Root committed
1689 1690 1691
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
1692
        State state = mKeyStore->getState(callingUid);
1693
        if (state != ::STATE_LOCKED) {
Kenny Root's avatar
Kenny Root committed
1694 1695 1696 1697 1698 1699
            ALOGD("calling unlock when not locked");
            return state;
        }

        const String8 password8(pw);
        return password(pw);
1700 1701
    }

Kenny Root's avatar
Kenny Root committed
1702
    int32_t zero() {
1703 1704 1705
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_ZERO)) {
            ALOGW("permission denied for %d: zero", callingUid);
Kenny Root's avatar
Kenny Root committed
1706 1707
            return -1;
        }
1708

Kenny Root's avatar
Kenny Root committed
1709
        return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR;
1710 1711
    }

1712 1713
    int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
            int32_t flags, Vector<sp<KeystoreArg> >* args) {
1714 1715 1716
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_INSERT)) {
            ALOGW("permission denied for %d: generate", callingUid);
Kenny Root's avatar
Kenny Root committed
1717 1718
            return ::PERMISSION_DENIED;
        }
1719

1720 1721 1722
        if (targetUid == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
Kenny Root's avatar
Kenny Root committed
1723 1724 1725
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
1726
        State state = mKeyStore->getState(callingUid);
1727 1728
        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
            ALOGW("calling generate in state: %d", state);
Kenny Root's avatar
Kenny Root committed
1729 1730
            return state;
        }
1731

Kenny Root's avatar
Kenny Root committed
1732 1733 1734
        uint8_t* data;
        size_t dataLength;
        int rc;
1735
        bool isFallback = false;
1736

Kenny Root's avatar
Kenny Root committed
1737 1738 1739 1740
        const keymaster_device_t* device = mKeyStore->getDevice();
        if (device == NULL) {
            return ::SYSTEM_ERROR;
        }
1741

Kenny Root's avatar
Kenny Root committed
1742 1743 1744
        if (device->generate_keypair == NULL) {
            return ::SYSTEM_ERROR;
        }
1745

1746
        if (keyType == EVP_PKEY_DSA) {
1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
            keymaster_dsa_keygen_params_t dsa_params;
            memset(&dsa_params, '\0', sizeof(dsa_params));

            if (keySize == -1) {
                keySize = DSA_DEFAULT_KEY_SIZE;
            } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE
                    || keySize > DSA_MAX_KEY_SIZE) {
                ALOGI("invalid key size %d", keySize);
                return ::SYSTEM_ERROR;
            }
            dsa_params.key_size = keySize;

            if (args->size() == 3) {
                sp<KeystoreArg> gArg = args->itemAt(0);
                sp<KeystoreArg> pArg = args->itemAt(1);
                sp<KeystoreArg> qArg = args->itemAt(2);

                if (gArg != NULL && pArg != NULL && qArg != NULL) {
                    dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data());
                    dsa_params.generator_len = gArg->size();

                    dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data());
                    dsa_params.prime_p_len = pArg->size();

                    dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data());
                    dsa_params.prime_q_len = qArg->size();
                } else {
                    ALOGI("not all DSA parameters were read");
                    return ::SYSTEM_ERROR;
                }
            } else if (args->size() != 0) {
                ALOGI("DSA args must be 3");
                return ::SYSTEM_ERROR;
            }

1782 1783 1784 1785 1786 1787 1788
            if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) {
                rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
            } else {
                isFallback = true;
                rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
            }
        } else if (keyType == EVP_PKEY_EC) {
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799
            keymaster_ec_keygen_params_t ec_params;
            memset(&ec_params, '\0', sizeof(ec_params));

            if (keySize == -1) {
                keySize = EC_DEFAULT_KEY_SIZE;
            } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
                ALOGI("invalid key size %d", keySize);
                return ::SYSTEM_ERROR;
            }
            ec_params.field_size = keySize;

1800 1801 1802 1803 1804 1805
            if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) {
                rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
            } else {
                isFallback = true;
                rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
            }
1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
        } else if (keyType == EVP_PKEY_RSA) {
            keymaster_rsa_keygen_params_t rsa_params;
            memset(&rsa_params, '\0', sizeof(rsa_params));
            rsa_params.public_exponent = RSA_DEFAULT_EXPONENT;

            if (keySize == -1) {
                keySize = RSA_DEFAULT_KEY_SIZE;
            } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
                ALOGI("invalid key size %d", keySize);
                return ::SYSTEM_ERROR;
            }
            rsa_params.modulus_size = keySize;

            if (args->size() > 1) {
1820
                ALOGI("invalid number of arguments: %zu", args->size());
1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845
                return ::SYSTEM_ERROR;
            } else if (args->size() == 1) {
                sp<KeystoreArg> pubExpBlob = args->itemAt(0);
                if (pubExpBlob != NULL) {
                    Unique_BIGNUM pubExpBn(
                            BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()),
                                    pubExpBlob->size(), NULL));
                    if (pubExpBn.get() == NULL) {
                        ALOGI("Could not convert public exponent to BN");
                        return ::SYSTEM_ERROR;
                    }
                    unsigned long pubExp = BN_get_word(pubExpBn.get());
                    if (pubExp == 0xFFFFFFFFL) {
                        ALOGI("cannot represent public exponent as a long value");
                        return ::SYSTEM_ERROR;
                    }
                    rsa_params.public_exponent = pubExp;
                }
            }

            rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
        } else {
            ALOGW("Unsupported key type %d", keyType);
            rc = -1;
        }
1846

Kenny Root's avatar
Kenny Root committed
1847 1848 1849
        if (rc) {
            return ::SYSTEM_ERROR;
        }
1850

Kenny Root's avatar
Kenny Root committed
1851 1852
        String8 name8(name);
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
1853

Kenny Root's avatar
Kenny Root committed
1854 1855 1856
        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
        free(data);

1857
        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
1858 1859
        keyBlob.setFallback(isFallback);

Kenny Root's avatar
Kenny Root committed
1860
        return mKeyStore->put(filename.string(), &keyBlob, callingUid);
1861 1862
    }

1863 1864
    int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid,
            int32_t flags) {
1865 1866 1867
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_INSERT)) {
            ALOGW("permission denied for %d: import", callingUid);
Kenny Root's avatar
Kenny Root committed
1868 1869
            return ::PERMISSION_DENIED;
        }
1870

1871 1872 1873
        if (targetUid == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
Kenny Root's avatar
Kenny Root committed
1874 1875 1876
            return ::PERMISSION_DENIED;
        }

1877
        State state = mKeyStore->getState(targetUid);
1878
        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
Kenny Root's avatar
Kenny Root committed
1879 1880 1881
            ALOGD("calling import in state: %d", state);
            return state;
        }
1882

Kenny Root's avatar
Kenny Root committed
1883
        String8 name8(name);
1884
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
1885

1886
        return mKeyStore->importKey(data, length, filename.string(), targetUid, flags);
1887 1888
    }

Kenny Root's avatar
Kenny Root committed
1889 1890
    int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
            size_t* outLength) {
1891 1892 1893
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_SIGN)) {
            ALOGW("permission denied for %d: saw", callingUid);
Kenny Root's avatar
Kenny Root committed
1894 1895
            return ::PERMISSION_DENIED;
        }
1896

Kenny Root's avatar
Kenny Root committed
1897 1898
        Blob keyBlob;
        String8 name8(name);
1899

1900
        ALOGV("sign %s from uid %d", name8.string(), callingUid);
Kenny Root's avatar
Kenny Root committed
1901
        int rc;
1902

Kenny Root's avatar
Kenny Root committed
1903
        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
1904
                ::TYPE_KEY_PAIR);
Kenny Root's avatar
Kenny Root committed
1905 1906 1907
        if (responseCode != ::NO_ERROR) {
            return responseCode;
        }
1908

Kenny Root's avatar
Kenny Root committed
1909 1910 1911 1912 1913
        const keymaster_device_t* device = mKeyStore->getDevice();
        if (device == NULL) {
            ALOGE("no keymaster device; cannot sign");
            return ::SYSTEM_ERROR;
        }
1914

Kenny Root's avatar
Kenny Root committed
1915 1916 1917 1918
        if (device->sign_data == NULL) {
            ALOGE("device doesn't implement signing");
            return ::SYSTEM_ERROR;
        }
1919

Kenny Root's avatar
Kenny Root committed
1920 1921 1922 1923
        keymaster_rsa_sign_params_t params;
        params.digest_type = DIGEST_NONE;
        params.padding_type = PADDING_NONE;

1924 1925 1926 1927 1928 1929 1930
        if (keyBlob.isFallback()) {
            rc = openssl_sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
                    length, out, outLength);
        } else {
            rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
                    length, out, outLength);
        }
Kenny Root's avatar
Kenny Root committed
1931 1932 1933 1934
        if (rc) {
            ALOGW("device couldn't sign data");
            return ::SYSTEM_ERROR;
        }
1935

Kenny Root's avatar
Kenny Root committed
1936
        return ::NO_ERROR;
1937 1938
    }

Kenny Root's avatar
Kenny Root committed
1939 1940
    int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
            const uint8_t* signature, size_t signatureLength) {
1941 1942 1943
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_VERIFY)) {
            ALOGW("permission denied for %d: verify", callingUid);
Kenny Root's avatar
Kenny Root committed
1944 1945
            return ::PERMISSION_DENIED;
        }
1946

Kenny Root's avatar
Kenny Root committed
1947
        State state = mKeyStore->getState(callingUid);
1948
        if (!isKeystoreUnlocked(state)) {
Kenny Root's avatar
Kenny Root committed
1949 1950 1951
            ALOGD("calling verify in state: %d", state);
            return state;
        }
1952

Kenny Root's avatar
Kenny Root committed
1953 1954 1955
        Blob keyBlob;
        String8 name8(name);
        int rc;
1956

Kenny Root's avatar
Kenny Root committed
1957
        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
1958
                TYPE_KEY_PAIR);
Kenny Root's avatar
Kenny Root committed
1959 1960 1961
        if (responseCode != ::NO_ERROR) {
            return responseCode;
        }
1962

Kenny Root's avatar
Kenny Root committed
1963 1964 1965 1966
        const keymaster_device_t* device = mKeyStore->getDevice();
        if (device == NULL) {
            return ::SYSTEM_ERROR;
        }
1967

Kenny Root's avatar
Kenny Root committed
1968 1969 1970 1971 1972 1973 1974
        if (device->verify_data == NULL) {
            return ::SYSTEM_ERROR;
        }

        keymaster_rsa_sign_params_t params;
        params.digest_type = DIGEST_NONE;
        params.padding_type = PADDING_NONE;
1975

1976 1977 1978 1979 1980 1981 1982
        if (keyBlob.isFallback()) {
            rc = openssl_verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
                    dataLength, signature, signatureLength);
        } else {
            rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
                    dataLength, signature, signatureLength);
        }
Kenny Root's avatar
Kenny Root committed
1983 1984 1985 1986 1987
        if (rc) {
            return ::SYSTEM_ERROR;
        } else {
            return ::NO_ERROR;
        }
1988 1989
    }

Kenny Root's avatar
Kenny Root committed
1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001
    /*
     * TODO: The abstraction between things stored in hardware and regular blobs
     * of data stored on the filesystem should be moved down to keystore itself.
     * Unfortunately the Java code that calls this has naming conventions that it
     * knows about. Ideally keystore shouldn't be used to store random blobs of
     * data.
     *
     * Until that happens, it's necessary to have a separate "get_pubkey" and
     * "del_key" since the Java code doesn't really communicate what it's
     * intentions are.
     */
    int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
2002 2003 2004
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_GET)) {
            ALOGW("permission denied for %d: get_pubkey", callingUid);
Kenny Root's avatar
Kenny Root committed
2005 2006
            return ::PERMISSION_DENIED;
        }
2007

Kenny Root's avatar
Kenny Root committed
2008 2009
        Blob keyBlob;
        String8 name8(name);
2010

2011
        ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid);
2012

Kenny Root's avatar
Kenny Root committed
2013
        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
Kenny Root's avatar
Kenny Root committed
2014 2015 2016 2017
                TYPE_KEY_PAIR);
        if (responseCode != ::NO_ERROR) {
            return responseCode;
        }
2018

Kenny Root's avatar
Kenny Root committed
2019 2020 2021 2022
        const keymaster_device_t* device = mKeyStore->getDevice();
        if (device == NULL) {
            return ::SYSTEM_ERROR;
        }
2023

Kenny Root's avatar
Kenny Root committed
2024 2025 2026 2027
        if (device->get_keypair_public == NULL) {
            ALOGE("device has no get_keypair_public implementation!");
            return ::SYSTEM_ERROR;
        }
Kenny Root's avatar
Kenny Root committed
2028

2029 2030 2031 2032 2033 2034 2035 2036
        int rc;
        if (keyBlob.isFallback()) {
            rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
                    pubkeyLength);
        } else {
            rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
                    pubkeyLength);
        }
Kenny Root's avatar
Kenny Root committed
2037 2038 2039
        if (rc) {
            return ::SYSTEM_ERROR;
        }
Kenny Root's avatar
Kenny Root committed
2040

Kenny Root's avatar
Kenny Root committed
2041
        return ::NO_ERROR;
Kenny Root's avatar
Kenny Root committed
2042 2043
    }

2044
    int32_t del_key(const String16& name, int targetUid) {
2045 2046 2047
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_DELETE)) {
            ALOGW("permission denied for %d: del_key", callingUid);
Kenny Root's avatar
Kenny Root committed
2048 2049
            return ::PERMISSION_DENIED;
        }
Kenny Root's avatar
Kenny Root committed
2050

2051 2052 2053
        if (targetUid == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
Kenny Root's avatar
Kenny Root committed
2054 2055 2056
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
2057
        String8 name8(name);
2058
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
Kenny Root's avatar
Kenny Root committed
2059

Kenny Root's avatar
Kenny Root committed
2060
        Blob keyBlob;
Kenny Root's avatar
Kenny Root committed
2061
        ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR,
2062
                targetUid);
Kenny Root's avatar
Kenny Root committed
2063 2064 2065
        if (responseCode != ::NO_ERROR) {
            return responseCode;
        }
2066

Kenny Root's avatar
Kenny Root committed
2067
        ResponseCode rc = ::NO_ERROR;
2068

Kenny Root's avatar
Kenny Root committed
2069 2070 2071 2072 2073
        const keymaster_device_t* device = mKeyStore->getDevice();
        if (device == NULL) {
            rc = ::SYSTEM_ERROR;
        } else {
            // A device doesn't have to implement delete_keypair.
2074
            if (device->delete_keypair != NULL && !keyBlob.isFallback()) {
Kenny Root's avatar
Kenny Root committed
2075 2076 2077 2078 2079
                if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
                    rc = ::SYSTEM_ERROR;
                }
            }
        }
2080

Kenny Root's avatar
Kenny Root committed
2081 2082 2083
        if (rc != ::NO_ERROR) {
            return rc;
        }
2084

Kenny Root's avatar
Kenny Root committed
2085
        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
2086
    }
Kenny Root's avatar
Kenny Root committed
2087 2088

    int32_t grant(const String16& name, int32_t granteeUid) {
2089 2090 2091
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_GRANT)) {
            ALOGW("permission denied for %d: grant", callingUid);
Kenny Root's avatar
Kenny Root committed
2092 2093 2094
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
2095
        State state = mKeyStore->getState(callingUid);
2096
        if (!isKeystoreUnlocked(state)) {
Kenny Root's avatar
Kenny Root committed
2097 2098 2099 2100 2101
            ALOGD("calling grant in state: %d", state);
            return state;
        }

        String8 name8(name);
Kenny Root's avatar
Kenny Root committed
2102
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
Kenny Root's avatar
Kenny Root committed
2103

Kenny Root's avatar
Kenny Root committed
2104
        if (access(filename.string(), R_OK) == -1) {
Kenny Root's avatar
Kenny Root committed
2105 2106 2107
            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
        }

Kenny Root's avatar
Kenny Root committed
2108
        mKeyStore->addGrant(filename.string(), granteeUid);
Kenny Root's avatar
Kenny Root committed
2109
        return ::NO_ERROR;
2110
    }
Kenny Root's avatar
Kenny Root committed
2111 2112

    int32_t ungrant(const String16& name, int32_t granteeUid) {
2113 2114 2115
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_GRANT)) {
            ALOGW("permission denied for %d: ungrant", callingUid);
Kenny Root's avatar
Kenny Root committed
2116 2117 2118
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
2119
        State state = mKeyStore->getState(callingUid);
2120
        if (!isKeystoreUnlocked(state)) {
Kenny Root's avatar
Kenny Root committed
2121 2122 2123 2124 2125
            ALOGD("calling ungrant in state: %d", state);
            return state;
        }

        String8 name8(name);
Kenny Root's avatar
Kenny Root committed
2126
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
Kenny Root's avatar
Kenny Root committed
2127

Kenny Root's avatar
Kenny Root committed
2128
        if (access(filename.string(), R_OK) == -1) {
Kenny Root's avatar
Kenny Root committed
2129 2130 2131
            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
        }

Kenny Root's avatar
Kenny Root committed
2132
        return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
2133
    }
Kenny Root's avatar
Kenny Root committed
2134 2135

    int64_t getmtime(const String16& name) {
2136 2137 2138
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_GET)) {
            ALOGW("permission denied for %d: getmtime", callingUid);
Kenny Root's avatar
Kenny Root committed
2139
            return -1L;
Kenny Root's avatar
Kenny Root committed
2140 2141 2142
        }

        String8 name8(name);
Kenny Root's avatar
Kenny Root committed
2143
        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
Kenny Root's avatar
Kenny Root committed
2144

Kenny Root's avatar
Kenny Root committed
2145 2146
        if (access(filename.string(), R_OK) == -1) {
            ALOGW("could not access %s for getmtime", filename.string());
Kenny Root's avatar
Kenny Root committed
2147
            return -1L;
2148
        }
Kenny Root's avatar
Kenny Root committed
2149

Kenny Root's avatar
Kenny Root committed
2150
        int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY));
Kenny Root's avatar
Kenny Root committed
2151
        if (fd < 0) {
Kenny Root's avatar
Kenny Root committed
2152
            ALOGW("could not open %s for getmtime", filename.string());
Kenny Root's avatar
Kenny Root committed
2153
            return -1L;
Kenny Root's avatar
Kenny Root committed
2154 2155 2156 2157 2158 2159
        }

        struct stat s;
        int ret = fstat(fd, &s);
        close(fd);
        if (ret == -1) {
Kenny Root's avatar
Kenny Root committed
2160
            ALOGW("could not stat %s for getmtime", filename.string());
Kenny Root's avatar
Kenny Root committed
2161
            return -1L;
Kenny Root's avatar
Kenny Root committed
2162 2163
        }

Kenny Root's avatar
Kenny Root committed
2164
        return static_cast<int64_t>(s.st_mtime);
2165
    }
Kenny Root's avatar
Kenny Root committed
2166

2167 2168
    int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
            int32_t destUid) {
Kenny Root's avatar
Kenny Root committed
2169
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2170 2171
        if (!has_permission(callingUid, P_DUPLICATE)) {
            ALOGW("permission denied for %d: duplicate", callingUid);
Kenny Root's avatar
Kenny Root committed
2172 2173 2174
            return -1L;
        }

Kenny Root's avatar
Kenny Root committed
2175
        State state = mKeyStore->getState(callingUid);
Kenny Root's avatar
Kenny Root committed
2176
        if (!isKeystoreUnlocked(state)) {
2177
            ALOGD("calling duplicate in state: %d", state);
Kenny Root's avatar
Kenny Root committed
2178 2179 2180
            return state;
        }

2181 2182 2183 2184
        if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) {
            srcUid = callingUid;
        } else if (!is_granted_to(callingUid, srcUid)) {
            ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid);
Kenny Root's avatar
Kenny Root committed
2185 2186 2187
            return ::PERMISSION_DENIED;
        }

2188 2189 2190
        if (destUid == -1) {
            destUid = callingUid;
        }
Kenny Root's avatar
Kenny Root committed
2191

2192 2193 2194 2195 2196 2197
        if (srcUid != destUid) {
            if (static_cast<uid_t>(srcUid) != callingUid) {
                ALOGD("can only duplicate from caller to other or to same uid: "
                      "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid);
                return ::PERMISSION_DENIED;
            }
Kenny Root's avatar
Kenny Root committed
2198

2199 2200 2201 2202
            if (!is_granted_to(callingUid, destUid)) {
                ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid);
                return ::PERMISSION_DENIED;
            }
Kenny Root's avatar
Kenny Root committed
2203 2204
        }

2205
        String8 source8(srcKey);
Kenny Root's avatar
Kenny Root committed
2206
        String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid));
2207 2208

        String8 target8(destKey);
2209
        String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid));
Kenny Root's avatar
Kenny Root committed
2210

Kenny Root's avatar
Kenny Root committed
2211 2212
        if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
            ALOGD("destination already exists: %s", targetFile.string());
Kenny Root's avatar
Kenny Root committed
2213 2214 2215
            return ::SYSTEM_ERROR;
        }

2216
        Blob keyBlob;
Kenny Root's avatar
Kenny Root committed
2217
        ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY,
2218
                srcUid);
2219 2220
        if (responseCode != ::NO_ERROR) {
            return responseCode;
Kenny Root's avatar
Kenny Root committed
2221
        }
2222

2223
        return mKeyStore->put(targetFile.string(), &keyBlob, destUid);
Kenny Root's avatar
Kenny Root committed
2224 2225
    }

2226 2227
    int32_t is_hardware_backed(const String16& keyType) {
        return mKeyStore->isHardwareBacked(keyType) ? 1 : 0;
2228 2229
    }

2230 2231
    int32_t clear_uid(int64_t targetUid64) {
        uid_t targetUid = static_cast<uid_t>(targetUid64);
2232 2233 2234 2235 2236 2237
        uid_t callingUid = IPCThreadState::self()->getCallingUid();
        if (!has_permission(callingUid, P_CLEAR_UID)) {
            ALOGW("permission denied for %d: clear_uid", callingUid);
            return ::PERMISSION_DENIED;
        }

Kenny Root's avatar
Kenny Root committed
2238
        State state = mKeyStore->getState(callingUid);
2239 2240 2241 2242 2243
        if (!isKeystoreUnlocked(state)) {
            ALOGD("calling clear_uid in state: %d", state);
            return state;
        }

2244 2245 2246 2247 2248 2249
        if (targetUid64 == -1) {
            targetUid = callingUid;
        } else if (!is_granted_to(callingUid, targetUid)) {
            return ::PERMISSION_DENIED;
        }

2250 2251
        const keymaster_device_t* device = mKeyStore->getDevice();
        if (device == NULL) {
Kenny Root's avatar
Kenny Root committed
2252
            ALOGW("can't get keymaster device");
2253 2254 2255
            return ::SYSTEM_ERROR;
        }

2256
        UserState* userState = mKeyStore->getUserState(targetUid);
Kenny Root's avatar
Kenny Root committed
2257
        DIR* dir = opendir(userState->getUserDirName());
2258
        if (!dir) {
Kenny Root's avatar
Kenny Root committed
2259
            ALOGW("can't open user directory: %s", strerror(errno));
2260 2261 2262
            return ::SYSTEM_ERROR;
        }

Kenny Root's avatar
Kenny Root committed
2263
        char prefix[NAME_MAX];
2264
        int n = snprintf(prefix, NAME_MAX, "%u_", targetUid);
2265 2266 2267 2268 2269

        ResponseCode rc = ::NO_ERROR;

        struct dirent* file;
        while ((file = readdir(dir)) != NULL) {
Kenny Root's avatar
Kenny Root committed
2270 2271
            // We only care about files.
            if (file->d_type != DT_REG) {
2272 2273 2274
                continue;
            }

Kenny Root's avatar
Kenny Root committed
2275 2276 2277 2278 2279 2280 2281 2282
            // Skip anything that starts with a "."
            if (file->d_name[0] == '.') {
                continue;
            }

            if (strncmp(prefix, file->d_name, n)) {
                continue;
            }
2283

Kenny Root's avatar
Kenny Root committed
2284
            String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name));
2285
            Blob keyBlob;
2286
            if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, targetUid)
Kenny Root's avatar
Kenny Root committed
2287 2288
                    != ::NO_ERROR) {
                ALOGW("couldn't open %s", filename.string());
2289 2290 2291 2292 2293
                continue;
            }

            if (keyBlob.getType() == ::TYPE_KEY_PAIR) {
                // A device doesn't have to implement delete_keypair.
2294
                if (device->delete_keypair != NULL && !keyBlob.isFallback()) {
2295 2296
                    if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
                        rc = ::SYSTEM_ERROR;
Kenny Root's avatar
Kenny Root committed
2297
                        ALOGW("device couldn't remove %s", filename.string());
2298 2299 2300 2301
                    }
                }
            }

Kenny Root's avatar
Kenny Root committed
2302
            if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) {
2303
                rc = ::SYSTEM_ERROR;
Kenny Root's avatar
Kenny Root committed
2304
                ALOGW("couldn't unlink %s", filename.string());
2305 2306 2307 2308 2309 2310 2311
            }
        }
        closedir(dir);

        return rc;
    }

Kenny Root's avatar
Kenny Root committed
2312
private:
2313 2314 2315 2316 2317 2318 2319 2320 2321
    inline bool isKeystoreUnlocked(State state) {
        switch (state) {
        case ::STATE_NO_ERROR:
            return true;
        case ::STATE_UNINITIALIZED:
        case ::STATE_LOCKED:
            return false;
        }
        return false;
2322
    }
Kenny Root's avatar
Kenny Root committed
2323 2324 2325 2326 2327

    ::KeyStore* mKeyStore;
};

}; // namespace android
2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342

int main(int argc, char* argv[]) {
    if (argc < 2) {
        ALOGE("A directory must be specified!");
        return 1;
    }
    if (chdir(argv[1]) == -1) {
        ALOGE("chdir: %s: %s", argv[1], strerror(errno));
        return 1;
    }

    Entropy entropy;
    if (!entropy.open()) {
        return 1;
    }
2343 2344 2345 2346 2347 2348 2349 2350

    keymaster_device_t* dev;
    if (keymaster_device_initialize(&dev)) {
        ALOGE("keystore keymaster could not be initialized; exiting");
        return 1;
    }

    KeyStore keyStore(&entropy, dev);
Kenny Root's avatar
Kenny Root committed
2351
    keyStore.initialize();
Kenny Root's avatar
Kenny Root committed
2352 2353 2354 2355 2356 2357
    android::sp<android::IServiceManager> sm = android::defaultServiceManager();
    android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
    android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy);
    if (ret != android::OK) {
        ALOGE("Couldn't register binder service!");
        return -1;
2358
    }
2359

Kenny Root's avatar
Kenny Root committed
2360 2361 2362 2363 2364
    /*
     * We're the only thread in existence, so we're just going to process
     * Binder transaction as a single-threaded program.
     */
    android::IPCThreadState::self()->joinThreadPool();
2365

Kenny Root's avatar
Kenny Root committed
2366
    keymaster_device_release(dev);
2367 2368
    return 1;
}