keystore.cpp revision 7c1eb75a6898452867ca28a4d7fad2d91edca615
1a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* 2a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Copyright (C) 2009 The Android Open Source Project 3a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 4a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * you may not use this file except in compliance with the License. 6a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * You may obtain a copy of the License at 7a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 8a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 10a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Unless required by applicable law or agreed to in writing, software 11a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * See the License for the specific language governing permissions and 14a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * limitations under the License. 15a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root */ 16a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root//#define LOG_NDEBUG 0 1807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#define LOG_TAG "keystore" 1907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h> 21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h> 22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h> 23aaf9802da6cea710e0777abb852724e1825cad63Elliott Hughes#include <strings.h> 24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h> 25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h> 26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h> 27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h> 28655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <errno.h> 29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 31822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 37a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 39822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 40a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 42822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 43a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h> 4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4617208e0de5a42722901d803118745cca25fd10c1Kenny Root#include <keymaster/softkeymaster.h> 4717208e0de5a42722901d803118745cca25fd10c1Kenny Root 4826cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h> 49655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h> 50655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h> 5170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 5207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 5307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 62eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn#include <selinux/android.h> 63eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 6496427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h" 6596427baf0094d50047049d329b0779c3c910402cKenny Root 66a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 68a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 69a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 70a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 71a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 72a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 73a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 74a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 75a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 7796427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete { 7896427baf0094d50047049d329b0779c3c910402cKenny Root void operator()(BIGNUM* p) const { 7996427baf0094d50047049d329b0779c3c910402cKenny Root BN_free(p); 8096427baf0094d50047049d329b0779c3c910402cKenny Root } 8196427baf0094d50047049d329b0779c3c910402cKenny Root}; 8296427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM; 8396427baf0094d50047049d329b0779c3c910402cKenny Root 84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubakerstatic int fallback_keymaster_device_initialize(keymaster_device_t** dev) { 131fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker int rc; 132fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = openssl_open(reinterpret_cast<hw_module_t*>(&softkeymaster_module), 133fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker KEYSTORE_KEYMASTER, 134fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker reinterpret_cast<hw_device_t**>(dev)); 135fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker if (rc) { 136fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker ALOGE("could not open softkeymaster device (%s)", 137fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker strerror(-rc)); 138fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker goto out; 139fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 140fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 0; 141fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubakerout: 142fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker *dev = NULL; 143fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return rc; 144fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker} 145fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 14970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 15007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 15107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 15207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 15507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 1564e865753346fc6a075966972a7a98051818859dbRobin Lee P_TEST = 1 << 0, 1574e865753346fc6a075966972a7a98051818859dbRobin Lee P_GET = 1 << 1, 1584e865753346fc6a075966972a7a98051818859dbRobin Lee P_INSERT = 1 << 2, 1594e865753346fc6a075966972a7a98051818859dbRobin Lee P_DELETE = 1 << 3, 1604e865753346fc6a075966972a7a98051818859dbRobin Lee P_EXIST = 1 << 4, 1614e865753346fc6a075966972a7a98051818859dbRobin Lee P_SAW = 1 << 5, 1624e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET = 1 << 6, 1634e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD = 1 << 7, 1644e865753346fc6a075966972a7a98051818859dbRobin Lee P_LOCK = 1 << 8, 1654e865753346fc6a075966972a7a98051818859dbRobin Lee P_UNLOCK = 1 << 9, 1664e865753346fc6a075966972a7a98051818859dbRobin Lee P_ZERO = 1 << 10, 1674e865753346fc6a075966972a7a98051818859dbRobin Lee P_SIGN = 1 << 11, 1684e865753346fc6a075966972a7a98051818859dbRobin Lee P_VERIFY = 1 << 12, 1694e865753346fc6a075966972a7a98051818859dbRobin Lee P_GRANT = 1 << 13, 1704e865753346fc6a075966972a7a98051818859dbRobin Lee P_DUPLICATE = 1 << 14, 1714e865753346fc6a075966972a7a98051818859dbRobin Lee P_CLEAR_UID = 1 << 15, 1724e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET_UID = 1 << 16, 1734e865753346fc6a075966972a7a98051818859dbRobin Lee P_SYNC_UID = 1 << 17, 1744e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD_UID = 1 << 18, 17507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 17607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 17807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 17907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 18007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 18107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 18207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 18407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 18507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 186eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */ 187eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = { 188eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "test", 189eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "get", 190eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "insert", 191eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "delete", 192eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "exist", 193eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "saw", 194eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "reset", 195eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "password", 196eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "lock", 197eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "unlock", 198eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "zero", 199eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "sign", 200eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "verify", 201eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "grant", 202eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "duplicate", 2034e865753346fc6a075966972a7a98051818859dbRobin Lee "clear_uid", 2044e865753346fc6a075966972a7a98051818859dbRobin Lee "reset_uid", 2054e865753346fc6a075966972a7a98051818859dbRobin Lee "sync_uid", 2064e865753346fc6a075966972a7a98051818859dbRobin Lee "password_uid", 207eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}; 208eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 20907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 21007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 21107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 21207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 21507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 21607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 21707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 21807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 21907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 22007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 22107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 222eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx; 223eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled; 224eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 225eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) { 226eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn unsigned int index = ffs(perm); 227eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) { 228eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return perm_labels[index - 1]; 229eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 230eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("Keystore: Failed to retrieve permission label.\n"); 231eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn abort(); 232eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 233eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 234eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 235655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 236655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 237655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 238655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 239655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 240655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 241655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 242655b958eb2180c7c06889f83f606d23421bf038cKenny Root 243655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 244655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 245655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 246655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 247655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 248655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 249655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 250655b958eb2180c7c06889f83f606d23421bf038cKenny Root 251a25b2a397fff48dea7bce16af2065e6f5f043956Chih-Hung Hsiehstatic bool keystore_selinux_check_access(uid_t /*uid*/, perm_t perm, pid_t spid) { 252eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!ks_is_selinux_enabled) { 253eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return true; 254eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 255eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 256eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn char *sctx = NULL; 257eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *selinux_class = "keystore_key"; 258eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *str_perm = get_perm_label(perm); 259eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 260eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!str_perm) { 261eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 262eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 263eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 264eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getpidcon(spid, &sctx) != 0) { 265eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Failed to get source pid context.\n"); 266eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 267eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 26866dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 269eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm, 270eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn NULL) == 0; 271eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn freecon(sctx); 272eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return allowed; 273eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 274eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 275eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) { 276655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 277655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 278655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 279655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 280655b958eb2180c7c06889f83f606d23421bf038cKenny Root 28107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 284eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (user.perms & perm) && 285eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 289eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (DEFAULT_PERMS & perm) && 290eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 29207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 293494689083467ec372a58f094f041c8f102f39393Kenny Root/** 294494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 295494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 296494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 297494689083467ec372a58f094f041c8f102f39393Kenny Root */ 29807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 29907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 30007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 30107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 30207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 30307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 30407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 30507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 30607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 30707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 30807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 309494689083467ec372a58f094f041c8f102f39393Kenny Root/** 310494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 311494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 312494689083467ec372a58f094f041c8f102f39393Kenny Root */ 313494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 314494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 315494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 316494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 317494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 318494689083467ec372a58f094f041c8f102f39393Kenny Root } 319494689083467ec372a58f094f041c8f102f39393Kenny Root } 320494689083467ec372a58f094f041c8f102f39393Kenny Root 321494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 322494689083467ec372a58f094f041c8f102f39393Kenny Root} 323494689083467ec372a58f094f041c8f102f39393Kenny Root 324007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root/** 325007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * Allow the system to perform some privileged tasks that have to do with 326007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * system maintenance. This should not be used for any function that uses 327007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * the keys in any way (e.g., signing). 328007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root */ 329007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Rootstatic bool is_self_or_system(uid_t callingUid, uid_t targetUid) { 330007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root return callingUid == targetUid || callingUid == AID_SYSTEM; 331007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root} 332007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 340655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 341655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 342655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 343655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 344655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 345655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 346655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 347655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 348655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 349655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 350655b958eb2180c7c06889f83f606d23421bf038cKenny Root 35107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 35207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 35307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 355655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 359655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 360655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 36470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 36570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 36670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 36707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 37707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 37807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 37907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 38007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 38107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 38207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 38307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 38407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 38507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 38607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 38707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 38807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 38907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 39007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 39107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 39207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 39307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 39407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 39507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 39607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 39807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 407150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 4085281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 409150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 420150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 421150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 422150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 423150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 435150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 442150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 443150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4505187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 463f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 478822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 483822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 484f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 495d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 496822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 497822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 499822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 500822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 501f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 502822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 50507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 50607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 512822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 51307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 514822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 515f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 516ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 517ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 518ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 519ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 520ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5295187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5335187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5375187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 5385187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 5395187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 5405187818895c4c5f650a611c40531b1dff7764c18Kenny Root 5415187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 545822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 546822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 547822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 548822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 549f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 550f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 551f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 552f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 553f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 554f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 555f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 556f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 557f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 558f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 559f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 560f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 561f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 562f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 563f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 564f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 56517208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 56617208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 56717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 56817208e0de5a42722901d803118745cca25fd10c1Kenny Root 56917208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 57017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 57117208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 57217208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 57317208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 57417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 57517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 57617208e0de5a42722901d803118745cca25fd10c1Kenny Root 577822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 578822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 579822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 580822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 581822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 582822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 583822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 584822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 585822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 586822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 587822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 588822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 589f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 593f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 595f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 596f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 597f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 598f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 599f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 600f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 617f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 618f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 619f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 620f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 621f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 622f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 623f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 624f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 630150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 631150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 632150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 633150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 641150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 645150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 646150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 647150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 648150ca934edb745de3666a6492b039900df228ff0Kenny Root } 649150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 652f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 653f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 654150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 655150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 665f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 666f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 667f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 668f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 669f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 676f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 679f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 680f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 681f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 682f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 683f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 684f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 685f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 686f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 687f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 688f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 689f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 690f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 691f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 692f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 693f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 694f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 695f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 70707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 709a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 714655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 715655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 716655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 717655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 718655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 719655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 72070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 721655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 722655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 723655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 724655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 72570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 726655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 727655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 728655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 729655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 730655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 731655b958eb2180c7c06889f83f606d23421bf038cKenny Root 732655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 733a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 735a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 73770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 738655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 739655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root 741655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 742655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 743655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 744655b958eb2180c7c06889f83f606d23421bf038cKenny Root 745655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 746655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 748655b958eb2180c7c06889f83f606d23421bf038cKenny Root 749655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 750655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 751655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 752655b958eb2180c7c06889f83f606d23421bf038cKenny Root 753655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 754655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 755655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 756655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 757655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7605187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7645187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 768655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 769655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 770655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 771655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 772655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 77370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 77470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 775655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 776655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 779655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 78407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7874e865753346fc6a075966972a7a98051818859dbRobin Lee ResponseCode copyMasterKey(UserState* src) { 7884e865753346fc6a075966972a7a98051818859dbRobin Lee if (mState != STATE_UNINITIALIZED) { 7894e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7904e865753346fc6a075966972a7a98051818859dbRobin Lee } 7914e865753346fc6a075966972a7a98051818859dbRobin Lee if (src->getState() != STATE_NO_ERROR) { 7924e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7934e865753346fc6a075966972a7a98051818859dbRobin Lee } 7944e865753346fc6a075966972a7a98051818859dbRobin Lee memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES); 7954e865753346fc6a075966972a7a98051818859dbRobin Lee setupMasterKeys(); 7964e865753346fc6a075966972a7a98051818859dbRobin Lee return ::NO_ERROR; 7974e865753346fc6a075966972a7a98051818859dbRobin Lee } 7984e865753346fc6a075966972a7a98051818859dbRobin Lee 799655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 804822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 805f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 808655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 809655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 810150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 833f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 834f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 835a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 836f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 840a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 841655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 842a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 844655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 851a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 858a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 869a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 873a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 876a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 878a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 879a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 882a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 889931fac098f2ae35aa1da26ced57962c9a21f95cfKenny Root if (file->d_name[0] == '.' && strcmp(".masterkey", file->d_name)) { 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 894a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 895a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 896a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 897a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 898a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 899655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root 957655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root 962655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 963655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 964fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker KeyStore(Entropy* entropy, keymaster_device_t* device, keymaster_device_t* fallback) 965655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 967fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker , mFallbackDevice(fallback) 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 977c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mGrants.clear(); 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 983c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mMasterKeys.clear(); 984655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 985655b958eb2180c7c06889f83f606d23421bf038cKenny Root 986fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker keymaster_device_t *getDevice() const { 987655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 988655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 989655b958eb2180c7c06889f83f606d23421bf038cKenny Root 990fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker keymaster_device_t *getFallbackDevice() const { 991fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return mFallbackDevice; 992fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 993fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 994fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker keymaster_device_t *getDeviceForBlob(const Blob& blob) const { 995fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return blob.isFallback() ? mFallbackDevice: mDevice; 996fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 997fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 998655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 999655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 1000655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 1001655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 1002655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1003655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1004655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 1008655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 1009655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 1014655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1015655b958eb2180c7c06889f83f606d23421bf038cKenny Root 10164e865753346fc6a075966972a7a98051818859dbRobin Lee ResponseCode copyMasterKey(uid_t src, uid_t uid) { 10174e865753346fc6a075966972a7a98051818859dbRobin Lee UserState *userState = getUserState(uid); 10184e865753346fc6a075966972a7a98051818859dbRobin Lee UserState *initState = getUserState(src); 10194e865753346fc6a075966972a7a98051818859dbRobin Lee return userState->copyMasterKey(initState); 10204e865753346fc6a075966972a7a98051818859dbRobin Lee } 10214e865753346fc6a075966972a7a98051818859dbRobin Lee 1022655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 102350122db50bcb6c1aab50ef235c8f9d264b50e97aRobin Lee UserState* userState = getUserState(uid); 1024655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 1025655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1026655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 102850122db50bcb6c1aab50ef235c8f9d264b50e97aRobin Lee UserState* userState = getUserState(uid); 1029655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1031655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1032655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 1033a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1034655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1035655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 1036655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1037655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1038655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 1039a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1040655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1041655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 1042655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 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::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 1048655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 1049655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1051655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 10524b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::String8 prefix(""); 10534b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::Vector<android::String16> aliases; 10544b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (saw(prefix, &aliases, uid) != ::NO_ERROR) { 10554b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 10564b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 10574b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 1058655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 10594b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee for (uint32_t i = 0; i < aliases.size(); i++) { 10604b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::String8 filename(aliases[i]); 10614b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee filename = android::String8::format("%s/%s", userState->getUserDirName(), 10624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee getKeyName(filename).string()); 10634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee del(filename, ::TYPE_ANY, uid); 10644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 10654b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 1066655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1067655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 1068655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 1069655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1070655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1071655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 1072655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 107331e27468b6d822adbd2aec9219a68c206aa6957cKenny Root if (userState == NULL || userState->getState() == STATE_UNINITIALIZED) { 1074655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1075655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1076655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1077655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 1078a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 1079a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 1080a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1081655b958eb2180c7c06889f83f606d23421bf038cKenny Root 108231e27468b6d822adbd2aec9219a68c206aa6957cKenny Root bool result = true; 108331e27468b6d822adbd2aec9219a68c206aa6957cKenny Root struct dirent* file; 1084a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 1085655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1086655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1087655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1088655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1089655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1090655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1091655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1092655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1093655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1094655b958eb2180c7c06889f83f606d23421bf038cKenny Root 109531e27468b6d822adbd2aec9219a68c206aa6957cKenny Root result = false; 109631e27468b6d822adbd2aec9219a68c206aa6957cKenny Root break; 1097a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1098a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 1099a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 1100a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1101a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1102655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 1103655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1104655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1105655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 1106a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1107a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1108655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 1109655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1110f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1111f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 1112822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1113822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1114822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1115822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1116822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 111707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1118cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1119cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1120cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1121cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 1124f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1125f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1126cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1127cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1128cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1129822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1130822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 113117208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 113217208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 113317208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 113417208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 113517208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 113617208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 113717208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 113817208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 113917208e0de5a42722901d803118745cca25fd10c1Kenny Root uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 114017208e0de5a42722901d803118745cca25fd10c1Kenny Root 114117208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 114217208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 114317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 114417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid); 114517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 114617208e0de5a42722901d803118745cca25fd10c1Kenny Root } 114717208e0de5a42722901d803118745cca25fd10c1Kenny Root 1148d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1149822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1150822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1151822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1152822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1153822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1154a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1155a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1156655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1157655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1158f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1159f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1160a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 11624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ResponseCode del(const char *filename, const BlobType type, uid_t uid) { 11634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee Blob keyBlob; 11644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ResponseCode rc = get(filename, &keyBlob, type, uid); 11654b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (rc != ::NO_ERROR) { 11664b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return rc; 11674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11684b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11694b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 11704b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // A device doesn't have to implement delete_keypair. 11714b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mDevice->delete_keypair != NULL && !keyBlob.isFallback()) { 11724b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mDevice->delete_keypair(mDevice, keyBlob.getValue(), keyBlob.getLength())) { 11734b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee rc = ::SYSTEM_ERROR; 11744b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11754b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11764b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11774b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (rc != ::NO_ERROR) { 11784b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return rc; 11794b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11804b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11814b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 11824b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11834b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11844b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ResponseCode saw(const android::String8& prefix, android::Vector<android::String16> *matches, 11854b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee uid_t uid) { 11864b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11874b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee UserState* userState = getUserState(uid); 11884b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t n = prefix.length(); 11894b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11904b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee DIR* dir = opendir(userState->getUserDirName()); 11914b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!dir) { 11924b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("can't open directory for user: %s", strerror(errno)); 11934b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 11944b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11954b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11964b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee struct dirent* file; 11974b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee while ((file = readdir(dir)) != NULL) { 11984b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // We only care about files. 11994b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_type != DT_REG) { 12004b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12014b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12024b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12034b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // Skip anything that starts with a "." 12044b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_name[0] == '.') { 12054b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12064b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12074b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12084b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!strncmp(prefix.string(), file->d_name, n)) { 12094b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee const char* p = &file->d_name[n]; 12104b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t plen = strlen(p); 12114b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12124b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t extra = decode_key_length(p, plen); 12134b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee char *match = (char*) malloc(extra + 1); 12144b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (match != NULL) { 12154b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee decode_key(match, p, plen); 12164b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee matches->push(android::String16(match, extra)); 12174b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee free(match); 12184b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } else { 12194b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("could not allocate match of size %zd", extra); 12204b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12214b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12224b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12234b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee closedir(dir); 12244b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 12254b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12264b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 122707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1228655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1229655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1230655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 123107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1232a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1233655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 123470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 123707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1238655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1239655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1240655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1241655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1242655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1243655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1244655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1245655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 124670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 124770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 124870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 124970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1250a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1251a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 125270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 125370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1254f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1255f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1256822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1257822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1258822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1259822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1260822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1261822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1262822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1263822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1264822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 126517208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 126607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 1268a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root /* 1269a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * Maybe the device doesn't support this type of key. Try to use the 1270a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * software fallback keymaster implementation. This is a little bit 1271a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * lazier than checking the PKCS#8 key type, but the software 1272a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * implementation will do that anyway. 1273a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root */ 12747c1eb75a6898452867ca28a4d7fad2d91edca615Chad Brubaker rc = mFallbackDevice->import_keypair(mFallbackDevice, key, keyLen, &data, &dataLength); 1275a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root isFallback = true; 127617208e0de5a42722901d803118745cca25fd10c1Kenny Root 127717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 127817208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 127917208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 128017208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1281822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1282822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1283822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1284822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1285822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1286f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 128717208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1288f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1289655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 12921b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 12931b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 12941b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 12951b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 12961b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 12971b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 12981b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 12991b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 13001b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 13011b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 13021b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 13031b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 13041b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 13058ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 13068ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1307655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1308655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 130986b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 1310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1311655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1312655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1313655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1314655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1316655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1317655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1318655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 131986b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 1320655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1321655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1322655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1323655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1324655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 132570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1326655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 132786b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1328655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 132986b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1330655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1331655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1332655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 133386b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(), 133486b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1336655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1339655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1340655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1343655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1344655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1345655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1346655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1347655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1348655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1349655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1350655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1359655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1360655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1366655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1370655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1372655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1373655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1374655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1376655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1387655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 13891b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 139107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1392655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1393fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker keymaster_device_t* mFallbackDevice; 1394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 139870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 140270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 140970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 141170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 141270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 141370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 141470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 141570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 141670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1417822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1418822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1419822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1420822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1421655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1422655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1423822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1424822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1425822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1426822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1427822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1428822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1429822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1430822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1431822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1432655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1433822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1434822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1435822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1436822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1437822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1438f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1439f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1440f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1441f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1442f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1443f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1444f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1445f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1446f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1447822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1448822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1449822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1450cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1452822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1454822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1455cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1456cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1460822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1461822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1463822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1465655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1478822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1483822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 148670c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 148770c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1490822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1493f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1494f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1495822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1496822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1497822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1499655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1500822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 150170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1502655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1503655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1504655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1505655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1506655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1507655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1508655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1509655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1510655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1511655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1512655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 151370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 151470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1515655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1516655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1517655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1518655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1519655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1520655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1521655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1522655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1523655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1524655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1525655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1526655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 152770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1528655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1529655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 153070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 153170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1532655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1533655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1534655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1535655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1536655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1537655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1538655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1539655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1540655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1541655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1542655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1543655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1544655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1545655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1546655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1547655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1548655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1549655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1550655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1551655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1552655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1553655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1554655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1555655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1556655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1557655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1558655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1559655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1560655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1562655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1563655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1564655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1565655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1566655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1568655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1569655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1570655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1571655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1572655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1574655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1575655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1576655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1578655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1579655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1581655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1582655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1583655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1584655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1585655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1586655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1587655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1588655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1589655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1590655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1591655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1592655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1593655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1594655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1595655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1596655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1597655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1598655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1599655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1600655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 160170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1602655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 160370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1604655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1605655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 160670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 16071b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 16081b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 160907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 161007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 161107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 161207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 161307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 161407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 161507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 161707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1622d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1623eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1624eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_TEST, spid)) { 1625d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1629655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1633d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1634eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1635eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 1636d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 163807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 164266dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 1643655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1644494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 164507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1646655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 164707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 164807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 165007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 165207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 165307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 165507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 165607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1659f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1660f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1661eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1662d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1663eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1664d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 166507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 166607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1668f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1669f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1670f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1671f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1672f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1673f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1674494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1675494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1676494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1677b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1678b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1679b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 168007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1681655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 168207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 168307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1684ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1685ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 1686fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(filename.string(), &keyBlob, targetUid); 1687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1689494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1690d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1691eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1692eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 1693d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1697494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1698494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1699494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1700b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1701b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1702b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1704655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 17054b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return mKeyStore->del(filename.string(), ::TYPE_GENERIC, targetUid); 1706298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1707298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1708494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1709d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1710eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1711eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_EXIST, spid)) { 1712d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 171307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1716494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1717494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1718494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1719b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1720b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1721b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 172207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1723655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1725655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 172607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1729298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1730298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1731494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1732d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1733eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1734eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SAW, spid)) { 1735d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 173707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1739494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1740494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1741494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1742b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1743b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1744b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 174507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1746655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 174707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17484b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mKeyStore->saw(filename, matches, targetUid) != ::NO_ERROR) { 17494b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 175007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 175107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1752298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1753298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1755d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1756eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1757eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_RESET, spid)) { 1758d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 176007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 17624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 176507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 176607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 176707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 177007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 177107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 177207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1773d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1774eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1775eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_PASSWORD, spid)) { 1776d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 178007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1782655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 178307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 178407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1785655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 178607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 178707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 178807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1789655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 179007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 179207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1793655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 179407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 179707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 179907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1800d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1801eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1802eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_LOCK, spid)) { 1803d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 180407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 180507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1807655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 18089d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 180907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 181007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 181107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1813655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 181407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 181570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 181707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1818d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1819eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1820eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_UNLOCK, spid)) { 1821d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 182207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 182307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 182407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1825655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 18269d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 182707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 182807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 182907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 183007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 183107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 183207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 183370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 183470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 183507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1836d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1837eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1838eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_ZERO, spid)) { 1839d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 184007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 184107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 184270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1843655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 184470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 184570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 184696427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 184796427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1848d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1849eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1850eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1851d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 185207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 185307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 185470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1855494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1856494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1857494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1858b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1859b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1860b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1861655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1862f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1863f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 186407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 186507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 186707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 186807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 186907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 187017208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 187170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 187207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 1873fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker const keymaster_device_t* fallback = mKeyStore->getFallbackDevice(); 187407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 187507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 187607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 187770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 187807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 187907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 188007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 188170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188217208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 188396427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 188496427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 188596427baf0094d50047049d329b0779c3c910402cKenny Root 188696427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 188796427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 188896427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 188996427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 189096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 189196427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 189296427baf0094d50047049d329b0779c3c910402cKenny Root } 189396427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 189496427baf0094d50047049d329b0779c3c910402cKenny Root 189596427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 189696427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 189796427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 189896427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 189996427baf0094d50047049d329b0779c3c910402cKenny Root 190096427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 190196427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 190296427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 190396427baf0094d50047049d329b0779c3c910402cKenny Root 190496427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 190596427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 190696427baf0094d50047049d329b0779c3c910402cKenny Root 190796427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 190896427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 190996427baf0094d50047049d329b0779c3c910402cKenny Root } else { 191096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 191196427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 191296427baf0094d50047049d329b0779c3c910402cKenny Root } 191396427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 191496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 191596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 191696427baf0094d50047049d329b0779c3c910402cKenny Root } 191796427baf0094d50047049d329b0779c3c910402cKenny Root 19181d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_DSA)) { 191917208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 192017208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 192117208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 1922fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = fallback->generate_keypair(fallback, TYPE_DSA, &dsa_params, &data, 1923fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker &dataLength); 192417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 192517208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 192696427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 192796427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 192896427baf0094d50047049d329b0779c3c910402cKenny Root 192996427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 193096427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 193196427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 193296427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 193396427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 193496427baf0094d50047049d329b0779c3c910402cKenny Root } 193596427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 193696427baf0094d50047049d329b0779c3c910402cKenny Root 19371d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_EC)) { 193817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 193917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 194017208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 1941fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = fallback->generate_keypair(fallback, TYPE_EC, &ec_params, &data, &dataLength); 194217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 194396427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 194496427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 194596427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 194696427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 194796427baf0094d50047049d329b0779c3c910402cKenny Root 194896427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 194996427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 195096427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 195196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 195296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 195396427baf0094d50047049d329b0779c3c910402cKenny Root } 195496427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 195596427baf0094d50047049d329b0779c3c910402cKenny Root 195696427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 19576489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin ALOGI("invalid number of arguments: %zu", args->size()); 195896427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 195996427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 196096427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 196196427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 196296427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 196396427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 196496427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 196596427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 196696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 196796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 196896427baf0094d50047049d329b0779c3c910402cKenny Root } 196996427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 197096427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 197196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 197296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 197396427baf0094d50047049d329b0779c3c910402cKenny Root } 197496427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 197596427baf0094d50047049d329b0779c3c910402cKenny Root } 197696427baf0094d50047049d329b0779c3c910402cKenny Root } 197796427baf0094d50047049d329b0779c3c910402cKenny Root 197896427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 197996427baf0094d50047049d329b0779c3c910402cKenny Root } else { 198096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 198196427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 198296427baf0094d50047049d329b0779c3c910402cKenny Root } 198370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 198507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1988655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1989655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 199070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 199107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 199207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1994ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 199517208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 199617208e0de5a42722901d803118745cca25fd10c1Kenny Root 1997655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 199870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 199970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2000f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 2001f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 2002d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2003eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2004eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 2005d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 200607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 200707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2009494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2010494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2011494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2012b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2013b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2014b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 2015fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root State state = mKeyStore->getState(targetUid); 2016f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 201707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 201807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 201907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 202070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 202107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 202260898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 202370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2024fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->importKey(data, length, filename.string(), targetUid, flags); 202570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 202670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 202707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 202807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 2029d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2030eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2031eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SIGN, spid)) { 2032d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 203307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 203407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20359a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 203607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 203707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 203870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2039d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 204007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 204170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2042655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2043d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 204607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 204770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2048fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker const keymaster_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 204907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 205007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 205107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 205207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 205370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 205407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 205507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 205607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 205870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 205907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 2062fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 2063fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker length, out, outLength); 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 207070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 207170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 2074d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2075eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2076eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_VERIFY, spid)) { 2077d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 207807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2081655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20829d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 208307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 208407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 208507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 208907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 209070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2091655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2092494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 209507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2097fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker const keymaster_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 210007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 210407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 210707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 210807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 210970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2110fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 2111fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker dataLength, signature, signatureLength); 211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 211607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 211870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 211907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 212407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 212507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 212607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 212807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 212907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 213007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 2131d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2132eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2133eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2134d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 213607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 213770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 213807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 213907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 214070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2141d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 214270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2143655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 214507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 214607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 214707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 214870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2149fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker const keymaster_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 215107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 215607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 215707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2158344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 215917208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 2160fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 2161fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker pubkeyLength); 216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 216307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 216407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2165344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 216607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2167344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2168344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2169494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2170d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2171eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2172eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 2173d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 217407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 217507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2176344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2177494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2178494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2179494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2180b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2181b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2182b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 218307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2184fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 21854b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return mKeyStore->del(filename.string(), ::TYPE_KEY_PAIR, targetUid); 2186a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 218707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 218807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2189d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2190eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2191eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2192d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 219307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 219407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2196655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21979d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 219807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 219907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 220007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 220107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 220207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2203655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 220407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2205655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 220607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 220707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2209655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 221007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 221207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 221307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2214d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2215eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2216eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2217d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 221807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 221907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 222007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2221655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22229d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 222307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 222407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 222507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 222607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 222707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2228655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 222907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2230655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 223107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 223207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 223307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2234655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 223607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 223707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2238d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2239eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2240eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2241d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 224236a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 224307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 224407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 224507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2246655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 224707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2248655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2249655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 225036a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2251a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 225207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2253655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 225407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2255655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 225636a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 225707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 225807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 225907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 226007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 226107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 226207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2263655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 226436a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 226507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 226607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 226736a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2268a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 226907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2270d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2271d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 22720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2273eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2274eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DUPLICATE, spid)) { 2275d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 22760225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 22770225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2279655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22800225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2281d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 22820225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 22830225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22840225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2285d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2286d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2287d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2288d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 22890225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 22900225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22910225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2292d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2293d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2294d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22950225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2296d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2297d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2298d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2299d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2300d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2301d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 23020225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2303d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2304d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2305d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2306d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 23070225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23080225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2309d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2310655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2311d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2312d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2313fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid)); 23140225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2315655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2316655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 23170225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 23180225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23190225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2320d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2321655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2322fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root srcUid); 2323d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2324d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 23250225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2326d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2327fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, destUid); 23280225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23290225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 23301b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 23311b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 23328ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 23338ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2334fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int32_t clear_uid(int64_t targetUid64) { 2335fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root uid_t targetUid = static_cast<uid_t>(targetUid64); 2336a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2337eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2338eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_CLEAR_UID, spid)) { 2339a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2340a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2341a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2342a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2343fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (targetUid64 == -1) { 2344fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid = callingUid; 2345007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root } else if (!is_self_or_system(callingUid, targetUid)) { 2346007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root ALOGW("permission denied for %d: clear_uid %d", callingUid, targetUid); 2347fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return ::PERMISSION_DENIED; 2348fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root } 2349fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root 2350a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2351a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2352655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2353a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2354a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2355a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23564b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 prefix = String8::format("%u_", targetUid); 23574b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee Vector<String16> aliases; 23584b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mKeyStore->saw(prefix, &aliases, targetUid) != ::NO_ERROR) { 2359a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2360a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2361a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee for (uint32_t i = 0; i < aliases.size(); i++) { 23634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 name8(aliases[i]); 23644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 23654b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee mKeyStore->del(filename.string(), ::TYPE_ANY, targetUid); 2366a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 23674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 2368a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2369a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23704b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee int32_t reset_uid(int32_t targetUid) { 23714e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 23724e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 23734b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 23744e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_RESET_UID, spid)) { 23754b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid); 23764e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 23774e865753346fc6a075966972a7a98051818859dbRobin Lee } 23784b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!is_self_or_system(callingUid, targetUid)) { 23794b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid); 23804e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 23814e865753346fc6a075966972a7a98051818859dbRobin Lee } 23824e865753346fc6a075966972a7a98051818859dbRobin Lee 23834b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return mKeyStore->reset(targetUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 23844e865753346fc6a075966972a7a98051818859dbRobin Lee } 23854e865753346fc6a075966972a7a98051818859dbRobin Lee 23864e865753346fc6a075966972a7a98051818859dbRobin Lee int32_t sync_uid(int32_t sourceUid, int32_t targetUid) { 23874e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 23884e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 23894e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_SYNC_UID, spid)) { 23904e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid); 23914e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 23924e865753346fc6a075966972a7a98051818859dbRobin Lee } 23934e865753346fc6a075966972a7a98051818859dbRobin Lee if (callingUid != AID_SYSTEM) { 23944e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid); 23954e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 23964e865753346fc6a075966972a7a98051818859dbRobin Lee } 23974e865753346fc6a075966972a7a98051818859dbRobin Lee if (sourceUid == targetUid) { 23984e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 23994e865753346fc6a075966972a7a98051818859dbRobin Lee } 24004e865753346fc6a075966972a7a98051818859dbRobin Lee 24014e865753346fc6a075966972a7a98051818859dbRobin Lee // Initialise user keystore with existing master key held in-memory 24024e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->copyMasterKey(sourceUid, targetUid); 24034e865753346fc6a075966972a7a98051818859dbRobin Lee } 24044e865753346fc6a075966972a7a98051818859dbRobin Lee 24054e865753346fc6a075966972a7a98051818859dbRobin Lee int32_t password_uid(const String16& pw, int32_t targetUid) { 24064e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 24074e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 24084e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_PASSWORD_UID, spid)) { 24094e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid); 24104e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24114e865753346fc6a075966972a7a98051818859dbRobin Lee } 24124e865753346fc6a075966972a7a98051818859dbRobin Lee if (callingUid != AID_SYSTEM) { 24134e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid); 24144e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24154e865753346fc6a075966972a7a98051818859dbRobin Lee } 24164e865753346fc6a075966972a7a98051818859dbRobin Lee 24174e865753346fc6a075966972a7a98051818859dbRobin Lee const String8 password8(pw); 24184e865753346fc6a075966972a7a98051818859dbRobin Lee 24194e865753346fc6a075966972a7a98051818859dbRobin Lee switch (mKeyStore->getState(targetUid)) { 24204e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_UNINITIALIZED: { 24214e865753346fc6a075966972a7a98051818859dbRobin Lee // generate master key, encrypt with password, write to file, initialize mMasterKey*. 24224e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->initializeUser(password8, targetUid); 24234e865753346fc6a075966972a7a98051818859dbRobin Lee } 24244e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_NO_ERROR: { 24254e865753346fc6a075966972a7a98051818859dbRobin Lee // rewrite master key with new password. 24264e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->writeMasterKey(password8, targetUid); 24274e865753346fc6a075966972a7a98051818859dbRobin Lee } 24284e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_LOCKED: { 24294e865753346fc6a075966972a7a98051818859dbRobin Lee // read master key, decrypt with password, initialize mMasterKey*. 24304e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->readMasterKey(password8, targetUid); 24314e865753346fc6a075966972a7a98051818859dbRobin Lee } 24324e865753346fc6a075966972a7a98051818859dbRobin Lee } 24334e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 24344e865753346fc6a075966972a7a98051818859dbRobin Lee } 24354e865753346fc6a075966972a7a98051818859dbRobin Lee 243607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 24379d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 24389d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 24399d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 24409d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 24419d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 24429d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 24439d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 24449d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 24459d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 244707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 24481d448c074a86ef5d05a22fdf1358718976628a86Kenny Root bool isKeyTypeSupported(const keymaster_device_t* device, keymaster_keypair_t keyType) { 24491d448c074a86ef5d05a22fdf1358718976628a86Kenny Root const int32_t device_api = device->common.module->module_api_version; 24501d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) { 24511d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24521d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24531d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 24541d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 24551d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24561d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 24571d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 24581d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24591d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) { 24601d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 24611d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 24621d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 24631d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 24641d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_DSA; 24651d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 24661d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_EC; 24671d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 24681d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 24691d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24701d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else { 24711d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return keyType == TYPE_RSA; 24721d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24731d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 24741d448c074a86ef5d05a22fdf1358718976628a86Kenny Root 247507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 247607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 247707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 247807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 249470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 249570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 249670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 249770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 249870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 249970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 250070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2501fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker keymaster_device_t* fallback; 2502fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker if (fallback_keymaster_device_initialize(&fallback)) { 2503fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker ALOGE("software keymaster could not be initialized; exiting"); 2504fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 1; 2505fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 2506fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 2507eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ks_is_selinux_enabled = is_selinux_enabled(); 2508eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (ks_is_selinux_enabled) { 2509eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn union selinux_callback cb; 2510eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn cb.func_log = selinux_log_callback; 2511eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 2512eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getcon(&tctx) != 0) { 2513eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n"); 2514eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return -1; 2515eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2516eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 2517eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGI("SELinux: Keystore SELinux is disabled.\n"); 2518eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2519eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 2520fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker KeyStore keyStore(&entropy, dev, fallback); 2521655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 252207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 252307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 252407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 252507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 252607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 252707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 252970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 253007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 253107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 253207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 253307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 253407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 253570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 253607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2539