keystore.cpp revision aaf9802da6cea710e0777abb852724e1825cad63
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
1707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root//#define LOG_NDEBUG 0
1807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#define LOG_TAG "keystore"
1907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h>
21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h>
22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h>
23aaf9802da6cea710e0777abb852724e1825cad63Elliott Hughes#include <strings.h>
24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h>
25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h>
26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h>
27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h>
28655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <errno.h>
29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h>
30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h>
31822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h>
32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h>
33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h>
34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h>
35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h>
36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h>
37a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h>
39822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h>
40a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h>
41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h>
42822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h>
43a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h>
4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
4617208e0de5a42722901d803118745cca25fd10c1Kenny Root#include <keymaster/softkeymaster.h>
4717208e0de5a42722901d803118745cca25fd10c1Kenny Root
4826cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h>
49655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h>
50655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h>
5170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
5207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h>
5307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h>
5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h>
5507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h>
57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h>
58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h>
59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
6007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h>
61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
62eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn#include <selinux/android.h>
63eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
6496427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h"
6596427baf0094d50047049d329b0779c3c910402cKenny Root
66a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation,
67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and
68a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a
69a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than
70a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */
71a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
72a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE        ((NAME_MAX - 15) / 2)
73a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE      32768
74a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE   VALUE_SIZE
75a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
7796427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete {
7896427baf0094d50047049d329b0779c3c910402cKenny Root    void operator()(BIGNUM* p) const {
7996427baf0094d50047049d329b0779c3c910402cKenny Root        BN_free(p);
8096427baf0094d50047049d329b0779c3c910402cKenny Root    }
8196427baf0094d50047049d329b0779c3c910402cKenny Root};
8296427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
8396427baf0094d50047049d329b0779c3c910402cKenny Root
84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete {
85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(BIO* p) const {
86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        BIO_free(p);
87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete {
92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(EVP_PKEY* p) const {
93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        EVP_PKEY_free(p);
94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete {
99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        PKCS8_PRIV_KEY_INFO_free(p);
101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) {
10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const hw_module_t* mod;
11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not find any keystore module");
11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = keymaster_open(mod, dev);
11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not open keymaster device in %s (%s)",
11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout:
12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *dev = NULL;
12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return rc;
12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) {
13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_close(dev);
13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
13370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
13407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/***************
13507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS *
13607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/
13707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
13807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */
13907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum {
1404e865753346fc6a075966972a7a98051818859dbRobin Lee    P_TEST          = 1 << 0,
1414e865753346fc6a075966972a7a98051818859dbRobin Lee    P_GET           = 1 << 1,
1424e865753346fc6a075966972a7a98051818859dbRobin Lee    P_INSERT        = 1 << 2,
1434e865753346fc6a075966972a7a98051818859dbRobin Lee    P_DELETE        = 1 << 3,
1444e865753346fc6a075966972a7a98051818859dbRobin Lee    P_EXIST         = 1 << 4,
1454e865753346fc6a075966972a7a98051818859dbRobin Lee    P_SAW           = 1 << 5,
1464e865753346fc6a075966972a7a98051818859dbRobin Lee    P_RESET         = 1 << 6,
1474e865753346fc6a075966972a7a98051818859dbRobin Lee    P_PASSWORD      = 1 << 7,
1484e865753346fc6a075966972a7a98051818859dbRobin Lee    P_LOCK          = 1 << 8,
1494e865753346fc6a075966972a7a98051818859dbRobin Lee    P_UNLOCK        = 1 << 9,
1504e865753346fc6a075966972a7a98051818859dbRobin Lee    P_ZERO          = 1 << 10,
1514e865753346fc6a075966972a7a98051818859dbRobin Lee    P_SIGN          = 1 << 11,
1524e865753346fc6a075966972a7a98051818859dbRobin Lee    P_VERIFY        = 1 << 12,
1534e865753346fc6a075966972a7a98051818859dbRobin Lee    P_GRANT         = 1 << 13,
1544e865753346fc6a075966972a7a98051818859dbRobin Lee    P_DUPLICATE     = 1 << 14,
1554e865753346fc6a075966972a7a98051818859dbRobin Lee    P_CLEAR_UID     = 1 << 15,
1564e865753346fc6a075966972a7a98051818859dbRobin Lee    P_RESET_UID     = 1 << 16,
1574e865753346fc6a075966972a7a98051818859dbRobin Lee    P_SYNC_UID      = 1 << 17,
1584e865753346fc6a075966972a7a98051818859dbRobin Lee    P_PASSWORD_UID  = 1 << 18,
15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t;
16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid {
16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    uid_t uid;
16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    uid_t euid;
16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = {
16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_VPN, AID_SYSTEM},
16607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_WIFI, AID_SYSTEM},
16707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_ROOT, AID_SYSTEM},
16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root};
16907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
170eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */
171eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = {
172eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "test",
173eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "get",
174eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "insert",
175eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "delete",
176eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "exist",
177eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "saw",
178eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "reset",
179eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "password",
180eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "lock",
181eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "unlock",
182eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "zero",
183eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "sign",
184eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "verify",
185eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "grant",
186eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "duplicate",
1874e865753346fc6a075966972a7a98051818859dbRobin Lee    "clear_uid",
1884e865753346fc6a075966972a7a98051818859dbRobin Lee    "reset_uid",
1894e865753346fc6a075966972a7a98051818859dbRobin Lee    "sync_uid",
1904e865753346fc6a075966972a7a98051818859dbRobin Lee    "password_uid",
191eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn};
192eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
19307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm {
19407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    uid_t uid;
19507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    perm_t perms;
19607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = {
19707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) },
19807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_VPN,    static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
19907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_WIFI,   static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
20007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_ROOT,   static_cast<perm_t>(P_GET) },
20107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root};
20207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
20307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN
20407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        | P_VERIFY);
20507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
206eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx;
207eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled;
208eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
209eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) {
210eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    unsigned int index = ffs(perm);
211eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) {
212eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return perm_labels[index - 1];
213eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    } else {
214eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        ALOGE("Keystore: Failed to retrieve permission label.\n");
215eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        abort();
216eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
217eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}
218eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
219655b958eb2180c7c06889f83f606d23421bf038cKenny Root/**
220655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current
221655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID.
222655b958eb2180c7c06889f83f606d23421bf038cKenny Root */
223655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) {
224655b958eb2180c7c06889f83f606d23421bf038cKenny Root    return uid % AID_USER;
225655b958eb2180c7c06889f83f606d23421bf038cKenny Root}
226655b958eb2180c7c06889f83f606d23421bf038cKenny Root
227655b958eb2180c7c06889f83f606d23421bf038cKenny Root/**
228655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current
229655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID.
230655b958eb2180c7c06889f83f606d23421bf038cKenny Root */
231655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) {
232655b958eb2180c7c06889f83f606d23421bf038cKenny Root    return uid / AID_USER;
233655b958eb2180c7c06889f83f606d23421bf038cKenny Root}
234655b958eb2180c7c06889f83f606d23421bf038cKenny Root
235a25b2a397fff48dea7bce16af2065e6f5f043956Chih-Hung Hsiehstatic bool keystore_selinux_check_access(uid_t /*uid*/, perm_t perm, pid_t spid) {
236eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (!ks_is_selinux_enabled) {
237eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return true;
238eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
239eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
240eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    char *sctx = NULL;
241eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    const char *selinux_class = "keystore_key";
242eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    const char *str_perm = get_perm_label(perm);
243eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
244eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (!str_perm) {
245eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return false;
246eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
247eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
248eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (getpidcon(spid, &sctx) != 0) {
249eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        ALOGE("SELinux: Failed to get source pid context.\n");
250eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return false;
251eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
25266dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich
253eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm,
254eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            NULL) == 0;
255eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    freecon(sctx);
256eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    return allowed;
257eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}
258eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
259eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) {
260655b958eb2180c7c06889f83f606d23421bf038cKenny Root    // All system users are equivalent for multi-user support.
261655b958eb2180c7c06889f83f606d23421bf038cKenny Root    if (get_app_id(uid) == AID_SYSTEM) {
262655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uid = AID_SYSTEM;
263655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
264655b958eb2180c7c06889f83f606d23421bf038cKenny Root
26507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) {
26607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        struct user_perm user = user_perms[i];
26707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (user.uid == uid) {
268eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            return (user.perms & perm) &&
269eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn                keystore_selinux_check_access(uid, perm, spid);
27007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
27107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
27207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
273eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    return (DEFAULT_PERMS & perm) &&
274eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        keystore_selinux_check_access(uid, perm, spid);
27507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}
27607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
277494689083467ec372a58f094f041c8f102f39393Kenny Root/**
278494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for
279494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed
280494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace.
281494689083467ec372a58f094f041c8f102f39393Kenny Root */
28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) {
28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        struct user_euid user = user_euids[i];
28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (user.uid == uid) {
28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return user.euid;
28707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
28807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
29007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    return uid;
29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}
29207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
293494689083467ec372a58f094f041c8f102f39393Kenny Root/**
294494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's
295494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace.
296494689083467ec372a58f094f041c8f102f39393Kenny Root */
297494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) {
298494689083467ec372a58f094f041c8f102f39393Kenny Root    for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
299494689083467ec372a58f094f041c8f102f39393Kenny Root        struct user_euid user = user_euids[i];
300494689083467ec372a58f094f041c8f102f39393Kenny Root        if (user.euid == callingUid && user.uid == targetUid) {
301494689083467ec372a58f094f041c8f102f39393Kenny Root            return true;
302494689083467ec372a58f094f041c8f102f39393Kenny Root        }
303494689083467ec372a58f094f041c8f102f39393Kenny Root    }
304494689083467ec372a58f094f041c8f102f39393Kenny Root
305494689083467ec372a58f094f041c8f102f39393Kenny Root    return false;
306494689083467ec372a58f094f041c8f102f39393Kenny Root}
307494689083467ec372a58f094f041c8f102f39393Kenny Root
308007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root/**
309007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * Allow the system to perform some privileged tasks that have to do with
310007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * system maintenance. This should not be used for any function that uses
311007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * the keys in any way (e.g., signing).
312007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root */
313007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Rootstatic bool is_self_or_system(uid_t callingUid, uid_t targetUid) {
314007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root    return callingUid == targetUid || callingUid == AID_SYSTEM;
315007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root}
316007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root
317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary
318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded
319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first
320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into
321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */
323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
324655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) {
325655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
326655b958eb2180c7c06889f83f606d23421bf038cKenny Root    size_t length = keyName.length();
327655b958eb2180c7c06889f83f606d23421bf038cKenny Root    for (int i = length; i > 0; --i, ++in) {
328655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (*in < '0' || *in > '~') {
329655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ++length;
330655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
331655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
332655b958eb2180c7c06889f83f606d23421bf038cKenny Root    return length;
333655b958eb2180c7c06889f83f606d23421bf038cKenny Root}
334655b958eb2180c7c06889f83f606d23421bf038cKenny Root
33507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) {
33607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
33707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    size_t length = keyName.length();
338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = length; i > 0; --i, ++in, ++out) {
339655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (*in < '0' || *in > '~') {
340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = '+' + (*in >> 6);
341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *++out = '0' + (*in & 0x3F);
342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ++length;
343655b958eb2180c7c06889f83f606d23421bf038cKenny Root        } else {
344655b958eb2180c7c06889f83f606d23421bf038cKenny Root            *out = *in;
345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
34870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return length;
34970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
35070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
35107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*
35207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name.
35307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string.
35407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *
35507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated.
35607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */
35707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) {
35807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    size_t outLength = 0;
35907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
36007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (const char* end = in + length; in < end; in++) {
36107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        /* This combines with the next character. */
36207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (*in < '0' || *in > '~') {
36307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            continue;
36407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
36507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
36607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        outLength++;
36707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    return outLength;
36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}
37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) {
37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (const char* end = in + length; in < end; in++) {
37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (*in < '0' || *in > '~') {
37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            /* Truncate combining characters at the end. */
37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (in + 1 >= end) {
37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                break;
37707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
37807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
37907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *out = (*in++ - '+') << 6;
38007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *out++ |= (*in - '0') & 0x3F;
381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
38207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *out++ = *in;
383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) {
389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
391150ca934edb745de3666a6492b039900df228ff0Kenny Root        ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining));
3925281edbc9445065479e92a6c86da462f3943c2caKenny Root        if (n <= 0) {
393150ca934edb745de3666a6492b039900df228ff0Kenny Root            return size - remaining;
394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) {
402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
404150ca934edb745de3666a6492b039900df228ff0Kenny Root        ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining));
405150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (n < 0) {
406150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("write failed: %s", strerror(errno));
407150ca934edb745de3666a6492b039900df228ff0Kenny Root            return size - remaining;
408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy {
416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy() : mRandom(-1) {}
418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ~Entropy() {
419150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (mRandom >= 0) {
420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            close(mRandom);
421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool open() {
425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* randomDevice = "/dev/urandom";
426150ca934edb745de3666a6492b039900df228ff0Kenny Root        mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY));
427150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (mRandom < 0) {
428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ALOGE("open: %s: %s", randomDevice, strerror(errno));
429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4345187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool generate_random_data(uint8_t* data, size_t size) const {
435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (readFully(mRandom, data, size) == size);
436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int mRandom;
440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and
443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size
444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in
445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two
446822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version,
447f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other
448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob()
449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */
450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: **
452822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction:
453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   metadata || Enc(MD5(data) || data)
454822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing:
456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Derive independent keys for encryption and MAC:
458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kenc = AES_encrypt(masterKey, "Encrypt")
459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kmac = AES_encrypt(masterKey, "MAC")
460822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
461822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Store this:
462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
463822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *             HMAC(Kmac, metadata || Enc(data))
464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */
465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob {
466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t version;
467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t type;
468f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    uint8_t flags;
469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t info;
470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t vector[AES_BLOCK_SIZE];
471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t encrypted[0]; // Marks offset to encrypted data.
472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t digest[MD5_DIGEST_LENGTH];
473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t digested[0]; // Marks offset to digested data.
474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int32_t length; // in network byte order when encrypted
475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
478822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum {
479d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root    TYPE_ANY = 0, // meta type that matches anything
480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_GENERIC = 1,
481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_MASTER_KEY = 2,
482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_KEY_PAIR = 3,
483822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType;
484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
485f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2;
486822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob {
488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
48907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength,
49007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            BlobType type) {
491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = valueLength;
492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value, value, valueLength);
493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.info = infoLength;
495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value + valueLength, info, infoLength);
496822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
49707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        mBlob.version = CURRENT_BLOB_VERSION;
498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
499f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
500ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        if (type == TYPE_MASTER_KEY) {
501ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root            mBlob.flags = KEYSTORE_FLAG_ENCRYPTED;
502ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        } else {
503ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root            mBlob.flags = KEYSTORE_FLAG_NONE;
504ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        }
505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob(blob b) {
508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob = b;
509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob() {}
512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5135187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getValue() const {
514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.value;
515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5175187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int32_t getLength() const {
518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.length;
519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5215187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getInfo() const {
5225187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return mBlob.value + mBlob.length;
5235187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
5245187818895c4c5f650a611c40531b1dff7764c18Kenny Root
5255187818895c4c5f650a611c40531b1dff7764c18Kenny Root    uint8_t getInfoLength() const {
526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.info;
527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
529822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t getVersion() const {
530822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return mBlob.version;
531822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
532822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
533f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    bool isEncrypted() const {
534f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (mBlob.version < 2) {
535f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            return true;
536f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
537f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
538f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED;
539f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    }
540f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
541f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    void setEncrypted(bool encrypted) {
542f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (encrypted) {
543f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED;
544f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        } else {
545f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED;
546f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
547f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    }
548f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
54917208e0de5a42722901d803118745cca25fd10c1Kenny Root    bool isFallback() const {
55017208e0de5a42722901d803118745cca25fd10c1Kenny Root        return mBlob.flags & KEYSTORE_FLAG_FALLBACK;
55117208e0de5a42722901d803118745cca25fd10c1Kenny Root    }
55217208e0de5a42722901d803118745cca25fd10c1Kenny Root
55317208e0de5a42722901d803118745cca25fd10c1Kenny Root    void setFallback(bool fallback) {
55417208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (fallback) {
55517208e0de5a42722901d803118745cca25fd10c1Kenny Root            mBlob.flags |= KEYSTORE_FLAG_FALLBACK;
55617208e0de5a42722901d803118745cca25fd10c1Kenny Root        } else {
55717208e0de5a42722901d803118745cca25fd10c1Kenny Root            mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK;
55817208e0de5a42722901d803118745cca25fd10c1Kenny Root        }
55917208e0de5a42722901d803118745cca25fd10c1Kenny Root    }
56017208e0de5a42722901d803118745cca25fd10c1Kenny Root
561822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setVersion(uint8_t version) {
562822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.version = version;
563822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
564822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
565822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    BlobType getType() const {
566822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return BlobType(mBlob.type);
567822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
568822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
569822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setType(BlobType type) {
570822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
571822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
572822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
573f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) {
574f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ALOGV("writing blob %s", filename);
575f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted()) {
576f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (state != STATE_NO_ERROR) {
577f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                ALOGD("couldn't insert encrypted blob while not unlocked");
578f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return LOCKED;
579f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
580f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
581f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
582f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                ALOGW("Could not read random data for: %s", filename);
583f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return SYSTEM_ERROR;
584f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // data includes the value and the value's length
588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t dataLength = mBlob.length + sizeof(mBlob.length);
589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // pad data to the AES_BLOCK_SIZE
590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                                 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // encrypted data includes the digest value
593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // move info after space for padding
595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // zero padding area
597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = htonl(mBlob.length);
600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
601f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted()) {
602f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            MD5(mBlob.digested, digestedLength, mBlob.digest);
603f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
604f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            uint8_t vector[AES_BLOCK_SIZE];
605f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
606f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
607f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                            aes_key, vector, AES_ENCRYPT);
608f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = encryptedLength + headerLength + mBlob.info;
612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* tmpFileName = ".tmp";
614150ca934edb745de3666a6492b039900df228ff0Kenny Root        int out = TEMP_FAILURE_RETRY(open(tmpFileName,
615150ca934edb745de3666a6492b039900df228ff0Kenny Root                O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
616150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (out < 0) {
617150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno));
618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(out) != 0) {
622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (writtenBytes != fileLength) {
625150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(tmpFileName);
627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
629150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (rename(tmpFileName, filename) == -1) {
630150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("could not rename blob to %s: %s", filename, strerror(errno));
631150ca934edb745de3666a6492b039900df228ff0Kenny Root            return SYSTEM_ERROR;
632150ca934edb745de3666a6492b039900df228ff0Kenny Root        }
633150ca934edb745de3666a6492b039900df228ff0Kenny Root        return NO_ERROR;
634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
636f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) {
637f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ALOGV("reading blob %s", filename);
638150ca934edb745de3666a6492b039900df228ff0Kenny Root        int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
639150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (in < 0) {
640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // fileLength may be less than sizeof(mBlob) since the in
643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // memory version has extra padding to tolerate rounding up to
644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES_BLOCK_SIZE
645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
649f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
650f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted() && (state != STATE_NO_ERROR)) {
651f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            return LOCKED;
652f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
653f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (fileLength < headerLength) {
656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
660f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (encryptedLength < 0) {
661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
663f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
664f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ssize_t digestedLength;
665f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted()) {
666f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (encryptedLength % AES_BLOCK_SIZE != 0) {
667f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return VALUE_CORRUPTED;
668f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
669f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
670f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
671f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                            mBlob.vector, AES_DECRYPT);
672f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
673f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            uint8_t computedDigest[MD5_DIGEST_LENGTH];
674f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            MD5(mBlob.digested, digestedLength, computedDigest);
675f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
676f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return VALUE_CORRUPTED;
677f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
678f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        } else {
679f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            digestedLength = encryptedLength;
680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = ntohl(mBlob.length);
684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.length < 0 || mBlob.length > maxValueLength) {
685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.info != 0) {
688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // move info from after padding to after data
689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
69107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct blob mBlob;
696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
698655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState {
699655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic:
700655b958eb2180c7c06889f83f606d23421bf038cKenny Root    UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) {
701655b958eb2180c7c06889f83f606d23421bf038cKenny Root        asprintf(&mUserDir, "user_%u", mUserId);
702655b958eb2180c7c06889f83f606d23421bf038cKenny Root        asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir);
703655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
70470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
705655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ~UserState() {
706655b958eb2180c7c06889f83f606d23421bf038cKenny Root        free(mUserDir);
707655b958eb2180c7c06889f83f606d23421bf038cKenny Root        free(mMasterKeyFile);
708655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
70970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
710655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool initialize() {
711655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) {
712655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGE("Could not create directory '%s'", mUserDir);
713655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return false;
714655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
715655b958eb2180c7c06889f83f606d23421bf038cKenny Root
716655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(mMasterKeyFile, R_OK) == 0) {
717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_LOCKED);
718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_UNINITIALIZED);
720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
72170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
722655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return true;
723655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
724655b958eb2180c7c06889f83f606d23421bf038cKenny Root
725655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uid_t getUserId() const {
726655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mUserId;
727655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
728655b958eb2180c7c06889f83f606d23421bf038cKenny Root
729655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const char* getUserDirName() const {
730655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mUserDir;
731655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
732655b958eb2180c7c06889f83f606d23421bf038cKenny Root
733655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const char* getMasterKeyFileName() const {
734655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mMasterKeyFile;
735655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
736655b958eb2180c7c06889f83f606d23421bf038cKenny Root
737655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void setState(State state) {
738655b958eb2180c7c06889f83f606d23421bf038cKenny Root        mState = state;
739655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
740655b958eb2180c7c06889f83f606d23421bf038cKenny Root            mRetry = MAX_RETRY;
741655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7445187818895c4c5f650a611c40531b1dff7764c18Kenny Root    State getState() const {
745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mState;
746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7485187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int8_t getRetry() const {
749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mRetry;
750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
752655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void zeroizeMasterKeysInMemory() {
753655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(mMasterKey, 0, sizeof(mMasterKey));
754655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(mSalt, 0, sizeof(mSalt));
755655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
756655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
75770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
75870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
759655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode initialize(const android::String8& pw, Entropy* entropy) {
760655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!generateMasterKey(entropy)) {
761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
763655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode response = writeMasterKey(pw, entropy);
764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response != NO_ERROR) {
765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setupMasterKeys();
76807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7714e865753346fc6a075966972a7a98051818859dbRobin Lee    ResponseCode copyMasterKey(UserState* src) {
7724e865753346fc6a075966972a7a98051818859dbRobin Lee        if (mState != STATE_UNINITIALIZED) {
7734e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::SYSTEM_ERROR;
7744e865753346fc6a075966972a7a98051818859dbRobin Lee        }
7754e865753346fc6a075966972a7a98051818859dbRobin Lee        if (src->getState() != STATE_NO_ERROR) {
7764e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::SYSTEM_ERROR;
7774e865753346fc6a075966972a7a98051818859dbRobin Lee        }
7784e865753346fc6a075966972a7a98051818859dbRobin Lee        memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES);
7794e865753346fc6a075966972a7a98051818859dbRobin Lee        setupMasterKeys();
7804e865753346fc6a075966972a7a98051818859dbRobin Lee        return ::NO_ERROR;
7814e865753346fc6a075966972a7a98051818859dbRobin Lee    }
7824e865753346fc6a075966972a7a98051818859dbRobin Lee
783655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) {
784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
788822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
789f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy);
790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
792655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) {
793655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
794150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (in < 0) {
795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // we read the raw blob to just to get the salt to generate
799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES key, then we create the Blob to use with decryptBlob
800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        blob rawBlob;
801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // find salt at EOF if present, otherwise we have an old file
806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t* salt;
807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = NULL;
811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        Blob masterKeyBlob(rawBlob);
817f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey,
818f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                STATE_NO_ERROR);
819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == SYSTEM_ERROR) {
820f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            return response;
821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // if salt was missing, generate one and write a new master key file with the salt.
824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (salt == NULL) {
825655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (!generateSalt(entropy)) {
826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    return SYSTEM_ERROR;
827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                }
828655b958eb2180c7c06889f83f606d23421bf038cKenny Root                response = writeMasterKey(pw, entropy);
829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (response == NO_ERROR) {
831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                setupMasterKeys();
833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
835a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRetry <= 0) {
837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            reset();
838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return UNINITIALIZED;
839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
840a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        --mRetry;
841a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        switch (mRetry) {
842a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 0: return WRONG_PASSWORD_0;
843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 1: return WRONG_PASSWORD_1;
844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 2: return WRONG_PASSWORD_2;
845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 3: return WRONG_PASSWORD_3;
846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            default: return WRONG_PASSWORD_3;
847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
850655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY* getEncryptionKey() {
851655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return &mMasterKeyEncryption;
852655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
854655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY* getDecryptionKey() {
855655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return &mMasterKeyDecryption;
856655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
858655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool reset() {
859655b958eb2180c7c06889f83f606d23421bf038cKenny Root        DIR* dir = opendir(getUserDirName());
860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
861655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("couldn't open user directory: %s", strerror(errno));
862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
864655b958eb2180c7c06889f83f606d23421bf038cKenny Root
865655b958eb2180c7c06889f83f606d23421bf038cKenny Root        struct dirent* file;
866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
867655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // We only care about files.
868655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (file->d_type != DT_REG) {
869655b958eb2180c7c06889f83f606d23421bf038cKenny Root                continue;
870655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
871655b958eb2180c7c06889f83f606d23421bf038cKenny Root
872655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Skip anything that starts with a "."
873931fac098f2ae35aa1da26ced57962c9a21f95cfKenny Root            if (file->d_name[0] == '.' && strcmp(".masterkey", file->d_name)) {
874655b958eb2180c7c06889f83f606d23421bf038cKenny Root                continue;
875655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
876655b958eb2180c7c06889f83f606d23421bf038cKenny Root
877655b958eb2180c7c06889f83f606d23421bf038cKenny Root            unlinkat(dirfd(dir), file->d_name, 0);
878a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
879a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
880a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
881a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
882a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
883655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate:
884655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const int MASTER_KEY_SIZE_BYTES = 16;
885655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
886655b958eb2180c7c06889f83f606d23421bf038cKenny Root
887655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const int MAX_RETRY = 4;
888655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const size_t SALT_SIZE = 16;
889655b958eb2180c7c06889f83f606d23421bf038cKenny Root
890655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
891655b958eb2180c7c06889f83f606d23421bf038cKenny Root            uint8_t* salt) {
892655b958eb2180c7c06889f83f606d23421bf038cKenny Root        size_t saltSize;
893655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (salt != NULL) {
894655b958eb2180c7c06889f83f606d23421bf038cKenny Root            saltSize = SALT_SIZE;
895655b958eb2180c7c06889f83f606d23421bf038cKenny Root        } else {
896655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
897655b958eb2180c7c06889f83f606d23421bf038cKenny Root            salt = (uint8_t*) "keystore";
898655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // sizeof = 9, not strlen = 8
899655b958eb2180c7c06889f83f606d23421bf038cKenny Root            saltSize = sizeof("keystore");
900655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
901655b958eb2180c7c06889f83f606d23421bf038cKenny Root
902655b958eb2180c7c06889f83f606d23421bf038cKenny Root        PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt,
903655b958eb2180c7c06889f83f606d23421bf038cKenny Root                saltSize, 8192, keySize, key);
904655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
905655b958eb2180c7c06889f83f606d23421bf038cKenny Root
906655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool generateSalt(Entropy* entropy) {
907655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return entropy->generate_random_data(mSalt, sizeof(mSalt));
908655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
909655b958eb2180c7c06889f83f606d23421bf038cKenny Root
910655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool generateMasterKey(Entropy* entropy) {
911655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
912655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return false;
913655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
914655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!generateSalt(entropy)) {
915655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return false;
916655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
917655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return true;
918655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
919655b958eb2180c7c06889f83f606d23421bf038cKenny Root
920655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void setupMasterKeys() {
921655b958eb2180c7c06889f83f606d23421bf038cKenny Root        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
922655b958eb2180c7c06889f83f606d23421bf038cKenny Root        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
923655b958eb2180c7c06889f83f606d23421bf038cKenny Root        setState(STATE_NO_ERROR);
924655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
925655b958eb2180c7c06889f83f606d23421bf038cKenny Root
926655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uid_t mUserId;
927655b958eb2180c7c06889f83f606d23421bf038cKenny Root
928655b958eb2180c7c06889f83f606d23421bf038cKenny Root    char* mUserDir;
929655b958eb2180c7c06889f83f606d23421bf038cKenny Root    char* mMasterKeyFile;
930655b958eb2180c7c06889f83f606d23421bf038cKenny Root
931655b958eb2180c7c06889f83f606d23421bf038cKenny Root    State mState;
932655b958eb2180c7c06889f83f606d23421bf038cKenny Root    int8_t mRetry;
933655b958eb2180c7c06889f83f606d23421bf038cKenny Root
934655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
935655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uint8_t mSalt[SALT_SIZE];
936655b958eb2180c7c06889f83f606d23421bf038cKenny Root
937655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY mMasterKeyEncryption;
938655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY mMasterKeyDecryption;
939655b958eb2180c7c06889f83f606d23421bf038cKenny Root};
940655b958eb2180c7c06889f83f606d23421bf038cKenny Root
941655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct {
942655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uint32_t uid;
943655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const uint8_t* filename;
944655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t;
945655b958eb2180c7c06889f83f606d23421bf038cKenny Root
946655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore {
947655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic:
948655b958eb2180c7c06889f83f606d23421bf038cKenny Root    KeyStore(Entropy* entropy, keymaster_device_t* device)
949655b958eb2180c7c06889f83f606d23421bf038cKenny Root        : mEntropy(entropy)
950655b958eb2180c7c06889f83f606d23421bf038cKenny Root        , mDevice(device)
951655b958eb2180c7c06889f83f606d23421bf038cKenny Root    {
952655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(&mMetaData, '\0', sizeof(mMetaData));
953655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
954655b958eb2180c7c06889f83f606d23421bf038cKenny Root
955655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ~KeyStore() {
956655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
957655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mGrants.end(); it++) {
958655b958eb2180c7c06889f83f606d23421bf038cKenny Root            delete *it;
959655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
960c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang        mGrants.clear();
961655b958eb2180c7c06889f83f606d23421bf038cKenny Root
962655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
963655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mMasterKeys.end(); it++) {
964655b958eb2180c7c06889f83f606d23421bf038cKenny Root            delete *it;
965655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
966c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang        mMasterKeys.clear();
967655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
968655b958eb2180c7c06889f83f606d23421bf038cKenny Root
969655b958eb2180c7c06889f83f606d23421bf038cKenny Root    keymaster_device_t* getDevice() const {
970655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mDevice;
971655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
972655b958eb2180c7c06889f83f606d23421bf038cKenny Root
973655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode initialize() {
974655b958eb2180c7c06889f83f606d23421bf038cKenny Root        readMetaData();
975655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (upgradeKeystore()) {
976655b958eb2180c7c06889f83f606d23421bf038cKenny Root            writeMetaData();
977655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
978655b958eb2180c7c06889f83f606d23421bf038cKenny Root
979655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return ::NO_ERROR;
980655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
981655b958eb2180c7c06889f83f606d23421bf038cKenny Root
982655b958eb2180c7c06889f83f606d23421bf038cKenny Root    State getState(uid_t uid) {
983655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return getUserState(uid)->getState();
984655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
985655b958eb2180c7c06889f83f606d23421bf038cKenny Root
986655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode initializeUser(const android::String8& pw, uid_t uid) {
987655b958eb2180c7c06889f83f606d23421bf038cKenny Root        UserState* userState = getUserState(uid);
988655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState->initialize(pw, mEntropy);
989655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
990655b958eb2180c7c06889f83f606d23421bf038cKenny Root
9914e865753346fc6a075966972a7a98051818859dbRobin Lee    ResponseCode copyMasterKey(uid_t src, uid_t uid) {
9924e865753346fc6a075966972a7a98051818859dbRobin Lee        UserState *userState = getUserState(uid);
9934e865753346fc6a075966972a7a98051818859dbRobin Lee        UserState *initState = getUserState(src);
9944e865753346fc6a075966972a7a98051818859dbRobin Lee        return userState->copyMasterKey(initState);
9954e865753346fc6a075966972a7a98051818859dbRobin Lee    }
9964e865753346fc6a075966972a7a98051818859dbRobin Lee
997655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) {
99850122db50bcb6c1aab50ef235c8f9d264b50e97aRobin Lee        UserState* userState = getUserState(uid);
999655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState->writeMasterKey(pw, mEntropy);
1000655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1001655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1002655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode readMasterKey(const android::String8& pw, uid_t uid) {
100350122db50bcb6c1aab50ef235c8f9d264b50e97aRobin Lee        UserState* userState = getUserState(uid);
1004655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState->readMasterKey(pw, mEntropy);
1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::String8 getKeyName(const android::String8& keyName) {
1008a77e809ecff5190790906fb7a3c527259c735071Douglas Leung        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
1009655b958eb2180c7c06889f83f606d23421bf038cKenny Root        encode_key(encoded, keyName);
1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return android::String8(encoded);
1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) {
1014a77e809ecff5190790906fb7a3c527259c735071Douglas Leung        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
1015655b958eb2180c7c06889f83f606d23421bf038cKenny Root        encode_key(encoded, keyName);
1016655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return android::String8::format("%u_%s", uid, encoded);
1017655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1018655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1019655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) {
1020a77e809ecff5190790906fb7a3c527259c735071Douglas Leung        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
1021655b958eb2180c7c06889f83f606d23421bf038cKenny Root        encode_key(encoded, keyName);
1022655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid,
1023655b958eb2180c7c06889f83f606d23421bf038cKenny Root                encoded);
1024655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1025655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool reset(uid_t uid) {
10274b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        android::String8 prefix("");
10284b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        android::Vector<android::String16> aliases;
10294b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (saw(prefix, &aliases, uid) != ::NO_ERROR) {
10304b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return ::SYSTEM_ERROR;
10314b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
10324b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
1033655b958eb2180c7c06889f83f606d23421bf038cKenny Root        UserState* userState = getUserState(uid);
10344b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        for (uint32_t i = 0; i < aliases.size(); i++) {
10354b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            android::String8 filename(aliases[i]);
10364b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            filename = android::String8::format("%s/%s", userState->getUserDirName(),
10374b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    getKeyName(filename).string());
10384b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            del(filename, ::TYPE_ANY, uid);
10394b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
10404b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
1041655b958eb2180c7c06889f83f606d23421bf038cKenny Root        userState->zeroizeMasterKeysInMemory();
1042655b958eb2180c7c06889f83f606d23421bf038cKenny Root        userState->setState(STATE_UNINITIALIZED);
1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState->reset();
1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1045655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1046655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool isEmpty(uid_t uid) const {
1047655b958eb2180c7c06889f83f606d23421bf038cKenny Root        const UserState* userState = getUserState(uid);
104831e27468b6d822adbd2aec9219a68c206aa6957cKenny Root        if (userState == NULL || userState->getState() == STATE_UNINITIALIZED) {
1049655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return true;
1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1052655b958eb2180c7c06889f83f606d23421bf038cKenny Root        DIR* dir = opendir(userState->getUserDirName());
1053a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
1054a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return true;
1055a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1056655b958eb2180c7c06889f83f606d23421bf038cKenny Root
105731e27468b6d822adbd2aec9219a68c206aa6957cKenny Root        bool result = true;
105831e27468b6d822adbd2aec9219a68c206aa6957cKenny Root        struct dirent* file;
1059a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
1060655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // We only care about files.
1061655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (file->d_type != DT_REG) {
1062655b958eb2180c7c06889f83f606d23421bf038cKenny Root                continue;
1063655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1064655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1065655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Skip anything that starts with a "."
1066655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (file->d_name[0] == '.') {
1067655b958eb2180c7c06889f83f606d23421bf038cKenny Root                continue;
1068655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1069655b958eb2180c7c06889f83f606d23421bf038cKenny Root
107031e27468b6d822adbd2aec9219a68c206aa6957cKenny Root            result = false;
107131e27468b6d822adbd2aec9219a68c206aa6957cKenny Root            break;
1072a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1073a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
1074a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return result;
1075a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1076a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1077655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void lock(uid_t uid) {
1078655b958eb2180c7c06889f83f606d23421bf038cKenny Root        UserState* userState = getUserState(uid);
1079655b958eb2180c7c06889f83f606d23421bf038cKenny Root        userState->zeroizeMasterKeysInMemory();
1080655b958eb2180c7c06889f83f606d23421bf038cKenny Root        userState->setState(STATE_LOCKED);
1081a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1082a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1083655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) {
1084655b958eb2180c7c06889f83f606d23421bf038cKenny Root        UserState* userState = getUserState(uid);
1085f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
1086f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                userState->getState());
1087822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc != NO_ERROR) {
1088822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return rc;
1089822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1090822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1091822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        const uint8_t version = keyBlob->getVersion();
109207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (version < CURRENT_BLOB_VERSION) {
1093cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root            /* If we upgrade the key, we need to write it to disk again. Then
1094cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root             * it must be read it again since the blob is encrypted each time
1095cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root             * it's written.
1096cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root             */
1097655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (upgradeBlob(filename, keyBlob, version, type, uid)) {
1098655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR
1099f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                        || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
1100f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                                userState->getState())) != NO_ERROR) {
1101cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root                    return rc;
1102cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root                }
1103cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root            }
1104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
110617208e0de5a42722901d803118745cca25fd10c1Kenny Root        /*
110717208e0de5a42722901d803118745cca25fd10c1Kenny Root         * This will upgrade software-backed keys to hardware-backed keys when
110817208e0de5a42722901d803118745cca25fd10c1Kenny Root         * the HAL for the device supports the newer key types.
110917208e0de5a42722901d803118745cca25fd10c1Kenny Root         */
111017208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (rc == NO_ERROR && type == TYPE_KEY_PAIR
111117208e0de5a42722901d803118745cca25fd10c1Kenny Root                && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2
111217208e0de5a42722901d803118745cca25fd10c1Kenny Root                && keyBlob->isFallback()) {
111317208e0de5a42722901d803118745cca25fd10c1Kenny Root            ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename,
111417208e0de5a42722901d803118745cca25fd10c1Kenny Root                    uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
111517208e0de5a42722901d803118745cca25fd10c1Kenny Root
111617208e0de5a42722901d803118745cca25fd10c1Kenny Root            // The HAL allowed the import, reget the key to have the "fresh"
111717208e0de5a42722901d803118745cca25fd10c1Kenny Root            // version.
111817208e0de5a42722901d803118745cca25fd10c1Kenny Root            if (imported == NO_ERROR) {
111917208e0de5a42722901d803118745cca25fd10c1Kenny Root                rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid);
112017208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
112117208e0de5a42722901d803118745cca25fd10c1Kenny Root        }
112217208e0de5a42722901d803118745cca25fd10c1Kenny Root
1123d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (type != TYPE_ANY && keyBlob->getType() != type) {
1124822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
1125822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return KEY_NOT_FOUND;
1126822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1127822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1128822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return rc;
1129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1131655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) {
1132655b958eb2180c7c06889f83f606d23421bf038cKenny Root        UserState* userState = getUserState(uid);
1133f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(),
1134f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                mEntropy);
1135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
11374b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    ResponseCode del(const char *filename, const BlobType type, uid_t uid) {
11384b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        Blob keyBlob;
11394b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        ResponseCode rc = get(filename, &keyBlob, type, uid);
11404b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (rc != ::NO_ERROR) {
11414b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return rc;
11424b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
11434b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11444b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (keyBlob.getType() == ::TYPE_KEY_PAIR) {
11454b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            // A device doesn't have to implement delete_keypair.
11464b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (mDevice->delete_keypair != NULL && !keyBlob.isFallback()) {
11474b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                if (mDevice->delete_keypair(mDevice, keyBlob.getValue(), keyBlob.getLength())) {
11484b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    rc = ::SYSTEM_ERROR;
11494b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                }
11504b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
11514b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
11524b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (rc != ::NO_ERROR) {
11534b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return rc;
11544b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
11554b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11564b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
11574b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    }
11584b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11594b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    ResponseCode saw(const android::String8& prefix, android::Vector<android::String16> *matches,
11604b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            uid_t uid) {
11614b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        UserState* userState = getUserState(uid);
11634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        size_t n = prefix.length();
11644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11654b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        DIR* dir = opendir(userState->getUserDirName());
11664b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (!dir) {
11674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            ALOGW("can't open directory for user: %s", strerror(errno));
11684b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return ::SYSTEM_ERROR;
11694b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
11704b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11714b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        struct dirent* file;
11724b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        while ((file = readdir(dir)) != NULL) {
11734b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            // We only care about files.
11744b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (file->d_type != DT_REG) {
11754b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                continue;
11764b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
11774b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11784b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            // Skip anything that starts with a "."
11794b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (file->d_name[0] == '.') {
11804b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                continue;
11814b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
11824b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11834b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (!strncmp(prefix.string(), file->d_name, n)) {
11844b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                const char* p = &file->d_name[n];
11854b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                size_t plen = strlen(p);
11864b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
11874b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                size_t extra = decode_key_length(p, plen);
11884b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                char *match = (char*) malloc(extra + 1);
11894b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                if (match != NULL) {
11904b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    decode_key(match, p, plen);
11914b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    matches->push(android::String16(match, extra));
11924b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    free(match);
11934b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                } else {
11944b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    ALOGW("could not allocate match of size %zd", extra);
11954b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                }
11964b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
11974b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
11984b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        closedir(dir);
11994b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return ::NO_ERROR;
12004b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    }
12014b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
120207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    void addGrant(const char* filename, uid_t granteeUid) {
1203655b958eb2180c7c06889f83f606d23421bf038cKenny Root        const grant_t* existing = getGrant(filename, granteeUid);
1204655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (existing == NULL) {
1205655b958eb2180c7c06889f83f606d23421bf038cKenny Root            grant_t* grant = new grant_t;
120607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            grant->uid = granteeUid;
1207a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom            grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
1208655b958eb2180c7c06889f83f606d23421bf038cKenny Root            mGrants.add(grant);
120970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
121070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
121170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
121207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    bool removeGrant(const char* filename, uid_t granteeUid) {
1213655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mGrants.end(); it++) {
1215655b958eb2180c7c06889f83f606d23421bf038cKenny Root            grant_t* grant = *it;
1216655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (grant->uid == granteeUid
1217655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root                mGrants.erase(it);
1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return true;
1220655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
122170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
122270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return false;
122370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
122470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1225a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    bool hasGrant(const char* filename, const uid_t uid) const {
1226a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom        return getGrant(filename, uid) != NULL;
122770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
122870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1229f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid,
1230f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            int32_t flags) {
1231822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t* data;
1232822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        size_t dataLength;
1233822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        int rc;
1234822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1235822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (mDevice->import_keypair == NULL) {
1236822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Keymaster doesn't support import!");
1237822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1238822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1239822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
124017208e0de5a42722901d803118745cca25fd10c1Kenny Root        bool isFallback = false;
124107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength);
1242822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc) {
1243a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root            /*
1244a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * Maybe the device doesn't support this type of key. Try to use the
1245a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * software fallback keymaster implementation. This is a little bit
1246a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * lazier than checking the PKCS#8 key type, but the software
1247a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * implementation will do that anyway.
1248a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             */
1249a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root            rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength);
1250a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root            isFallback = true;
125117208e0de5a42722901d803118745cca25fd10c1Kenny Root
125217208e0de5a42722901d803118745cca25fd10c1Kenny Root            if (rc) {
125317208e0de5a42722901d803118745cca25fd10c1Kenny Root                ALOGE("Error while importing keypair: %d", rc);
125417208e0de5a42722901d803118745cca25fd10c1Kenny Root                return SYSTEM_ERROR;
125517208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
1256822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1257822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1258822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
1259822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        free(data);
1260822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1261f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
126217208e0de5a42722901d803118745cca25fd10c1Kenny Root        keyBlob.setFallback(isFallback);
1263f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
1264655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return put(filename, &keyBlob, uid);
1265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
1266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
12671b0e3933900c7ea21189704d5db64e7346aee7afKenny Root    bool isHardwareBacked(const android::String16& keyType) const {
12681b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        if (mDevice == NULL) {
12691b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            ALOGW("can't get keymaster device");
12701b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            return false;
12711b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        }
12721b0e3933900c7ea21189704d5db64e7346aee7afKenny Root
12731b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        if (sRSAKeyType == keyType) {
12741b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0;
12751b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        } else {
12761b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0
12771b0e3933900c7ea21189704d5db64e7346aee7afKenny Root                    && (mDevice->common.module->module_api_version
12781b0e3933900c7ea21189704d5db64e7346aee7afKenny Root                            >= KEYMASTER_MODULE_API_VERSION_0_2);
12791b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        }
12808ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root    }
12818ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root
1282655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid,
1283655b958eb2180c7c06889f83f606d23421bf038cKenny Root            const BlobType type) {
128486b16e8c0d353af97f0411917789308dba417295Kenny Root        android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid));
1285a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1286655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid);
1287655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (responseCode == NO_ERROR) {
1288655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return responseCode;
1289655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1290a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1291655b958eb2180c7c06889f83f606d23421bf038cKenny Root        // If this is one of the legacy UID->UID mappings, use it.
1292655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uid_t euid = get_keystore_euid(uid);
1293655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (euid != uid) {
129486b16e8c0d353af97f0411917789308dba417295Kenny Root            filepath8 = getKeyNameForUidWithDir(keyName, euid);
1295655b958eb2180c7c06889f83f606d23421bf038cKenny Root            responseCode = get(filepath8.string(), keyBlob, type, uid);
1296655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (responseCode == NO_ERROR) {
1297655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return responseCode;
1298655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1299655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
130070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1301655b958eb2180c7c06889f83f606d23421bf038cKenny Root        // They might be using a granted key.
130286b16e8c0d353af97f0411917789308dba417295Kenny Root        android::String8 filename8 = getKeyName(keyName);
1303655b958eb2180c7c06889f83f606d23421bf038cKenny Root        char* end;
130486b16e8c0d353af97f0411917789308dba417295Kenny Root        strtoul(filename8.string(), &end, 10);
1305655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (end[0] != '_' || end[1] == 0) {
1306655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return KEY_NOT_FOUND;
1307655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
130886b16e8c0d353af97f0411917789308dba417295Kenny Root        filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(),
130986b16e8c0d353af97f0411917789308dba417295Kenny Root                filename8.string());
1310655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!hasGrant(filepath8.string(), uid)) {
1311655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return responseCode;
1312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1314655b958eb2180c7c06889f83f606d23421bf038cKenny Root        // It is a granted key. Try to load it.
1315655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return get(filepath8.string(), keyBlob, type, uid);
1316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1318655b958eb2180c7c06889f83f606d23421bf038cKenny Root    /**
1319655b958eb2180c7c06889f83f606d23421bf038cKenny Root     * Returns any existing UserState or creates it if it doesn't exist.
1320655b958eb2180c7c06889f83f606d23421bf038cKenny Root     */
1321655b958eb2180c7c06889f83f606d23421bf038cKenny Root    UserState* getUserState(uid_t uid) {
1322655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uid_t userId = get_user_id(uid);
1323655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1324655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
1325655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mMasterKeys.end(); it++) {
1326655b958eb2180c7c06889f83f606d23421bf038cKenny Root            UserState* state = *it;
1327655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (state->getUserId() == userId) {
1328655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return state;
1329655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1331655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1332655b958eb2180c7c06889f83f606d23421bf038cKenny Root        UserState* userState = new UserState(userId);
1333655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!userState->initialize()) {
1334655b958eb2180c7c06889f83f606d23421bf038cKenny Root            /* There's not much we can do if initialization fails. Trying to
1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root             * unlock the keystore for that user will fail as well, so any
1336655b958eb2180c7c06889f83f606d23421bf038cKenny Root             * subsequent request for this user will just return SYSTEM_ERROR.
1337655b958eb2180c7c06889f83f606d23421bf038cKenny Root             */
1338655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGE("User initialization failed for %u; subsuquent operations will fail", userId);
1339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1340655b958eb2180c7c06889f83f606d23421bf038cKenny Root        mMasterKeys.add(userState);
1341655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState;
1342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1344655b958eb2180c7c06889f83f606d23421bf038cKenny Root    /**
1345655b958eb2180c7c06889f83f606d23421bf038cKenny Root     * Returns NULL if the UserState doesn't already exist.
1346655b958eb2180c7c06889f83f606d23421bf038cKenny Root     */
1347655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const UserState* getUserState(uid_t uid) const {
1348655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uid_t userId = get_user_id(uid);
1349655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1350655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin());
1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mMasterKeys.end(); it++) {
1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root            UserState* state = *it;
1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (state->getUserId() == userId) {
1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return state;
1355655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return NULL;
1359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1361655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate:
1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const char* sOldMasterKey;
1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const char* sMetaDataFile;
13641b0e3933900c7ea21189704d5db64e7346aee7afKenny Root    static const android::String16 sRSAKeyType;
1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root    Entropy* mEntropy;
136607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root    keymaster_device_t* mDevice;
1368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::Vector<UserState*> mMasterKeys;
1370655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::Vector<grant_t*> mGrants;
137270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1373655b958eb2180c7c06889f83f606d23421bf038cKenny Root    typedef struct {
1374655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uint32_t version;
1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root    } keystore_metadata_t;
137670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root    keystore_metadata_t mMetaData;
1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const grant_t* getGrant(const char* filename, uid_t uid) const {
1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<grant_t*>::const_iterator it(mGrants.begin());
1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mGrants.end(); it++) {
1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root            grant_t* grant = *it;
138370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            if (grant->uid == uid
1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
138570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                return grant;
138670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            }
138770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
138870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
138970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
139070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1391822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
1392822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Upgrade code. This will upgrade the key from the current version
1393822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * to whatever is newest.
1394822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root            const BlobType type, uid_t uid) {
1397822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        bool updated = false;
1398822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t version = oldVersion;
1399822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1400822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /* From V0 -> V1: All old types were unknown */
1401822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (version == 0) {
1402822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("upgrading to version 1 and setting type %d", type);
1403822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1404822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setType(type);
1405822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            if (type == TYPE_KEY_PAIR) {
1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root                importBlobAsKey(blob, filename, uid);
1407822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            }
1408822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            version = 1;
1409822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            updated = true;
1410822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1411822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1412f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        /* From V1 -> V2: All old keys were encrypted */
1413f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (version == 1) {
1414f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            ALOGV("upgrading to version 2");
1415f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
1416f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            blob->setEncrypted(true);
1417f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            version = 2;
1418f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            updated = true;
1419f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
1420f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
1421822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /*
1422822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * If we've updated, set the key blob to the right version
1423822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * and write it.
1424cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root         */
1425822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (updated) {
1426822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("updated and writing file %s", filename);
1427822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setVersion(version);
1428822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1429cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root
1430cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root        return updated;
1431822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
1432822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1433822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
1434822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Takes a blob that is an PEM-encoded RSA key as a byte array and
1435822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * converts it to a DER-encoded PKCS#8 for import into a keymaster.
1436822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Then it overwrites the original blob with the new blob
1437822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * format that is returned from the keymaster.
1438822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
1439655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) {
1440822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        // We won't even write to the blob directly with this BIO, so const_cast is okay.
1441822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
1442822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (b.get() == NULL) {
1443822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Problem instantiating BIO");
1444822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1445822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1446822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1447822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
1448822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (pkey.get() == NULL) {
1449822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't read old PEM file");
1450822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1452822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
1454822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
1455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (len < 0) {
1456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't measure PKCS#8 length");
1457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
146070c9889c5ca912e7c492580e1999f18ab65b267bKenny Root        UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]);
146170c9889c5ca912e7c492580e1999f18ab65b267bKenny Root        uint8_t* tmp = pkcs8key.get();
1462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
1463822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't convert to PKCS#8");
1464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1465822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1467f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid,
1468f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
1469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc != NO_ERROR) {
1470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return rc;
1471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1473655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return get(filename, blob, TYPE_KEY_PAIR, uid);
1474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
147570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1476655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void readMetaData() {
1477655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY));
1478655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (in < 0) {
1479655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return;
1480655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1481655b958eb2180c7c06889f83f606d23421bf038cKenny Root        size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData));
1482655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (fileLength != sizeof(mMetaData)) {
1483655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength,
1484655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    sizeof(mMetaData));
1485655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1486655b958eb2180c7c06889f83f606d23421bf038cKenny Root        close(in);
148770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
148870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1489655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void writeMetaData() {
1490655b958eb2180c7c06889f83f606d23421bf038cKenny Root        const char* tmpFileName = ".metadata.tmp";
1491655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int out = TEMP_FAILURE_RETRY(open(tmpFileName,
1492655b958eb2180c7c06889f83f606d23421bf038cKenny Root                O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
1493655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (out < 0) {
1494655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGE("couldn't write metadata file: %s", strerror(errno));
1495655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return;
1496655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1497655b958eb2180c7c06889f83f606d23421bf038cKenny Root        size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData));
1498655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (fileLength != sizeof(mMetaData)) {
1499655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
1500655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    sizeof(mMetaData));
150170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
1502655b958eb2180c7c06889f83f606d23421bf038cKenny Root        close(out);
1503655b958eb2180c7c06889f83f606d23421bf038cKenny Root        rename(tmpFileName, sMetaDataFile);
150470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
150570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1506655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool upgradeKeystore() {
1507655b958eb2180c7c06889f83f606d23421bf038cKenny Root        bool upgraded = false;
1508655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1509655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (mMetaData.version == 0) {
1510655b958eb2180c7c06889f83f606d23421bf038cKenny Root            UserState* userState = getUserState(0);
1511655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1512655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Initialize first so the directory is made.
1513655b958eb2180c7c06889f83f606d23421bf038cKenny Root            userState->initialize();
1514655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1515655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Migrate the old .masterkey file to user 0.
1516655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (access(sOldMasterKey, R_OK) == 0) {
1517655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) {
1518655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
1519655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    return false;
1520655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1521655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1522655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1523655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Initialize again in case we had a key.
1524655b958eb2180c7c06889f83f606d23421bf038cKenny Root            userState->initialize();
1525655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1526655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Try to migrate existing keys.
1527655b958eb2180c7c06889f83f606d23421bf038cKenny Root            DIR* dir = opendir(".");
1528655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (!dir) {
1529655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Give up now; maybe we can upgrade later.
1530655b958eb2180c7c06889f83f606d23421bf038cKenny Root                ALOGE("couldn't open keystore's directory; something is wrong");
1531655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return false;
1532655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1533655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1534655b958eb2180c7c06889f83f606d23421bf038cKenny Root            struct dirent* file;
1535655b958eb2180c7c06889f83f606d23421bf038cKenny Root            while ((file = readdir(dir)) != NULL) {
1536655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // We only care about files.
1537655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (file->d_type != DT_REG) {
1538655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1539655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1540655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1541655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Skip anything that starts with a "."
1542655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (file->d_name[0] == '.') {
1543655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1544655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1545655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1546655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Find the current file's user.
1547655b958eb2180c7c06889f83f606d23421bf038cKenny Root                char* end;
1548655b958eb2180c7c06889f83f606d23421bf038cKenny Root                unsigned long thisUid = strtoul(file->d_name, &end, 10);
1549655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (end[0] != '_' || end[1] == 0) {
1550655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1551655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1552655b958eb2180c7c06889f83f606d23421bf038cKenny Root                UserState* otherUser = getUserState(thisUid);
1553655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (otherUser->getUserId() != 0) {
1554655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    unlinkat(dirfd(dir), file->d_name, 0);
1555655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1556655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1557655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Rename the file into user directory.
1558655b958eb2180c7c06889f83f606d23421bf038cKenny Root                DIR* otherdir = opendir(otherUser->getUserDirName());
1559655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (otherdir == NULL) {
1560655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    ALOGW("couldn't open user directory for rename");
1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1562655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1563655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
1564655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
1565655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1566655b958eb2180c7c06889f83f606d23421bf038cKenny Root                closedir(otherdir);
1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1568655b958eb2180c7c06889f83f606d23421bf038cKenny Root            closedir(dir);
1569655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1570655b958eb2180c7c06889f83f606d23421bf038cKenny Root            mMetaData.version = 1;
1571655b958eb2180c7c06889f83f606d23421bf038cKenny Root            upgraded = true;
1572655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1574655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return upgraded;
157570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
1576655b958eb2180c7c06889f83f606d23421bf038cKenny Root};
157770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1578655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey";
1579655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata";
158070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
15811b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA");
15821b0e3933900c7ea21189704d5db64e7346aee7afKenny Root
158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android {
158407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient {
158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic:
158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    KeyStoreProxy(KeyStore* keyStore)
158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        : mKeyStore(keyStore)
158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
1590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    void binderDied(const wp<IBinder>&) {
159207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        ALOGE("binder death detected");
159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
1594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
159507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t test() {
1596d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1597eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1598eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_TEST, spid)) {
1599d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: test", callingUid);
160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
160107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1603655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mKeyStore->getState(callingUid);
1604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
160607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
1607d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1608eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1609eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_GET, spid)) {
1610d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: get", callingUid);
161107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
161207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
161407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
161507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
161666dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich
1617655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
1618494689083467ec372a58f094f041c8f102f39393Kenny Root                TYPE_GENERIC);
161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
1620655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("Could not read %s", name8.string());
162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *item = NULL;
162207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *itemLength = 0;
162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
162407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
162507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        *item = (uint8_t*) malloc(keyBlob.getLength());
162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        memcpy(*item, keyBlob.getValue(), keyBlob.getLength());
162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        *itemLength = keyBlob.getLength();
162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
1631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1633f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid,
1634f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            int32_t flags) {
1635eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1636d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1637eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_INSERT, spid)) {
1638d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: insert", callingUid);
163907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1642f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        State state = mKeyStore->getState(callingUid);
1643f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
1644f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            ALOGD("calling get in state: %d", state);
1645f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            return state;
1646f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
1647f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
1648494689083467ec372a58f094f041c8f102f39393Kenny Root        if (targetUid == -1) {
1649494689083467ec372a58f094f041c8f102f39393Kenny Root            targetUid = callingUid;
1650494689083467ec372a58f094f041c8f102f39393Kenny Root        } else if (!is_granted_to(callingUid, targetUid)) {
1651b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1652b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1653b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
1655655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
165607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
165707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
1658ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
1659ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root
1660fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        return mKeyStore->put(filename.string(), &keyBlob, targetUid);
1661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1663494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t del(const String16& name, int targetUid) {
1664d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1665eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1666eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_DELETE, spid)) {
1667d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: del", callingUid);
166807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
166907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
167007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1671494689083467ec372a58f094f041c8f102f39393Kenny Root        if (targetUid == -1) {
1672494689083467ec372a58f094f041c8f102f39393Kenny Root            targetUid = callingUid;
1673494689083467ec372a58f094f041c8f102f39393Kenny Root        } else if (!is_granted_to(callingUid, targetUid)) {
1674b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1675b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1676b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
167707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
1678655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
16794b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return mKeyStore->del(filename.string(), ::TYPE_GENERIC, targetUid);
1680298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1681298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1682494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t exist(const String16& name, int targetUid) {
1683d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1684eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1685eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_EXIST, spid)) {
1686d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: exist", callingUid);
168707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
168807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1690494689083467ec372a58f094f041c8f102f39393Kenny Root        if (targetUid == -1) {
1691494689083467ec372a58f094f041c8f102f39393Kenny Root            targetUid = callingUid;
1692494689083467ec372a58f094f041c8f102f39393Kenny Root        } else if (!is_granted_to(callingUid, targetUid)) {
1693b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1694b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1695b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
1697655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
169807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1699655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
170007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
1703298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1704298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1705494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) {
1706d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1707eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1708eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_SAW, spid)) {
1709d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: saw", callingUid);
171007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
171107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1713494689083467ec372a58f094f041c8f102f39393Kenny Root        if (targetUid == -1) {
1714494689083467ec372a58f094f041c8f102f39393Kenny Root            targetUid = callingUid;
1715494689083467ec372a58f094f041c8f102f39393Kenny Root        } else if (!is_granted_to(callingUid, targetUid)) {
1716b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1717b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1718b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
171907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const String8 prefix8(prefix);
1720655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
172107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
17224b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (mKeyStore->saw(filename, matches, targetUid) != ::NO_ERROR) {
17234b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return ::SYSTEM_ERROR;
172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
172507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
1726298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1727298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
172807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t reset() {
1729d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1730eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1731eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_RESET, spid)) {
1732d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: reset", callingUid);
173307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
173407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
17364b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
1737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
173907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    /*
174007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * Here is the history. To improve the security, the parameters to generate the
174107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * master key has been changed. To make a seamless transition, we update the
174207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * file using the same password when the user unlock it for the first time. If
174307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * any thing goes wrong during the transition, the new file will not overwrite
174407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * the old one. This avoids permanent damages of the existing data.
174507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     */
174607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t password(const String16& password) {
1747d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1748eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1749eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_PASSWORD, spid)) {
1750d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: password", callingUid);
175107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
175207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const String8 password8(password);
1755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1756655b958eb2180c7c06889f83f606d23421bf038cKenny Root        switch (mKeyStore->getState(callingUid)) {
175707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            case ::STATE_UNINITIALIZED: {
175807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                // generate master key, encrypt with password, write to file, initialize mMasterKey*.
1759655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return mKeyStore->initializeUser(password8, callingUid);
176007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
176107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            case ::STATE_NO_ERROR: {
176207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                // rewrite master key with new password.
1763655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return mKeyStore->writeMasterKey(password8, callingUid);
176407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
176507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            case ::STATE_LOCKED: {
176607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                // read master key, decrypt with password, initialize mMasterKey*.
1767655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return mKeyStore->readMasterKey(password8, callingUid);
176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
177007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::SYSTEM_ERROR;
177107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
1772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
177307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t lock() {
1774d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1775eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1776eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_LOCK, spid)) {
1777d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: lock", callingUid);
177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
177907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
178007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1781655b958eb2180c7c06889f83f606d23421bf038cKenny Root        State state = mKeyStore->getState(callingUid);
17829d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        if (state != ::STATE_NO_ERROR) {
178307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("calling lock in state: %d", state);
178407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
178507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
178670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1787655b958eb2180c7c06889f83f606d23421bf038cKenny Root        mKeyStore->lock(callingUid);
178807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
178970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
1790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
179107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t unlock(const String16& pw) {
1792d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1793eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1794eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_UNLOCK, spid)) {
1795d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: unlock", callingUid);
179607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
179707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
179807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1799655b958eb2180c7c06889f83f606d23421bf038cKenny Root        State state = mKeyStore->getState(callingUid);
18009d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        if (state != ::STATE_LOCKED) {
180107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("calling unlock when not locked");
180207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
180307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
180407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
180507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const String8 password8(pw);
180607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return password(pw);
180770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
180870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
180907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t zero() {
1810d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1811eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1812eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_ZERO, spid)) {
1813d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: zero", callingUid);
181407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
181507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
181670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1817655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR;
181870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
181970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
182096427baf0094d50047049d329b0779c3c910402cKenny Root    int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
182196427baf0094d50047049d329b0779c3c910402cKenny Root            int32_t flags, Vector<sp<KeystoreArg> >* args) {
1822d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1823eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1824eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_INSERT, spid)) {
1825d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: generate", callingUid);
182607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
182707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
182870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1829494689083467ec372a58f094f041c8f102f39393Kenny Root        if (targetUid == -1) {
1830494689083467ec372a58f094f041c8f102f39393Kenny Root            targetUid = callingUid;
1831494689083467ec372a58f094f041c8f102f39393Kenny Root        } else if (!is_granted_to(callingUid, targetUid)) {
1832b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1833b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1834b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
1835655b958eb2180c7c06889f83f606d23421bf038cKenny Root        State state = mKeyStore->getState(callingUid);
1836f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
1837f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            ALOGW("calling generate in state: %d", state);
183807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
183907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
184070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
184107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        uint8_t* data;
184207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        size_t dataLength;
184307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int rc;
184417208e0de5a42722901d803118745cca25fd10c1Kenny Root        bool isFallback = false;
184570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
184607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const keymaster_device_t* device = mKeyStore->getDevice();
184707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
184807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
184907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
185070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
185107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->generate_keypair == NULL) {
185207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
185307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
185470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
185517208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (keyType == EVP_PKEY_DSA) {
185696427baf0094d50047049d329b0779c3c910402cKenny Root            keymaster_dsa_keygen_params_t dsa_params;
185796427baf0094d50047049d329b0779c3c910402cKenny Root            memset(&dsa_params, '\0', sizeof(dsa_params));
185896427baf0094d50047049d329b0779c3c910402cKenny Root
185996427baf0094d50047049d329b0779c3c910402cKenny Root            if (keySize == -1) {
186096427baf0094d50047049d329b0779c3c910402cKenny Root                keySize = DSA_DEFAULT_KEY_SIZE;
186196427baf0094d50047049d329b0779c3c910402cKenny Root            } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE
186296427baf0094d50047049d329b0779c3c910402cKenny Root                    || keySize > DSA_MAX_KEY_SIZE) {
186396427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("invalid key size %d", keySize);
186496427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
186596427baf0094d50047049d329b0779c3c910402cKenny Root            }
186696427baf0094d50047049d329b0779c3c910402cKenny Root            dsa_params.key_size = keySize;
186796427baf0094d50047049d329b0779c3c910402cKenny Root
186896427baf0094d50047049d329b0779c3c910402cKenny Root            if (args->size() == 3) {
186996427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> gArg = args->itemAt(0);
187096427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> pArg = args->itemAt(1);
187196427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> qArg = args->itemAt(2);
187296427baf0094d50047049d329b0779c3c910402cKenny Root
187396427baf0094d50047049d329b0779c3c910402cKenny Root                if (gArg != NULL && pArg != NULL && qArg != NULL) {
187496427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data());
187596427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.generator_len = gArg->size();
187696427baf0094d50047049d329b0779c3c910402cKenny Root
187796427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data());
187896427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_p_len = pArg->size();
187996427baf0094d50047049d329b0779c3c910402cKenny Root
188096427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data());
188196427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_q_len = qArg->size();
188296427baf0094d50047049d329b0779c3c910402cKenny Root                } else {
188396427baf0094d50047049d329b0779c3c910402cKenny Root                    ALOGI("not all DSA parameters were read");
188496427baf0094d50047049d329b0779c3c910402cKenny Root                    return ::SYSTEM_ERROR;
188596427baf0094d50047049d329b0779c3c910402cKenny Root                }
188696427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (args->size() != 0) {
188796427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("DSA args must be 3");
188896427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
188996427baf0094d50047049d329b0779c3c910402cKenny Root            }
189096427baf0094d50047049d329b0779c3c910402cKenny Root
18911d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            if (isKeyTypeSupported(device, TYPE_DSA)) {
189217208e0de5a42722901d803118745cca25fd10c1Kenny Root                rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
189317208e0de5a42722901d803118745cca25fd10c1Kenny Root            } else {
189417208e0de5a42722901d803118745cca25fd10c1Kenny Root                isFallback = true;
189517208e0de5a42722901d803118745cca25fd10c1Kenny Root                rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
189617208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
189717208e0de5a42722901d803118745cca25fd10c1Kenny Root        } else if (keyType == EVP_PKEY_EC) {
189896427baf0094d50047049d329b0779c3c910402cKenny Root            keymaster_ec_keygen_params_t ec_params;
189996427baf0094d50047049d329b0779c3c910402cKenny Root            memset(&ec_params, '\0', sizeof(ec_params));
190096427baf0094d50047049d329b0779c3c910402cKenny Root
190196427baf0094d50047049d329b0779c3c910402cKenny Root            if (keySize == -1) {
190296427baf0094d50047049d329b0779c3c910402cKenny Root                keySize = EC_DEFAULT_KEY_SIZE;
190396427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
190496427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("invalid key size %d", keySize);
190596427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
190696427baf0094d50047049d329b0779c3c910402cKenny Root            }
190796427baf0094d50047049d329b0779c3c910402cKenny Root            ec_params.field_size = keySize;
190896427baf0094d50047049d329b0779c3c910402cKenny Root
19091d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            if (isKeyTypeSupported(device, TYPE_EC)) {
191017208e0de5a42722901d803118745cca25fd10c1Kenny Root                rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
191117208e0de5a42722901d803118745cca25fd10c1Kenny Root            } else {
191217208e0de5a42722901d803118745cca25fd10c1Kenny Root                isFallback = true;
191317208e0de5a42722901d803118745cca25fd10c1Kenny Root                rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
191417208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
191596427baf0094d50047049d329b0779c3c910402cKenny Root        } else if (keyType == EVP_PKEY_RSA) {
191696427baf0094d50047049d329b0779c3c910402cKenny Root            keymaster_rsa_keygen_params_t rsa_params;
191796427baf0094d50047049d329b0779c3c910402cKenny Root            memset(&rsa_params, '\0', sizeof(rsa_params));
191896427baf0094d50047049d329b0779c3c910402cKenny Root            rsa_params.public_exponent = RSA_DEFAULT_EXPONENT;
191996427baf0094d50047049d329b0779c3c910402cKenny Root
192096427baf0094d50047049d329b0779c3c910402cKenny Root            if (keySize == -1) {
192196427baf0094d50047049d329b0779c3c910402cKenny Root                keySize = RSA_DEFAULT_KEY_SIZE;
192296427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
192396427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("invalid key size %d", keySize);
192496427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
192596427baf0094d50047049d329b0779c3c910402cKenny Root            }
192696427baf0094d50047049d329b0779c3c910402cKenny Root            rsa_params.modulus_size = keySize;
192796427baf0094d50047049d329b0779c3c910402cKenny Root
192896427baf0094d50047049d329b0779c3c910402cKenny Root            if (args->size() > 1) {
19296489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin                ALOGI("invalid number of arguments: %zu", args->size());
193096427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
193196427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (args->size() == 1) {
193296427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> pubExpBlob = args->itemAt(0);
193396427baf0094d50047049d329b0779c3c910402cKenny Root                if (pubExpBlob != NULL) {
193496427baf0094d50047049d329b0779c3c910402cKenny Root                    Unique_BIGNUM pubExpBn(
193596427baf0094d50047049d329b0779c3c910402cKenny Root                            BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()),
193696427baf0094d50047049d329b0779c3c910402cKenny Root                                    pubExpBlob->size(), NULL));
193796427baf0094d50047049d329b0779c3c910402cKenny Root                    if (pubExpBn.get() == NULL) {
193896427baf0094d50047049d329b0779c3c910402cKenny Root                        ALOGI("Could not convert public exponent to BN");
193996427baf0094d50047049d329b0779c3c910402cKenny Root                        return ::SYSTEM_ERROR;
194096427baf0094d50047049d329b0779c3c910402cKenny Root                    }
194196427baf0094d50047049d329b0779c3c910402cKenny Root                    unsigned long pubExp = BN_get_word(pubExpBn.get());
194296427baf0094d50047049d329b0779c3c910402cKenny Root                    if (pubExp == 0xFFFFFFFFL) {
194396427baf0094d50047049d329b0779c3c910402cKenny Root                        ALOGI("cannot represent public exponent as a long value");
194496427baf0094d50047049d329b0779c3c910402cKenny Root                        return ::SYSTEM_ERROR;
194596427baf0094d50047049d329b0779c3c910402cKenny Root                    }
194696427baf0094d50047049d329b0779c3c910402cKenny Root                    rsa_params.public_exponent = pubExp;
194796427baf0094d50047049d329b0779c3c910402cKenny Root                }
194896427baf0094d50047049d329b0779c3c910402cKenny Root            }
194996427baf0094d50047049d329b0779c3c910402cKenny Root
195096427baf0094d50047049d329b0779c3c910402cKenny Root            rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
195196427baf0094d50047049d329b0779c3c910402cKenny Root        } else {
195296427baf0094d50047049d329b0779c3c910402cKenny Root            ALOGW("Unsupported key type %d", keyType);
195396427baf0094d50047049d329b0779c3c910402cKenny Root            rc = -1;
195496427baf0094d50047049d329b0779c3c910402cKenny Root        }
195570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
195607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
195707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
195807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
195970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1960655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 name8(name);
1961655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
196270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
196307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
196407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        free(data);
196507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1966ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
196717208e0de5a42722901d803118745cca25fd10c1Kenny Root        keyBlob.setFallback(isFallback);
196817208e0de5a42722901d803118745cca25fd10c1Kenny Root
1969655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mKeyStore->put(filename.string(), &keyBlob, callingUid);
197070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
197170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1972f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid,
1973f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            int32_t flags) {
1974d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
1975eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
1976eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_INSERT, spid)) {
1977d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: import", callingUid);
197807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
197907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
198070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1981494689083467ec372a58f094f041c8f102f39393Kenny Root        if (targetUid == -1) {
1982494689083467ec372a58f094f041c8f102f39393Kenny Root            targetUid = callingUid;
1983494689083467ec372a58f094f041c8f102f39393Kenny Root        } else if (!is_granted_to(callingUid, targetUid)) {
1984b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1985b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1986b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
1987fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        State state = mKeyStore->getState(targetUid);
1988f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
198907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("calling import in state: %d", state);
199007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
199107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
199270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
199460898896c3f3b2245d10076cac64346c956dbaa5Kenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
199570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1996fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        return mKeyStore->importKey(data, length, filename.string(), targetUid, flags);
199770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
199870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
199907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
200007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t* outLength) {
2001d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2002eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2003eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_SIGN, spid)) {
2004d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: saw", callingUid);
200507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
200607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
20079a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root
200807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
200907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
201070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2011d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        ALOGV("sign %s from uid %d", name8.string(), callingUid);
201207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int rc;
201370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2014655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
2015d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root                ::TYPE_KEY_PAIR);
201607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
201707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
201807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
201970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
202007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const keymaster_device_t* device = mKeyStore->getDevice();
202107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
202207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGE("no keymaster device; cannot sign");
202307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
202407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
202570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
202607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->sign_data == NULL) {
202707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGE("device doesn't implement signing");
202807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
202907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
203070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
203107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        keymaster_rsa_sign_params_t params;
203207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.digest_type = DIGEST_NONE;
203307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.padding_type = PADDING_NONE;
203407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
203517208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (keyBlob.isFallback()) {
203617208e0de5a42722901d803118745cca25fd10c1Kenny Root            rc = openssl_sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
203717208e0de5a42722901d803118745cca25fd10c1Kenny Root                    length, out, outLength);
203817208e0de5a42722901d803118745cca25fd10c1Kenny Root        } else {
203917208e0de5a42722901d803118745cca25fd10c1Kenny Root            rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
204017208e0de5a42722901d803118745cca25fd10c1Kenny Root                    length, out, outLength);
204117208e0de5a42722901d803118745cca25fd10c1Kenny Root        }
204207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
204307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGW("device couldn't sign data");
204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
204670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
204707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
204870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
204970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
205007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
205107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const uint8_t* signature, size_t signatureLength) {
2052d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2053eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2054eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_VERIFY, spid)) {
2055d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: verify", callingUid);
205607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
205870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2059655b958eb2180c7c06889f83f606d23421bf038cKenny Root        State state = mKeyStore->getState(callingUid);
20609d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        if (!isKeystoreUnlocked(state)) {
206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("calling verify in state: %d", state);
206207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
206470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int rc;
206870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2069655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
2070494689083467ec372a58f094f041c8f102f39393Kenny Root                TYPE_KEY_PAIR);
207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
207470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const keymaster_device_t* device = mKeyStore->getDevice();
207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
207707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
207807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
207970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
208007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->verify_data == NULL) {
208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
208207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
208307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
208407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        keymaster_rsa_sign_params_t params;
208507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.digest_type = DIGEST_NONE;
208607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.padding_type = PADDING_NONE;
208770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
208817208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (keyBlob.isFallback()) {
208917208e0de5a42722901d803118745cca25fd10c1Kenny Root            rc = openssl_verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
209017208e0de5a42722901d803118745cca25fd10c1Kenny Root                    dataLength, signature, signatureLength);
209117208e0de5a42722901d803118745cca25fd10c1Kenny Root        } else {
209217208e0de5a42722901d803118745cca25fd10c1Kenny Root            rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
209317208e0de5a42722901d803118745cca25fd10c1Kenny Root                    dataLength, signature, signatureLength);
209417208e0de5a42722901d803118745cca25fd10c1Kenny Root        }
209507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
209607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
209707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } else {
209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::NO_ERROR;
209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
210070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
210170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    /*
210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * TODO: The abstraction between things stored in hardware and regular blobs
210407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * of data stored on the filesystem should be moved down to keystore itself.
210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * Unfortunately the Java code that calls this has naming conventions that it
210607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * knows about. Ideally keystore shouldn't be used to store random blobs of
210707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * data.
210807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     *
210907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * Until that happens, it's necessary to have a separate "get_pubkey" and
211007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * "del_key" since the Java code doesn't really communicate what it's
211107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * intentions are.
211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     */
211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
2114d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2115eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2116eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_GET, spid)) {
2117d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: get_pubkey", callingUid);
211807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
211907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
212070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
212370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2124d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid);
212570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2126655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                TYPE_KEY_PAIR);
212807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
212907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
213007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
213170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
213207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const keymaster_device_t* device = mKeyStore->getDevice();
213307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
213670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->get_keypair_public == NULL) {
213807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGE("device has no get_keypair_public implementation!");
213907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
214007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
2141344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root
214217208e0de5a42722901d803118745cca25fd10c1Kenny Root        int rc;
214317208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (keyBlob.isFallback()) {
214417208e0de5a42722901d803118745cca25fd10c1Kenny Root            rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
214517208e0de5a42722901d803118745cca25fd10c1Kenny Root                    pubkeyLength);
214617208e0de5a42722901d803118745cca25fd10c1Kenny Root        } else {
214717208e0de5a42722901d803118745cca25fd10c1Kenny Root            rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
214817208e0de5a42722901d803118745cca25fd10c1Kenny Root                    pubkeyLength);
214917208e0de5a42722901d803118745cca25fd10c1Kenny Root        }
215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
215107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
2153344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root
215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
2155344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root    }
2156344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root
2157494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t del_key(const String16& name, int targetUid) {
2158d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2159eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2160eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_DELETE, spid)) {
2161d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: del_key", callingUid);
216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
216307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
2164344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root
2165494689083467ec372a58f094f041c8f102f39393Kenny Root        if (targetUid == -1) {
2166494689083467ec372a58f094f041c8f102f39393Kenny Root            targetUid = callingUid;
2167494689083467ec372a58f094f041c8f102f39393Kenny Root        } else if (!is_granted_to(callingUid, targetUid)) {
2168b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
2169b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
2170b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
217107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
2172fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
21734b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return mKeyStore->del(filename.string(), ::TYPE_KEY_PAIR, targetUid);
2174a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
217507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
217607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t grant(const String16& name, int32_t granteeUid) {
2177d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2178eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2179eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_GRANT, spid)) {
2180d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: grant", callingUid);
218107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
218207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
218307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2184655b958eb2180c7c06889f83f606d23421bf038cKenny Root        State state = mKeyStore->getState(callingUid);
21859d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        if (!isKeystoreUnlocked(state)) {
218607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("calling grant in state: %d", state);
218707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
218807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
218907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
219007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
2191655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
219207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2193655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
219407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
219507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
219607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2197655b958eb2180c7c06889f83f606d23421bf038cKenny Root        mKeyStore->addGrant(filename.string(), granteeUid);
219807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
2199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
220007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
220107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t ungrant(const String16& name, int32_t granteeUid) {
2202d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2203eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2204eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_GRANT, spid)) {
2205d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: ungrant", callingUid);
220607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
220707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2209655b958eb2180c7c06889f83f606d23421bf038cKenny Root        State state = mKeyStore->getState(callingUid);
22109d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        if (!isKeystoreUnlocked(state)) {
221107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("calling ungrant in state: %d", state);
221207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
221307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
221407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
221507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
2216655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
221707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2218655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
221907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
222007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
222107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2222655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
2223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
222407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
222507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int64_t getmtime(const String16& name) {
2226d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2227eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2228eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_GET, spid)) {
2229d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: getmtime", callingUid);
223036a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
223107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
223207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
223307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
2234655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
223507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2236655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
2237655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("could not access %s for getmtime", filename.string());
223836a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
2239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
224007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2241655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY));
224207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (fd < 0) {
2243655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("could not open %s for getmtime", filename.string());
224436a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
224507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
224607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
224707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        struct stat s;
224807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int ret = fstat(fd, &s);
224907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        close(fd);
225007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (ret == -1) {
2251655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("could not stat %s for getmtime", filename.string());
225236a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
225307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
225407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
225536a9e231e03734cd2143383d26388455c1764e17Kenny Root        return static_cast<int64_t>(s.st_mtime);
2256a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
225707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2258d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root    int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
2259d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            int32_t destUid) {
22600225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2261eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2262eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_DUPLICATE, spid)) {
2263d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGW("permission denied for %d: duplicate", callingUid);
22640225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return -1L;
22650225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22660225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2267655b958eb2180c7c06889f83f606d23421bf038cKenny Root        State state = mKeyStore->getState(callingUid);
22680225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        if (!isKeystoreUnlocked(state)) {
2269d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGD("calling duplicate in state: %d", state);
22700225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return state;
22710225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2273d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) {
2274d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            srcUid = callingUid;
2275d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        } else if (!is_granted_to(callingUid, srcUid)) {
2276d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid);
22770225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return ::PERMISSION_DENIED;
22780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22790225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2280d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (destUid == -1) {
2281d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            destUid = callingUid;
2282d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        }
22830225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2284d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (srcUid != destUid) {
2285d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            if (static_cast<uid_t>(srcUid) != callingUid) {
2286d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                ALOGD("can only duplicate from caller to other or to same uid: "
2287d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                      "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid);
2288d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                return ::PERMISSION_DENIED;
2289d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            }
22900225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2291d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            if (!is_granted_to(callingUid, destUid)) {
2292d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid);
2293d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                return ::PERMISSION_DENIED;
2294d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            }
22950225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22960225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2297d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        String8 source8(srcKey);
2298655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid));
2299d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root
2300d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        String8 target8(destKey);
2301fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid));
23020225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2303655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
2304655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGD("destination already exists: %s", targetFile.string());
23050225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return ::SYSTEM_ERROR;
23060225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
23070225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2308d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        Blob keyBlob;
2309655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY,
2310fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root                srcUid);
2311d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (responseCode != ::NO_ERROR) {
2312d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            return responseCode;
23130225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
2314d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root
2315fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        return mKeyStore->put(targetFile.string(), &keyBlob, destUid);
23160225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root    }
23170225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
23181b0e3933900c7ea21189704d5db64e7346aee7afKenny Root    int32_t is_hardware_backed(const String16& keyType) {
23191b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        return mKeyStore->isHardwareBacked(keyType) ? 1 : 0;
23208ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root    }
23218ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root
2322fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root    int32_t clear_uid(int64_t targetUid64) {
2323fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        uid_t targetUid = static_cast<uid_t>(targetUid64);
2324a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2325eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2326eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_CLEAR_UID, spid)) {
2327a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root            ALOGW("permission denied for %d: clear_uid", callingUid);
2328a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root            return ::PERMISSION_DENIED;
2329a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        }
2330a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root
2331fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        if (targetUid64 == -1) {
2332fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root            targetUid = callingUid;
2333007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root        } else if (!is_self_or_system(callingUid, targetUid)) {
2334007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root            ALOGW("permission denied for %d: clear_uid %d", callingUid, targetUid);
2335fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root            return ::PERMISSION_DENIED;
2336fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        }
2337fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root
2338a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        const keymaster_device_t* device = mKeyStore->getDevice();
2339a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        if (device == NULL) {
2340655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("can't get keymaster device");
2341a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root            return ::SYSTEM_ERROR;
2342a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        }
2343a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root
23444b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        String8 prefix = String8::format("%u_", targetUid);
23454b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        Vector<String16> aliases;
23464b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (mKeyStore->saw(prefix, &aliases, targetUid) != ::NO_ERROR) {
2347a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root            return ::SYSTEM_ERROR;
2348a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        }
2349a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root
23504b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        for (uint32_t i = 0; i < aliases.size(); i++) {
23514b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            String8 name8(aliases[i]);
23524b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
23534b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            mKeyStore->del(filename.string(), ::TYPE_ANY, targetUid);
2354a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        }
23554b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return ::NO_ERROR;
2356a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root    }
2357a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root
23584b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    int32_t reset_uid(int32_t targetUid) {
23594e865753346fc6a075966972a7a98051818859dbRobin Lee        uid_t callingUid = IPCThreadState::self()->getCallingUid();
23604e865753346fc6a075966972a7a98051818859dbRobin Lee        pid_t spid = IPCThreadState::self()->getCallingPid();
23614b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
23624e865753346fc6a075966972a7a98051818859dbRobin Lee        if (!has_permission(callingUid, P_RESET_UID, spid)) {
23634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid);
23644e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
23654e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23664b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (!is_self_or_system(callingUid, targetUid)) {
23674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid);
23684e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
23694e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23704e865753346fc6a075966972a7a98051818859dbRobin Lee
23714b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return mKeyStore->reset(targetUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
23724e865753346fc6a075966972a7a98051818859dbRobin Lee    }
23734e865753346fc6a075966972a7a98051818859dbRobin Lee
23744e865753346fc6a075966972a7a98051818859dbRobin Lee    int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {
23754e865753346fc6a075966972a7a98051818859dbRobin Lee        uid_t callingUid = IPCThreadState::self()->getCallingUid();
23764e865753346fc6a075966972a7a98051818859dbRobin Lee        pid_t spid = IPCThreadState::self()->getCallingPid();
23774e865753346fc6a075966972a7a98051818859dbRobin Lee        if (!has_permission(callingUid, P_SYNC_UID, spid)) {
23784e865753346fc6a075966972a7a98051818859dbRobin Lee            ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid);
23794e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
23804e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23814e865753346fc6a075966972a7a98051818859dbRobin Lee        if (callingUid != AID_SYSTEM) {
23824e865753346fc6a075966972a7a98051818859dbRobin Lee            ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid);
23834e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
23844e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23854e865753346fc6a075966972a7a98051818859dbRobin Lee        if (sourceUid == targetUid) {
23864e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::SYSTEM_ERROR;
23874e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23884e865753346fc6a075966972a7a98051818859dbRobin Lee
23894e865753346fc6a075966972a7a98051818859dbRobin Lee        // Initialise user keystore with existing master key held in-memory
23904e865753346fc6a075966972a7a98051818859dbRobin Lee        return mKeyStore->copyMasterKey(sourceUid, targetUid);
23914e865753346fc6a075966972a7a98051818859dbRobin Lee    }
23924e865753346fc6a075966972a7a98051818859dbRobin Lee
23934e865753346fc6a075966972a7a98051818859dbRobin Lee    int32_t password_uid(const String16& pw, int32_t targetUid) {
23944e865753346fc6a075966972a7a98051818859dbRobin Lee        uid_t callingUid = IPCThreadState::self()->getCallingUid();
23954e865753346fc6a075966972a7a98051818859dbRobin Lee        pid_t spid = IPCThreadState::self()->getCallingPid();
23964e865753346fc6a075966972a7a98051818859dbRobin Lee        if (!has_permission(callingUid, P_PASSWORD_UID, spid)) {
23974e865753346fc6a075966972a7a98051818859dbRobin Lee            ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid);
23984e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
23994e865753346fc6a075966972a7a98051818859dbRobin Lee        }
24004e865753346fc6a075966972a7a98051818859dbRobin Lee        if (callingUid != AID_SYSTEM) {
24014e865753346fc6a075966972a7a98051818859dbRobin Lee            ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid);
24024e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
24034e865753346fc6a075966972a7a98051818859dbRobin Lee        }
24044e865753346fc6a075966972a7a98051818859dbRobin Lee
24054e865753346fc6a075966972a7a98051818859dbRobin Lee        const String8 password8(pw);
24064e865753346fc6a075966972a7a98051818859dbRobin Lee
24074e865753346fc6a075966972a7a98051818859dbRobin Lee        switch (mKeyStore->getState(targetUid)) {
24084e865753346fc6a075966972a7a98051818859dbRobin Lee            case ::STATE_UNINITIALIZED: {
24094e865753346fc6a075966972a7a98051818859dbRobin Lee                // generate master key, encrypt with password, write to file, initialize mMasterKey*.
24104e865753346fc6a075966972a7a98051818859dbRobin Lee                return mKeyStore->initializeUser(password8, targetUid);
24114e865753346fc6a075966972a7a98051818859dbRobin Lee            }
24124e865753346fc6a075966972a7a98051818859dbRobin Lee            case ::STATE_NO_ERROR: {
24134e865753346fc6a075966972a7a98051818859dbRobin Lee                // rewrite master key with new password.
24144e865753346fc6a075966972a7a98051818859dbRobin Lee                return mKeyStore->writeMasterKey(password8, targetUid);
24154e865753346fc6a075966972a7a98051818859dbRobin Lee            }
24164e865753346fc6a075966972a7a98051818859dbRobin Lee            case ::STATE_LOCKED: {
24174e865753346fc6a075966972a7a98051818859dbRobin Lee                // read master key, decrypt with password, initialize mMasterKey*.
24184e865753346fc6a075966972a7a98051818859dbRobin Lee                return mKeyStore->readMasterKey(password8, targetUid);
24194e865753346fc6a075966972a7a98051818859dbRobin Lee            }
24204e865753346fc6a075966972a7a98051818859dbRobin Lee        }
24214e865753346fc6a075966972a7a98051818859dbRobin Lee        return ::SYSTEM_ERROR;
24224e865753346fc6a075966972a7a98051818859dbRobin Lee    }
24234e865753346fc6a075966972a7a98051818859dbRobin Lee
242407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate:
24259d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root    inline bool isKeystoreUnlocked(State state) {
24269d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        switch (state) {
24279d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        case ::STATE_NO_ERROR:
24289d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root            return true;
24299d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        case ::STATE_UNINITIALIZED:
24309d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        case ::STATE_LOCKED:
24319d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root            return false;
24329d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        }
24339d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        return false;
2434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
243507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
24361d448c074a86ef5d05a22fdf1358718976628a86Kenny Root    bool isKeyTypeSupported(const keymaster_device_t* device, keymaster_keypair_t keyType) {
24371d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        const int32_t device_api = device->common.module->module_api_version;
24381d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) {
24391d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            switch (keyType) {
24401d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_RSA:
24411d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_DSA:
24421d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_EC:
24431d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return true;
24441d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                default:
24451d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return false;
24461d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            }
24471d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) {
24481d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            switch (keyType) {
24491d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_RSA:
24501d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return true;
24511d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_DSA:
24521d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return device->flags & KEYMASTER_SUPPORTS_DSA;
24531d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_EC:
24541d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return device->flags & KEYMASTER_SUPPORTS_EC;
24551d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                default:
24561d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return false;
24571d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            }
24581d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        } else {
24591d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            return keyType == TYPE_RSA;
24601d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        }
24611d448c074a86ef5d05a22fdf1358718976628a86Kenny Root    }
24621d448c074a86ef5d05a22fdf1358718976628a86Kenny Root
246307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    ::KeyStore* mKeyStore;
246407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root};
246507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
246607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android
2467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) {
2469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (argc < 2) {
2470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("A directory must be specified!");
2471a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
2472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
2473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (chdir(argv[1]) == -1) {
2474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("chdir: %s: %s", argv[1], strerror(errno));
2475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
2476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
2477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
2478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy entropy;
2479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!entropy.open()) {
2480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
2481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
248270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
248370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    keymaster_device_t* dev;
248470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (keymaster_device_initialize(&dev)) {
248570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("keystore keymaster could not be initialized; exiting");
248670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return 1;
248770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
248870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2489eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    ks_is_selinux_enabled = is_selinux_enabled();
2490eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (ks_is_selinux_enabled) {
2491eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        union selinux_callback cb;
2492eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        cb.func_log = selinux_log_callback;
2493eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        selinux_set_callback(SELINUX_CB_LOG, cb);
2494eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (getcon(&tctx) != 0) {
2495eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n");
2496eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            return -1;
2497eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        }
2498eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    } else {
2499eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        ALOGI("SELinux: Keystore SELinux is disabled.\n");
2500eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
2501eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
250270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    KeyStore keyStore(&entropy, dev);
2503655b958eb2180c7c06889f83f606d23421bf038cKenny Root    keyStore.initialize();
250407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::sp<android::IServiceManager> sm = android::defaultServiceManager();
250507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
250607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy);
250707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    if (ret != android::OK) {
250807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        ALOGE("Couldn't register binder service!");
250907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return -1;
2510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
251170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
251207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    /*
251307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * We're the only thread in existence, so we're just going to process
251407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * Binder transaction as a single-threaded program.
251507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     */
251607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::IPCThreadState::self()->joinThreadPool();
251770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
251807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    keymaster_device_release(dev);
2519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return 1;
2520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
2521