1a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/*
2a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Copyright (C) 2009 The Android Open Source Project
3a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *
4a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
5a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * you may not use this file except in compliance with the License.
6a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * You may obtain a copy of the License at
7a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *
8a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
9a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *
10a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Unless required by applicable law or agreed to in writing, software
11a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
12a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * See the License for the specific language governing permissions and
14a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * limitations under the License.
15a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root */
16a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
17a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h>
18a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h>
19a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h>
20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h>
21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h>
22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h>
23a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h>
24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h>
25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h>
26822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h>
27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h>
28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h>
29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h>
30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h>
31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h>
32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h>
34822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h>
35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h>
36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h>
37822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h>
38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h>
4070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
41822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <utils/UniquePtr.h>
42822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/list.h>
4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root//#define LOG_NDEBUG 0
46a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define LOG_TAG "keystore"
47a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h>
48a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h>
49a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h>
50a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
51a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include "keystore.h"
52a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation,
54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and
55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a
56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than
57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */
58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE        ((NAME_MAX - 15) / 2)
60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE      32768
61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE   VALUE_SIZE
62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
63822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
64822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete {
65822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(BIO* p) const {
66822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        BIO_free(p);
67822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
68822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
69822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
70822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
71822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete {
72822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(EVP_PKEY* p) const {
73822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        EVP_PKEY_free(p);
74822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
75822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
77822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
78822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete {
79822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        PKCS8_PRIV_KEY_INFO_free(p);
81822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
82822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
86a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct Value {
87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Value(const uint8_t* orig, int origLen) {
88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        assert(origLen <= VALUE_SIZE);
89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        memcpy(value, orig, origLen);
90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        length = origLen;
91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Value() {
94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
96a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int length;
97a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE];
98a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
99a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootclass ValueString {
10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootpublic:
10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ValueString(const Value* orig) {
103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        assert(length <= VALUE_SIZE);
10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        length = orig->length;
10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value = new char[length + 1];
10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        memcpy(value, orig->value, length);
10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value[length] = '\0';
10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ~ValueString() {
11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        delete[] value;
11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const char* c_str() const {
11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return value;
11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char* release() {
11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        char* ret = value;
12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        value = NULL;
12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return ret;
12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootprivate:
12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    char* value;
12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    size_t length;
12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root};
12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) {
13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const hw_module_t* mod;
13370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
13470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
13570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not find any keystore module");
13670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
13770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
13870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = keymaster_open(mod, dev);
14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not open keymaster device in %s (%s)",
14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
14470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
14570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout:
14970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *dev = NULL;
15070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return rc;
15170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
15270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
15370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) {
15470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_close(dev);
15570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
15670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary
158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded
159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first
160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into
161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */
163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
16470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key(char* out, const Value* key) {
165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    const uint8_t* in = key->value;
166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int length = key->length;
167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = length; i > 0; --i, ++in, ++out) {
168a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (*in >= '0' && *in <= '~') {
169a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = *in;
170a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
171a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = '+' + (*in >> 6);
172a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *++out = '0' + (*in & 0x3F);
173a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ++length;
174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
175a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
17770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return length;
17870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
17970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
18070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const Value* key) {
18170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int n = snprintf(out, NAME_MAX, "%u_", uid);
18270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    out += n;
18370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
18470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return n + encode_key(out, key);
185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1875187818895c4c5f650a611c40531b1dff7764c18Kenny Rootstatic int decode_key(uint8_t* out, const char* in, int length) {
188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = 0; i < length; ++i, ++in, ++out) {
189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (*in >= '0' && *in <= '~') {
190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = *in;
191a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
192a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = (*in - '+') << 6;
193a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out |= (*++in - '0') & 0x3F;
194a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            --length;
195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
197a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
198a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return length;
199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
200a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
201a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) {
202a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
203a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
204a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, size));
205a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (n == -1 || n == 0) {
206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return size-remaining;
207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
214a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) {
215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, size));
218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (n == -1 || n == 0) {
219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return size-remaining;
220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy {
228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy() : mRandom(-1) {}
230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ~Entropy() {
231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRandom != -1) {
232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            close(mRandom);
233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool open() {
237a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* randomDevice = "/dev/urandom";
238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mRandom = ::open(randomDevice, O_RDONLY);
239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRandom == -1) {
240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ALOGE("open: %s: %s", randomDevice, strerror(errno));
241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2465187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool generate_random_data(uint8_t* data, size_t size) const {
247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (readFully(mRandom, data, size) == size);
248a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
249a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
250a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
251a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int mRandom;
252a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
253a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
254a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and
255a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size
256a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in
257a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two
258822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version,
259822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other
260a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob()
261a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */
262a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
263822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: **
264822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction:
265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   metadata || Enc(MD5(data) || data)
266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing:
268822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
269822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Derive independent keys for encryption and MAC:
270822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kenc = AES_encrypt(masterKey, "Encrypt")
271822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kmac = AES_encrypt(masterKey, "MAC")
272822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
273822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Store this:
274822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
275822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *             HMAC(Kmac, metadata || Enc(data))
276822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */
277a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob {
278822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t version;
279822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t type;
280822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t reserved;
281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t info;
282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t vector[AES_BLOCK_SIZE];
283822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t encrypted[0]; // Marks offset to encrypted data.
284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t digest[MD5_DIGEST_LENGTH];
285822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t digested[0]; // Marks offset to digested data.
286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int32_t length; // in network byte order when encrypted
287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
289a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum {
291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_GENERIC = 1,
292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_MASTER_KEY = 2,
293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_KEY_PAIR = 3,
294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType;
295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstatic const uint8_t CurrentBlobVersion = 1;
297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob {
299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength, BlobType type) {
301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = valueLength;
302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value, value, valueLength);
303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.info = infoLength;
305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value + valueLength, info, infoLength);
306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.version = CurrentBlobVersion;
308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob(blob b) {
312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob = b;
313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob() {}
316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3175187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getValue() const {
318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.value;
319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3215187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int32_t getLength() const {
322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.length;
323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3255187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getInfo() const {
3265187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return mBlob.value + mBlob.length;
3275187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
3285187818895c4c5f650a611c40531b1dff7764c18Kenny Root
3295187818895c4c5f650a611c40531b1dff7764c18Kenny Root    uint8_t getInfoLength() const {
330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.info;
331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
333822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t getVersion() const {
334822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return mBlob.version;
335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
336822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setVersion(uint8_t version) {
338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.version = version;
339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    BlobType getType() const {
342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return BlobType(mBlob.type);
343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setType(BlobType type) {
346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) {
350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // data includes the value and the value's length
355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t dataLength = mBlob.length + sizeof(mBlob.length);
356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // pad data to the AES_BLOCK_SIZE
357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                                 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // encrypted data includes the digest value
360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // move info after space for padding
362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // zero padding area
364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = htonl(mBlob.length);
367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        MD5(mBlob.digested, digestedLength, mBlob.digest);
368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t vector[AES_BLOCK_SIZE];
370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                        aes_key, vector, AES_ENCRYPT);
373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
374822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.reserved = 0;
375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = encryptedLength + headerLength + mBlob.info;
377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* tmpFileName = ".tmp";
379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int out = open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (out == -1) {
381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(out) != 0) {
385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (writtenBytes != fileLength) {
388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(tmpFileName);
389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR;
392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int in = open(filename, O_RDONLY);
396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (in == -1) {
397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // fileLength may be less than sizeof(mBlob) since the in
400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // memory version has extra padding to tolerate rounding up to
401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES_BLOCK_SIZE
402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (fileLength < headerLength) {
408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) {
413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                        mBlob.vector, AES_DECRYPT);
417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t computedDigest[MD5_DIGEST_LENGTH];
419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        MD5(mBlob.digested, digestedLength, computedDigest);
420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = ntohl(mBlob.length);
426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.length < 0 || mBlob.length > maxValueLength) {
427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.info != 0) {
430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // move info from after padding to after data
431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return NO_ERROR;
434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct blob mBlob;
438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
44070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct {
44170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    uint32_t uid;
442a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    const uint8_t* filename;
44370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
44470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    struct listnode plist;
44570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t;
44670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore {
448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
44970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    KeyStore(Entropy* entropy, keymaster_device_t* device)
4505187818895c4c5f650a611c40531b1dff7764c18Kenny Root        : mEntropy(entropy)
45170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        , mDevice(device)
4525187818895c4c5f650a611c40531b1dff7764c18Kenny Root        , mRetry(MAX_RETRY)
4535187818895c4c5f650a611c40531b1dff7764c18Kenny Root    {
454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (access(MASTER_KEY_FILE, R_OK) == 0) {
455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_LOCKED);
456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_UNINITIALIZED);
458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
45970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
46070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        list_init(&mGrants);
461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4635187818895c4c5f650a611c40531b1dff7764c18Kenny Root    State getState() const {
464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mState;
465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4675187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int8_t getRetry() const {
468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mRetry;
469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
47170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* getDevice() const {
47270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return mDevice;
47370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
47470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode initialize(Value* pw) {
476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!generateMasterKey()) {
477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ResponseCode response = writeMasterKey(pw);
480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response != NO_ERROR) {
481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setupMasterKeys();
484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return NO_ERROR;
485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode writeMasterKey(Value* pw) {
488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode readMasterKey(Value* pw) {
497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        int in = open(MASTER_KEY_FILE, O_RDONLY);
498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (in == -1) {
499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // we read the raw blob to just to get the salt to generate
503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES key, then we create the Blob to use with decryptBlob
504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        blob rawBlob;
505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // find salt at EOF if present, otherwise we have an old file
510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t* salt;
511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = NULL;
515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        Blob masterKeyBlob(rawBlob);
521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == SYSTEM_ERROR) {
523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // if salt was missing, generate one and write a new master key file with the salt.
527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (salt == NULL) {
528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                if (!generateSalt()) {
529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    return SYSTEM_ERROR;
530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                }
531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                response = writeMasterKey(pw);
532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (response == NO_ERROR) {
534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                setupMasterKeys();
536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRetry <= 0) {
540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            reset();
541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return UNINITIALIZED;
542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        --mRetry;
544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        switch (mRetry) {
545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 0: return WRONG_PASSWORD_0;
546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 1: return WRONG_PASSWORD_1;
547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 2: return WRONG_PASSWORD_2;
548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 3: return WRONG_PASSWORD_3;
549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            default: return WRONG_PASSWORD_3;
550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool reset() {
554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        clearMasterKeys();
555a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_UNINITIALIZED);
556a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        DIR* dir = opendir(".");
558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct dirent* file;
559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(file->d_name);
565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5705187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool isEmpty() const {
571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        DIR* dir = opendir(".");
572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        struct dirent* file;
573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return true;
575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        bool result = true;
577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (isKeyFile(file->d_name)) {
579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                result = false;
580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                break;
581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return result;
585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void lock() {
588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        clearMasterKeys();
589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_LOCKED);
590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
592822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) {
593822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
594822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc != NO_ERROR) {
595822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return rc;
596822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
597822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
598822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        const uint8_t version = keyBlob->getVersion();
599822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (version < CurrentBlobVersion) {
600822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            upgrade(filename, keyBlob, version, type);
601822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
602822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
603822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (keyBlob->getType() != type) {
604822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
605822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return KEY_NOT_FOUND;
606822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
607822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
608822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return rc;
609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ResponseCode put(const char* filename, Blob* keyBlob) {
612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
61570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void addGrant(const char* filename, const Value* uidValue) {
61670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uid_t uid;
61770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (!convertToUid(uidValue, &uid)) {
61870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return;
61970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
62070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
62170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        grant_t *grant = getGrant(filename, uid);
62270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (grant == NULL) {
62370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant = new grant_t;
62470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant->uid = uid;
625a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom            grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
62670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            list_add_tail(&mGrants, &grant->plist);
62770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
62870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
62970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
630a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    bool removeGrant(const char* filename, const Value* uidValue) {
63170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uid_t uid;
63270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (!convertToUid(uidValue, &uid)) {
63370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return false;
63470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
63570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
636a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom        grant_t *grant = getGrant(filename, uid);
63770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        if (grant != NULL) {
63870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            list_remove(&grant->plist);
63970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            delete grant;
64070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            return true;
64170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
64270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
64370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return false;
64470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
64570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
646a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    bool hasGrant(const char* filename, const uid_t uid) const {
647a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom        return getGrant(filename, uid) != NULL;
64870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
64970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
650822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    ResponseCode importKey(const Value* key, const char* filename) {
651822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t* data;
652822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        size_t dataLength;
653822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        int rc;
654822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
655822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (mDevice->import_keypair == NULL) {
656822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Keymaster doesn't support import!");
657822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
658822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
659822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
660822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        rc = mDevice->import_keypair(mDevice, key->value, key->length, &data, &dataLength);
661822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc) {
662822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Error while importing keypair: %d", rc);
663822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
664822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
665822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
666822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
667822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        free(data);
668822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
669822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return put(filename, &keyBlob);
670822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
671822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const char* MASTER_KEY_FILE;
674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MASTER_KEY_SIZE_BYTES = 16;
675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const int MAX_RETRY = 4;
678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static const size_t SALT_SIZE = 16;
679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy* mEntropy;
681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
68270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* mDevice;
68370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    State mState;
685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int8_t mRetry;
686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t mSalt[SALT_SIZE];
689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    AES_KEY mMasterKeyEncryption;
691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    AES_KEY mMasterKeyDecryption;
692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
69370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    struct listnode mGrants;
69470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void setState(State state) {
696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mState = state;
697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            mRetry = MAX_RETRY;
699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool generateSalt() {
703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool generateMasterKey() {
707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!generateSalt()) {
711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void setupMasterKeys() {
717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setState(STATE_NO_ERROR);
720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    void clearMasterKeys() {
723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mMasterKey, 0, sizeof(mMasterKey));
724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mSalt, 0, sizeof(mSalt));
725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) {
730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t saltSize;
731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (salt != NULL) {
732a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            saltSize = SALT_SIZE;
733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) "keystore";
736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // sizeof = 9, not strlen = 8
737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            saltSize = sizeof("keystore");
738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key);
740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    static bool isKeyFile(const char* filename) {
743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return ((strcmp(filename, MASTER_KEY_FILE) != 0)
744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                && (strcmp(filename, ".") != 0)
745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                && (strcmp(filename, "..") != 0));
746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
74770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
748a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    grant_t* getGrant(const char* filename, uid_t uid) const {
74970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        struct listnode *node;
75070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        grant_t *grant;
75170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
75270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        list_for_each(node, &mGrants) {
75370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            grant = node_to_item(node, grant_t, plist);
75470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            if (grant->uid == uid
755a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom                    && !strcmp(reinterpret_cast<const char*>(grant->filename),
756a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom                               filename)) {
75770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                return grant;
75870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            }
75970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
76070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
76170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
76270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
76370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
76470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    bool convertToUid(const Value* uidValue, uid_t* uid) const {
76570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ValueString uidString(uidValue);
76670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        char* end = NULL;
76770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        *uid = strtol(uidString.c_str(), &end, 10);
76870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return *end == '\0';
76970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
770822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
771822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
772822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Upgrade code. This will upgrade the key from the current version
773822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * to whatever is newest.
774822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
775822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) {
776822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        bool updated = false;
777822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t version = oldVersion;
778822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
779822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /* From V0 -> V1: All old types were unknown */
780822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (version == 0) {
781822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("upgrading to version 1 and setting type %d", type);
782822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
783822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setType(type);
784822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            if (type == TYPE_KEY_PAIR) {
785822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root                importBlobAsKey(blob, filename);
786822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            }
787822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            version = 1;
788822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            updated = true;
789822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
790822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
791822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /*
792822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * If we've updated, set the key blob to the right version
793822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * and write it.
794822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * */
795822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (updated) {
796822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("updated and writing file %s", filename);
797822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setVersion(version);
798822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            this->put(filename, blob);
799822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
800822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
801822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
802822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
803822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Takes a blob that is an PEM-encoded RSA key as a byte array and
804822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * converts it to a DER-encoded PKCS#8 for import into a keymaster.
805822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Then it overwrites the original blob with the new blob
806822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * format that is returned from the keymaster.
807822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
808