keystore.cpp revision 70e3a86abd2c412d602a018967c01c177eb6cf4e
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>
26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h>
27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h>
28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h>
29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h>
30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h>
31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h>
33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h>
34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h>
35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h>
3770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
3870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/list.h>
3970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
4070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root//#define LOG_NDEBUG 0
41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define LOG_TAG "keystore"
42a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h>
43a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h>
44a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h>
45a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
46a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include "keystore.h"
47a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
48a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation,
49a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and
50a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a
51a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than
52a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */
53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE        ((NAME_MAX - 15) / 2)
55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE      32768
56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE   VALUE_SIZE
57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct Value {
59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int length;
60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE];
61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
6370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootclass ValueString {
6470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootpublic:
6570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ValueString(const Value* orig) {
6670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        length = orig->length;
6770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value = new char[length + 1];
6870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        memcpy(value, orig->value, length);
6970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value[length] = '\0';
7070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
7170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
7270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ~ValueString() {
7370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        delete[] value;
7470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
7570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
7670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const char* c_str() const {
7770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return value;
7870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
7970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
8070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char* release() {
8170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        char* ret = value;
8270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value = NULL;
8370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return ret;
8470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
8570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
8670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootprivate:
8770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char* value;
8870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t length;
8970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root};
9070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
9170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) {
9270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
9370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
9470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const hw_module_t* mod;
9570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
9670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
9770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not find any keystore module");
9870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
9970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = keymaster_open(mod, dev);
10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
10370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not open keymaster device in %s (%s)",
10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout:
11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *dev = NULL;
11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return rc;
11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) {
11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_close(dev);
11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
119a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary
120a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded
121a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first
122a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into
123a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
124a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */
125a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key(char* out, const Value* key) {
127a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    const uint8_t* in = key->value;
128a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int length = key->length;
129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = length; i > 0; --i, ++in, ++out) {
130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (*in >= '0' && *in <= '~') {
131a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = *in;
132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
133a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = '+' + (*in >> 6);
134a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *++out = '0' + (*in & 0x3F);
135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ++length;
136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
137a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
138a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return length;
14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const Value* key) {
14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int n = snprintf(out, NAME_MAX, "%u_", uid);
14470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    out += n;
14570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return n + encode_key(out, key);
147a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
148a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1495187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic int decode_key(uint8_t* out, const char* in, int length) {
150a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = 0; i < length; ++i, ++in, ++out) {
151a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (*in >= '0' && *in <= '~') {
152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = *in;
153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
154a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = (*in - '+') << 6;
155a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out |= (*++in - '0') & 0x3F;
156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            --length;
157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return length;
161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) {
164a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size));
167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (n == -1 || n == 0) {
168a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return size-remaining;
169a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
171a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
172a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
173a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) {
177a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
178a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
179a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size));
180a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (n == -1 || n == 0) {
181a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return size-remaining;
182a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
183a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
184a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
187a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy {
190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy() : mRandom(-1) {}
192a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ~Entropy() {
193a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRandom != -1) {
194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            close(mRandom);
195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
198a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool open() {
199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* randomDevice = "/dev/urandom";
200a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mRandom = ::open(randomDevice, O_RDONLY);
201a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRandom == -1) {
202a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ALOGE("open: %s: %s", randomDevice, strerror(errno));
203a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
204a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
205a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2085187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool generate_random_data(uint8_t* data, size_t size) const {
209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (readFully(mRandom, data, size) == size);
210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int mRandom;
214a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and
217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size
218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in
219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two
220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * parts must be no more than VALUE_SIZE bytes. The first three bytes of the
221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * file are reserved for future use and are always set to zero. Fields other
222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob()
223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */
224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob {
226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t reserved[3];
227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t info;
228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t vector[AES_BLOCK_SIZE];
229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t encrypted[0];
230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t digest[MD5_DIGEST_LENGTH];
231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t digested[0];
232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int32_t length; // in network byte order when encrypted
233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob {
237a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength) {
239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = valueLength;
240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value, value, valueLength);
241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.info = infoLength;
243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value + valueLength, info, infoLength);
244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
246a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob(blob b) {
247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob = b;
248a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
249a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
250a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob() {}
251a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2525187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getValue() const {
253a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.value;
254a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
255a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2565187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int32_t getLength() const {
257a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.length;
258a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
259a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2605187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getInfo() const {
2615187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return mBlob.value + mBlob.length;
2625187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
2635187818895c4c5f650a611c40531b1dff7764c18Kenny Root
2645187818895c4c5f650a611c40531b1dff7764c18Kenny Root    uint8_t getInfoLength() const {
265a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.info;
266a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
267a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
268a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) {
269a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
270a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
271a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
272a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
273a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // data includes the value and the value's length
274a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t dataLength = mBlob.length + sizeof(mBlob.length);
275a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // pad data to the AES_BLOCK_SIZE
276a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
277a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                                 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
278a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // encrypted data includes the digest value
279a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
280a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // move info after space for padding
281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // zero padding area
283a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
285a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = htonl(mBlob.length);
286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        MD5(mBlob.digested, digestedLength, mBlob.digest);
287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t vector[AES_BLOCK_SIZE];
289a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
290a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
291a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                        aes_key, vector, AES_ENCRYPT);
292a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
293a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mBlob.reserved, 0, sizeof(mBlob.reserved));
294a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = encryptedLength + headerLength + mBlob.info;
296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* tmpFileName = ".tmp";
298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (out == -1) {
300a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(out) != 0) {
304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (writtenBytes != fileLength) {
307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(tmpFileName);
308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR;
311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int in = open(filename, O_RDONLY);
315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (in == -1) {
316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // fileLength may be less than sizeof(mBlob) since the in
319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // memory version has extra padding to tolerate rounding up to
320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES_BLOCK_SIZE
321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (fileLength < headerLength) {
327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) {
332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                        mBlob.vector, AES_DECRYPT);
336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t computedDigest[MD5_DIGEST_LENGTH];
338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        MD5(mBlob.digested, digestedLength, computedDigest);
339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = ntohl(mBlob.length);
345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.length < 0 || mBlob.length > maxValueLength) {
346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.info != 0) {
349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // move info from after padding to after data
350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return NO_ERROR;
353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct blob mBlob;
357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
35970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct {
36070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint32_t uid;
36170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const uint8_t* keyName;
36270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
36370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    struct listnode plist;
36470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t;
36570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore {
367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
36870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    KeyStore(Entropy* entropy, keymaster_device_t* device)
3695187818895c4c5f650a611c40531b1dff7764c18Kenny Root        : mEntropy(entropy)
37070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        , mDevice(device)
3715187818895c4c5f650a611c40531b1dff7764c18Kenny Root        , mRetry(MAX_RETRY)
3725187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {
373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (access(MASTER_KEY_FILE, R_OK) == 0) {
374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_LOCKED);
375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_UNINITIALIZED);
377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
37870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
37970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        list_init(&mGrants);
380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3825187818895c4c5f650a611c40531b1dff7764c18Kenny Root    State getState() const {
383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mState;
384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3865187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int8_t getRetry() const {
387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mRetry;
388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
39070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* getDevice() const {
39170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return mDevice;
39270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
39370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode initialize(Value* pw) {
395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!generateMasterKey()) {
396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ResponseCode response = writeMasterKey(pw);
399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response != NO_ERROR) {
400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setupMasterKeys();
403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return NO_ERROR;
404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode writeMasterKey(Value* pw) {
407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt));
412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode readMasterKey(Value* pw) {
416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int in = open(MASTER_KEY_FILE, O_RDONLY);
417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (in == -1) {
418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // we read the raw blob to just to get the salt to generate
422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES key, then we create the Blob to use with decryptBlob
423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        blob rawBlob;
424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // find salt at EOF if present, otherwise we have an old file
429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t* salt;
430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = NULL;
434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        Blob masterKeyBlob(rawBlob);
440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == SYSTEM_ERROR) {
442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // if salt was missing, generate one and write a new master key file with the salt.
446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (salt == NULL) {
447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                if (!generateSalt()) {
448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    return SYSTEM_ERROR;
449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                }
450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                response = writeMasterKey(pw);
451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (response == NO_ERROR) {
453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                setupMasterKeys();
455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRetry <= 0) {
459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            reset();
460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return UNINITIALIZED;
461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        --mRetry;
463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        switch (mRetry) {
464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 0: return WRONG_PASSWORD_0;
465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 1: return WRONG_PASSWORD_1;
466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 2: return WRONG_PASSWORD_2;
467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 3: return WRONG_PASSWORD_3;
468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            default: return WRONG_PASSWORD_3;
469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
471a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool reset() {
473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        clearMasterKeys();
474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_UNINITIALIZED);
475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        DIR* dir = opendir(".");
477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct dirent* file;
478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(file->d_name);
484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4895187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool isEmpty() const {
490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        DIR* dir = opendir(".");
491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct dirent* file;
492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return true;
494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        bool result = true;
496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (isKeyFile(file->d_name)) {
498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                result = false;
499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                break;
500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return result;
504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void lock() {
507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        clearMasterKeys();
508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_LOCKED);
509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode get(const char* filename, Blob* keyBlob) {
512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode put(const char* filename, Blob* keyBlob) {
516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
51970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void addGrant(const char* filename, const Value* uidValue) {
52070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uid_t uid;
52170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (!convertToUid(uidValue, &uid)) {
52270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return;
52370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
52470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
52570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        grant_t *grant = getGrant(filename, uid);
52670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (grant == NULL) {
52770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant = new grant_t;
52870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant->uid = uid;
52970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant->keyName = reinterpret_cast<const uint8_t*>(strdup(filename));
53070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            list_add_tail(&mGrants, &grant->plist);
53170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
53270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
53370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
53470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    bool removeGrant(const Value* keyValue, const Value* uidValue) {
53570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uid_t uid;
53670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (!convertToUid(uidValue, &uid)) {
53770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return false;
53870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
53970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
54070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ValueString keyString(keyValue);
54170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
54270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        grant_t *grant = getGrant(keyString.c_str(), uid);
54370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (grant != NULL) {
54470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            list_remove(&grant->plist);
54570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            delete grant;
54670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return true;
54770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
54870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
54970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return false;
55070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
55170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
55270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    bool hasGrant(const Value* keyValue, const uid_t uid) const {
55370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ValueString keyString(keyValue);
55470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return getGrant(keyString.c_str(), uid) != NULL;
55570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
55670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const char* MASTER_KEY_FILE;
559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MASTER_KEY_SIZE_BYTES = 16;
560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MAX_RETRY = 4;
563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const size_t SALT_SIZE = 16;
564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy* mEntropy;
566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
56770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* mDevice;
56870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    State mState;
570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int8_t mRetry;
571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t mSalt[SALT_SIZE];
574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    AES_KEY mMasterKeyEncryption;
576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    AES_KEY mMasterKeyDecryption;
577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
57870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    struct listnode mGrants;
57970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void setState(State state) {
581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mState = state;
582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            mRetry = MAX_RETRY;
584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool generateSalt() {
588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool generateMasterKey() {
592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!generateSalt()) {
596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void setupMasterKeys() {
602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_NO_ERROR);
605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void clearMasterKeys() {
608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mMasterKey, 0, sizeof(mMasterKey));
609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mSalt, 0, sizeof(mSalt));
610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) {
615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t saltSize;
616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (salt != NULL) {
617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            saltSize = SALT_SIZE;
618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) "keystore";
621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // sizeof = 9, not strlen = 8
622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            saltSize = sizeof("keystore");
623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key);
625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static bool isKeyFile(const char* filename) {
628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return ((strcmp(filename, MASTER_KEY_FILE) != 0)
629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                && (strcmp(filename, ".") != 0)
630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                && (strcmp(filename, "..") != 0));
631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
63270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
63370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    grant_t* getGrant(const char* keyName, uid_t uid) const {
63470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        struct listnode *node;
63570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        grant_t *grant;
63670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
63770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        list_for_each(node, &mGrants) {
63870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant = node_to_item(node, grant_t, plist);
63970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            if (grant->uid == uid
64070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                    && !strcmp(reinterpret_cast<const char*>(grant->keyName),
64170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                               keyName)) {
64270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                return grant;
64370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            }
64470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
64570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
64670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
64770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
64870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
64970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    bool convertToUid(const Value* uidValue, uid_t* uid) const {
65070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ValueString uidString(uidValue);
65170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        char* end = NULL;
65270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        *uid = strtol(uidString.c_str(), &end, 10);
65370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return *end == '\0';
65470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey";
658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the protocol used in both requests and responses:
660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *     code [length_1 message_1 ... length_n message_n] end-of-file
661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * where code is one byte long and lengths are unsigned 16-bit integers in
662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * network order. Thus the maximum length of a message is 65535 bytes. */
663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_code(int sock, int8_t* code) {
665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return recv(sock, code, 1, 0) == 1;
666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_message(int sock, uint8_t* message, int length) {
669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t bytes[2];
670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (recv(sock, &bytes[0], 1, 0) != 1 ||
671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        recv(sock, &bytes[1], 1, 0) != 1) {
672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return -1;
673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    } else {
674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int offset = bytes[0] << 8 | bytes[1];
675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (length < offset) {
676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return -1;
677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        length = offset;
679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        offset = 0;
680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while (offset < length) {
681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            int n = recv(sock, &message[offset], length - offset, 0);
682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (n <= 0) {
683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                return -1;
684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            offset += n;
686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return length;
689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic int recv_end_of_file(int sock) {
692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t byte;
693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return recv(sock, &byte, 1, 0) == 0;
694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic void send_code(int sock, int8_t code) {
697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send(sock, &code, 1, 0);
698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7005187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic void send_message(int sock, const uint8_t* message, int length) {
701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint16_t bytes = htons(length);
702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send(sock, &bytes, 2, 0);
703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send(sock, message, length, 0);
704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
70670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName,
70770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        const uid_t uid) {
70870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
70970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
71070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
71170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ResponseCode responseCode = keyStore->get(filename, keyBlob);
71270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode == NO_ERROR) {
71370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
71470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
71570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
71670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // If this is the Wifi or VPN user, they actually want system
71770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // UID keys.
71870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (uid == AID_WIFI || uid == AID_VPN) {
71970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        encode_key_for_uid(filename, AID_SYSTEM, keyName);
72070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        responseCode = keyStore->get(filename, keyBlob);
72170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (responseCode == NO_ERROR) {
72270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return responseCode;
72370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
72470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
72570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
72670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // They might be using a granted key.
72770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (!keyStore->hasGrant(keyName, uid)) {
72870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
72970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
73070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
73170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // It is a granted key. Try to load it.
73270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key(filename, keyName);
73370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return keyStore->get(filename, keyBlob);
73470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
73570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here are the actions. Each of them is a function without arguments. All
737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * information is defined in global variables, which are set properly before
738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * performing an action. The number of parameters required by each action is
739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * fixed and defined in a table. If the return value of an action is positive,
740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * it will be treated as a response code and transmitted to the client. Note
741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that the lengths of parameters are checked when they are received, so
742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * boundary checks on parameters are omitted. */
743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0;
745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7465187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode test(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return (ResponseCode) keyStore->getState();
748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7505187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
75270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob keyBlob;
754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode responseCode = keyStore->get(filename, &keyBlob);
755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (responseCode != NO_ERROR) {
756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return responseCode;
757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send_code(sock, NO_ERROR);
759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send_message(sock, keyBlob.getValue(), keyBlob.getLength());
760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7635187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode insert(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* val,
7645187818895c4c5f650a611c40531b1dff7764c18Kenny Root        Value*) {
765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
76670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob keyBlob(val->value, val->length, NULL, 0);
768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return keyStore->put(filename, &keyBlob);
769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7715187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode del(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
77370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7775187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode exist(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
77970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (access(filename, R_OK) == -1) {
781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR;
784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7865187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode saw(KeyStore* keyStore, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) {
787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    DIR* dir = opendir(".");
788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!dir) {
789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return SYSTEM_ERROR;
790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    char filename[NAME_MAX];
79270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int n = encode_key_for_uid(filename, uid, keyPrefix);
793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    send_code(sock, NO_ERROR);
794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct dirent* file;
796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while ((file = readdir(dir)) != NULL) {
797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!strncmp(filename, file->d_name, n)) {
7985187818895c4c5f650a611c40531b1dff7764c18Kenny Root            const char* p = &file->d_name[n];
799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p));
800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            send_message(sock, keyPrefix->value, keyPrefix->length);
801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    closedir(dir);
804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
8075187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode reset(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return keyStore->reset() ? NO_ERROR : SYSTEM_ERROR;
809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the history. To improve the security, the parameters to generate the
812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * master key has been changed. To make a seamless transition, we update the
813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * file using the same password when the user unlock it for the first time. If
814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * any thing goes wrong during the transition, the new file will not overwrite
815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the old one. This avoids permanent damages of the existing data. */
816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
8175187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode password(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value*, Value*) {
818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    switch (keyStore->getState()) {
819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        case STATE_UNINITIALIZED: {
820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // generate master key, encrypt with password, write to file, initialize mMasterKey*.
821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return keyStore->initialize(pw);
822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        case STATE_NO_ERROR: {
824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // rewrite master key with new password.
825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return keyStore->writeMasterKey(pw);
826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        case STATE_LOCKED: {
828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // read master key, decrypt with password, initialize mMasterKey*.
829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return keyStore->readMasterKey(pw);
830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return SYSTEM_ERROR;
833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
8355187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode lock(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    keyStore->lock();
837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return NO_ERROR;
838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
8405187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused,
8415187818895c4c5f650a611c40531b1dff7764c18Kenny Root        Value* unused2) {
8425187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return password(keyStore, sock, uid, pw, unused, unused2);
843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
8455187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic ResponseCode zero(KeyStore* keyStore, int sock, uid_t uid, Value*, Value*, Value*) {
846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR;
847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
84970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode generate(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*,
85070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
85170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
85270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* data;
85370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t dataLength;
85470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
85570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
85670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
85770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
85870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
85970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
86170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->generate_keypair == NULL) {
86270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
86370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
86470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
86570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_rsa_keygen_params_t rsa_params;
86670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rsa_params.modulus_size = 2048;
86770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rsa_params.public_exponent = 0x10001;
86870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
86970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
87070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
87170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
87270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
87370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
87470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
87570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
87670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob(data, dataLength, NULL, 0);
87770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    free(data);
87870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
87970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return keyStore->put(filename, &keyBlob);
88070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
88170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
88270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode import(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* key,
88370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
88470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
88570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* data;
88670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t dataLength;
88770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
88870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
88970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
89070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
89170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("No keymaster device!");
89270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
89370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
89470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
89570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->import_keypair == NULL) {
89670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("Keymaster doesn't support import!");
89770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
89870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
89970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
90070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = device->import_keypair(device, key->value, key->length, &data, &dataLength);
90170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
90270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("Error while importing keypair: %d", rc);
90370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
90470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
90570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
90670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
90770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
90870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob(data, dataLength, NULL, 0);
90970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    free(data);
91070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
91170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return keyStore->put(filename, &keyBlob);
91270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
91370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
91470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/*
91570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * TODO: The abstraction between things stored in hardware and regular blobs
91670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * of data stored on the filesystem should be moved down to keystore itself.
91770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Unfortunately the Java code that calls this has naming conventions that it
91870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of
91970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * data.
92070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *
92170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and
92270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * "del_key" since the Java code doesn't really communicate what it's
92370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * intentions are.
92470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */
92570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
92670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
92770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid);
92870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
92970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid);
93070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
93170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
93270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
93370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
93470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
93570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
93670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
93770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
93870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
93970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->get_keypair_public == NULL) {
94070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("device has no get_keypair_public implementation!");
94170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
94270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
94370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
94470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* data = NULL;
94570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t dataLength;
94670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
94770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data,
94870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            &dataLength);
94970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
95070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
95170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
95270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
95370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_code(sock, NO_ERROR);
95470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_message(sock, data, dataLength);
95570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    free(data);
95670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
95770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
95870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
95970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
96070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode del_key(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*,
96170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
96270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
96370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
96470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
96570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ResponseCode responseCode = keyStore->get(filename, &keyBlob);
96670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
96770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
96870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
96970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
97070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
97170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
97270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
97370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
97470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
97570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->delete_keypair == NULL) {
97670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("device has no delete_keypair implementation!");
97770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
97870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
97970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
98070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* data = NULL;
98170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t dataLength;
98270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
98370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc = device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength());
98470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
98570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return rc ? SYSTEM_ERROR : NO_ERROR;
98670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
98770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
98870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode sign(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data,
98970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value*) {
99070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ALOGV("sign %s from uid %d", ValueString(keyName).c_str(), uid);
99170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
99270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
99370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
99470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid);
99570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
99670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
99770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
99870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
99970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint8_t* signedData;
100070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t signedDataLength;
100170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
100270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
100370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
100470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
100570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
100670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
100770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->sign_data == NULL) {
100870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
100970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
101070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
101170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_rsa_sign_params_t params;
101270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.digest_type = DIGEST_NONE;
101370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.padding_type = PADDING_NONE;
101470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
101570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
101670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            data->value, data->length, &signedData, &signedDataLength);
101770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
101870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
101970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
102070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
102170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_code(sock, NO_ERROR);
102270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    send_message(sock, signedData, signedDataLength);
102370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return NO_ERROR_RESPONSE_CODE_SENT;
102470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
102570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
102670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode verify(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data,
102770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value* signature) {
102870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Blob keyBlob;
102970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
103070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
103170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid);
103270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (responseCode != NO_ERROR) {
103370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return responseCode;
103470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
103570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
103670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const keymaster_device_t* device = keyStore->getDevice();
103770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device == NULL) {
103870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
103970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
104070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
104170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (device->verify_data == NULL) {
104270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
104370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
104470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
104570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_rsa_sign_params_t params;
104670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.digest_type = DIGEST_NONE;
104770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    params.padding_type = PADDING_NONE;
104870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
104970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
105070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            data->value, data->length, signature->value, signature->length);
105170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
105270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return SYSTEM_ERROR;
105370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    } else {
105470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NO_ERROR;
105570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
105670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
105770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
105870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode grant(KeyStore* keyStore, int sock, uid_t uid, Value* keyName,
105970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value* granteeData, Value*) {
106070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
106170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
106270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (access(filename, R_OK) == -1) {
106370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
106470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
106570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
106670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keyStore->addGrant(filename, granteeData);
106770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return NO_ERROR;
106870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
106970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
107070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic ResponseCode ungrant(KeyStore* keyStore, int sock, uid_t uid, Value* keyName,
107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        Value* granteeData, Value*) {
107270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char filename[NAME_MAX];
107370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    encode_key_for_uid(filename, uid, keyName);
107470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (access(filename, R_OK) == -1) {
107570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
107670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
107770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
107870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return keyStore->removeGrant(keyName, granteeData) ? NO_ERROR : KEY_NOT_FOUND;
107970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
108070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
108170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/* Here are the permissions, actions, users, and the main function. */
1082a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootenum perm {
10835187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_TEST     = 1 << TEST,
10845187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_GET      = 1 << GET,
10855187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_INSERT   = 1 << INSERT,
10865187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_DELETE   = 1 << DELETE,
10875187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_EXIST    = 1 << EXIST,
10885187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_SAW      = 1 << SAW,
10895187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_RESET    = 1 << RESET,
10905187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_PASSWORD = 1 << PASSWORD,
10915187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_LOCK     = 1 << LOCK,
10925187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_UNLOCK   = 1 << UNLOCK,
10935187818895c4c5f650a611c40531b1dff7764c18Kenny Root    P_ZERO     = 1 << ZERO,
109470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    P_SIGN     = 1 << SIGN,
109570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    P_VERIFY   = 1 << VERIFY,
109670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    P_GRANT    = 1 << GRANT,
1097a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
1098a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
10995187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic const int MAX_PARAM = 3;
1100a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1101a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic const State STATE_ANY = (State) 0;
1102a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1103a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct action {
11045187818895c4c5f650a611c40531b1dff7764c18Kenny Root    ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2,
11055187818895c4c5f650a611c40531b1dff7764c18Kenny Root            Value* param3);
1106a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int8_t code;
1107a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    State state;
1108a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint32_t perm;
1109a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int lengths[MAX_PARAM];
1110a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} actions[] = {
11115187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {test,       CommandCodes[TEST],       STATE_ANY,      P_TEST,     {0, 0, 0}},
11125187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {get,        CommandCodes[GET],        STATE_NO_ERROR, P_GET,      {KEY_SIZE, 0, 0}},
11135187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {insert,     CommandCodes[INSERT],     STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, VALUE_SIZE, 0}},
11145187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {del,        CommandCodes[DELETE],     STATE_ANY,      P_DELETE,   {KEY_SIZE, 0, 0}},
11155187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {exist,      CommandCodes[EXIST],      STATE_ANY,      P_EXIST,    {KEY_SIZE, 0, 0}},
11165187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {saw,        CommandCodes[SAW],        STATE_ANY,      P_SAW,      {KEY_SIZE, 0, 0}},
11175187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {reset,      CommandCodes[RESET],      STATE_ANY,      P_RESET,    {0, 0, 0}},
11185187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {password,   CommandCodes[PASSWORD],   STATE_ANY,      P_PASSWORD, {PASSWORD_SIZE, 0, 0}},
11195187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {lock,       CommandCodes[LOCK],       STATE_NO_ERROR, P_LOCK,     {0, 0, 0}},
11205187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {unlock,     CommandCodes[UNLOCK],     STATE_LOCKED,   P_UNLOCK,   {PASSWORD_SIZE, 0, 0}},
11215187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {zero,       CommandCodes[ZERO],       STATE_ANY,      P_ZERO,     {0, 0, 0}},
112270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {generate,   CommandCodes[GENERATE],   STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, 0, 0}},
112370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {import,     CommandCodes[IMPORT],     STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, VALUE_SIZE, 0}},
112470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {sign,       CommandCodes[SIGN],       STATE_NO_ERROR, P_SIGN,     {KEY_SIZE, VALUE_SIZE, 0}},
112570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {verify,     CommandCodes[VERIFY],     STATE_NO_ERROR, P_VERIFY,   {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}},
112670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET,      {KEY_SIZE, 0, 0}},
112770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {del_key,    CommandCodes[DEL_KEY],    STATE_ANY,      P_DELETE,   {KEY_SIZE, 0, 0}},
112870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {grant,      CommandCodes[GRANT],      STATE_NO_ERROR, P_GRANT,    {KEY_SIZE, KEY_SIZE, 0}},
112970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {ungrant,    CommandCodes[UNGRANT],    STATE_NO_ERROR, P_GRANT,    {KEY_SIZE, KEY_SIZE, 0}},
11305187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {NULL,       0,                        STATE_ANY,      0,          {0, 0, 0}},
1131a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
1132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1133a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic struct user {
1134a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uid_t uid;
1135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uid_t euid;
1136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint32_t perms;
1137a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} users[] = {
1138a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    {AID_SYSTEM,   ~0,         ~0},
113970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {AID_VPN,      AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
114070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {AID_WIFI,     AID_SYSTEM, P_GET | P_SIGN | P_VERIFY },
11415187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {AID_ROOT,     AID_SYSTEM, P_GET},
114270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    {~0,           ~0,         P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW |
114370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                               P_SIGN | P_VERIFY},
1144a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
1145a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1146a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) {
1147a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct user* user = users;
1148a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct action* action = actions;
1149a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int i;
1150a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1151a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (~user->uid && user->uid != uid) {
1152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ++user;
1153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1154a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (action->code && action->code != code) {
1155a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ++action;
1156a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!action->code) {
1158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return UNDEFINED_ACTION;
1159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!(action->perm & user->perms)) {
1161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return PERMISSION_DENIED;
1162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (action->state != STATE_ANY && action->state != keyStore->getState()) {
1164a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (ResponseCode) keyStore->getState();
1165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (~user->euid) {
1167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uid = user->euid;
1168a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1169a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Value params[MAX_PARAM];
1170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) {
1171a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        params[i].length = recv_message(sock, params[i].value, action->lengths[i]);
1172a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (params[i].length < 0) {
1173a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return PROTOCOL_ERROR;
1174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!recv_end_of_file(sock)) {
1177a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return PROTOCOL_ERROR;
1178a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
11795187818895c4c5f650a611c40531b1dff7764c18Kenny Root    return action->run(keyStore, sock, uid, &params[0], &params[1], &params[2]);
1180a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1181a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1182a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) {
118370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void* hardwareContext = NULL;
118470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int controlSocket = android_get_control_socket("keystore");
1186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (argc < 2) {
1187a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("A directory must be specified!");
1188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (chdir(argv[1]) == -1) {
1191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("chdir: %s: %s", argv[1], strerror(errno));
1192a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1193a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy entropy;
1196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!entropy.open()) {
1197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1198a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
119970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
120070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* dev;
120170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (keymaster_device_initialize(&dev)) {
120270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("keystore keymaster could not be initialized; exiting");
120370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return 1;
120470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
120570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (listen(controlSocket, 3) == -1) {
1207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("listen: %s", strerror(errno));
1208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
1209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    signal(SIGPIPE, SIG_IGN);
1212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
121370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    KeyStore keyStore(&entropy, dev);
1214a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int sock;
1215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while ((sock = accept(controlSocket, NULL, 0)) != -1) {
1216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct timeval tv;
1217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        tv.tv_sec = 3;
1218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
1219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
1220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct ucred cred;
1222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        socklen_t size = sizeof(cred);
1223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size);
1224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (credResult != 0) {
1225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ALOGW("getsockopt: %s", strerror(errno));
1226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
1227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            int8_t request;
1228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (recv_code(sock, &request)) {
1229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                State old_state = keyStore.getState();
1230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                ResponseCode response = process(&keyStore, sock, cred.uid, request);
1231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                if (response == NO_ERROR_RESPONSE_CODE_SENT) {
1232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    response = NO_ERROR;
1233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                } else {
1234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    send_code(sock, response);
1235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                }
1236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d",
1237a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     cred.uid,
1238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     request, response,
1239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     old_state, keyStore.getState(),
1240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                     keyStore.getRetry());
1241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
1242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        close(sock);
1244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ALOGE("accept: %s", strerror(errno));
124670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
124770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_release(dev);
124870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1249a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return 1;
1250a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
1251