keystore.cpp revision c0f031a867a6c3fa05732fcd72bd284d56073cf8
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
4480843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden#include <hardware/keymaster0.h>
4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
4667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker#include <keymaster/soft_keymaster_device.h>
470400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden#include <keymaster/soft_keymaster_logger.h>
480400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden#include <keymaster/softkeymaster.h>
4917208e0de5a42722901d803118745cca25fd10c1Kenny Root
5026cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h>
51655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h>
52655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h>
5370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h>
5507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h>
5607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h>
5707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h>
59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h>
60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h>
61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
6207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h>
63a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
64eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn#include <selinux/android.h>
65eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
66d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker#include "auth_token_table.h"
6796427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h"
6840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker#include "operation.h"
6996427baf0094d50047049d329b0779c3c910402cKenny Root
70a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation,
71a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and
72a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a
73a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than
74a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */
75a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
76a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE        ((NAME_MAX - 15) / 2)
77a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE      32768
78a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE   VALUE_SIZE
79a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
8196427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete {
8296427baf0094d50047049d329b0779c3c910402cKenny Root    void operator()(BIGNUM* p) const {
8396427baf0094d50047049d329b0779c3c910402cKenny Root        BN_free(p);
8496427baf0094d50047049d329b0779c3c910402cKenny Root    }
8596427baf0094d50047049d329b0779c3c910402cKenny Root};
8696427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
8796427baf0094d50047049d329b0779c3c910402cKenny Root
88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete {
89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(BIO* p) const {
90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        BIO_free(p);
91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete {
96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(EVP_PKEY* p) const {
97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        EVP_PKEY_free(p);
98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete {
103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        PKCS8_PRIV_KEY_INFO_free(p);
105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
106822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root};
107822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
108822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
10980843db63ed6b61c953a1243801117a15c9e8c38Shawn Willdenstatic int keymaster_device_initialize(keymaster0_device_t** dev) {
11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int rc;
11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const hw_module_t* mod;
11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not find any keystore module");
11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11980843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden    rc = keymaster0_open(mod, dev);
12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rc) {
12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not open keymaster device in %s (%s)",
12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        goto out;
12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout:
12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *dev = NULL;
13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return rc;
13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1330400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden// softkeymaster_logger appears not to be used in keystore, but it installs itself as the
1340400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden// logger used by SoftKeymasterDevice.
1350400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willdenstatic keymaster::SoftKeymasterLogger softkeymaster_logger;
1360400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden
13767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubakerstatic int fallback_keymaster_device_initialize(keymaster1_device_t** dev) {
13867d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    keymaster::SoftKeymasterDevice* softkeymaster =
13967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker            new keymaster::SoftKeymasterDevice();
1409fd05a9a6299e9688c8fcf755516ea254868d187Shawn Willden    *dev = softkeymaster->keymaster_device();
1419fd05a9a6299e9688c8fcf755516ea254868d187Shawn Willden    // softkeymaster will be freed by *dev->close_device; don't delete here.
142fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker    return 0;
143fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker}
144fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker
14580843db63ed6b61c953a1243801117a15c9e8c38Shawn Willdenstatic void keymaster_device_release(keymaster0_device_t* dev) {
14680843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden    keymaster0_close(dev);
14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/***************
15007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS *
15107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/
15207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */
15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum {
1554e865753346fc6a075966972a7a98051818859dbRobin Lee    P_TEST          = 1 << 0,
1564e865753346fc6a075966972a7a98051818859dbRobin Lee    P_GET           = 1 << 1,
1574e865753346fc6a075966972a7a98051818859dbRobin Lee    P_INSERT        = 1 << 2,
1584e865753346fc6a075966972a7a98051818859dbRobin Lee    P_DELETE        = 1 << 3,
1594e865753346fc6a075966972a7a98051818859dbRobin Lee    P_EXIST         = 1 << 4,
1604e865753346fc6a075966972a7a98051818859dbRobin Lee    P_SAW           = 1 << 5,
1614e865753346fc6a075966972a7a98051818859dbRobin Lee    P_RESET         = 1 << 6,
1624e865753346fc6a075966972a7a98051818859dbRobin Lee    P_PASSWORD      = 1 << 7,
1634e865753346fc6a075966972a7a98051818859dbRobin Lee    P_LOCK          = 1 << 8,
1644e865753346fc6a075966972a7a98051818859dbRobin Lee    P_UNLOCK        = 1 << 9,
1654e865753346fc6a075966972a7a98051818859dbRobin Lee    P_ZERO          = 1 << 10,
1664e865753346fc6a075966972a7a98051818859dbRobin Lee    P_SIGN          = 1 << 11,
1674e865753346fc6a075966972a7a98051818859dbRobin Lee    P_VERIFY        = 1 << 12,
1684e865753346fc6a075966972a7a98051818859dbRobin Lee    P_GRANT         = 1 << 13,
1694e865753346fc6a075966972a7a98051818859dbRobin Lee    P_DUPLICATE     = 1 << 14,
1704e865753346fc6a075966972a7a98051818859dbRobin Lee    P_CLEAR_UID     = 1 << 15,
1714e865753346fc6a075966972a7a98051818859dbRobin Lee    P_RESET_UID     = 1 << 16,
1724e865753346fc6a075966972a7a98051818859dbRobin Lee    P_SYNC_UID      = 1 << 17,
1734e865753346fc6a075966972a7a98051818859dbRobin Lee    P_PASSWORD_UID  = 1 << 18,
174d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker    P_ADD_AUTH      = 1 << 19,
175c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    P_USER_CHANGED  = 1 << 20,
17607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t;
17707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
17807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid {
17907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    uid_t uid;
18007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    uid_t euid;
18107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = {
18207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_VPN, AID_SYSTEM},
18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_WIFI, AID_SYSTEM},
18407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_ROOT, AID_SYSTEM},
18507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root};
18607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
187eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */
188eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = {
189eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "test",
190eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "get",
191eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "insert",
192eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "delete",
193eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "exist",
194eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "saw",
195eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "reset",
196eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "password",
197eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "lock",
198eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "unlock",
199eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "zero",
200eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "sign",
201eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "verify",
202eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "grant",
203eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    "duplicate",
2044e865753346fc6a075966972a7a98051818859dbRobin Lee    "clear_uid",
2054e865753346fc6a075966972a7a98051818859dbRobin Lee    "reset_uid",
2064e865753346fc6a075966972a7a98051818859dbRobin Lee    "sync_uid",
2074e865753346fc6a075966972a7a98051818859dbRobin Lee    "password_uid",
208d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker    "add_auth",
209c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    "user_changed",
210eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn};
211eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
21207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm {
21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    uid_t uid;
21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    perm_t perms;
21507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = {
21607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) },
21707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_VPN,    static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
21807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_WIFI,   static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
21907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {AID_ROOT,   static_cast<perm_t>(P_GET) },
22007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root};
22107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
22207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN
22307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        | P_VERIFY);
22407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
225eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx;
226eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled;
227eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
228eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) {
229eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    unsigned int index = ffs(perm);
230eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) {
231eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return perm_labels[index - 1];
232eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    } else {
233eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        ALOGE("Keystore: Failed to retrieve permission label.\n");
234eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        abort();
235eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
236eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}
237eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
238655b958eb2180c7c06889f83f606d23421bf038cKenny Root/**
239655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current
240655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID.
241655b958eb2180c7c06889f83f606d23421bf038cKenny Root */
242655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) {
243655b958eb2180c7c06889f83f606d23421bf038cKenny Root    return uid % AID_USER;
244655b958eb2180c7c06889f83f606d23421bf038cKenny Root}
245655b958eb2180c7c06889f83f606d23421bf038cKenny Root
246655b958eb2180c7c06889f83f606d23421bf038cKenny Root/**
247655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current
248655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID.
249655b958eb2180c7c06889f83f606d23421bf038cKenny Root */
250655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) {
251655b958eb2180c7c06889f83f606d23421bf038cKenny Root    return uid / AID_USER;
252655b958eb2180c7c06889f83f606d23421bf038cKenny Root}
253655b958eb2180c7c06889f83f606d23421bf038cKenny Root
254a25b2a397fff48dea7bce16af2065e6f5f043956Chih-Hung Hsiehstatic bool keystore_selinux_check_access(uid_t /*uid*/, perm_t perm, pid_t spid) {
255eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (!ks_is_selinux_enabled) {
256eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return true;
257eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
258eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
259eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    char *sctx = NULL;
260eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    const char *selinux_class = "keystore_key";
261eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    const char *str_perm = get_perm_label(perm);
262eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
263eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (!str_perm) {
264eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return false;
265eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
266eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
267eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (getpidcon(spid, &sctx) != 0) {
268eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        ALOGE("SELinux: Failed to get source pid context.\n");
269eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        return false;
270eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
27166dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich
272eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm,
273eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            NULL) == 0;
274eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    freecon(sctx);
275eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    return allowed;
276eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}
277eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
278eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) {
279655b958eb2180c7c06889f83f606d23421bf038cKenny Root    // All system users are equivalent for multi-user support.
280655b958eb2180c7c06889f83f606d23421bf038cKenny Root    if (get_app_id(uid) == AID_SYSTEM) {
281655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uid = AID_SYSTEM;
282655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
283655b958eb2180c7c06889f83f606d23421bf038cKenny Root
28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) {
28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        struct user_perm user = user_perms[i];
28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (user.uid == uid) {
287eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            return (user.perms & perm) &&
288eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn                keystore_selinux_check_access(uid, perm, spid);
28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
29007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
292eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    return (DEFAULT_PERMS & perm) &&
293eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        keystore_selinux_check_access(uid, perm, spid);
29407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}
29507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
296494689083467ec372a58f094f041c8f102f39393Kenny Root/**
297494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for
298494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed
299494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace.
300494689083467ec372a58f094f041c8f102f39393Kenny Root */
30107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) {
30207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
30307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        struct user_euid user = user_euids[i];
30407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (user.uid == uid) {
30507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return user.euid;
30607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
30707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
30807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
30907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    return uid;
31007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}
31107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
312494689083467ec372a58f094f041c8f102f39393Kenny Root/**
313494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's
314494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace.
315494689083467ec372a58f094f041c8f102f39393Kenny Root */
316494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) {
3179489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    if (callingUid == targetUid) {
3189489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        return true;
3199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    }
320494689083467ec372a58f094f041c8f102f39393Kenny Root    for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
321494689083467ec372a58f094f041c8f102f39393Kenny Root        struct user_euid user = user_euids[i];
322494689083467ec372a58f094f041c8f102f39393Kenny Root        if (user.euid == callingUid && user.uid == targetUid) {
323494689083467ec372a58f094f041c8f102f39393Kenny Root            return true;
324494689083467ec372a58f094f041c8f102f39393Kenny Root        }
325494689083467ec372a58f094f041c8f102f39393Kenny Root    }
326494689083467ec372a58f094f041c8f102f39393Kenny Root
327494689083467ec372a58f094f041c8f102f39393Kenny Root    return false;
328494689083467ec372a58f094f041c8f102f39393Kenny Root}
329494689083467ec372a58f094f041c8f102f39393Kenny Root
330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary
331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded
332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first
333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into
334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */
336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
337655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) {
338655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
339655b958eb2180c7c06889f83f606d23421bf038cKenny Root    size_t length = keyName.length();
340655b958eb2180c7c06889f83f606d23421bf038cKenny Root    for (int i = length; i > 0; --i, ++in) {
341655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (*in < '0' || *in > '~') {
342655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ++length;
343655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
344655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
345655b958eb2180c7c06889f83f606d23421bf038cKenny Root    return length;
346655b958eb2180c7c06889f83f606d23421bf038cKenny Root}
347655b958eb2180c7c06889f83f606d23421bf038cKenny Root
34807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) {
34907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
35007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    size_t length = keyName.length();
351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    for (int i = length; i > 0; --i, ++in, ++out) {
352655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (*in < '0' || *in > '~') {
353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *out = '+' + (*in >> 6);
354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            *++out = '0' + (*in & 0x3F);
355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ++length;
356655b958eb2180c7c06889f83f606d23421bf038cKenny Root        } else {
357655b958eb2180c7c06889f83f606d23421bf038cKenny Root            *out = *in;
358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
36170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return length;
36270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
36370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
36407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*
36507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name.
36607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string.
36707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *
36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated.
36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */
37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) {
37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    size_t outLength = 0;
37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (const char* end = in + length; in < end; in++) {
37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        /* This combines with the next character. */
37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (*in < '0' || *in > '~') {
37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            continue;
37707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
37807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
37907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        outLength++;
38007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
38107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    return outLength;
38207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}
38307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
38407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) {
38507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    for (const char* end = in + length; in < end; in++) {
38607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (*in < '0' || *in > '~') {
38707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            /* Truncate combining characters at the end. */
38807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            if (in + 1 >= end) {
38907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                break;
39007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
39107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
39207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *out = (*in++ - '+') << 6;
39307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *out++ |= (*in - '0') & 0x3F;
394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
39507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *out++ = *in;
396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    *out = '\0';
399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(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(read(fd, data, remaining));
4055281edbc9445065479e92a6c86da462f3943c2caKenny Root        if (n <= 0) {
406150ca934edb745de3666a6492b039900df228ff0Kenny Root            return size - remaining;
407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) {
415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    size_t remaining = size;
416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    while (remaining > 0) {
417150ca934edb745de3666a6492b039900df228ff0Kenny Root        ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining));
418150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (n < 0) {
419150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("write failed: %s", strerror(errno));
420150ca934edb745de3666a6492b039900df228ff0Kenny Root            return size - remaining;
421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        data += n;
423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        remaining -= n;
424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return size;
426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy {
429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy() : mRandom(-1) {}
431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    ~Entropy() {
432150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (mRandom >= 0) {
433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            close(mRandom);
434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    bool open() {
438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* randomDevice = "/dev/urandom";
439150ca934edb745de3666a6492b039900df228ff0Kenny Root        mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY));
440150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (mRandom < 0) {
441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            ALOGE("open: %s: %s", randomDevice, strerror(errno));
442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
4475187818895c4c5f650a611c40531b1dff7764c18Kenny Root    bool generate_random_data(uint8_t* data, size_t size) const {
448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return (readFully(mRandom, data, size) == size);
449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int mRandom;
453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and
456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size
457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in
458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two
459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version,
460f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other
461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob()
462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */
463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: **
465822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction:
466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   metadata || Enc(MD5(data) || data)
467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing:
469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Derive independent keys for encryption and MAC:
471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kenc = AES_encrypt(masterKey, "Encrypt")
472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     Kmac = AES_encrypt(masterKey, "MAC")
473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *
474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *   Store this:
475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *     metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root *             HMAC(Kmac, metadata || Enc(data))
477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */
478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob {
479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t version;
480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t type;
481f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    uint8_t flags;
482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t info;
483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t vector[AES_BLOCK_SIZE];
484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t encrypted[0]; // Marks offset to encrypted data.
485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t digest[MD5_DIGEST_LENGTH];
486822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t digested[0]; // Marks offset to digested data.
487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    int32_t length; // in network byte order when encrypted
488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum {
492d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root    TYPE_ANY = 0, // meta type that matches anything
493822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_GENERIC = 1,
494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_MASTER_KEY = 2,
495822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    TYPE_KEY_PAIR = 3,
49617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker    TYPE_KEYMASTER_10 = 4,
497822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType;
498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
499f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2;
500822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob {
502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic:
50307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength,
50407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            BlobType type) {
5051773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin        memset(&mBlob, 0, sizeof(mBlob));
506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = valueLength;
507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value, value, valueLength);
508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.info = infoLength;
510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memcpy(mBlob.value + valueLength, info, infoLength);
511822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
51207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        mBlob.version = CURRENT_BLOB_VERSION;
513822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
514f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
515ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        if (type == TYPE_MASTER_KEY) {
516ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root            mBlob.flags = KEYSTORE_FLAG_ENCRYPTED;
517ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        } else {
518ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root            mBlob.flags = KEYSTORE_FLAG_NONE;
519ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        }
520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Blob(blob b) {
523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob = b;
524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5261773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin    Blob() {
5271773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin        memset(&mBlob, 0, sizeof(mBlob));
5281773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin    }
529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5305187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getValue() const {
531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.value;
532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5345187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int32_t getLength() const {
535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.length;
536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
5385187818895c4c5f650a611c40531b1dff7764c18Kenny Root    const uint8_t* getInfo() const {
5395187818895c4c5f650a611c40531b1dff7764c18Kenny Root        return mBlob.value + mBlob.length;
5405187818895c4c5f650a611c40531b1dff7764c18Kenny Root    }
5415187818895c4c5f650a611c40531b1dff7764c18Kenny Root
5425187818895c4c5f650a611c40531b1dff7764c18Kenny Root    uint8_t getInfoLength() const {
543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mBlob.info;
544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
546822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    uint8_t getVersion() const {
547822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return mBlob.version;
548822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
549822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
550f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    bool isEncrypted() const {
551f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (mBlob.version < 2) {
552f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            return true;
553f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
554f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
555f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED;
556f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    }
557f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
558f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    void setEncrypted(bool encrypted) {
559f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (encrypted) {
560f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED;
561f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        } else {
562f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED;
563f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
564f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    }
565f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
56617208e0de5a42722901d803118745cca25fd10c1Kenny Root    bool isFallback() const {
56717208e0de5a42722901d803118745cca25fd10c1Kenny Root        return mBlob.flags & KEYSTORE_FLAG_FALLBACK;
56817208e0de5a42722901d803118745cca25fd10c1Kenny Root    }
56917208e0de5a42722901d803118745cca25fd10c1Kenny Root
57017208e0de5a42722901d803118745cca25fd10c1Kenny Root    void setFallback(bool fallback) {
57117208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (fallback) {
57217208e0de5a42722901d803118745cca25fd10c1Kenny Root            mBlob.flags |= KEYSTORE_FLAG_FALLBACK;
57317208e0de5a42722901d803118745cca25fd10c1Kenny Root        } else {
57417208e0de5a42722901d803118745cca25fd10c1Kenny Root            mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK;
57517208e0de5a42722901d803118745cca25fd10c1Kenny Root        }
57617208e0de5a42722901d803118745cca25fd10c1Kenny Root    }
57717208e0de5a42722901d803118745cca25fd10c1Kenny Root
578822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setVersion(uint8_t version) {
579822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.version = version;
580822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
581822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
582822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    BlobType getType() const {
583822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return BlobType(mBlob.type);
584822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
585822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
586822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    void setType(BlobType type) {
587822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        mBlob.type = uint8_t(type);
588822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
589822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) {
591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ALOGV("writing blob %s", filename);
592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted()) {
593f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (state != STATE_NO_ERROR) {
594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                ALOGD("couldn't insert encrypted blob while not unlocked");
595f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return LOCKED;
596f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
597f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
598f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
599f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                ALOGW("Could not read random data for: %s", filename);
600f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return SYSTEM_ERROR;
601f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // data includes the value and the value's length
605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t dataLength = mBlob.length + sizeof(mBlob.length);
606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // pad data to the AES_BLOCK_SIZE
607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1)
608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                                 / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // encrypted data includes the digest value
610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // move info after space for padding
612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // zero padding area
614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = htonl(mBlob.length);
617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
618f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted()) {
619f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            MD5(mBlob.digested, digestedLength, mBlob.digest);
620f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
621f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            uint8_t vector[AES_BLOCK_SIZE];
622f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
623f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength,
624f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                            aes_key, vector, AES_ENCRYPT);
625f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = encryptedLength + headerLength + mBlob.info;
629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        const char* tmpFileName = ".tmp";
631150ca934edb745de3666a6492b039900df228ff0Kenny Root        int out = TEMP_FAILURE_RETRY(open(tmpFileName,
632150ca934edb745de3666a6492b039900df228ff0Kenny Root                O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
633150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (out < 0) {
634150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno));
635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength);
638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(out) != 0) {
639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (writtenBytes != fileLength) {
642150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            unlink(tmpFileName);
644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
646150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (rename(tmpFileName, filename) == -1) {
647150ca934edb745de3666a6492b039900df228ff0Kenny Root            ALOGW("could not rename blob to %s: %s", filename, strerror(errno));
648150ca934edb745de3666a6492b039900df228ff0Kenny Root            return SYSTEM_ERROR;
649150ca934edb745de3666a6492b039900df228ff0Kenny Root        }
650150ca934edb745de3666a6492b039900df228ff0Kenny Root        return NO_ERROR;
651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
653f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) {
654f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ALOGV("reading blob %s", filename);
655150ca934edb745de3666a6492b039900df228ff0Kenny Root        int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
656150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (in < 0) {
657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // fileLength may be less than sizeof(mBlob) since the in
660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // memory version has extra padding to tolerate rounding up to
661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES_BLOCK_SIZE
662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob));
663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
666f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
667f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted() && (state != STATE_NO_ERROR)) {
668f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            return LOCKED;
669f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
670f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob);
672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (fileLength < headerLength) {
673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
677f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (encryptedLength < 0) {
678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
680f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
681f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ssize_t digestedLength;
682f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (isEncrypted()) {
683f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (encryptedLength % AES_BLOCK_SIZE != 0) {
684f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return VALUE_CORRUPTED;
685f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
686f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
687f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key,
688f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                            mBlob.vector, AES_DECRYPT);
689f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
690f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            uint8_t computedDigest[MD5_DIGEST_LENGTH];
691f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            MD5(mBlob.digested, digestedLength, computedDigest);
692f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
693f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                return VALUE_CORRUPTED;
694f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            }
695f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        } else {
696f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            digestedLength = encryptedLength;
697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        mBlob.length = ntohl(mBlob.length);
701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.length < 0 || mBlob.length > maxValueLength) {
702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return VALUE_CORRUPTED;
703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mBlob.info != 0) {
705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // move info from after padding to after data
706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
70807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate:
712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    struct blob mBlob;
713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root};
714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
715655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState {
716655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic:
717655b958eb2180c7c06889f83f606d23421bf038cKenny Root    UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) {
718655b958eb2180c7c06889f83f606d23421bf038cKenny Root        asprintf(&mUserDir, "user_%u", mUserId);
719655b958eb2180c7c06889f83f606d23421bf038cKenny Root        asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir);
720655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
72170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
722655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ~UserState() {
723655b958eb2180c7c06889f83f606d23421bf038cKenny Root        free(mUserDir);
724655b958eb2180c7c06889f83f606d23421bf038cKenny Root        free(mMasterKeyFile);
725655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
72670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
727655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool initialize() {
728655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) {
729655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGE("Could not create directory '%s'", mUserDir);
730655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return false;
731655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
732655b958eb2180c7c06889f83f606d23421bf038cKenny Root
733655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(mMasterKeyFile, R_OK) == 0) {
734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_LOCKED);
735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            setState(STATE_UNINITIALIZED);
737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
73870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
739655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return true;
740655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
741655b958eb2180c7c06889f83f606d23421bf038cKenny Root
742655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uid_t getUserId() const {
743655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mUserId;
744655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
745655b958eb2180c7c06889f83f606d23421bf038cKenny Root
746655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const char* getUserDirName() const {
747655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mUserDir;
748655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
749655b958eb2180c7c06889f83f606d23421bf038cKenny Root
750655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const char* getMasterKeyFileName() const {
751655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mMasterKeyFile;
752655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
753655b958eb2180c7c06889f83f606d23421bf038cKenny Root
754655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void setState(State state) {
755655b958eb2180c7c06889f83f606d23421bf038cKenny Root        mState = state;
756655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
757655b958eb2180c7c06889f83f606d23421bf038cKenny Root            mRetry = MAX_RETRY;
758655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7615187818895c4c5f650a611c40531b1dff7764c18Kenny Root    State getState() const {
762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mState;
763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7655187818895c4c5f650a611c40531b1dff7764c18Kenny Root    int8_t getRetry() const {
766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return mRetry;
767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
769655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void zeroizeMasterKeysInMemory() {
770655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(mMasterKey, 0, sizeof(mMasterKey));
771655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(mSalt, 0, sizeof(mSalt));
772655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
773655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
77470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
77570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
77696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    bool deleteMasterKey() {
77796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        setState(STATE_UNINITIALIZED);
77896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        zeroizeMasterKeysInMemory();
77996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        return unlink(mMasterKeyFile) == 0 || errno == ENOENT;
78096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    }
78196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker
782655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode initialize(const android::String8& pw, Entropy* entropy) {
783655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!generateMasterKey(entropy)) {
784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
786655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode response = writeMasterKey(pw, entropy);
787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response != NO_ERROR) {
788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        setupMasterKeys();
79107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
792a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
7944e865753346fc6a075966972a7a98051818859dbRobin Lee    ResponseCode copyMasterKey(UserState* src) {
7954e865753346fc6a075966972a7a98051818859dbRobin Lee        if (mState != STATE_UNINITIALIZED) {
7964e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::SYSTEM_ERROR;
7974e865753346fc6a075966972a7a98051818859dbRobin Lee        }
7984e865753346fc6a075966972a7a98051818859dbRobin Lee        if (src->getState() != STATE_NO_ERROR) {
7994e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::SYSTEM_ERROR;
8004e865753346fc6a075966972a7a98051818859dbRobin Lee        }
8014e865753346fc6a075966972a7a98051818859dbRobin Lee        memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES);
8024e865753346fc6a075966972a7a98051818859dbRobin Lee        setupMasterKeys();
8034e865753346fc6a075966972a7a98051818859dbRobin Lee        return ::NO_ERROR;
8044e865753346fc6a075966972a7a98051818859dbRobin Lee    }
8054e865753346fc6a075966972a7a98051818859dbRobin Lee
806655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) {
807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
811822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
812f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy);
813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
815655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) {
816655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
817150ca934edb745de3666a6492b039900df228ff0Kenny Root        if (in < 0) {
818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // we read the raw blob to just to get the salt to generate
822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // the AES key, then we create the Blob to use with decryptBlob
823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        blob rawBlob;
824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob));
825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (close(in) != 0) {
826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return SYSTEM_ERROR;
827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        // find salt at EOF if present, otherwise we have an old file
829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t* salt;
830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) {
831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = (uint8_t*) &rawBlob + length - SALT_SIZE;
832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        } else {
833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            salt = NULL;
834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
835a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_KEY passwordAesKey;
838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        Blob masterKeyBlob(rawBlob);
840f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey,
841f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                STATE_NO_ERROR);
842a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == SYSTEM_ERROR) {
843f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            return response;
844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            // if salt was missing, generate one and write a new master key file with the salt.
847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (salt == NULL) {
848655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (!generateSalt(entropy)) {
849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                    return SYSTEM_ERROR;
850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                }
851655b958eb2180c7c06889f83f606d23421bf038cKenny Root                response = writeMasterKey(pw, entropy);
852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            if (response == NO_ERROR) {
854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root                setupMasterKeys();
856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            }
857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return response;
858a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (mRetry <= 0) {
860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            reset();
861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return UNINITIALIZED;
862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        --mRetry;
864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        switch (mRetry) {
865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 0: return WRONG_PASSWORD_0;
866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 1: return WRONG_PASSWORD_1;
867a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 2: return WRONG_PASSWORD_2;
868a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            case 3: return WRONG_PASSWORD_3;
869a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            default: return WRONG_PASSWORD_3;
870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
871a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
872a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
873655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY* getEncryptionKey() {
874655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return &mMasterKeyEncryption;
875655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
876a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
877655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY* getDecryptionKey() {
878655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return &mMasterKeyDecryption;
879655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
880a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
881655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool reset() {
882655b958eb2180c7c06889f83f606d23421bf038cKenny Root        DIR* dir = opendir(getUserDirName());
883a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
88496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            // If the directory doesn't exist then nothing to do.
88596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            if (errno == ENOENT) {
88696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                return true;
88796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            }
888655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("couldn't open user directory: %s", strerror(errno));
889a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return false;
890a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
891655b958eb2180c7c06889f83f606d23421bf038cKenny Root
892655b958eb2180c7c06889f83f606d23421bf038cKenny Root        struct dirent* file;
893a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
89496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            // skip . and ..
89596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            if (!strcmp(".", file->d_name) || !strcmp("..", file->d_name)) {
896655b958eb2180c7c06889f83f606d23421bf038cKenny Root                continue;
897655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
898655b958eb2180c7c06889f83f606d23421bf038cKenny Root
899655b958eb2180c7c06889f83f606d23421bf038cKenny Root            unlinkat(dirfd(dir), file->d_name, 0);
900a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
901a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
902a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return true;
903a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
904a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
905655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate:
906655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const int MASTER_KEY_SIZE_BYTES = 16;
907655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
908655b958eb2180c7c06889f83f606d23421bf038cKenny Root
909655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const int MAX_RETRY = 4;
910655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const size_t SALT_SIZE = 16;
911655b958eb2180c7c06889f83f606d23421bf038cKenny Root
912655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
913655b958eb2180c7c06889f83f606d23421bf038cKenny Root            uint8_t* salt) {
914655b958eb2180c7c06889f83f606d23421bf038cKenny Root        size_t saltSize;
915655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (salt != NULL) {
916655b958eb2180c7c06889f83f606d23421bf038cKenny Root            saltSize = SALT_SIZE;
917655b958eb2180c7c06889f83f606d23421bf038cKenny Root        } else {
918655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
919655b958eb2180c7c06889f83f606d23421bf038cKenny Root            salt = (uint8_t*) "keystore";
920655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // sizeof = 9, not strlen = 8
921655b958eb2180c7c06889f83f606d23421bf038cKenny Root            saltSize = sizeof("keystore");
922655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
923655b958eb2180c7c06889f83f606d23421bf038cKenny Root
924655b958eb2180c7c06889f83f606d23421bf038cKenny Root        PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt,
925655b958eb2180c7c06889f83f606d23421bf038cKenny Root                saltSize, 8192, keySize, key);
926655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
927655b958eb2180c7c06889f83f606d23421bf038cKenny Root
928655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool generateSalt(Entropy* entropy) {
929655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return entropy->generate_random_data(mSalt, sizeof(mSalt));
930655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
931655b958eb2180c7c06889f83f606d23421bf038cKenny Root
932655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool generateMasterKey(Entropy* entropy) {
933655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
934655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return false;
935655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
936655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!generateSalt(entropy)) {
937655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return false;
938655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
939655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return true;
940655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
941655b958eb2180c7c06889f83f606d23421bf038cKenny Root
942655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void setupMasterKeys() {
943655b958eb2180c7c06889f83f606d23421bf038cKenny Root        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
944655b958eb2180c7c06889f83f606d23421bf038cKenny Root        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
945655b958eb2180c7c06889f83f606d23421bf038cKenny Root        setState(STATE_NO_ERROR);
946655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
947655b958eb2180c7c06889f83f606d23421bf038cKenny Root
948655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uid_t mUserId;
949655b958eb2180c7c06889f83f606d23421bf038cKenny Root
950655b958eb2180c7c06889f83f606d23421bf038cKenny Root    char* mUserDir;
951655b958eb2180c7c06889f83f606d23421bf038cKenny Root    char* mMasterKeyFile;
952655b958eb2180c7c06889f83f606d23421bf038cKenny Root
953655b958eb2180c7c06889f83f606d23421bf038cKenny Root    State mState;
954655b958eb2180c7c06889f83f606d23421bf038cKenny Root    int8_t mRetry;
955655b958eb2180c7c06889f83f606d23421bf038cKenny Root
956655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
957655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uint8_t mSalt[SALT_SIZE];
958655b958eb2180c7c06889f83f606d23421bf038cKenny Root
959655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY mMasterKeyEncryption;
960655b958eb2180c7c06889f83f606d23421bf038cKenny Root    AES_KEY mMasterKeyDecryption;
961655b958eb2180c7c06889f83f606d23421bf038cKenny Root};
962655b958eb2180c7c06889f83f606d23421bf038cKenny Root
963655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct {
964655b958eb2180c7c06889f83f606d23421bf038cKenny Root    uint32_t uid;
965655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const uint8_t* filename;
966655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t;
967655b958eb2180c7c06889f83f606d23421bf038cKenny Root
968655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore {
969655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic:
97067d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    KeyStore(Entropy* entropy, keymaster1_device_t* device, keymaster1_device_t* fallback)
971655b958eb2180c7c06889f83f606d23421bf038cKenny Root        : mEntropy(entropy)
972655b958eb2180c7c06889f83f606d23421bf038cKenny Root        , mDevice(device)
973fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker        , mFallbackDevice(fallback)
974655b958eb2180c7c06889f83f606d23421bf038cKenny Root    {
975655b958eb2180c7c06889f83f606d23421bf038cKenny Root        memset(&mMetaData, '\0', sizeof(mMetaData));
976655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
977655b958eb2180c7c06889f83f606d23421bf038cKenny Root
978655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ~KeyStore() {
979655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
980655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mGrants.end(); it++) {
981655b958eb2180c7c06889f83f606d23421bf038cKenny Root            delete *it;
982655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
983c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang        mGrants.clear();
984655b958eb2180c7c06889f83f606d23421bf038cKenny Root
985655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
986655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mMasterKeys.end(); it++) {
987655b958eb2180c7c06889f83f606d23421bf038cKenny Root            delete *it;
988655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
989c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang        mMasterKeys.clear();
990655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
991655b958eb2180c7c06889f83f606d23421bf038cKenny Root
99267d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    /**
99367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker     * Depending on the hardware keymaster version is this may return a
99467d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker     * keymaster0_device_t* cast to a keymaster1_device_t*. All methods from
99567d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker     * keymaster0 are safe to call, calls to keymaster1_device_t methods should
99667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker     * be guarded by a check on the device's version.
99767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker     */
99867d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    keymaster1_device_t *getDevice() const {
999655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mDevice;
1000655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1001655b958eb2180c7c06889f83f606d23421bf038cKenny Root
100267d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    keymaster1_device_t *getFallbackDevice() const {
1003fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker        return mFallbackDevice;
1004fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker    }
1005fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker
100667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    keymaster1_device_t *getDeviceForBlob(const Blob& blob) const {
1007fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker        return blob.isFallback() ? mFallbackDevice: mDevice;
1008fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker    }
1009fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker
1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode initialize() {
1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root        readMetaData();
1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (upgradeKeystore()) {
1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root            writeMetaData();
1014655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1015655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1016655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return ::NO_ERROR;
1017655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1018655b958eb2180c7c06889f83f606d23421bf038cKenny Root
101972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    State getState(uid_t userId) {
102072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return getUserState(userId)->getState();
1021655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1022655b958eb2180c7c06889f83f606d23421bf038cKenny Root
102372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode initializeUser(const android::String8& pw, uid_t userId) {
102472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
1025655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState->initialize(pw, mEntropy);
1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root
102872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser) {
102972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState *userState = getUserState(dstUser);
103072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState *initState = getUserState(srcUser);
10314e865753346fc6a075966972a7a98051818859dbRobin Lee        return userState->copyMasterKey(initState);
10324e865753346fc6a075966972a7a98051818859dbRobin Lee    }
10334e865753346fc6a075966972a7a98051818859dbRobin Lee
103472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode writeMasterKey(const android::String8& pw, uid_t userId) {
103572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
1036655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState->writeMasterKey(pw, mEntropy);
1037655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1038655b958eb2180c7c06889f83f606d23421bf038cKenny Root
103972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode readMasterKey(const android::String8& pw, uid_t userId) {
104072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
1041655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState->readMasterKey(pw, mEntropy);
1042655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::String8 getKeyName(const android::String8& keyName) {
1045a77e809ecff5190790906fb7a3c527259c735071Douglas Leung        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
1046655b958eb2180c7c06889f83f606d23421bf038cKenny Root        encode_key(encoded, keyName);
1047655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return android::String8(encoded);
1048655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1049655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) {
1051a77e809ecff5190790906fb7a3c527259c735071Douglas Leung        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
1052655b958eb2180c7c06889f83f606d23421bf038cKenny Root        encode_key(encoded, keyName);
1053655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return android::String8::format("%u_%s", uid, encoded);
1054655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1056655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) {
1057a77e809ecff5190790906fb7a3c527259c735071Douglas Leung        char encoded[encode_key_length(keyName) + 1];	// add 1 for null char
1058655b958eb2180c7c06889f83f606d23421bf038cKenny Root        encode_key(encoded, keyName);
105972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
1060655b958eb2180c7c06889f83f606d23421bf038cKenny Root                encoded);
1061655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1062655b958eb2180c7c06889f83f606d23421bf038cKenny Root
106396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    /*
106496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker     * Delete entries owned by userId. If keepUnencryptedEntries is true
106596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker     * then only encrypted entries will be removed, otherwise all entries will
106696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker     * be removed.
106796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker     */
106896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    void resetUser(uid_t userId, bool keepUnenryptedEntries) {
10694b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        android::String8 prefix("");
10704b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        android::Vector<android::String16> aliases;
107172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
107272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        if (saw(prefix, &aliases, userId) != ::NO_ERROR) {
107396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            return;
10744b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
10754b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        for (uint32_t i = 0; i < aliases.size(); i++) {
10764b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            android::String8 filename(aliases[i]);
10774b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            filename = android::String8::format("%s/%s", userState->getUserDirName(),
107896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                                                getKeyName(filename).string());
107996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            bool shouldDelete = true;
108096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            if (keepUnenryptedEntries) {
108196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                Blob blob;
108272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                ResponseCode rc = get(filename, &blob, ::TYPE_ANY, userId);
108396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker
108496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                /* get can fail if the blob is encrypted and the state is
108596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                 * not unlocked, only skip deleting blobs that were loaded and
108696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                 * who are not encrypted. If there are blobs we fail to read for
108796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                 * other reasons err on the safe side and delete them since we
108896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                 * can't tell if they're encrypted.
108996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                 */
109096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                shouldDelete = !(rc == ::NO_ERROR && !blob.isEncrypted());
109196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            }
109296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            if (shouldDelete) {
109372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                del(filename, ::TYPE_ANY, userId);
109496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            }
109596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        }
109696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        if (!userState->deleteMasterKey()) {
109796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            ALOGE("Failed to delete user %d's master key", userId);
109896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        }
109996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        if (!keepUnenryptedEntries) {
110096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            if(!userState->reset()) {
110196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                ALOGE("Failed to remove user %d's directory", userId);
110296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            }
11034b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
1104655b958eb2180c7c06889f83f606d23421bf038cKenny Root    }
1105655b958eb2180c7c06889f83f606d23421bf038cKenny Root
110672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    bool isEmpty(uid_t userId) const {
110772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        const UserState* userState = getUserState(userId);
110896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        if (userState == NULL) {
1109655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return true;
1110655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1111655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1112655b958eb2180c7c06889f83f606d23421bf038cKenny Root        DIR* dir = opendir(userState->getUserDirName());
1113a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        if (!dir) {
1114a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root            return true;
1115a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1116655b958eb2180c7c06889f83f606d23421bf038cKenny Root
111731e27468b6d822adbd2aec9219a68c206aa6957cKenny Root        bool result = true;
111831e27468b6d822adbd2aec9219a68c206aa6957cKenny Root        struct dirent* file;
1119a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        while ((file = readdir(dir)) != NULL) {
1120655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // We only care about files.
1121655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (file->d_type != DT_REG) {
1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root                continue;
1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1124655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1125655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Skip anything that starts with a "."
1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (file->d_name[0] == '.') {
1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root                continue;
1128655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1129655b958eb2180c7c06889f83f606d23421bf038cKenny Root
113031e27468b6d822adbd2aec9219a68c206aa6957cKenny Root            result = false;
113131e27468b6d822adbd2aec9219a68c206aa6957cKenny Root            break;
1132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1133a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        closedir(dir);
1134a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return result;
1135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
113772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    void lock(uid_t userId) {
113872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
1139655b958eb2180c7c06889f83f606d23421bf038cKenny Root        userState->zeroizeMasterKeysInMemory();
1140655b958eb2180c7c06889f83f606d23421bf038cKenny Root        userState->setState(STATE_LOCKED);
1141a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1142a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
114372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) {
114472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
1145f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
1146f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                userState->getState());
1147822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc != NO_ERROR) {
1148822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return rc;
1149822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1150822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1151822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        const uint8_t version = keyBlob->getVersion();
115207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (version < CURRENT_BLOB_VERSION) {
1153cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root            /* If we upgrade the key, we need to write it to disk again. Then
1154cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root             * it must be read it again since the blob is encrypted each time
1155cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root             * it's written.
1156cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root             */
115772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker            if (upgradeBlob(filename, keyBlob, version, type, userId)) {
115872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                if ((rc = this->put(filename, keyBlob, userId)) != NO_ERROR
1159f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                        || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
1160f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                                userState->getState())) != NO_ERROR) {
1161cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root                    return rc;
1162cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root                }
1163cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root            }
1164822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1165822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
116617208e0de5a42722901d803118745cca25fd10c1Kenny Root        /*
116717208e0de5a42722901d803118745cca25fd10c1Kenny Root         * This will upgrade software-backed keys to hardware-backed keys when
116817208e0de5a42722901d803118745cca25fd10c1Kenny Root         * the HAL for the device supports the newer key types.
116917208e0de5a42722901d803118745cca25fd10c1Kenny Root         */
117017208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (rc == NO_ERROR && type == TYPE_KEY_PAIR
117117208e0de5a42722901d803118745cca25fd10c1Kenny Root                && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2
117217208e0de5a42722901d803118745cca25fd10c1Kenny Root                && keyBlob->isFallback()) {
117317208e0de5a42722901d803118745cca25fd10c1Kenny Root            ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename,
117472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                    userId, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
117517208e0de5a42722901d803118745cca25fd10c1Kenny Root
117617208e0de5a42722901d803118745cca25fd10c1Kenny Root            // The HAL allowed the import, reget the key to have the "fresh"
117717208e0de5a42722901d803118745cca25fd10c1Kenny Root            // version.
117817208e0de5a42722901d803118745cca25fd10c1Kenny Root            if (imported == NO_ERROR) {
117972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId);
118017208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
118117208e0de5a42722901d803118745cca25fd10c1Kenny Root        }
118217208e0de5a42722901d803118745cca25fd10c1Kenny Root
1183d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (type != TYPE_ANY && keyBlob->getType() != type) {
1184822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
1185822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return KEY_NOT_FOUND;
1186822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1187822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1188822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return rc;
1189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
119172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode put(const char* filename, Blob* keyBlob, uid_t userId) {
119272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
1193f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(),
1194f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                mEntropy);
1195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1196a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
119772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode del(const char *filename, const BlobType type, uid_t userId) {
11984b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        Blob keyBlob;
119972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        ResponseCode rc = get(filename, &keyBlob, type, userId);
12004b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (rc != ::NO_ERROR) {
12014b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return rc;
12024b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
12034b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12044b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (keyBlob.getType() == ::TYPE_KEY_PAIR) {
12054b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            // A device doesn't have to implement delete_keypair.
12064b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (mDevice->delete_keypair != NULL && !keyBlob.isFallback()) {
12074b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                if (mDevice->delete_keypair(mDevice, keyBlob.getValue(), keyBlob.getLength())) {
12084b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    rc = ::SYSTEM_ERROR;
12094b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                }
12104b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
12114b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
121217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
121317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            keymaster1_device_t* dev = getDeviceForBlob(keyBlob);
121417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            if (dev->delete_key) {
121517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker                keymaster_key_blob_t blob;
121617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker                blob.key_material = keyBlob.getValue();
121717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker                blob.key_material_size = keyBlob.getLength();
121817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker                dev->delete_key(dev, &blob);
121917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            }
122017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        }
12214b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (rc != ::NO_ERROR) {
12224b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return rc;
12234b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
12244b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12254b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
12264b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    }
12274b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12284b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    ResponseCode saw(const android::String8& prefix, android::Vector<android::String16> *matches,
122972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker            uid_t userId) {
12304b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
123172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        UserState* userState = getUserState(userId);
12324b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        size_t n = prefix.length();
12334b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12344b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        DIR* dir = opendir(userState->getUserDirName());
12354b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        if (!dir) {
12364b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            ALOGW("can't open directory for user: %s", strerror(errno));
12374b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return ::SYSTEM_ERROR;
12384b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
12394b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12404b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        struct dirent* file;
12414b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        while ((file = readdir(dir)) != NULL) {
12424b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            // We only care about files.
12434b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (file->d_type != DT_REG) {
12444b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                continue;
12454b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
12464b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12474b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            // Skip anything that starts with a "."
12484b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (file->d_name[0] == '.') {
12494b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                continue;
12504b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
12514b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12524b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            if (!strncmp(prefix.string(), file->d_name, n)) {
12534b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                const char* p = &file->d_name[n];
12544b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                size_t plen = strlen(p);
12554b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
12564b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                size_t extra = decode_key_length(p, plen);
12574b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                char *match = (char*) malloc(extra + 1);
12584b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                if (match != NULL) {
12594b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    decode_key(match, p, plen);
12604b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    matches->push(android::String16(match, extra));
12614b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    free(match);
12624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                } else {
12634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                    ALOGW("could not allocate match of size %zd", extra);
12644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee                }
12654b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            }
12664b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        }
12674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        closedir(dir);
12684b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return ::NO_ERROR;
12694b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    }
12704b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee
127107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    void addGrant(const char* filename, uid_t granteeUid) {
1272655b958eb2180c7c06889f83f606d23421bf038cKenny Root        const grant_t* existing = getGrant(filename, granteeUid);
1273655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (existing == NULL) {
1274655b958eb2180c7c06889f83f606d23421bf038cKenny Root            grant_t* grant = new grant_t;
127507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            grant->uid = granteeUid;
1276a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom            grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
1277655b958eb2180c7c06889f83f606d23421bf038cKenny Root            mGrants.add(grant);
127870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
127970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
128070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
128107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    bool removeGrant(const char* filename, uid_t granteeUid) {
1282655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
1283655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mGrants.end(); it++) {
1284655b958eb2180c7c06889f83f606d23421bf038cKenny Root            grant_t* grant = *it;
1285655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (grant->uid == granteeUid
1286655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
1287655b958eb2180c7c06889f83f606d23421bf038cKenny Root                mGrants.erase(it);
1288655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return true;
1289655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
129070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
129170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return false;
129270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
129370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1294a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom    bool hasGrant(const char* filename, const uid_t uid) const {
1295a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom        return getGrant(filename, uid) != NULL;
129670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
129770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
129872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t userId,
1299f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            int32_t flags) {
1300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t* data;
1301822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        size_t dataLength;
1302822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        int rc;
1303822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1304822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (mDevice->import_keypair == NULL) {
1305822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Keymaster doesn't support import!");
1306822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
130917208e0de5a42722901d803118745cca25fd10c1Kenny Root        bool isFallback = false;
131007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength);
1311822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc) {
1312a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root            /*
1313a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * Maybe the device doesn't support this type of key. Try to use the
1314a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * software fallback keymaster implementation. This is a little bit
1315a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * lazier than checking the PKCS#8 key type, but the software
1316a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             * implementation will do that anyway.
1317a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root             */
13187c1eb75a6898452867ca28a4d7fad2d91edca615Chad Brubaker            rc = mFallbackDevice->import_keypair(mFallbackDevice, key, keyLen, &data, &dataLength);
1319a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root            isFallback = true;
132017208e0de5a42722901d803118745cca25fd10c1Kenny Root
132117208e0de5a42722901d803118745cca25fd10c1Kenny Root            if (rc) {
132217208e0de5a42722901d803118745cca25fd10c1Kenny Root                ALOGE("Error while importing keypair: %d", rc);
132317208e0de5a42722901d803118745cca25fd10c1Kenny Root                return SYSTEM_ERROR;
132417208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
1325822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1326822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1327822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
1328822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        free(data);
1329822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1330f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
133117208e0de5a42722901d803118745cca25fd10c1Kenny Root        keyBlob.setFallback(isFallback);
1332f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
133372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return put(filename, &keyBlob, userId);
1334822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
1335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
13361b0e3933900c7ea21189704d5db64e7346aee7afKenny Root    bool isHardwareBacked(const android::String16& keyType) const {
13371b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        if (mDevice == NULL) {
13381b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            ALOGW("can't get keymaster device");
13391b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            return false;
13401b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        }
13411b0e3933900c7ea21189704d5db64e7346aee7afKenny Root
13421b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        if (sRSAKeyType == keyType) {
13431b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0;
13441b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        } else {
13451b0e3933900c7ea21189704d5db64e7346aee7afKenny Root            return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0
13461b0e3933900c7ea21189704d5db64e7346aee7afKenny Root                    && (mDevice->common.module->module_api_version
13471b0e3933900c7ea21189704d5db64e7346aee7afKenny Root                            >= KEYMASTER_MODULE_API_VERSION_0_2);
13481b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        }
13498ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root    }
13508ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root
1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid,
1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root            const BlobType type) {
135386b16e8c0d353af97f0411917789308dba417295Kenny Root        android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid));
135472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        uid_t userId = get_user_id(uid);
1355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
135672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        ResponseCode responseCode = get(filepath8.string(), keyBlob, type, userId);
1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (responseCode == NO_ERROR) {
1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return responseCode;
1359655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root        // If this is one of the legacy UID->UID mappings, use it.
1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uid_t euid = get_keystore_euid(uid);
1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (euid != uid) {
136486b16e8c0d353af97f0411917789308dba417295Kenny Root            filepath8 = getKeyNameForUidWithDir(keyName, euid);
136572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker            responseCode = get(filepath8.string(), keyBlob, type, userId);
1366655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (responseCode == NO_ERROR) {
1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return responseCode;
1368655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
137070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root        // They might be using a granted key.
137286b16e8c0d353af97f0411917789308dba417295Kenny Root        android::String8 filename8 = getKeyName(keyName);
1373655b958eb2180c7c06889f83f606d23421bf038cKenny Root        char* end;
137486b16e8c0d353af97f0411917789308dba417295Kenny Root        strtoul(filename8.string(), &end, 10);
1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (end[0] != '_' || end[1] == 0) {
1376655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return KEY_NOT_FOUND;
1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
137872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        filepath8 = android::String8::format("%s/%s", getUserState(userId)->getUserDirName(),
137986b16e8c0d353af97f0411917789308dba417295Kenny Root                filename8.string());
1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!hasGrant(filepath8.string(), uid)) {
1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return responseCode;
1382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root        // It is a granted key. Try to load it.
138572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return get(filepath8.string(), keyBlob, type, userId);
1386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root    /**
1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root     * Returns any existing UserState or creates it if it doesn't exist.
1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root     */
139172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    UserState* getUserState(uid_t userId) {
1392655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mMasterKeys.end(); it++) {
1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root            UserState* state = *it;
1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (state->getUserId() == userId) {
1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return state;
1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root        UserState* userState = new UserState(userId);
1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (!userState->initialize()) {
1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root            /* There's not much we can do if initialization fails. Trying to
1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root             * unlock the keystore for that user will fail as well, so any
1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root             * subsequent request for this user will just return SYSTEM_ERROR.
1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root             */
1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGE("User initialization failed for %u; subsuquent operations will fail", userId);
1407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root        mMasterKeys.add(userState);
1409655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return userState;
1410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root    /**
141372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker     * Returns any existing UserState or creates it if it doesn't exist.
1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root     */
141572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    UserState* getUserStateByUid(uid_t uid) {
1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uid_t userId = get_user_id(uid);
141772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return getUserState(userId);
141872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    }
1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root
142072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    /**
142172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker     * Returns NULL if the UserState doesn't already exist.
142272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker     */
142372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    const UserState* getUserState(uid_t userId) const {
1424655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin());
1425655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mMasterKeys.end(); it++) {
1426655b958eb2180c7c06889f83f606d23421bf038cKenny Root            UserState* state = *it;
1427655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (state->getUserId() == userId) {
1428655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return state;
1429655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1430655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1432655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return NULL;
1433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
143572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    /**
143672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker     * Returns NULL if the UserState doesn't already exist.
143772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker     */
143872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    const UserState* getUserStateByUid(uid_t uid) const {
143972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        uid_t userId = get_user_id(uid);
144072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return getUserState(userId);
144172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker    }
144272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker
1443655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate:
1444655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const char* sOldMasterKey;
1445655b958eb2180c7c06889f83f606d23421bf038cKenny Root    static const char* sMetaDataFile;
14461b0e3933900c7ea21189704d5db64e7346aee7afKenny Root    static const android::String16 sRSAKeyType;
1447655b958eb2180c7c06889f83f606d23421bf038cKenny Root    Entropy* mEntropy;
144807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
144967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    keymaster1_device_t* mDevice;
145067d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    keymaster1_device_t* mFallbackDevice;
1451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1452655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::Vector<UserState*> mMasterKeys;
1453655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1454655b958eb2180c7c06889f83f606d23421bf038cKenny Root    android::Vector<grant_t*> mGrants;
145570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1456655b958eb2180c7c06889f83f606d23421bf038cKenny Root    typedef struct {
1457655b958eb2180c7c06889f83f606d23421bf038cKenny Root        uint32_t version;
1458655b958eb2180c7c06889f83f606d23421bf038cKenny Root    } keystore_metadata_t;
145970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1460655b958eb2180c7c06889f83f606d23421bf038cKenny Root    keystore_metadata_t mMetaData;
1461655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1462655b958eb2180c7c06889f83f606d23421bf038cKenny Root    const grant_t* getGrant(const char* filename, uid_t uid) const {
1463655b958eb2180c7c06889f83f606d23421bf038cKenny Root        for (android::Vector<grant_t*>::const_iterator it(mGrants.begin());
1464655b958eb2180c7c06889f83f606d23421bf038cKenny Root                it != mGrants.end(); it++) {
1465655b958eb2180c7c06889f83f606d23421bf038cKenny Root            grant_t* grant = *it;
146670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            if (grant->uid == uid
1467655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
146870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root                return grant;
146970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            }
147070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
147170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
147270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
147370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
1475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Upgrade code. This will upgrade the key from the current version
1476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * to whatever is newest.
1477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
1478655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
1479655b958eb2180c7c06889f83f606d23421bf038cKenny Root            const BlobType type, uid_t uid) {
1480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        bool updated = false;
1481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        uint8_t version = oldVersion;
1482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1483822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /* From V0 -> V1: All old types were unknown */
1484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (version == 0) {
1485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("upgrading to version 1 and setting type %d", type);
1486822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setType(type);
1488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            if (type == TYPE_KEY_PAIR) {
1489655b958eb2180c7c06889f83f606d23421bf038cKenny Root                importBlobAsKey(blob, filename, uid);
1490822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            }
1491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            version = 1;
1492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            updated = true;
1493822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1495f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        /* From V1 -> V2: All old keys were encrypted */
1496f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        if (version == 1) {
1497f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            ALOGV("upgrading to version 2");
1498f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
1499f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            blob->setEncrypted(true);
1500f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            version = 2;
1501f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            updated = true;
1502f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root        }
1503f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root
1504822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        /*
1505822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * If we've updated, set the key blob to the right version
1506822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root         * and write it.
1507cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root         */
1508822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (updated) {
1509822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGV("updated and writing file %s", filename);
1510822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            blob->setVersion(version);
1511822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1512cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root
1513cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root        return updated;
1514822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
1515822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1516822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /**
1517822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Takes a blob that is an PEM-encoded RSA key as a byte array and
1518822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * converts it to a DER-encoded PKCS#8 for import into a keymaster.
1519822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * Then it overwrites the original blob with the new blob
1520822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     * format that is returned from the keymaster.
1521822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root     */
1522655b958eb2180c7c06889f83f606d23421bf038cKenny Root    ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) {
1523822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        // We won't even write to the blob directly with this BIO, so const_cast is okay.
1524822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
1525822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (b.get() == NULL) {
1526822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Problem instantiating BIO");
1527822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1528822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1529822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1530822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
1531822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (pkey.get() == NULL) {
1532822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't read old PEM file");
1533822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1534822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1535822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1536822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
1537822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
1538822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (len < 0) {
1539822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't measure PKCS#8 length");
1540822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1541822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1542822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
154370c9889c5ca912e7c492580e1999f18ab65b267bKenny Root        UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]);
154470c9889c5ca912e7c492580e1999f18ab65b267bKenny Root        uint8_t* tmp = pkcs8key.get();
1545822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
1546822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            ALOGE("Couldn't convert to PKCS#8");
1547822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return SYSTEM_ERROR;
1548822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1549822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
155072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        ResponseCode rc = importKey(pkcs8key.get(), len, filename, get_user_id(uid),
1551f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root                blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
1552822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        if (rc != NO_ERROR) {
1553822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            return rc;
1554822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        }
1555822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
1556655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return get(filename, blob, TYPE_KEY_PAIR, uid);
1557822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
155870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1559655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void readMetaData() {
1560655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY));
1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (in < 0) {
1562655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return;
1563655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1564655b958eb2180c7c06889f83f606d23421bf038cKenny Root        size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData));
1565655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (fileLength != sizeof(mMetaData)) {
1566655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength,
1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    sizeof(mMetaData));
1568655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1569655b958eb2180c7c06889f83f606d23421bf038cKenny Root        close(in);
157070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
157170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1572655b958eb2180c7c06889f83f606d23421bf038cKenny Root    void writeMetaData() {
1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root        const char* tmpFileName = ".metadata.tmp";
1574655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int out = TEMP_FAILURE_RETRY(open(tmpFileName,
1575655b958eb2180c7c06889f83f606d23421bf038cKenny Root                O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
1576655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (out < 0) {
1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGE("couldn't write metadata file: %s", strerror(errno));
1578655b958eb2180c7c06889f83f606d23421bf038cKenny Root            return;
1579655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root        size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData));
1581655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (fileLength != sizeof(mMetaData)) {
1582655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
1583655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    sizeof(mMetaData));
158470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        }
1585655b958eb2180c7c06889f83f606d23421bf038cKenny Root        close(out);
1586655b958eb2180c7c06889f83f606d23421bf038cKenny Root        rename(tmpFileName, sMetaDataFile);
158770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
158870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1589655b958eb2180c7c06889f83f606d23421bf038cKenny Root    bool upgradeKeystore() {
1590655b958eb2180c7c06889f83f606d23421bf038cKenny Root        bool upgraded = false;
1591655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1592655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (mMetaData.version == 0) {
159372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker            UserState* userState = getUserStateByUid(0);
1594655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1595655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Initialize first so the directory is made.
1596655b958eb2180c7c06889f83f606d23421bf038cKenny Root            userState->initialize();
1597655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1598655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Migrate the old .masterkey file to user 0.
1599655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (access(sOldMasterKey, R_OK) == 0) {
1600655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) {
1601655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
1602655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    return false;
1603655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1604655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1605655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1606655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Initialize again in case we had a key.
1607655b958eb2180c7c06889f83f606d23421bf038cKenny Root            userState->initialize();
1608655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1609655b958eb2180c7c06889f83f606d23421bf038cKenny Root            // Try to migrate existing keys.
1610655b958eb2180c7c06889f83f606d23421bf038cKenny Root            DIR* dir = opendir(".");
1611655b958eb2180c7c06889f83f606d23421bf038cKenny Root            if (!dir) {
1612655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Give up now; maybe we can upgrade later.
1613655b958eb2180c7c06889f83f606d23421bf038cKenny Root                ALOGE("couldn't open keystore's directory; something is wrong");
1614655b958eb2180c7c06889f83f606d23421bf038cKenny Root                return false;
1615655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1616655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1617655b958eb2180c7c06889f83f606d23421bf038cKenny Root            struct dirent* file;
1618655b958eb2180c7c06889f83f606d23421bf038cKenny Root            while ((file = readdir(dir)) != NULL) {
1619655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // We only care about files.
1620655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (file->d_type != DT_REG) {
1621655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1622655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1623655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1624655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Skip anything that starts with a "."
1625655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (file->d_name[0] == '.') {
1626655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1627655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1628655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1629655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Find the current file's user.
1630655b958eb2180c7c06889f83f606d23421bf038cKenny Root                char* end;
1631655b958eb2180c7c06889f83f606d23421bf038cKenny Root                unsigned long thisUid = strtoul(file->d_name, &end, 10);
1632655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (end[0] != '_' || end[1] == 0) {
1633655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1634655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
163572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                UserState* otherUser = getUserStateByUid(thisUid);
1636655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (otherUser->getUserId() != 0) {
1637655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    unlinkat(dirfd(dir), file->d_name, 0);
1638655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1639655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1640655b958eb2180c7c06889f83f606d23421bf038cKenny Root                // Rename the file into user directory.
1641655b958eb2180c7c06889f83f606d23421bf038cKenny Root                DIR* otherdir = opendir(otherUser->getUserDirName());
1642655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (otherdir == NULL) {
1643655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    ALOGW("couldn't open user directory for rename");
1644655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    continue;
1645655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1646655b958eb2180c7c06889f83f606d23421bf038cKenny Root                if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
1647655b958eb2180c7c06889f83f606d23421bf038cKenny Root                    ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root                }
1649655b958eb2180c7c06889f83f606d23421bf038cKenny Root                closedir(otherdir);
1650655b958eb2180c7c06889f83f606d23421bf038cKenny Root            }
1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root            closedir(dir);
1652655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1653655b958eb2180c7c06889f83f606d23421bf038cKenny Root            mMetaData.version = 1;
1654655b958eb2180c7c06889f83f606d23421bf038cKenny Root            upgraded = true;
1655655b958eb2180c7c06889f83f606d23421bf038cKenny Root        }
1656655b958eb2180c7c06889f83f606d23421bf038cKenny Root
1657655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return upgraded;
165870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
1659655b958eb2180c7c06889f83f606d23421bf038cKenny Root};
166070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
1661655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey";
1662655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata";
166370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
16641b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA");
16651b0e3933900c7ea21189704d5db64e7346aee7afKenny Root
166607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android {
166707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient {
166807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic:
166907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    KeyStoreProxy(KeyStore* keyStore)
167040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        : mKeyStore(keyStore),
167140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker          mOperationMap(this)
167207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    {
167307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
1674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
167540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    void binderDied(const wp<IBinder>& who) {
167640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
167740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        for (auto token: operations) {
167840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            abort(token);
167940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
168007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
1681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
168207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t test() {
16839489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_TEST)) {
168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
168507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
168772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->getState(get_user_id(IPCThreadState::self()->getCallingUid()));
1688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
16919489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_GET)) {
169207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
16959489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
169707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
169866dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich
1699655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
1700494689083467ec372a58f094f041c8f102f39393Kenny Root                TYPE_GENERIC);
170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
1702655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("Could not read %s", name8.string());
170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *item = NULL;
170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            *itemLength = 0;
170507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
170607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
170707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
170807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        *item = (uint8_t*) malloc(keyBlob.getLength());
170907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        memcpy(*item, keyBlob.getValue(), keyBlob.getLength());
171007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        *itemLength = keyBlob.getLength();
171107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
1713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1715f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid,
1716f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            int32_t flags) {
17179489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
17189489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid,
17199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker                                                    flags & KEYSTORE_FLAG_ENCRYPTED);
17209489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (result != ::NO_ERROR) {
17219489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return result;
1722b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1723b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
1725655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
172607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
1728ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
1729ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root
173072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid));
1731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1732a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1733494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t del(const String16& name, int targetUid) {
17349489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
17359489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_DELETE, targetUid)) {
1736b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1737b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
173807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
1739655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
174072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
1741298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1742298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1743494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t exist(const String16& name, int targetUid) {
17449489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
17459489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_EXIST, targetUid)) {
1746b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1747b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
1748b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root
174907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
1750655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
175107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
1752655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
175307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
175507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
1756298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1757298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
1758494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) {
17599489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
17609489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_SAW, targetUid)) {
1761b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root            return ::PERMISSION_DENIED;
1762b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root        }
176307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const String8 prefix8(prefix);
1764655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
176507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
176672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        if (mKeyStore->saw(filename, matches, get_user_id(targetUid)) != ::NO_ERROR) {
17674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            return ::SYSTEM_ERROR;
176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
1770298e7b1b0f9116e2054d594d7538379d86585035Kenny Root    }
1771298e7b1b0f9116e2054d594d7538379d86585035Kenny Root
177207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t reset() {
17739489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_RESET)) {
177407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
177507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
17779489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
177896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        mKeyStore->resetUser(get_user_id(callingUid), false);
177996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        return ::NO_ERROR;
1780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
1781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
178296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    int32_t onUserPasswordChanged(int32_t userId, const String16& password) {
17839489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_PASSWORD)) {
178407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
178507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
1786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
178707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const String8 password8(password);
178896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        // Flush the auth token table to prevent stale tokens from sticking
178996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        // around.
179096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        mAuthTokenTable.Clear();
179196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker
179296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        if (password.size() == 0) {
179396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
179472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker            mKeyStore->resetUser(userId, true);
179596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            return ::NO_ERROR;
179696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        } else {
179772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker            switch (mKeyStore->getState(userId)) {
179896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                case ::STATE_UNINITIALIZED: {
179996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                    // generate master key, encrypt with password, write to file,
180096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                    // initialize mMasterKey*.
180172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                    return mKeyStore->initializeUser(password8, userId);
180296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                }
180396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                case ::STATE_NO_ERROR: {
180496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                    // rewrite master key with new password.
180572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                    return mKeyStore->writeMasterKey(password8, userId);
180696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                }
180796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                case ::STATE_LOCKED: {
180896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                    ALOGE("Changing user %d's password while locked, clearing old encryption",
180996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                          userId);
181072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                    mKeyStore->resetUser(userId, true);
181172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                    return mKeyStore->initializeUser(password8, userId);
181296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker                }
181307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            }
181496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            return ::SYSTEM_ERROR;
181507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
181607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    }
1817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
1818c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    int32_t onUserAdded(int32_t userId, int32_t parentId) {
1819c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (!checkBinderPermission(P_USER_CHANGED)) {
1820c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return ::PERMISSION_DENIED;
1821c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1822c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1823c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        // Sanity check that the new user has an empty keystore.
1824c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (!mKeyStore->isEmpty(userId)) {
1825c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            ALOGW("New user %d's keystore not empty. Clearing old entries.", userId);
1826c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1827c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        // Unconditionally clear the keystore, just to be safe.
1828c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        mKeyStore->resetUser(userId, false);
1829c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1830c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        // If the user has a parent user then use the parent's
1831c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        // masterkey/password, otherwise there's nothing to do.
1832c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (parentId != -1) {
1833c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return mKeyStore->copyMasterKey(parentId, userId);
1834c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        } else {
1835c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return ::NO_ERROR;
1836c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1837c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    }
1838c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1839c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    int32_t onUserRemoved(int32_t userId) {
1840c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        if (!checkBinderPermission(P_USER_CHANGED)) {
1841c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker            return ::PERMISSION_DENIED;
1842c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        }
1843c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
1844c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        mKeyStore->resetUser(userId, false);
1845c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker        return ::NO_ERROR;
1846c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker    }
1847c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker
184807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t lock() {
18499489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_LOCK)) {
185007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
185107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
185207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
185372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        uid_t userId = get_user_id(IPCThreadState::self()->getCallingUid());
185472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        State state = mKeyStore->getState(userId);
18559d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        if (state != ::STATE_NO_ERROR) {
185607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGD("calling lock in state: %d", state);
185707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
185807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
185970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
186072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        mKeyStore->lock(userId);
186107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
186270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
1863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
186496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker    int32_t unlock(int32_t userId, const String16& pw) {
18659489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_UNLOCK)) {
186607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
186707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
186807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
186972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        State state = mKeyStore->getState(userId);
18709d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        if (state != ::STATE_LOCKED) {
187196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker            ALOGI("calling unlock when not locked, ignoring.");
187207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return state;
187307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
187407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
187507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        const String8 password8(pw);
187696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        // read master key, decrypt with password, initialize mMasterKey*.
187772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->readMasterKey(password8, userId);
187870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
187970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
188007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t zero() {
18819489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_ZERO)) {
188207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return -1;
188307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
188470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
18859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
188672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->isEmpty(get_user_id(callingUid)) ? ::KEY_NOT_FOUND : ::NO_ERROR;
188770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
188870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
188996427baf0094d50047049d329b0779c3c910402cKenny Root    int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
189096427baf0094d50047049d329b0779c3c910402cKenny Root            int32_t flags, Vector<sp<KeystoreArg> >* args) {
18919489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
18929489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid,
18939489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
18949489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (result != ::NO_ERROR) {
18959489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return result;
189607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
189707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        uint8_t* data;
189807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        size_t dataLength;
189907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int rc;
190017208e0de5a42722901d803118745cca25fd10c1Kenny Root        bool isFallback = false;
190170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
190267d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker        const keymaster1_device_t* device = mKeyStore->getDevice();
190367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker        const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice();
190407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
190507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
190607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
190770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
190807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->generate_keypair == NULL) {
190907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
191007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
191170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
191217208e0de5a42722901d803118745cca25fd10c1Kenny Root        if (keyType == EVP_PKEY_DSA) {
191396427baf0094d50047049d329b0779c3c910402cKenny Root            keymaster_dsa_keygen_params_t dsa_params;
191496427baf0094d50047049d329b0779c3c910402cKenny Root            memset(&dsa_params, '\0', sizeof(dsa_params));
191596427baf0094d50047049d329b0779c3c910402cKenny Root
191696427baf0094d50047049d329b0779c3c910402cKenny Root            if (keySize == -1) {
191796427baf0094d50047049d329b0779c3c910402cKenny Root                keySize = DSA_DEFAULT_KEY_SIZE;
191896427baf0094d50047049d329b0779c3c910402cKenny Root            } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE
191996427baf0094d50047049d329b0779c3c910402cKenny Root                    || keySize > DSA_MAX_KEY_SIZE) {
192096427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("invalid key size %d", keySize);
192196427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
192296427baf0094d50047049d329b0779c3c910402cKenny Root            }
192396427baf0094d50047049d329b0779c3c910402cKenny Root            dsa_params.key_size = keySize;
192496427baf0094d50047049d329b0779c3c910402cKenny Root
192596427baf0094d50047049d329b0779c3c910402cKenny Root            if (args->size() == 3) {
192696427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> gArg = args->itemAt(0);
192796427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> pArg = args->itemAt(1);
192896427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> qArg = args->itemAt(2);
192996427baf0094d50047049d329b0779c3c910402cKenny Root
193096427baf0094d50047049d329b0779c3c910402cKenny Root                if (gArg != NULL && pArg != NULL && qArg != NULL) {
193196427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data());
193296427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.generator_len = gArg->size();
193396427baf0094d50047049d329b0779c3c910402cKenny Root
193496427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data());
193596427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_p_len = pArg->size();
193696427baf0094d50047049d329b0779c3c910402cKenny Root
193796427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data());
193896427baf0094d50047049d329b0779c3c910402cKenny Root                    dsa_params.prime_q_len = qArg->size();
193996427baf0094d50047049d329b0779c3c910402cKenny Root                } else {
194096427baf0094d50047049d329b0779c3c910402cKenny Root                    ALOGI("not all DSA parameters were read");
194196427baf0094d50047049d329b0779c3c910402cKenny Root                    return ::SYSTEM_ERROR;
194296427baf0094d50047049d329b0779c3c910402cKenny Root                }
194396427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (args->size() != 0) {
194496427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("DSA args must be 3");
194596427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
194696427baf0094d50047049d329b0779c3c910402cKenny Root            }
194796427baf0094d50047049d329b0779c3c910402cKenny Root
19481d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            if (isKeyTypeSupported(device, TYPE_DSA)) {
194917208e0de5a42722901d803118745cca25fd10c1Kenny Root                rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
195017208e0de5a42722901d803118745cca25fd10c1Kenny Root            } else {
195117208e0de5a42722901d803118745cca25fd10c1Kenny Root                isFallback = true;
1952fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker                rc = fallback->generate_keypair(fallback, TYPE_DSA, &dsa_params, &data,
1953fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker                                                &dataLength);
195417208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
195517208e0de5a42722901d803118745cca25fd10c1Kenny Root        } else if (keyType == EVP_PKEY_EC) {
195696427baf0094d50047049d329b0779c3c910402cKenny Root            keymaster_ec_keygen_params_t ec_params;
195796427baf0094d50047049d329b0779c3c910402cKenny Root            memset(&ec_params, '\0', sizeof(ec_params));
195896427baf0094d50047049d329b0779c3c910402cKenny Root
195996427baf0094d50047049d329b0779c3c910402cKenny Root            if (keySize == -1) {
196096427baf0094d50047049d329b0779c3c910402cKenny Root                keySize = EC_DEFAULT_KEY_SIZE;
196196427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
196296427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("invalid key size %d", keySize);
196396427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
196496427baf0094d50047049d329b0779c3c910402cKenny Root            }
196596427baf0094d50047049d329b0779c3c910402cKenny Root            ec_params.field_size = keySize;
196696427baf0094d50047049d329b0779c3c910402cKenny Root
19671d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            if (isKeyTypeSupported(device, TYPE_EC)) {
196817208e0de5a42722901d803118745cca25fd10c1Kenny Root                rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
196917208e0de5a42722901d803118745cca25fd10c1Kenny Root            } else {
197017208e0de5a42722901d803118745cca25fd10c1Kenny Root                isFallback = true;
1971fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker                rc = fallback->generate_keypair(fallback, TYPE_EC, &ec_params, &data, &dataLength);
197217208e0de5a42722901d803118745cca25fd10c1Kenny Root            }
197396427baf0094d50047049d329b0779c3c910402cKenny Root        } else if (keyType == EVP_PKEY_RSA) {
197496427baf0094d50047049d329b0779c3c910402cKenny Root            keymaster_rsa_keygen_params_t rsa_params;
197596427baf0094d50047049d329b0779c3c910402cKenny Root            memset(&rsa_params, '\0', sizeof(rsa_params));
197696427baf0094d50047049d329b0779c3c910402cKenny Root            rsa_params.public_exponent = RSA_DEFAULT_EXPONENT;
197796427baf0094d50047049d329b0779c3c910402cKenny Root
197896427baf0094d50047049d329b0779c3c910402cKenny Root            if (keySize == -1) {
197996427baf0094d50047049d329b0779c3c910402cKenny Root                keySize = RSA_DEFAULT_KEY_SIZE;
198096427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
198196427baf0094d50047049d329b0779c3c910402cKenny Root                ALOGI("invalid key size %d", keySize);
198296427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
198396427baf0094d50047049d329b0779c3c910402cKenny Root            }
198496427baf0094d50047049d329b0779c3c910402cKenny Root            rsa_params.modulus_size = keySize;
198596427baf0094d50047049d329b0779c3c910402cKenny Root
198696427baf0094d50047049d329b0779c3c910402cKenny Root            if (args->size() > 1) {
19876489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin                ALOGI("invalid number of arguments: %zu", args->size());
198896427baf0094d50047049d329b0779c3c910402cKenny Root                return ::SYSTEM_ERROR;
198996427baf0094d50047049d329b0779c3c910402cKenny Root            } else if (args->size() == 1) {
199096427baf0094d50047049d329b0779c3c910402cKenny Root                sp<KeystoreArg> pubExpBlob = args->itemAt(0);
199196427baf0094d50047049d329b0779c3c910402cKenny Root                if (pubExpBlob != NULL) {
199296427baf0094d50047049d329b0779c3c910402cKenny Root                    Unique_BIGNUM pubExpBn(
199396427baf0094d50047049d329b0779c3c910402cKenny Root                            BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()),
199496427baf0094d50047049d329b0779c3c910402cKenny Root                                    pubExpBlob->size(), NULL));
199596427baf0094d50047049d329b0779c3c910402cKenny Root                    if (pubExpBn.get() == NULL) {
199696427baf0094d50047049d329b0779c3c910402cKenny Root                        ALOGI("Could not convert public exponent to BN");
199796427baf0094d50047049d329b0779c3c910402cKenny Root                        return ::SYSTEM_ERROR;
199896427baf0094d50047049d329b0779c3c910402cKenny Root                    }
199996427baf0094d50047049d329b0779c3c910402cKenny Root                    unsigned long pubExp = BN_get_word(pubExpBn.get());
200096427baf0094d50047049d329b0779c3c910402cKenny Root                    if (pubExp == 0xFFFFFFFFL) {
200196427baf0094d50047049d329b0779c3c910402cKenny Root                        ALOGI("cannot represent public exponent as a long value");
200296427baf0094d50047049d329b0779c3c910402cKenny Root                        return ::SYSTEM_ERROR;
200396427baf0094d50047049d329b0779c3c910402cKenny Root                    }
200496427baf0094d50047049d329b0779c3c910402cKenny Root                    rsa_params.public_exponent = pubExp;
200596427baf0094d50047049d329b0779c3c910402cKenny Root                }
200696427baf0094d50047049d329b0779c3c910402cKenny Root            }
200796427baf0094d50047049d329b0779c3c910402cKenny Root
200896427baf0094d50047049d329b0779c3c910402cKenny Root            rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
200996427baf0094d50047049d329b0779c3c910402cKenny Root        } else {
201096427baf0094d50047049d329b0779c3c910402cKenny Root            ALOGW("Unsupported key type %d", keyType);
201196427baf0094d50047049d329b0779c3c910402cKenny Root            rc = -1;
201296427baf0094d50047049d329b0779c3c910402cKenny Root        }
201370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
201407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
201607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
201770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2018655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 name8(name);
20199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
202070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
202107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
202207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        free(data);
202307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2024ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
202517208e0de5a42722901d803118745cca25fd10c1Kenny Root        keyBlob.setFallback(isFallback);
202617208e0de5a42722901d803118745cca25fd10c1Kenny Root
202772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid));
202870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
202970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2030f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root    int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid,
2031f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root            int32_t flags) {
20329489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
20339489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid,
20349489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
20359489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (result != ::NO_ERROR) {
20369489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return result;
203707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
203807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
203960898896c3f3b2245d10076cac64346c956dbaa5Kenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
204070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
204172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->importKey(data, length, filename.string(), get_user_id(targetUid),
204272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                                    flags);
204370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
204470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
204607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            size_t* outLength) {
20479489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_SIGN)) {
204807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
204907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
20509a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root
20519489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
205207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
205307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
205470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2055d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        ALOGV("sign %s from uid %d", name8.string(), callingUid);
205670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2057655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
2058d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root                ::TYPE_KEY_PAIR);
205907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
206270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
206367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker        const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob);
206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGE("no keymaster device; cannot sign");
206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
206870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->sign_data == NULL) {
207007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGE("device doesn't implement signing");
207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
207370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
207407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        keymaster_rsa_sign_params_t params;
207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.digest_type = DIGEST_NONE;
207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.padding_type = PADDING_NONE;
20779489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
2078fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker                length, out, outLength);
207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
208007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGW("device couldn't sign data");
208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
208207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
208370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
208407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
208570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
208670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            const uint8_t* signature, size_t signatureLength) {
20899489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_VERIFY)) {
209007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
209107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
209270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
20939489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
209507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
209607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int rc;
209770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2098655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
2099494689083467ec372a58f094f041c8f102f39393Kenny Root                TYPE_KEY_PAIR);
210007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
210107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
210370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
210467d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker        const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob);
210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
210607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
210707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
210870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
210907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->verify_data == NULL) {
211007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
211107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        keymaster_rsa_sign_params_t params;
211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.digest_type = DIGEST_NONE;
211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        params.padding_type = PADDING_NONE;
211670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2117fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker        rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
2118fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker                dataLength, signature, signatureLength);
211907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        } else {
212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::NO_ERROR;
212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
212470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
212570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
212607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    /*
212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * TODO: The abstraction between things stored in hardware and regular blobs
212807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * of data stored on the filesystem should be moved down to keystore itself.
212907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * Unfortunately the Java code that calls this has naming conventions that it
213007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * knows about. Ideally keystore shouldn't be used to store random blobs of
213107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * data.
213207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     *
213307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * Until that happens, it's necessary to have a separate "get_pubkey" and
213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * "del_key" since the Java code doesn't really communicate what it's
213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * intentions are.
213607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     */
213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
2138d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
21399489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_GET)) {
2140d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: get_pubkey", callingUid);
214107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::PERMISSION_DENIED;
214207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
214370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        Blob keyBlob;
214507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
214670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2147d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid);
214870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2149655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root                TYPE_KEY_PAIR);
215107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (responseCode != ::NO_ERROR) {
215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return responseCode;
215307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
215470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
215567d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker        const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob);
215607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device == NULL) {
215707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
215807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
215970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
216007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (device->get_keypair_public == NULL) {
216107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            ALOGE("device has no get_keypair_public implementation!");
216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
216307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
2164344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root
216517208e0de5a42722901d803118745cca25fd10c1Kenny Root        int rc;
2166fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker        rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
2167fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker                pubkeyLength);
216807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (rc) {
216907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return ::SYSTEM_ERROR;
217007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
2171344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root
217207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
2173344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root    }
2174344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root
2175494689083467ec372a58f094f041c8f102f39393Kenny Root    int32_t del_key(const String16& name, int targetUid) {
21769489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        return del(name, targetUid);
2177a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
217807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
217907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t grant(const String16& name, int32_t granteeUid) {
2180d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
21819489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT);
21829489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (result != ::NO_ERROR) {
21839489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return result;
218407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
218507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
218607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
2187655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
218807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2189655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
219007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
219107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
219207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2193655b958eb2180c7c06889f83f606d23421bf038cKenny Root        mKeyStore->addGrant(filename.string(), granteeUid);
219407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return ::NO_ERROR;
2195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
219607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
219707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int32_t ungrant(const String16& name, int32_t granteeUid) {
2198d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
21999489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT);
22009489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (result != ::NO_ERROR) {
22019489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return result;
220207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
220307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
220407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
2205655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
220607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2207655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
220907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
221007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2211655b958eb2180c7c06889f83f606d23421bf038cKenny Root        return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
2212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
221307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
221407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    int64_t getmtime(const String16& name) {
2215d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
22169489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_GET)) {
2217d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root            ALOGW("permission denied for %d: getmtime", callingUid);
221836a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
221907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
222007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
222107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        String8 name8(name);
2222655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
222307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2224655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(filename.string(), R_OK) == -1) {
2225655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("could not access %s for getmtime", filename.string());
222636a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
2227a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        }
222807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2229655b958eb2180c7c06889f83f606d23421bf038cKenny Root        int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY));
223007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (fd < 0) {
2231655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("could not open %s for getmtime", filename.string());
223236a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
223307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
223407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
223507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        struct stat s;
223607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        int ret = fstat(fd, &s);
223707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        close(fd);
223807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        if (ret == -1) {
2239655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGW("could not stat %s for getmtime", filename.string());
224036a9e231e03734cd2143383d26388455c1764e17Kenny Root            return -1L;
224107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        }
224207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
224336a9e231e03734cd2143383d26388455c1764e17Kenny Root        return static_cast<int64_t>(s.st_mtime);
2244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
224507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
2246d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root    int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
2247d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            int32_t destUid) {
22480225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2249eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        pid_t spid = IPCThreadState::self()->getCallingPid();
2250eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (!has_permission(callingUid, P_DUPLICATE, spid)) {
2251d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGW("permission denied for %d: duplicate", callingUid);
22520225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return -1L;
22530225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22540225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
225572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        State state = mKeyStore->getState(get_user_id(callingUid));
22560225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        if (!isKeystoreUnlocked(state)) {
2257d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGD("calling duplicate in state: %d", state);
22580225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return state;
22590225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22600225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2261d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) {
2262d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            srcUid = callingUid;
2263d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        } else if (!is_granted_to(callingUid, srcUid)) {
2264d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid);
22650225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return ::PERMISSION_DENIED;
22660225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22670225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2268d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (destUid == -1) {
2269d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            destUid = callingUid;
2270d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        }
22710225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2272d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (srcUid != destUid) {
2273d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            if (static_cast<uid_t>(srcUid) != callingUid) {
2274d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                ALOGD("can only duplicate from caller to other or to same uid: "
2275d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                      "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid);
2276d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                return ::PERMISSION_DENIED;
2277d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            }
22780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2279d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            if (!is_granted_to(callingUid, destUid)) {
2280d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid);
2281d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root                return ::PERMISSION_DENIED;
2282d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            }
22830225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22840225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2285d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        String8 source8(srcKey);
2286655b958eb2180c7c06889f83f606d23421bf038cKenny Root        String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid));
2287d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root
2288d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        String8 target8(destKey);
2289fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root        String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid));
22900225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2291655b958eb2180c7c06889f83f606d23421bf038cKenny Root        if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
2292655b958eb2180c7c06889f83f606d23421bf038cKenny Root            ALOGD("destination already exists: %s", targetFile.string());
22930225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root            return ::SYSTEM_ERROR;
22940225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
22950225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
2296d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        Blob keyBlob;
2297655b958eb2180c7c06889f83f606d23421bf038cKenny Root        ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY,
229872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                get_user_id(srcUid));
2299d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root        if (responseCode != ::NO_ERROR) {
2300d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root            return responseCode;
23010225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root        }
2302d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root
230372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->put(targetFile.string(), &keyBlob, get_user_id(destUid));
23040225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root    }
23050225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root
23061b0e3933900c7ea21189704d5db64e7346aee7afKenny Root    int32_t is_hardware_backed(const String16& keyType) {
23071b0e3933900c7ea21189704d5db64e7346aee7afKenny Root        return mKeyStore->isHardwareBacked(keyType) ? 1 : 0;
23088ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root    }
23098ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root
2310fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root    int32_t clear_uid(int64_t targetUid64) {
23119489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t targetUid = getEffectiveUid(targetUid64);
2312b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker        if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
2313a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root            return ::PERMISSION_DENIED;
2314a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        }
2315a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root
23164b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        String8 prefix = String8::format("%u_", targetUid);
23174b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        Vector<String16> aliases;
231872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        if (mKeyStore->saw(prefix, &aliases, get_user_id(targetUid)) != ::NO_ERROR) {
2319a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root            return ::SYSTEM_ERROR;
2320a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        }
2321a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root
23224b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        for (uint32_t i = 0; i < aliases.size(); i++) {
23234b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            String8 name8(aliases[i]);
23244b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee            String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
232572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker            mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
2326a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root        }
23274b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee        return ::NO_ERROR;
2328a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root    }
2329a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root
23304b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee    int32_t reset_uid(int32_t targetUid) {
233196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        // TODO: Remove this method from the binder interface
23329489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
233396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker        return onUserPasswordChanged(get_user_id(targetUid), String16(""));
23344e865753346fc6a075966972a7a98051818859dbRobin Lee    }
23354e865753346fc6a075966972a7a98051818859dbRobin Lee
23364e865753346fc6a075966972a7a98051818859dbRobin Lee    int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {
23379489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_SYNC_UID, targetUid)) {
23384e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
23394e865753346fc6a075966972a7a98051818859dbRobin Lee        }
234072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        uid_t sourceUser = get_user_id(sourceUid);
234172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        uid_t targetUser = get_user_id(targetUid);
23429489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
234372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        if (sourceUser == targetUser) {
23444e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::SYSTEM_ERROR;
23454e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23464e865753346fc6a075966972a7a98051818859dbRobin Lee
23474e865753346fc6a075966972a7a98051818859dbRobin Lee        // Initialise user keystore with existing master key held in-memory
234872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->copyMasterKey(sourceUser, targetUser);
23494e865753346fc6a075966972a7a98051818859dbRobin Lee    }
23504e865753346fc6a075966972a7a98051818859dbRobin Lee
23514e865753346fc6a075966972a7a98051818859dbRobin Lee    int32_t password_uid(const String16& pw, int32_t targetUid) {
23529489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        targetUid = getEffectiveUid(targetUid);
23539489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_PASSWORD, targetUid)) {
23544e865753346fc6a075966972a7a98051818859dbRobin Lee            return ::PERMISSION_DENIED;
23554e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23564e865753346fc6a075966972a7a98051818859dbRobin Lee        const String8 password8(pw);
235772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        uid_t userId = get_user_id(targetUid);
23584e865753346fc6a075966972a7a98051818859dbRobin Lee
235972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        switch (mKeyStore->getState(userId)) {
23604e865753346fc6a075966972a7a98051818859dbRobin Lee            case ::STATE_UNINITIALIZED: {
23614e865753346fc6a075966972a7a98051818859dbRobin Lee                // generate master key, encrypt with password, write to file, initialize mMasterKey*.
236272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                return mKeyStore->initializeUser(password8, userId);
23634e865753346fc6a075966972a7a98051818859dbRobin Lee            }
23644e865753346fc6a075966972a7a98051818859dbRobin Lee            case ::STATE_NO_ERROR: {
23654e865753346fc6a075966972a7a98051818859dbRobin Lee                // rewrite master key with new password.
236672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                return mKeyStore->writeMasterKey(password8, userId);
23674e865753346fc6a075966972a7a98051818859dbRobin Lee            }
23684e865753346fc6a075966972a7a98051818859dbRobin Lee            case ::STATE_LOCKED: {
23694e865753346fc6a075966972a7a98051818859dbRobin Lee                // read master key, decrypt with password, initialize mMasterKey*.
237072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker                return mKeyStore->readMasterKey(password8, userId);
23714e865753346fc6a075966972a7a98051818859dbRobin Lee            }
23724e865753346fc6a075966972a7a98051818859dbRobin Lee        }
23734e865753346fc6a075966972a7a98051818859dbRobin Lee        return ::SYSTEM_ERROR;
23744e865753346fc6a075966972a7a98051818859dbRobin Lee    }
23754e865753346fc6a075966972a7a98051818859dbRobin Lee
23769c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker    int32_t addRngEntropy(const uint8_t* data, size_t dataLength) {
23779c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        const keymaster1_device_t* device = mKeyStore->getDevice();
23789c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice();
23799c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        int32_t devResult = KM_ERROR_UNIMPLEMENTED;
23809c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        int32_t fallbackResult = KM_ERROR_UNIMPLEMENTED;
23819c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
23829c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker                device->add_rng_entropy != NULL) {
23839c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker            devResult = device->add_rng_entropy(device, data, dataLength);
23849c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        }
23859c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        if (fallback->add_rng_entropy) {
23869c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker            fallbackResult = fallback->add_rng_entropy(fallback, data, dataLength);
23879c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        }
23889c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        if (devResult) {
23899c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker            return devResult;
23909c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        }
23919c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        if (fallbackResult) {
23929c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker            return fallbackResult;
23939c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        }
23949c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker        return ::NO_ERROR;
23959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
23969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
239717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker    int32_t generateKey(const String16& name, const KeymasterArguments& params,
2398154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                        const uint8_t* entropy, size_t entropyLength, int uid, int flags,
2399154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                        KeyCharacteristics* outCharacteristics) {
24009489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid = getEffectiveUid(uid);
24019489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid,
24029489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
24039489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (rc != ::NO_ERROR) {
24049489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return rc;
240517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        }
240617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
24079489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        rc = KM_ERROR_UNIMPLEMENTED;
240817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        bool isFallback = false;
240917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        keymaster_key_blob_t blob;
241017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        keymaster_key_characteristics_t *out = NULL;
241117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
241217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        const keymaster1_device_t* device = mKeyStore->getDevice();
241317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice();
241417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        if (device == NULL) {
241517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            return ::SYSTEM_ERROR;
241617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        }
2417154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker        // TODO: Seed from Linux RNG before this.
241817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
241917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker                device->generate_key != NULL) {
2420154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            if (!entropy) {
2421154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = KM_ERROR_OK;
2422154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            } else if (device->add_rng_entropy) {
2423154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = device->add_rng_entropy(device, entropy, entropyLength);
2424154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            } else {
2425154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = KM_ERROR_UNIMPLEMENTED;
2426154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            }
2427154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            if (rc == KM_ERROR_OK) {
2428154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = device->generate_key(device, params.params.data(), params.params.size(),
2429154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                                          &blob, &out);
2430154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            }
243117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        }
243217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        // If the HW device didn't support generate_key or generate_key failed
243317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        // fall back to the software implementation.
243417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        if (rc && fallback->generate_key != NULL) {
243517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            isFallback = true;
2436154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            if (!entropy) {
2437154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = KM_ERROR_OK;
2438154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            } else if (fallback->add_rng_entropy) {
2439154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = fallback->add_rng_entropy(fallback, entropy, entropyLength);
2440154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            } else {
2441154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = KM_ERROR_UNIMPLEMENTED;
2442154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            }
2443154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            if (rc == KM_ERROR_OK) {
2444154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                rc = fallback->generate_key(fallback, params.params.data(), params.params.size(),
2445154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                                            &blob,
2446154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                                            &out);
2447154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            }
244817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        }
244917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
245017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        if (out) {
245117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            if (outCharacteristics) {
245217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker                outCharacteristics->characteristics = *out;
245317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            } else {
245417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker                keymaster_free_characteristics(out);
245517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            }
245617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            free(out);
245717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        }
245817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
245917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        if (rc) {
246017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker            return rc;
246117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        }
246217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
246317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        String8 name8(name);
246417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
246517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
246617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
246717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        keyBlob.setFallback(isFallback);
246817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
246917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
247017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker        free(const_cast<uint8_t*>(blob.key_material));
247117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker
247272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
24739899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
24749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
2475f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker    int32_t getKeyCharacteristics(const String16& name,
2476d663442b590b59250062335cc057478001b8e439Chad Brubaker                                  const keymaster_blob_t* clientId,
2477d663442b590b59250062335cc057478001b8e439Chad Brubaker                                  const keymaster_blob_t* appData,
2478f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker                                  KeyCharacteristics* outCharacteristics) {
2479f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        if (!outCharacteristics) {
2480f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker            return KM_ERROR_UNEXPECTED_NULL_POINTER;
2481f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        }
2482f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker
2483f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2484f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker
2485f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        Blob keyBlob;
2486f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        String8 name8(name);
2487f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        int rc;
2488f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker
2489f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
2490f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker                TYPE_KEYMASTER_10);
2491f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        if (responseCode != ::NO_ERROR) {
2492f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker            return responseCode;
2493f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        }
2494f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        keymaster_key_blob_t key;
2495f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        key.key_material_size = keyBlob.getLength();
2496f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        key.key_material = keyBlob.getValue();
2497f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob);
2498f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        keymaster_key_characteristics_t *out = NULL;
2499f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        if (!dev->get_key_characteristics) {
2500f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker            ALOGW("device does not implement get_key_characteristics");
2501f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker            return KM_ERROR_UNIMPLEMENTED;
2502f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        }
2503d663442b590b59250062335cc057478001b8e439Chad Brubaker        rc = dev->get_key_characteristics(dev, &key, clientId, appData, &out);
2504f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        if (out) {
2505f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker            outCharacteristics->characteristics = *out;
2506f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker            free(out);
2507f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        }
2508f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker        return rc ? rc : ::NO_ERROR;
25099899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
25109899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
25114c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker    int32_t importKey(const String16& name, const KeymasterArguments& params,
25124c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                                keymaster_key_format_t format, const uint8_t *keyData,
25134c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                                size_t keyLength, int uid, int flags,
25144c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                                KeyCharacteristics* outCharacteristics) {
25159489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid = getEffectiveUid(uid);
25169489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid,
25179489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
25189489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (rc != ::NO_ERROR) {
25199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return rc;
25204c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        }
25214c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker
25229489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        rc = KM_ERROR_UNIMPLEMENTED;
25234c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        bool isFallback = false;
25244c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        keymaster_key_blob_t blob;
25254c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        keymaster_key_characteristics_t *out = NULL;
25264c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker
25274c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        const keymaster1_device_t* device = mKeyStore->getDevice();
25284c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice();
25294c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        if (device == NULL) {
25304c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            return ::SYSTEM_ERROR;
25314c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        }
25324c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
25334c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                device->import_key != NULL) {
25344c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            rc = device->import_key(device, params.params.data(), params.params.size(),
25354c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                                    format, keyData, keyLength, &blob, &out);
25364c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        }
25374c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        if (rc && fallback->import_key != NULL) {
25384c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            isFallback = true;
25394c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            rc = fallback->import_key(fallback, params.params.data(), params.params.size(),
25404c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                                      format, keyData, keyLength, &blob, &out);
25414c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        }
25424c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        if (out) {
25434c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            if (outCharacteristics) {
25444c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                outCharacteristics->characteristics = *out;
25454c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            } else {
25464c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker                keymaster_free_characteristics(out);
25474c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            }
25484c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            free(out);
25494c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        }
25504c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        if (rc) {
25514c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker            return rc;
25524c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        }
25534c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker
25544c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        String8 name8(name);
25554c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
25564c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker
25574c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
25584c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        keyBlob.setFallback(isFallback);
25594c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
25604c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker
25614c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker        free((void*) blob.key_material);
25624c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker
256372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
25649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
25659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
256607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker    void exportKey(const String16& name, keymaster_key_format_t format,
2567d663442b590b59250062335cc057478001b8e439Chad Brubaker                           const keymaster_blob_t* clientId,
2568d663442b590b59250062335cc057478001b8e439Chad Brubaker                           const keymaster_blob_t* appData, ExportResult* result) {
256907b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker
257007b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
257107b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker
257207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        Blob keyBlob;
257307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        String8 name8(name);
257407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        int rc;
257507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker
257607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
257707b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker                TYPE_KEYMASTER_10);
257807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        if (responseCode != ::NO_ERROR) {
257907b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker            result->resultCode = responseCode;
258007b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker            return;
258107b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        }
258207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        keymaster_key_blob_t key;
258307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        key.key_material_size = keyBlob.getLength();
258407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        key.key_material = keyBlob.getValue();
258507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob);
258607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        if (!dev->export_key) {
258707b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker            result->resultCode = KM_ERROR_UNIMPLEMENTED;
258807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker            return;
258907b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        }
259007b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        uint8_t* ptr = NULL;
2591d663442b590b59250062335cc057478001b8e439Chad Brubaker        rc = dev->export_key(dev, format, &key, clientId, appData,
259207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker                                             &ptr, &result->dataLength);
259307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        result->exportData.reset(ptr);
259407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker        result->resultCode = rc ? rc : ::NO_ERROR;
25959899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
25969899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
2597ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker
259840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    void begin(const sp<IBinder>& appToken, const String16& name, keymaster_purpose_t purpose,
2599154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker               bool pruneable, const KeymasterArguments& params, const uint8_t* entropy,
2600154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker               size_t entropyLength, KeymasterArguments* outParams, OperationResult* result) {
260140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        if (!result || !outParams) {
260240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            ALOGE("Unexpected null arguments to begin()");
260340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return;
260440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
260540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
260640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
260740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
260840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            result->resultCode = ::PERMISSION_DENIED;
260940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return;
261040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
26110cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (!checkAllowedOperationParams(params.params)) {
26120cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            result->resultCode = KM_ERROR_INVALID_ARGUMENT;
26130cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            return;
26140cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
261540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        Blob keyBlob;
261640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        String8 name8(name);
261740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
261840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker                TYPE_KEYMASTER_10);
261940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        if (responseCode != ::NO_ERROR) {
262040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            result->resultCode = responseCode;
262140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return;
262240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
262340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        keymaster_key_blob_t key;
262440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        key.key_material_size = keyBlob.getLength();
262540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        key.key_material = keyBlob.getValue();
262640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        keymaster_key_param_t* out;
262740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        size_t outSize;
262840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        keymaster_operation_handle_t handle;
262940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob);
2630154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker        keymaster_error_t err = KM_ERROR_UNIMPLEMENTED;
263106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        std::vector<keymaster_key_param_t> opParams(params.params);
2632ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        Unique_keymaster_key_characteristics characteristics;
2633ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        characteristics.reset(new keymaster_key_characteristics_t);
2634ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        err = getOperationCharacteristics(key, dev, opParams, characteristics.get());
2635ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        if (err) {
2636ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker            result->resultCode = err;
2637ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker            return;
2638ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        }
26390cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        const hw_auth_token_t* authToken = NULL;
26400cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        int32_t authResult = getAuthToken(characteristics.get(), 0, &authToken,
264106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker                                                /*failOnTokenMissing*/ false);
26420cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // If per-operation auth is needed we need to begin the operation and
26430cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // the client will need to authorize that operation before calling
26440cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // update. Any other auth issues stop here.
26450cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (authResult != ::NO_ERROR && authResult != ::OP_AUTH_NEEDED) {
26460cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            result->resultCode = authResult;
264706801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker            return;
264806801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        }
26490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        addAuthToParams(&opParams, authToken);
2650154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker        // Add entropy to the device first.
2651154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker        if (entropy) {
2652154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            if (dev->add_rng_entropy) {
2653154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                err = dev->add_rng_entropy(dev, entropy, entropyLength);
2654154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            } else {
2655154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                err = KM_ERROR_UNIMPLEMENTED;
2656154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            }
2657154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            if (err) {
2658154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                result->resultCode = err;
2659154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker                return;
2660154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker            }
2661154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker        }
266206801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        err = dev->begin(dev, purpose, &key, opParams.data(), opParams.size(), &out, &outSize,
266306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker                         &handle);
266440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker
266540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        // If there are too many operations abort the oldest operation that was
266640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        // started as pruneable and try again.
266740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        while (err == KM_ERROR_TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) {
266840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation();
266940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            ALOGD("Ran out of operation handles, trying to prune %p", oldest.get());
267040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            if (abort(oldest) != ::NO_ERROR) {
267140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker                break;
267240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            }
26730cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            err = dev->begin(dev, purpose, &key, opParams.data(), opParams.size(), &out, &outSize,
267440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker                             &handle);
267540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
267640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        if (err) {
267740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            result->resultCode = err;
267840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return;
267940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
268040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        if (out) {
268140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            outParams->params.assign(out, out + outSize);
268240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            free(out);
268340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
26849899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
2685ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        sp<IBinder> operationToken = mOperationMap.addOperation(handle, dev, appToken,
2686ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker                                                                characteristics.release(),
268706801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker                                                                pruneable);
26880cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (authToken) {
26890cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            mOperationMap.setOperationAuthToken(operationToken, authToken);
26900cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
26910cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // Return the authentication lookup result. If this is a per operation
26920cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the
26930cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // application should get an auth token using the handle before the
26940cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // first call to update, which will fail if keystore hasn't received the
26950cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        // auth token.
26960cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        result->resultCode = authResult;
269740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->token = operationToken;
2698c3a1856bbe2e39d5b3430f5f088b12fd710a159fChad Brubaker        result->handle = handle;
26999899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
27009899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
270140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    void update(const sp<IBinder>& token, const KeymasterArguments& params, const uint8_t* data,
270240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker                size_t dataLength, OperationResult* result) {
27030cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (!checkAllowedOperationParams(params.params)) {
27040cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            result->resultCode = KM_ERROR_INVALID_ARGUMENT;
27050cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            return;
27060cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
270740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        const keymaster1_device_t* dev;
270840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        keymaster_operation_handle_t handle;
27090cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (!mOperationMap.getOperation(token, &handle, &dev, NULL)) {
271040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
271140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return;
271240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
271340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        uint8_t* output_buf = NULL;
271440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        size_t output_length = 0;
271540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        size_t consumed = 0;
271606801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        std::vector<keymaster_key_param_t> opParams(params.params);
27170cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams);
27180cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (authResult != ::NO_ERROR) {
271906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker            result->resultCode = authResult;
272006801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker            return;
272106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        }
272206801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        keymaster_error_t err = dev->update(dev, handle, opParams.data(), opParams.size(), data,
272306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker                                            dataLength, &consumed, &output_buf, &output_length);
272440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->data.reset(output_buf);
272540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->dataLength = output_length;
272640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->inputConsumed = consumed;
272740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->resultCode = err ? (int32_t) err : ::NO_ERROR;
272840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    }
272940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker
273040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    void finish(const sp<IBinder>& token, const KeymasterArguments& params,
273140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker                const uint8_t* signature, size_t signatureLength, OperationResult* result) {
27320cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (!checkAllowedOperationParams(params.params)) {
27330cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            result->resultCode = KM_ERROR_INVALID_ARGUMENT;
27340cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            return;
27350cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
273640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        const keymaster1_device_t* dev;
273740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        keymaster_operation_handle_t handle;
27380cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (!mOperationMap.getOperation(token, &handle, &dev, NULL)) {
273940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
274040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return;
274140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
274240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        uint8_t* output_buf = NULL;
274340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        size_t output_length = 0;
274406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        std::vector<keymaster_key_param_t> opParams(params.params);
27450cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams);
27460cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (authResult != ::NO_ERROR) {
274706801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker            result->resultCode = authResult;
274806801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker            return;
274906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        }
27500cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker
275106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        keymaster_error_t err = dev->finish(dev, handle, opParams.data(), opParams.size(),
275206801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker                                            signature, signatureLength, &output_buf,
275306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker                                            &output_length);
275440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        // Remove the operation regardless of the result
275540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        mOperationMap.removeOperation(token);
275606801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        mAuthTokenTable.MarkCompleted(handle);
275740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->data.reset(output_buf);
275840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->dataLength = output_length;
275940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        result->resultCode = err ? (int32_t) err : ::NO_ERROR;
276040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    }
276140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker
276240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    int32_t abort(const sp<IBinder>& token) {
276340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        const keymaster1_device_t* dev;
276440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        keymaster_operation_handle_t handle;
276506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        if (!mOperationMap.getOperation(token, &handle, &dev, NULL)) {
276640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return KM_ERROR_INVALID_OPERATION_HANDLE;
276740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
276840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        mOperationMap.removeOperation(token);
276906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        int32_t rc;
277040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        if (!dev->abort) {
277106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker            rc = KM_ERROR_UNIMPLEMENTED;
277206801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        } else {
277306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker            rc = dev->abort(dev, handle);
277440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
277506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        mAuthTokenTable.MarkCompleted(handle);
277640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        if (rc) {
277740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker            return rc;
277840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        }
277940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker        return ::NO_ERROR;
27809899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker    }
27819899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker
27822ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    bool isOperationAuthorized(const sp<IBinder>& token) {
27832ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        const keymaster1_device_t* dev;
27842ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        keymaster_operation_handle_t handle;
2785ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        const keymaster_key_characteristics_t* characteristics;
2786ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker        if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
27872ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker            return false;
27882ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker        }
27890cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        const hw_auth_token_t* authToken = NULL;
27900cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        mOperationMap.getOperationAuthToken(token, &authToken);
279106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker        std::vector<keymaster_key_param_t> ignored;
27920cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        int32_t authResult = addOperationAuthTokenIfNeeded(token, &ignored);
27930cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        return authResult == ::NO_ERROR;
27942ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    }
27952ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker
2796d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker    int32_t addAuthToken(const uint8_t* token, size_t length) {
27979489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(P_ADD_AUTH)) {
27989489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            ALOGW("addAuthToken: permission denied for %d",
27999489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker                  IPCThreadState::self()->getCallingUid());
2800d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker            return ::PERMISSION_DENIED;
2801d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        }
2802d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        if (length != sizeof(hw_auth_token_t)) {
2803d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker            return KM_ERROR_INVALID_ARGUMENT;
2804d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        }
2805d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        hw_auth_token_t* authToken = new hw_auth_token_t;
2806d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        memcpy(reinterpret_cast<void*>(authToken), token, sizeof(hw_auth_token_t));
2807d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        // The table takes ownership of authToken.
2808d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        mAuthTokenTable.AddAuthenticationToken(authToken);
2809d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker        return ::NO_ERROR;
28102ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker    }
28112ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker
281207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate:
28139489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    static const int32_t UID_SELF = -1;
28149489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
28159489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    /**
28169489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * Get the effective target uid for a binder operation that takes an
28179489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * optional uid as the target.
28189489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     */
28199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    inline uid_t getEffectiveUid(int32_t targetUid) {
28209489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (targetUid == UID_SELF) {
28219489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return IPCThreadState::self()->getCallingUid();
28229489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        }
28239489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        return static_cast<uid_t>(targetUid);
28249489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    }
28259489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
28269489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    /**
28279489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * Check if the caller of the current binder method has the required
28289489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * permission and if acting on other uids the grants to do so.
28299489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     */
28309489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    inline bool checkBinderPermission(perm_t permission, int32_t targetUid = UID_SELF) {
28319489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
28329489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        pid_t spid = IPCThreadState::self()->getCallingPid();
28339489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!has_permission(callingUid, permission, spid)) {
28349489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
28359489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return false;
28369489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        }
28379489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!is_granted_to(callingUid, getEffectiveUid(targetUid))) {
28389489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            ALOGW("uid %d not granted to act for %d", callingUid, targetUid);
28399489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return false;
28409489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        }
28419489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        return true;
28429489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    }
28439489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
28449489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    /**
28459489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * Check if the caller of the current binder method has the required
2846b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker     * permission and the target uid is the caller or the caller is system.
2847b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker     */
2848b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker    inline bool checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid) {
2849b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
2850b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker        pid_t spid = IPCThreadState::self()->getCallingPid();
2851b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker        if (!has_permission(callingUid, permission, spid)) {
2852b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker            ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
2853b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker            return false;
2854b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker        }
2855b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker        return getEffectiveUid(targetUid) == callingUid || callingUid == AID_SYSTEM;
2856b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker    }
2857b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker
2858b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker    /**
2859b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker     * Check if the caller of the current binder method has the required
28609489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * permission or the target of the operation is the caller's uid. This is
28619489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * for operation where the permission is only for cross-uid activity and all
28629489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * uids are allowed to act on their own (ie: clearing all entries for a
28639489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * given uid).
28649489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     */
28659489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    inline bool checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid) {
28669489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        uid_t callingUid = IPCThreadState::self()->getCallingUid();
28679489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (getEffectiveUid(targetUid) == callingUid) {
28689489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return true;
28699489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        } else {
28709489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return checkBinderPermission(permission, targetUid);
28719489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        }
28729489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    }
28739489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
28749489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    /**
28759489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * Helper method to check that the caller has the required permission as
28769489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * well as the keystore is in the unlocked state if checkUnlocked is true.
28779489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     *
28789489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and
28799489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * otherwise the state of keystore when not unlocked and checkUnlocked is
28809489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     * true.
28819489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker     */
28829489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    inline int32_t checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid = -1,
28839489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker                                                 bool checkUnlocked = true) {
28849489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (!checkBinderPermission(permission, targetUid)) {
28859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return ::PERMISSION_DENIED;
28869489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        }
288772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker        State state = mKeyStore->getState(get_user_id(getEffectiveUid(targetUid)));
28889489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        if (checkUnlocked && !isKeystoreUnlocked(state)) {
28899489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker            return state;
28909489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        }
28919489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
28929489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker        return ::NO_ERROR;
28939489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
28949489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker    }
28959489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker
28969d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root    inline bool isKeystoreUnlocked(State state) {
28979d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        switch (state) {
28989d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        case ::STATE_NO_ERROR:
28999d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root            return true;
29009d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        case ::STATE_UNINITIALIZED:
29019d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        case ::STATE_LOCKED:
29029d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root            return false;
29039d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        }
29049d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root        return false;
2905a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
290607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
290767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    bool isKeyTypeSupported(const keymaster1_device_t* device, keymaster_keypair_t keyType) {
29081d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        const int32_t device_api = device->common.module->module_api_version;
29091d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) {
29101d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            switch (keyType) {
29111d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_RSA:
29121d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_DSA:
29131d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_EC:
29141d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return true;
29151d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                default:
29161d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return false;
29171d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            }
29181d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) {
29191d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            switch (keyType) {
29201d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_RSA:
29211d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return true;
29221d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_DSA:
29231d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return device->flags & KEYMASTER_SUPPORTS_DSA;
29241d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                case TYPE_EC:
29251d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return device->flags & KEYMASTER_SUPPORTS_EC;
29261d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                default:
29271d448c074a86ef5d05a22fdf1358718976628a86Kenny Root                    return false;
29281d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            }
29291d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        } else {
29301d448c074a86ef5d05a22fdf1358718976628a86Kenny Root            return keyType == TYPE_RSA;
29311d448c074a86ef5d05a22fdf1358718976628a86Kenny Root        }
29321d448c074a86ef5d05a22fdf1358718976628a86Kenny Root    }
29331d448c074a86ef5d05a22fdf1358718976628a86Kenny Root
29340cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    /**
29350cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * Check that all keymaster_key_param_t's provided by the application are
29360cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * allowed. Any parameter that keystore adds itself should be disallowed here.
29370cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     */
29380cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    bool checkAllowedOperationParams(const std::vector<keymaster_key_param_t>& params) {
29390cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        for (auto param: params) {
29400cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            switch (param.tag) {
29410cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                case KM_TAG_AUTH_TOKEN:
29420cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                    return false;
29430cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                default:
29440cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                    break;
29450cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            }
29460cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
29470cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        return true;
29480cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    }
29490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker
29500cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    keymaster_error_t getOperationCharacteristics(const keymaster_key_blob_t& key,
29510cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                    const keymaster1_device_t* dev,
29520cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                    const std::vector<keymaster_key_param_t>& params,
29530cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                    keymaster_key_characteristics_t* out) {
29540cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        UniquePtr<keymaster_blob_t> appId;
29550cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        UniquePtr<keymaster_blob_t> appData;
29560cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        for (auto param : params) {
29570cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            if (param.tag == KM_TAG_APPLICATION_ID) {
29580cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                appId.reset(new keymaster_blob_t);
29590cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                appId->data = param.blob.data;
29600cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                appId->data_length = param.blob.data_length;
29610cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            } else if (param.tag == KM_TAG_APPLICATION_DATA) {
29620cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                appData.reset(new keymaster_blob_t);
29630cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                appData->data = param.blob.data;
29640cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                appData->data_length = param.blob.data_length;
29650cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            }
29660cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
29670cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        keymaster_key_characteristics_t* result = NULL;
29680cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (!dev->get_key_characteristics) {
29690cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            return KM_ERROR_UNIMPLEMENTED;
29700cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
29710cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        keymaster_error_t error = dev->get_key_characteristics(dev, &key, appId.get(),
29720cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                                               appData.get(), &result);
29730cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (result) {
29740cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            *out = *result;
29750cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            free(result);
29760cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
29770cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        return error;
29780cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    }
29790cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker
29800cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    /**
29810cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * Get the auth token for this operation from the auth token table.
29820cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *
29830cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * Returns ::NO_ERROR if the auth token was set or none was required.
29840cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         ::OP_AUTH_NEEDED if it is a per op authorization, no
29850cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         authorization token exists for that operation and
29860cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         failOnTokenMissing is false.
29870cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
29880cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         token for the operation
29890cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     */
29900cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    int32_t getAuthToken(const keymaster_key_characteristics_t* characteristics,
29910cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                         keymaster_operation_handle_t handle,
29920cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                         const hw_auth_token_t** authToken,
29930cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                         bool failOnTokenMissing = true) {
29940cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker
29950cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        std::vector<keymaster_key_param_t> allCharacteristics;
29960cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        for (size_t i = 0; i < characteristics->sw_enforced.length; i++) {
29970cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            allCharacteristics.push_back(characteristics->sw_enforced.params[i]);
29980cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
29990cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        for (size_t i = 0; i < characteristics->hw_enforced.length; i++) {
30000cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            allCharacteristics.push_back(characteristics->hw_enforced.params[i]);
30010cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
30020cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        keymaster::AuthTokenTable::Error err =
30030cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                mAuthTokenTable.FindAuthorization(allCharacteristics.data(),
30040cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                                  allCharacteristics.size(), handle, authToken);
30050cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        switch (err) {
30060cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            case keymaster::AuthTokenTable::OK:
30070cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            case keymaster::AuthTokenTable::AUTH_NOT_REQUIRED:
30080cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                return ::NO_ERROR;
30090cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            case keymaster::AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
30100cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            case keymaster::AuthTokenTable::AUTH_TOKEN_EXPIRED:
30110cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            case keymaster::AuthTokenTable::AUTH_TOKEN_WRONG_SID:
30120cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                return KM_ERROR_KEY_USER_NOT_AUTHENTICATED;
30130cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            case keymaster::AuthTokenTable::OP_HANDLE_REQUIRED:
30140cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                return failOnTokenMissing ? (int32_t) KM_ERROR_KEY_USER_NOT_AUTHENTICATED :
30150cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                        (int32_t) ::OP_AUTH_NEEDED;
30160cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            default:
30170cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                ALOGE("Unexpected FindAuthorization return value %d", err);
30180cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                return KM_ERROR_INVALID_ARGUMENT;
30190cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
30200cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    }
30210cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker
30220cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    inline void addAuthToParams(std::vector<keymaster_key_param_t>* params,
30230cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                const hw_auth_token_t* token) {
30240cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        if (token) {
30250cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            params->push_back(keymaster_param_blob(KM_TAG_AUTH_TOKEN,
30260cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                                   reinterpret_cast<const uint8_t*>(token),
30270cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                                   sizeof(hw_auth_token_t)));
30280cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
30290cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    }
30300cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker
30310cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    /**
30320cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * Add the auth token for the operation to the param list if the operation
30330cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * requires authorization. Uses the cached result in the OperationMap if available
30340cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * otherwise gets the token from the AuthTokenTable and caches the result.
30350cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *
30360cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     * Returns ::NO_ERROR if the auth token was added or not needed.
30370cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not
30380cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         authenticated.
30390cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
30400cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     *         operation token.
30410cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker     */
30420cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    int32_t addOperationAuthTokenIfNeeded(sp<IBinder> token,
30430cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                                          std::vector<keymaster_key_param_t>* params) {
30440cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        const hw_auth_token_t* authToken = NULL;
30457169a8470f6539036addf3c960b075af224e83e2Chad Brubaker        mOperationMap.getOperationAuthToken(token, &authToken);
30467169a8470f6539036addf3c960b075af224e83e2Chad Brubaker        if (!authToken) {
30470cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            const keymaster1_device_t* dev;
30480cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            keymaster_operation_handle_t handle;
30490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            const keymaster_key_characteristics_t* characteristics = NULL;
30500cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
30510cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                return KM_ERROR_INVALID_OPERATION_HANDLE;
30520cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            }
30530cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            int32_t result = getAuthToken(characteristics, handle, &authToken);
30540cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            if (result != ::NO_ERROR) {
30550cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                return result;
30560cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            }
30570cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            if (authToken) {
30580cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker                mOperationMap.setOperationAuthToken(token, authToken);
30590cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker            }
30600cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        }
30610cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        addAuthToParams(params, authToken);
30620cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker        return ::NO_ERROR;
30630cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker    }
30640cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker
306507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    ::KeyStore* mKeyStore;
306640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker    OperationMap mOperationMap;
3067d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker    keymaster::AuthTokenTable mAuthTokenTable;
306807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root};
306907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root
307007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android
3071a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3072a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) {
3073a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (argc < 2) {
3074a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("A directory must be specified!");
3075a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
3076a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
3077a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (chdir(argv[1]) == -1) {
3078a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        ALOGE("chdir: %s: %s", argv[1], strerror(errno));
3079a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
3080a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
3081a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root
3082a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    Entropy entropy;
3083a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    if (!entropy.open()) {
3084a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root        return 1;
3085a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
308670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
308780843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden    keymaster0_device_t* dev;
308870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (keymaster_device_initialize(&dev)) {
308970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("keystore keymaster could not be initialized; exiting");
309070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return 1;
309170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
309270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
309367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    keymaster1_device_t* fallback;
3094fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker    if (fallback_keymaster_device_initialize(&fallback)) {
3095fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker        ALOGE("software keymaster could not be initialized; exiting");
3096fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker        return 1;
3097fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker    }
3098fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker
3099eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    ks_is_selinux_enabled = is_selinux_enabled();
3100eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    if (ks_is_selinux_enabled) {
3101eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        union selinux_callback cb;
3102eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        cb.func_log = selinux_log_callback;
3103eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        selinux_set_callback(SELINUX_CB_LOG, cb);
3104eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        if (getcon(&tctx) != 0) {
3105eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n");
3106eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn            return -1;
3107eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        }
3108eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    } else {
3109eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn        ALOGI("SELinux: Keystore SELinux is disabled.\n");
3110eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn    }
3111eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn
311267d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker    KeyStore keyStore(&entropy, reinterpret_cast<keymaster1_device_t*>(dev), fallback);
3113655b958eb2180c7c06889f83f606d23421bf038cKenny Root    keyStore.initialize();
311407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::sp<android::IServiceManager> sm = android::defaultServiceManager();
311507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
311607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy);
311707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    if (ret != android::OK) {
311807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        ALOGE("Couldn't register binder service!");
311907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root        return -1;
3120a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    }
312170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
312207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    /*
312307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * We're the only thread in existence, so we're just going to process
312407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     * Binder transaction as a single-threaded program.
312507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root     */
312607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    android::IPCThreadState::self()->joinThreadPool();
312770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
312807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root    keymaster_device_release(dev);
3129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root    return 1;
3130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}
3131