keystore.cpp revision a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1
1a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/*
2a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Copyright (C) 2009 The Android Open Source Project
3a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *
4a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
5a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * you may not use this file except in compliance with the License.
6a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * You may obtain a copy of the License at
7a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *
8a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
9a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *
10a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Unless required by applicable law or agreed to in writing, software
11a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
12a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * See the License for the specific language governing permissions and
14a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * limitations under the License.
15a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root */
16a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
17a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h>
18a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h>
19a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h>
20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h>
21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h>
22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h>
23a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h>
24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h>
25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h>
26822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h>
27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h>
28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h>
29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h>
30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h>
31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h>
32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h>
34822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h>
35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h>
36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h>
37822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h>
38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h>
4070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
41822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <utils/UniquePtr.h>
42822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/list.h>
4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root//#define LOG_NDEBUG 0
46a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define LOG_TAG "keystore"
47a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h>
48a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h>
49a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h>
50a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
51a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include "keystore.h"
52a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation,
54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and
55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a
56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than
57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */
58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE        ((NAME_MAX - 15) / 2)
60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE      32768
61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE   VALUE_SIZE
62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
63822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
64822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete {
65822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(BIO* p) const {
66822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        BIO_free(p);
67822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
68822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
69822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
70822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
71822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete {
72822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(EVP_PKEY* p) const {
73822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        EVP_PKEY_free(p);
74822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
75822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
77822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
78822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete {
79822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        PKCS8_PRIV_KEY_INFO_free(p);
81822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
82822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
86a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct Value {
87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Value(const uint8_t* orig, int origLen) {
88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        assert(origLen <= VALUE_SIZE);
89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        memcpy(value, orig, origLen);
90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        length = origLen;
91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Value() {
94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
96a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int length;
97a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE];
98a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
99a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootclass ValueString {
10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootpublic:
10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ValueString(const Value* orig) {
103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        assert(length <= VALUE_SIZE);
10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        length = orig->length;
10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value = new char[length + 1];
10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        memcpy(value, orig->value, length);
10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value[length] = '\0';
10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ~ValueString() {
11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        delete[] value;
11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const char* c_str() const {
11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return value;
11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char* release() {
11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        char* ret = value;
12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value = NULL;
12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return ret;
12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootprivate:
12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char* value;
12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t length;
12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root};
12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) {
13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const hw_module_t* mod;
13370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
13470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
13570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not find any keystore module");
13670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
13770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
13870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = keymaster_open(mod, dev);
14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not open keymaster device in %s (%s)",
14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
14470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
14570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout:
14970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *dev = NULL;
15070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return rc;
15170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
15270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
15370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) {
15470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_close(dev);
15570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
15670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary
158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded
159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first
160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into
161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */
163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
16470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key(char* out, const Value* key) {
165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    const uint8_t* in = key->value;
166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int length = key->length;
167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = length; i > 0; --i, ++in, ++out) {
168a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (*in >= '0' && *in <= '~') {
169a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = *in;
170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
171a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = '+' + (*in >> 6);
172a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *++out = '0' + (*in & 0x3F);
173a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ++length;
174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
17770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return length;
17870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
17970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
18070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const Value* key) {
18170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int n = snprintf(out, NAME_MAX, "%u_", uid);
18270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    out += n;
18370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
18470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return n + encode_key(out, key);
185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1875187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic int decode_key(uint8_t* out, const char* in, int length) {
188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = 0; i < length; ++i, ++in, ++out) {
189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (*in >= '0' && *in <= '~') {
190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = *in;
191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
192a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = (*in - '+') << 6;
193a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out |= (*++in - '0') & 0x3F;
194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            --length;
195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
198a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return length;
199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
200a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
201a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) {
202a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
203a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
204a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size));
205a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (n == -1 || n == 0) {
206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return size-remaining;
207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
214a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) {
215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size));
218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (n == -1 || n == 0) {
219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return size-remaining;
220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy {
228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy() : mRandom(-1) {}
230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ~Entropy() {
231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRandom != -1) {
232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            close(mRandom);
233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool open() {
237a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* randomDevice = "/dev/urandom";
238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mRandom = ::open(randomDevice, O_RDONLY);
239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRandom == -1) {
240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ALOGE("open: %s: %s", randomDevice, strerror(errno));
241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2465187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool generate_random_data(uint8_t* data, size_t size) const {
247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (readFully(mRandom, data, size) == size);
248a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
249a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
250a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
251a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int mRandom;
252a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
253a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
254a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and
255a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size
256a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in
257a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two
258822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version,
259822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other
260a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob()
261a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */
262a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
263822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: **
264822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction:
265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   metadata || Enc(MD5(data) || data)
266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing:
268822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
269822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Derive independent keys for encryption and MAC:
270822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kenc = AES_encrypt(masterKey, "Encrypt")
271822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kmac = AES_encrypt(masterKey, "MAC")
272822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
273822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Store this:
274822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
275822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *             HMAC(Kmac, metadata || Enc(data))
276822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */
277a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob {
278822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t version;
279822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t type;
280822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t reserved;
281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t info;
282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t vector[AES_BLOCK_SIZE];
283822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t encrypted[0]; // Marks offset to encrypted data.
284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t digest[MD5_DIGEST_LENGTH];
285822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t digested[0]; // Marks offset to digested data.
286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int32_t length; // in network byte order when encrypted
287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
289a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum {
291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_GENERIC = 1,
292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_MASTER_KEY = 2,
293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_KEY_PAIR = 3,
294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType;
295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstatic const uint8_t CurrentBlobVersion = 1;
297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob {
299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength, BlobType type) {
301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = valueLength;
302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value, value, valueLength);
303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.info = infoLength;
305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value + valueLength, info, infoLength);
306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.version = CurrentBlobVersion;
308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob(blob b) {
312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob = b;
313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob() {}
316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3175187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getValue() const {
318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.value;
319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3215187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int32_t getLength() const {
322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.length;
323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3255187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getInfo() const {
3265187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return mBlob.value + mBlob.length;
3275187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
3285187818895c4c5f650a611c40531b1dff7764c18Kenny Root
3295187818895c4c5f650a611c40531b1dff7764c18Kenny Root    uint8_t getInfoLength() const {
330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.info;
331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
333822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t getVersion() const {
334822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return mBlob.version;
335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
336822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setVersion(uint8_t version) {
338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.version = version;
339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    BlobType getType() const {
342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return BlobType(mBlob.type);
343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setType(BlobType type) {
346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) {
350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // data includes the value and the value's length
355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t dataLength = mBlob.length + sizeof(mBlob.length);
356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // pad data to the AES_BLOCK_SIZE
357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                                 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // encrypted data includes the digest value
360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // move info after space for padding
362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // zero padding area
364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = htonl(mBlob.length);
367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        MD5(mBlob.digested, digestedLength, mBlob.digest);
368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t vector[AES_BLOCK_SIZE];
370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                        aes_key, vector, AES_ENCRYPT);
373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
374822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.reserved = 0;
375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = encryptedLength + headerLength + mBlob.info;
377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* tmpFileName = ".tmp";
379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (out == -1) {
381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(out) != 0) {
385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (writtenBytes != fileLength) {
388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(tmpFileName);
389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR;
392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int in = open(filename, O_RDONLY);
396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (in == -1) {
397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // fileLength may be less than sizeof(mBlob) since the in
400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // memory version has extra padding to tolerate rounding up to
401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES_BLOCK_SIZE
402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (fileLength < headerLength) {
408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) {
413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                        mBlob.vector, AES_DECRYPT);
417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t computedDigest[MD5_DIGEST_LENGTH];
419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        MD5(mBlob.digested, digestedLength, computedDigest);
420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = ntohl(mBlob.length);
426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.length < 0 || mBlob.length > maxValueLength) {
427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.info != 0) {
430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // move info from after padding to after data
431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return NO_ERROR;
434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct blob mBlob;
438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
44070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct {
44170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint32_t uid;
442a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    const uint8_t* filename;
44370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
44470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    struct listnode plist;
44570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t;
44670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore {
448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
44970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    KeyStore(Entropy* entropy, keymaster_device_t* device)
4505187818895c4c5f650a611c40531b1dff7764c18Kenny Root        : mEntropy(entropy)
45170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        , mDevice(device)
4525187818895c4c5f650a611c40531b1dff7764c18Kenny Root        , mRetry(MAX_RETRY)
4535187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {
454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (access(MASTER_KEY_FILE, R_OK) == 0) {
455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_LOCKED);
456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_UNINITIALIZED);
458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
45970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
46070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        list_init(&mGrants);
461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4635187818895c4c5f650a611c40531b1dff7764c18Kenny Root    State getState() const {
464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mState;
465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4675187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int8_t getRetry() const {
468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mRetry;
469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
47170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* getDevice() const {
47270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return mDevice;
47370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
47470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode initialize(Value* pw) {
476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!generateMasterKey()) {
477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ResponseCode response = writeMasterKey(pw);
480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response != NO_ERROR) {
481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setupMasterKeys();
484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return NO_ERROR;
485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode writeMasterKey(Value* pw) {
488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode readMasterKey(Value* pw) {
497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int in = open(MASTER_KEY_FILE, O_RDONLY);
498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (in == -1) {
499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // we read the raw blob to just to get the salt to generate
503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES key, then we create the Blob to use with decryptBlob
504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        blob rawBlob;
505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // find salt at EOF if present, otherwise we have an old file
510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t* salt;
511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = NULL;
515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        Blob masterKeyBlob(rawBlob);
521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == SYSTEM_ERROR) {
523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // if salt was missing, generate one and write a new master key file with the salt.
527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (salt == NULL) {
528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                if (!generateSalt()) {
529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    return SYSTEM_ERROR;
530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                }
531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                response = writeMasterKey(pw);
532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (response == NO_ERROR) {
534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                setupMasterKeys();
536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRetry <= 0) {
540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            reset();
541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return UNINITIALIZED;
542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        --mRetry;
544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        switch (mRetry) {
545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 0: return WRONG_PASSWORD_0;
546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 1: return WRONG_PASSWORD_1;
547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 2: return WRONG_PASSWORD_2;
548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 3: return WRONG_PASSWORD_3;
549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            default: return WRONG_PASSWORD_3;
550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool reset() {
554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        clearMasterKeys();
555a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_UNINITIALIZED);
556a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        DIR* dir = opendir(".");
558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct dirent* file;
559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(file->d_name);
565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5705187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool isEmpty() const {
571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        DIR* dir = opendir(".");
572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct dirent* file;
573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return true;
575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        bool result = true;
577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (isKeyFile(file->d_name)) {
579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                result = false;
580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                break;
581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return result;
585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void lock() {
588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        clearMasterKeys();
589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_LOCKED);
590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
592822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) {
593822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
594822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc != NO_ERROR) {
595822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return rc;
596822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
597822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
598822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        const uint8_t version = keyBlob->getVersion();
599822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (version < CurrentBlobVersion) {
600822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            upgrade(filename, keyBlob, version, type);
601822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
602822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
603822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (keyBlob->getType() != type) {
604822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
605822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return KEY_NOT_FOUND;
606822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
607822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
608822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return rc;
609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode put(const char* filename, Blob* keyBlob) {
612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
61570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void addGrant(const char* filename, const Value* uidValue) {
61670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uid_t uid;
61770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (!convertToUid(uidValue, &uid)) {
61870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return;
61970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
62070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
62170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        grant_t *grant = getGrant(filename, uid);
62270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (grant == NULL) {
62370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant = new grant_t;
62470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant->uid = uid;
625a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom            grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
62670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            list_add_tail(&mGrants, &grant->plist);
62770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
62870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
62970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
630a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    bool removeGrant(const char* filename, const Value* uidValue) {
63170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uid_t uid;
63270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (!convertToUid(uidValue, &uid)) {
63370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return false;
63470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
63570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
636a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom        grant_t *grant = getGrant(filename, uid);
63770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (grant != NULL) {
63870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            list_remove(&grant->plist);
63970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            delete grant;
64070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return true;
64170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
64270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
64370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return false;
64470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
64570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
646a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    bool hasGrant(const char* filename, const uid_t uid) const {
647a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom        return getGrant(filename, uid) != NULL;
64870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
64970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
650822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode importKey(const Value* key, const char* filename) {
651822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t* data;
652822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        size_t dataLength;
653822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        int rc;
654822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
655822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (mDevice->import_keypair == NULL) {
656822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Keymaster doesn't support import!");
657822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
658822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
659822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
660822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        rc = mDevice->import_keypair(mDevice, key->value, key->length, &data, &dataLength);
661822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc) {
662822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Error while importing keypair: %d", rc);
663822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
664822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
665822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
666822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
667822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        free(data);
668822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
669822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return put(filename, &keyBlob);
670822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
671822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const char* MASTER_KEY_FILE;
674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MASTER_KEY_SIZE_BYTES = 16;
675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MAX_RETRY = 4;
678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const size_t SALT_SIZE = 16;
679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy* mEntropy;
681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
68270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* mDevice;
68370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    State mState;
685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int8_t mRetry;
686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t mSalt[SALT_SIZE];
689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    AES_KEY mMasterKeyEncryption;
691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    AES_KEY mMasterKeyDecryption;
692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
69370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    struct listnode mGrants;
69470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void setState(State state) {
696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mState = state;
697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            mRetry = MAX_RETRY;
699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool generateSalt() {
703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool generateMasterKey() {
707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!generateSalt()) {
711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void setupMasterKeys() {
717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_NO_ERROR);
720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void clearMasterKeys() {
723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mMasterKey, 0, sizeof(mMasterKey));
724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mSalt, 0, sizeof(mSalt));
725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) {
730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t saltSize;
731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (salt != NULL) {
732a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            saltSize = SALT_SIZE;
733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) "keystore";
736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // sizeof = 9, not strlen = 8
737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            saltSize = sizeof("keystore");
738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key);
740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static bool isKeyFile(const char* filename) {
743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return ((strcmp(filename, MASTER_KEY_FILE) != 0)
744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                && (strcmp(filename, ".") != 0)
745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                && (strcmp(filename, "..") != 0));
746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
74770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
748a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    grant_t* getGrant(const char* filename, uid_t uid) const {
74970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        struct listnode *node;
75070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        grant_t *grant;
75170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
75270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        list_for_each(node, &mGrants) {
75370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant = node_to_item(node, grant_t, plist);
75470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            if (grant->uid == uid
755a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom                    && !strcmp(reinterpret_cast<const char*>(grant->filename),
756a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom                               filename)) {
75770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                return grant;
75870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            }
75970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
76070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
76170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
76270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
76370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
76470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    bool convertToUid(const Value* uidValue, uid_t* uid) const {
76570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ValueString uidString(uidValue);
76670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        char* end = NULL;
76770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        *uid = strtol(uidString.c_str(), &end, 10);
76870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return *end == '\0';
76970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
770822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
771822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
772822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Upgrade code. This will upgrade the key from the current version
773822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * to whatever is newest.
774822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
775822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) {
776822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        bool updated = false;
777822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t version = oldVersion;
778822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
779822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /* From V0 -> V1: All old types were unknown */
780822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (version == 0) {
781822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("upgrading to version 1 and setting type %d", type);
782822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
783822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setType(type);
784822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            if (type == TYPE_KEY_PAIR) {
785822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root                importBlobAsKey(blob, filename);
786822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            }
787822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            version = 1;
788822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            updated = true;
789822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
790822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
791822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /*
792822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * If we've updated, set the key blob to the right version
793822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * and write it.
794822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * */
795822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (updated) {
796822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("updated and writing file %s", filename);
797822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setVersion(version);
798822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            this->put(filename, blob);
799822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
800822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
801822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
802822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
803822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Takes a blob that is an PEM-encoded RSA key as a byte array and
804822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * converts it to a DER-encoded PKCS#8 for import into a keymaster.
805822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Then it overwrites the original blob with the new blob
806822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * format that is returned from the keymaster.
807822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
808822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode importBlobAsKey(Blob* blob, const char* filename) {
809822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        // We won't even write to the blob directly with this BIO, so const_cast is okay.
810822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
811822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (b.get() == NULL) {
812822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Problem instantiating BIO");
813822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
814822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
815822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
816822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
817822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (pkey.get() == NULL) {
818822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't read old PEM file");
819822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
820822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
821822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
822822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
823822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
824822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (len < 0) {
825822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't measure PKCS#8 length");
826822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
827822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
828822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
829822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Value pkcs8key;
830822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        pkcs8key.length = len;
831822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t* tmp = pkcs8key.value;
832822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
833822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't convert to PKCS#8");
834822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
835822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
836822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
837822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        ResponseCode rc = importKey(&pkcs8key, filename);
838822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc != NO_ERROR) {
839822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return rc;
840822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
841822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
842822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return get(filename, blob, TYPE_KEY_PAIR);
843822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey";
847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the protocol used in both requests and responses:
849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *     code [length_1 message_1 ... length_n message_n] end-of-file
850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * where code is one byte long and lengths are unsigned 16-bit integers in
851a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * network order. Thus the maximum length of a message is 65535 bytes. */
852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_code(int sock, int8_t* code) {
854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return recv(sock, code, 1, 0) == 1;
855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_message(int sock, uint8_t* message, int length) {
858a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t bytes[2];
859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (recv(sock, &bytes[0], 1, 0) != 1 ||
860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        recv(sock, &bytes[1], 1, 0) != 1) {
861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return -1;
862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    } else {
863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int offset = bytes[0] << 8 | bytes[1];
864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (length < offset) {
865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return -1;
866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
867a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        length = offset;
868a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        offset = 0;
869a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while (offset < length) {
870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            int n = recv(sock, &message[offset], length - offset, 0);
871a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (n <= 0) {
872a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                return -1;
873a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
874a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            offset += n;
875a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
876a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
877a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return length;
878a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
879a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
880a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_end_of_file(int sock) {
881a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t byte;
882a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return recv(sock, &byte, 1, 0) == 0;
883a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
884a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
885a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic void send_code(int sock, int8_t code) {
886a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send(sock, &code, 1, 0);
887a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
888a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
8895187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic void send_message(int sock, const uint8_t* message, int length) {
890a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint16_t bytes = htons(length);
891a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send(sock, &bytes, 2, 0);
892a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send(sock, message, length, 0);
893a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
894a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
89570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName,
896822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        const uid_t uid, const BlobType type) {
89770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
89870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
89970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
900822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode responseCode = keyStore->get(filename, keyBlob, type);
90170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode == NO_ERROR) {
90270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
90370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
90470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
90570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // If this is the Wifi or VPN user, they actually want system
90670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // UID keys.
90770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (uid == AID_WIFI || uid == AID_VPN) {
90870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        encode_key_for_uid(filename, AID_SYSTEM, keyName);
909822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        responseCode = keyStore->get(filename, keyBlob, type);
91070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (responseCode == NO_ERROR) {
91170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return responseCode;
91270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
91370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
91470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
91570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // They might be using a granted key.
916a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    encode_key(filename, keyName);
917a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    if (!keyStore->hasGrant(filename, uid)) {
91870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
91970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
92070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
92170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // It is a granted key. Try to load it.
922822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    return keyStore->get(filename, keyBlob, type);
92370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
92470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
925a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here are the actions. Each of them is a function without arguments. All
926a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * information is defined in global variables, which are set properly before
927a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * performing an action. The number of parameters required by each action is
928a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * fixed and defined in a table. If the return value of an action is positive,
929a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * it will be treated as a response code and transmitted to the client. Note
930a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that the lengths of parameters are checked when they are received, so
931a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * boundary checks on parameters are omitted. */
932a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
933a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0;
934a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
935da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode test(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
936a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return (ResponseCode) keyStore->getState();
937a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
938a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
9395187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
940a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
94170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
942a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob keyBlob;
943822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC);
944a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (responseCode != NO_ERROR) {
945a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return responseCode;
946a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
947a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send_code(sock, NO_ERROR);
948a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send_message(sock, keyBlob.getValue(), keyBlob.getLength());
949a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
950a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
951a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
952da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode insert(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* val,
9535187818895c4c5f650a611c40531b1dff7764c18Kenny Root        Value*) {
954a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
95570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
956822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Blob keyBlob(val->value, val->length, NULL, 0, TYPE_GENERIC);
957a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return keyStore->put(filename, &keyBlob);
958a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
959a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
960da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode del(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*, Value*) {
961a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
96270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
963822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Blob keyBlob;
964822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC);
965822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    if (responseCode != NO_ERROR) {
966822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return responseCode;
967822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
968a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
969a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
970a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
971da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode exist(KeyStore*, int, uid_t uid, Value* keyName, Value*, Value*) {
972a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
97370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
974a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (access(filename, R_OK) == -1) {
975a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
976a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
977a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR;
978a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
979a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
980da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode saw(KeyStore*, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) {
981a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    DIR* dir = opendir(".");
982a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!dir) {
983a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return SYSTEM_ERROR;
984a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
985a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
98670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int n = encode_key_for_uid(filename, uid, keyPrefix);
987a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send_code(sock, NO_ERROR);
988a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
989a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct dirent* file;
990a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while ((file = readdir(dir)) != NULL) {
991a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!strncmp(filename, file->d_name, n)) {
9925187818895c4c5f650a611c40531b1dff7764c18Kenny Root            const char* p = &file->d_name[n];
993a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p));
994a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            send_message(sock, keyPrefix->value, keyPrefix->length);
995a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
996a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
997a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    closedir(dir);
998a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
999a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1000a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1001da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode reset(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
1002298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    ResponseCode rc = keyStore->reset() ? NO_ERROR : SYSTEM_ERROR;
1003298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1004298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    const keymaster_device_t* device = keyStore->getDevice();
1005298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    if (device == NULL) {
1006298e7b1b0f9116e2054d594d7538379d86585035Kenny Root        ALOGE("No keymaster device!");
1007298e7b1b0f9116e2054d594d7538379d86585035Kenny Root        return SYSTEM_ERROR;
1008298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1009298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1010298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    if (device->delete_all == NULL) {
1011298e7b1b0f9116e2054d594d7538379d86585035Kenny Root        ALOGV("keymaster device doesn't implement delete_all");
1012298e7b1b0f9116e2054d594d7538379d86585035Kenny Root        return rc;
1013298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1014298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1015298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    if (device->delete_all(device)) {
1016298e7b1b0f9116e2054d594d7538379d86585035Kenny Root        ALOGE("Problem calling keymaster's delete_all");
1017298e7b1b0f9116e2054d594d7538379d86585035Kenny Root        return SYSTEM_ERROR;
1018298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1019298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1020298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    return rc;
1021a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1022a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1023a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the history. To improve the security, the parameters to generate the
1024a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * master key has been changed. To make a seamless transition, we update the
1025a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * file using the same password when the user unlock it for the first time. If
1026a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * any thing goes wrong during the transition, the new file will not overwrite
1027a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the old one. This avoids permanent damages of the existing data. */
1028a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1029da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode password(KeyStore* keyStore, int, uid_t, Value* pw, Value*, Value*) {
1030a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    switch (keyStore->getState()) {
1031a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        case STATE_UNINITIALIZED: {
1032a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // generate master key, encrypt with password, write to file, initialize mMasterKey*.
1033a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return keyStore->initialize(pw);
1034a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1035a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        case STATE_NO_ERROR: {
1036a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // rewrite master key with new password.
1037a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return keyStore->writeMasterKey(pw);
1038a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1039a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        case STATE_LOCKED: {
1040a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // read master key, decrypt with password, initialize mMasterKey*.
1041a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return keyStore->readMasterKey(pw);
1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1043a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1044a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return SYSTEM_ERROR;
1045a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1046a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1047da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode lock(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
1048a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    keyStore->lock();
1049a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR;
1050a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1051a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
10525187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused,
10535187818895c4c5f650a611c40531b1dff7764c18Kenny Root        Value* unused2) {
10545187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return password(keyStore, sock, uid, pw, unused, unused2);
1055a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1056a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1057da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode zero(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
1058a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR;
1059a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1060a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1061da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode generate(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*,
106270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
106370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
106470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* data;
106570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t dataLength;
106670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
106770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
106870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
106970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
107070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
1072a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
107370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->generate_keypair == NULL) {
107470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
107570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
107670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
107770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_rsa_keygen_params_t rsa_params;
107870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rsa_params.modulus_size = 2048;
107970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rsa_params.public_exponent = 0x10001;
108070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
108170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
108270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
108370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
108470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
108570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
108670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
108770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1088822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
108970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    free(data);
109070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
109170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return keyStore->put(filename, &keyBlob);
109270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
109370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1094da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode import(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* key,
109570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
109670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
109770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
109870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
109970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    return keyStore->importKey(key, filename);
110170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
110270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
110370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/*
110470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * TODO: The abstraction between things stored in hardware and regular blobs
110570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * of data stored on the filesystem should be moved down to keystore itself.
110670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Unfortunately the Java code that calls this has naming conventions that it
110770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of
110870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * data.
110970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *
111070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and
111170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * "del_key" since the Java code doesn't really communicate what it's
111270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * intentions are.
111370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */
111470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
111570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
111670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid);
111770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1118822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
111970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
112070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
112170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
112270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
112370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
112470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
112570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
112670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
112770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
112870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->get_keypair_public == NULL) {
112970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("device has no get_keypair_public implementation!");
113070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
113170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
113270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
113370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* data = NULL;
113470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t dataLength;
113570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
113670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data,
113770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            &dataLength);
113870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
113970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
114070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
114170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
114270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_code(sock, NO_ERROR);
114370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_message(sock, data, dataLength);
114470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    free(data);
114570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
114670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
114770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
114870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1149da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode del_key(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*,
115070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
115170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
115270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
115370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
1154822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_KEY_PAIR);
115570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
115670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
115770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
115870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
115970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
116070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
116170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
116270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
116370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
116470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->delete_keypair == NULL) {
116570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("device has no delete_keypair implementation!");
116670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
116770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
116870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
116970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc = device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength());
117070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
117170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return rc ? SYSTEM_ERROR : NO_ERROR;
117270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
117370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
117470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode sign(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data,
117570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
117670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ALOGV("sign %s from uid %d", ValueString(keyName).c_str(), uid);
117770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
117870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
117970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1180822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
118170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
118270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
118370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
118470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
118570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* signedData;
118670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t signedDataLength;
118770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
118870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
118970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
1190822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        ALOGE("no keymaster device; cannot sign");
119170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
119270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
119370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
119470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->sign_data == NULL) {
1195822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        ALOGE("device doesn't implement signing");
119670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
119770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
119870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
119970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_rsa_sign_params_t params;
120070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.digest_type = DIGEST_NONE;
120170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.padding_type = PADDING_NONE;
120270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
120370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
120470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            data->value, data->length, &signedData, &signedDataLength);
120570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
1206822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        ALOGW("device couldn't sign data");
120770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
120870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
120970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
121070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_code(sock, NO_ERROR);
121170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_message(sock, signedData, signedDataLength);
121270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
121370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
121470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1215da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode verify(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* data,
121670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value* signature) {
121770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
121870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
121970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1220822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
122170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
122270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
122370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
122470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
122570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
122670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
122770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
122870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
122970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
123070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->verify_data == NULL) {
123170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
123270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
123370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
123470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_rsa_sign_params_t params;
123570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.digest_type = DIGEST_NONE;
123670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.padding_type = PADDING_NONE;
123770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
123870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
123970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            data->value, data->length, signature->value, signature->length);
124070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
124170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
124270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    } else {
124370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NO_ERROR;
124470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
124570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
124670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1247da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode grant(KeyStore* keyStore, int, uid_t uid, Value* keyName,
124870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value* granteeData, Value*) {
124970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
125070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
125170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (access(filename, R_OK) == -1) {
125270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
125370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
125470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
125570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keyStore->addGrant(filename, granteeData);
125670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return NO_ERROR;
125770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
125870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1259da1ed9ab99c00698af64ec655ff668efffe2960dKenny Rootstatic ResponseCode ungrant(KeyStore* keyStore, int, uid_t uid, Value* keyName,
126070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value* granteeData, Value*) {
126170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
126270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
126370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (access(filename, R_OK) == -1) {
126470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
126570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
126670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1267a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    return keyStore->removeGrant(filename, granteeData) ? NO_ERROR : KEY_NOT_FOUND;
126870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
126970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
127070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* Here are the permissions, actions, users, and the main function. */
1271a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootenum perm {
12725187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_TEST     = 1 << TEST,
12735187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_GET      = 1 << GET,
12745187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_INSERT   = 1 << INSERT,
12755187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_DELETE   = 1 << DELETE,
12765187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_EXIST    = 1 << EXIST,
12775187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_SAW      = 1 << SAW,
12785187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_RESET    = 1 << RESET,
12795187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_PASSWORD = 1 << PASSWORD,
12805187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_LOCK     = 1 << LOCK,
12815187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_UNLOCK   = 1 << UNLOCK,
12825187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_ZERO     = 1 << ZERO,
128370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    P_SIGN     = 1 << SIGN,
128470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    P_VERIFY   = 1 << VERIFY,
128570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    P_GRANT    = 1 << GRANT,
1286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
1287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
12885187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic const int MAX_PARAM = 3;
1289a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1290a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const State STATE_ANY = (State) 0;
1291a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1292a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct action {
12935187818895c4c5f650a611c40531b1dff7764c18Kenny Root    ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2,
12945187818895c4c5f650a611c40531b1dff7764c18Kenny Root            Value* param3);
1295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int8_t code;
1296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    State state;
1297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint32_t perm;
1298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int lengths[MAX_PARAM];
1299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} actions[] = {
13005187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {test,       CommandCodes[TEST],       STATE_ANY,      P_TEST,     {0, 0, 0}},
13015187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {get,        CommandCodes[GET],        STATE_NO_ERROR, P_GET,      {KEY_SIZE, 0, 0}},
13025187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {insert,     CommandCodes[INSERT],     STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, VALUE_SIZE, 0}},
13035187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {del,        CommandCodes[DELETE],     STATE_ANY,      P_DELETE,   {KEY_SIZE, 0, 0}},
13045187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {exist,      CommandCodes[EXIST],      STATE_ANY,      P_EXIST,    {KEY_SIZE, 0, 0}},
13055187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {saw,        CommandCodes[SAW],        STATE_ANY,      P_SAW,      {KEY_SIZE, 0, 0}},
13065187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {reset,      CommandCodes[RESET],      STATE_ANY,      P_RESET,    {0, 0, 0}},
13075187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {password,   CommandCodes[PASSWORD],   STATE_ANY,      P_PASSWORD, {PASSWORD_SIZE, 0, 0}},
13085187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {lock,       CommandCodes[LOCK],       STATE_NO_ERROR, P_LOCK,     {0, 0, 0}},
13095187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {unlock,     CommandCodes[UNLOCK],     STATE_LOCKED,   P_UNLOCK,   {PASSWORD_SIZE, 0, 0}},
13105187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {zero,       CommandCodes[ZERO],       STATE_ANY,      P_ZERO,     {0, 0, 0}},
131170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {generate,   CommandCodes[GENERATE],   STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, 0, 0}},
131270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {import,     CommandCodes[IMPORT],     STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, VALUE_SIZE, 0}},
131370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {sign,       CommandCodes[SIGN],       STATE_NO_ERROR, P_SIGN,     {KEY_SIZE, VALUE_SIZE, 0}},
131470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {verify,     CommandCodes[VERIFY],     STATE_NO_ERROR, P_VERIFY,   {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}},
131570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET,      {KEY_SIZE, 0, 0}},
131670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {del_key,    CommandCodes[DEL_KEY],    STATE_ANY,      P_DELETE,   {KEY_SIZE, 0, 0}},
131770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {grant,      CommandCodes[GRANT],      STATE_NO_ERROR, P_GRANT,    {KEY_SIZE, KEY_SIZE, 0}},
131870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {ungrant,    CommandCodes[UNGRANT],    STATE_NO_ERROR, P_GRANT,    {KEY_SIZE, KEY_SIZE, 0}},
13195187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {NULL,       0,                        STATE_ANY,      0,          {0, 0, 0}},
1320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
1321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct user {
1323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uid_t uid;
1324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uid_t euid;
1325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint32_t perms;
1326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} users[] = {
1327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    {AID_SYSTEM,   ~0,         ~0},
132870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {AID_VPN,      AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
132970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {AID_WIFI,     AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
13305187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {AID_ROOT,     AID_SYSTEM, P_GET},
133170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {~0,           ~0,         P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW |
133270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                               P_SIGN | P_VERIFY},
1333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
1334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) {
1336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct user* user = users;
1337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct action* action = actions;
1338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int i;
1339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1340e95ce35d10d6e0a7315a57f30d9c88d89880a4e1Amith Yamasani    while (~user->uid && user->uid != (uid % AID_USER)) {
1341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ++user;
1342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (action->code && action->code != code) {
1344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ++action;
1345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!action->code) {
1347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return UNDEFINED_ACTION;
1348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!(action->perm & user->perms)) {
1350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return PERMISSION_DENIED;
1351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (action->state != STATE_ANY && action->state != keyStore->getState()) {
1353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (ResponseCode) keyStore->getState();
1354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (~user->euid) {
1356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uid = user->euid;
1357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Value params[MAX_PARAM];
1359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) {
1360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        params[i].length = recv_message(sock, params[i].value, action->lengths[i]);
1361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (params[i].length < 0) {
1362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return PROTOCOL_ERROR;
1363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!recv_end_of_file(sock)) {
1366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return PROTOCOL_ERROR;
1367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
13685187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return action->run(keyStore, sock, uid, &params[0], &params[1], &params[2]);
1369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) {
1372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int controlSocket = android_get_control_socket("keystore");
1373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (argc < 2) {
1374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("A directory must be specified!");
1375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (chdir(argv[1]) == -1) {
1378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("chdir: %s: %s", argv[1], strerror(errno));
1379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy entropy;
1383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!entropy.open()) {
1384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
138670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
138770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* dev;
138870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (keymaster_device_initialize(&dev)) {
138970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("keystore keymaster could not be initialized; exiting");
139070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return 1;
139170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
139270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (listen(controlSocket, 3) == -1) {
1394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("listen: %s", strerror(errno));
1395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    signal(SIGPIPE, SIG_IGN);
1399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
140070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    KeyStore keyStore(&entropy, dev);
1401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int sock;
1402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while ((sock = accept(controlSocket, NULL, 0)) != -1) {
1403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct timeval tv;
1404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        tv.tv_sec = 3;
1405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
1406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
1407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct ucred cred;
1409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        socklen_t size = sizeof(cred);
1410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size);
1411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (credResult != 0) {
1412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ALOGW("getsockopt: %s", strerror(errno));
1413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
1414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            int8_t request;
1415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (recv_code(sock, &request)) {
1416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                State old_state = keyStore.getState();
1417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                ResponseCode response = process(&keyStore, sock, cred.uid, request);
1418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                if (response == NO_ERROR_RESPONSE_CODE_SENT) {
1419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    response = NO_ERROR;
1420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                } else {
1421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    send_code(sock, response);
1422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                }
1423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d",
1424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     cred.uid,
1425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     request, response,
1426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     old_state, keyStore.getState(),
1427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     keyStore.getRetry());
1428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
1429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        close(sock);
1431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ALOGE("accept: %s", strerror(errno));
143370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
143470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_release(dev);
143570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return 1;
1437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1438