keystore.cpp revision 17d68b9520e66226f1c7b2e1b3bd183ac80ca58b
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 44a5bbf2fb2a4853ecf6ae77ffee3efeb7a862498aShawn Willden#include <hardware/keymaster0.h> 4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4617208e0de5a42722901d803118745cca25fd10c1Kenny Root#include <keymaster/softkeymaster.h> 47919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker#include <keymaster/soft_keymaster_device.h> 4817208e0de5a42722901d803118745cca25fd10c1Kenny Root 4926cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h> 50655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h> 51655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h> 5270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 5307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 63eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn#include <selinux/android.h> 64eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 6596427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h" 6696427baf0094d50047049d329b0779c3c910402cKenny Root 67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 68a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 69a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 70a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 71a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 72a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 73a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 74a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 75a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 76a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 77822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 7896427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete { 7996427baf0094d50047049d329b0779c3c910402cKenny Root void operator()(BIGNUM* p) const { 8096427baf0094d50047049d329b0779c3c910402cKenny Root BN_free(p); 8196427baf0094d50047049d329b0779c3c910402cKenny Root } 8296427baf0094d50047049d329b0779c3c910402cKenny Root}; 8396427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM; 8496427baf0094d50047049d329b0779c3c910402cKenny Root 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 106822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 107a5bbf2fb2a4853ecf6ae77ffee3efeb7a862498aShawn Willdenstatic int keymaster_device_initialize(keymaster0_device_t** dev) { 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 117a5bbf2fb2a4853ecf6ae77ffee3efeb7a862498aShawn Willden rc = keymaster0_open(mod, dev); 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 131919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubakerstatic int fallback_keymaster_device_initialize(keymaster1_device_t** dev) { 132919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker keymaster::SoftKeymasterDevice* softkeymaster = 133919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker new keymaster::SoftKeymasterDevice(); 134919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker // SoftKeymasterDevice is designed to make this cast safe. 135919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker *dev = reinterpret_cast<keymaster1_device_t*>(softkeymaster); 136fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 0; 137fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker} 138fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 139a5bbf2fb2a4853ecf6ae77ffee3efeb7a862498aShawn Willdenstatic void keymaster_device_release(keymaster0_device_t* dev) { 140a5bbf2fb2a4853ecf6ae77ffee3efeb7a862498aShawn Willden keymaster0_close(dev); 14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 14407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 14507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 14607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 14707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 14807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 1494e865753346fc6a075966972a7a98051818859dbRobin Lee P_TEST = 1 << 0, 1504e865753346fc6a075966972a7a98051818859dbRobin Lee P_GET = 1 << 1, 1514e865753346fc6a075966972a7a98051818859dbRobin Lee P_INSERT = 1 << 2, 1524e865753346fc6a075966972a7a98051818859dbRobin Lee P_DELETE = 1 << 3, 1534e865753346fc6a075966972a7a98051818859dbRobin Lee P_EXIST = 1 << 4, 1544e865753346fc6a075966972a7a98051818859dbRobin Lee P_SAW = 1 << 5, 1554e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET = 1 << 6, 1564e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD = 1 << 7, 1574e865753346fc6a075966972a7a98051818859dbRobin Lee P_LOCK = 1 << 8, 1584e865753346fc6a075966972a7a98051818859dbRobin Lee P_UNLOCK = 1 << 9, 1594e865753346fc6a075966972a7a98051818859dbRobin Lee P_ZERO = 1 << 10, 1604e865753346fc6a075966972a7a98051818859dbRobin Lee P_SIGN = 1 << 11, 1614e865753346fc6a075966972a7a98051818859dbRobin Lee P_VERIFY = 1 << 12, 1624e865753346fc6a075966972a7a98051818859dbRobin Lee P_GRANT = 1 << 13, 1634e865753346fc6a075966972a7a98051818859dbRobin Lee P_DUPLICATE = 1 << 14, 1644e865753346fc6a075966972a7a98051818859dbRobin Lee P_CLEAR_UID = 1 << 15, 1654e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET_UID = 1 << 16, 1664e865753346fc6a075966972a7a98051818859dbRobin Lee P_SYNC_UID = 1 << 17, 1674e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD_UID = 1 << 18, 16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 16907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 17107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 17207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 17307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 17407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 17507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 17607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 17707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 17807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 179eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */ 180eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = { 181eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "test", 182eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "get", 183eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "insert", 184eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "delete", 185eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "exist", 186eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "saw", 187eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "reset", 188eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "password", 189eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "lock", 190eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "unlock", 191eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "zero", 192eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "sign", 193eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "verify", 194eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "grant", 195eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "duplicate", 1964e865753346fc6a075966972a7a98051818859dbRobin Lee "clear_uid", 1974e865753346fc6a075966972a7a98051818859dbRobin Lee "reset_uid", 1984e865753346fc6a075966972a7a98051818859dbRobin Lee "sync_uid", 1994e865753346fc6a075966972a7a98051818859dbRobin Lee "password_uid", 200eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}; 201eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 20207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 20307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 20407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 20507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 20607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 20707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 20807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 20907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 21007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 21107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 21207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 215eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx; 216eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled; 217eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 218eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) { 219eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn unsigned int index = ffs(perm); 220eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) { 221eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return perm_labels[index - 1]; 222eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 223eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("Keystore: Failed to retrieve permission label.\n"); 224eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn abort(); 225eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 226eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 227eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 228655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 229655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 230655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 231655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 232655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 233655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 234655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 235655b958eb2180c7c06889f83f606d23421bf038cKenny Root 236655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 237655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 238655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 239655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 240655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 241655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 242655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 243655b958eb2180c7c06889f83f606d23421bf038cKenny Root 244a25b2a397fff48dea7bce16af2065e6f5f043956Chih-Hung Hsiehstatic bool keystore_selinux_check_access(uid_t /*uid*/, perm_t perm, pid_t spid) { 245eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!ks_is_selinux_enabled) { 246eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return true; 247eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 248eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 249eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn char *sctx = NULL; 250eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *selinux_class = "keystore_key"; 251eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *str_perm = get_perm_label(perm); 252eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 253eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!str_perm) { 254eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 255eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 256eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 257eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getpidcon(spid, &sctx) != 0) { 258eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Failed to get source pid context.\n"); 259eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 260eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 26166dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 262eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm, 263eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn NULL) == 0; 264eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn freecon(sctx); 265eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return allowed; 266eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 267eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 268eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) { 269655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 270655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 271655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 272655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 273655b958eb2180c7c06889f83f606d23421bf038cKenny Root 27407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 27507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 27607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 277eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (user.perms & perm) && 278eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 27907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 282eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (DEFAULT_PERMS & perm) && 283eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 286494689083467ec372a58f094f041c8f102f39393Kenny Root/** 287494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 288494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 289494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 290494689083467ec372a58f094f041c8f102f39393Kenny Root */ 29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 29207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 29307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 29407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 29507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 29607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 29907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 30007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 30107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 302494689083467ec372a58f094f041c8f102f39393Kenny Root/** 303494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 304494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 305494689083467ec372a58f094f041c8f102f39393Kenny Root */ 306494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 307494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 308494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 309494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 310494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 311494689083467ec372a58f094f041c8f102f39393Kenny Root } 312494689083467ec372a58f094f041c8f102f39393Kenny Root } 313494689083467ec372a58f094f041c8f102f39393Kenny Root 314494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 315494689083467ec372a58f094f041c8f102f39393Kenny Root} 316494689083467ec372a58f094f041c8f102f39393Kenny Root 317007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root/** 318007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * Allow the system to perform some privileged tasks that have to do with 319007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * system maintenance. This should not be used for any function that uses 320007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root * the keys in any way (e.g., signing). 321007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root */ 322007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Rootstatic bool is_self_or_system(uid_t callingUid, uid_t targetUid) { 323007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root return callingUid == targetUid || callingUid == AID_SYSTEM; 324007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root} 325007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 333655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 334655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 335655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 336655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 337655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 338655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 339655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 340655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 341655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 342655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 343655b958eb2180c7c06889f83f606d23421bf038cKenny Root 34407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 34507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 34607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 348655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 352655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 353655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 35770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 35870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 35970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 36007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 36107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 36207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 36307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 36407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 36507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 36607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 36707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 37707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 37807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 37907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 38007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 38107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 38207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 38307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 38407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 38507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 38607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 38707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 38807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 38907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 39107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 400150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 4015281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 402150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 413150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 414150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 415150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 416150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 428150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 435150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 436150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4435187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 455822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 456f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 460822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 461822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 463822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 465822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 477f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 488d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 490822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 49217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker TYPE_KEYMASTER_10 = 4, 493822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 495f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 496822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 49907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 50007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 506822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 50707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 508822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 509f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 510ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 511ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 512ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 513ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 514ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5235187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5275187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5315187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 5325187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 5335187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 5345187818895c4c5f650a611c40531b1dff7764c18Kenny Root 5355187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 539822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 540822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 541822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 542822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 543f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 544f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 545f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 546f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 547f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 548f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 549f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 550f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 551f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 552f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 553f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 554f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 555f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 556f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 557f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 558f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 55917208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 56017208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 56117208e0de5a42722901d803118745cca25fd10c1Kenny Root } 56217208e0de5a42722901d803118745cca25fd10c1Kenny Root 56317208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 56417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 56517208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 56617208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 56717208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 56817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 56917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 57017208e0de5a42722901d803118745cca25fd10c1Kenny Root 571822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 572822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 573822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 574822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 575822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 576822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 577822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 578822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 579822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 580822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 581822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 582822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 583f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 584f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 585f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 586f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 587f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 588f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 589f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 593f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 611f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 612f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 613f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 614f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 615f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 616f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 617f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 618f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 624150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 625150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 626150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 627150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 635150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 639150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 640150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 641150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 642150ca934edb745de3666a6492b039900df228ff0Kenny Root } 643150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 646f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 647f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 648150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 649150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 659f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 660f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 661f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 662f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 663f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 670f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 673f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 674f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 675f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 676f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 677f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 678f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 679f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 680f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 681f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 682f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 683f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 684f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 685f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 686f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 687f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 688f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 689f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 70107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 708655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 709655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 710655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 711655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 712655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 713655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 71470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 715655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 716655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 717655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 718655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 71970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 720655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 721655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 722655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 723655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 724655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 725655b958eb2180c7c06889f83f606d23421bf038cKenny Root 726655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 73170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 732655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 733655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 734655b958eb2180c7c06889f83f606d23421bf038cKenny Root 735655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 736655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 737655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 738655b958eb2180c7c06889f83f606d23421bf038cKenny Root 739655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 741655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 742655b958eb2180c7c06889f83f606d23421bf038cKenny Root 743655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 744655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 745655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 746655b958eb2180c7c06889f83f606d23421bf038cKenny Root 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 748655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 749655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 750655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 751655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7545187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7585187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 762655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 763655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 765655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 76770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 76870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 769655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 770655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 77807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7814e865753346fc6a075966972a7a98051818859dbRobin Lee ResponseCode copyMasterKey(UserState* src) { 7824e865753346fc6a075966972a7a98051818859dbRobin Lee if (mState != STATE_UNINITIALIZED) { 7834e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7844e865753346fc6a075966972a7a98051818859dbRobin Lee } 7854e865753346fc6a075966972a7a98051818859dbRobin Lee if (src->getState() != STATE_NO_ERROR) { 7864e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7874e865753346fc6a075966972a7a98051818859dbRobin Lee } 7884e865753346fc6a075966972a7a98051818859dbRobin Lee memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES); 7894e865753346fc6a075966972a7a98051818859dbRobin Lee setupMasterKeys(); 7904e865753346fc6a075966972a7a98051818859dbRobin Lee return ::NO_ERROR; 7914e865753346fc6a075966972a7a98051818859dbRobin Lee } 7924e865753346fc6a075966972a7a98051818859dbRobin Lee 793655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 798822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 799f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 802655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 803655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 804150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 827f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 828f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 830f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 835655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 838655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 840a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 841a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 842a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 851a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 858a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 861655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 862655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 864655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 865655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 867a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 872a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 873a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 874655b958eb2180c7c06889f83f606d23421bf038cKenny Root 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 876a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 883931fac098f2ae35aa1da26ced57962c9a21f95cfKenny Root if (file->d_name[0] == '.' && strcmp(".masterkey", file->d_name)) { 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 888a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 889a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 890a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 891a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 892a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 893655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root 951655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root 956655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 957655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 958919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker KeyStore(Entropy* entropy, keymaster1_device_t* device, keymaster1_device_t* fallback) 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 961fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker , mFallbackDevice(fallback) 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 963655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 964655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 965655b958eb2180c7c06889f83f606d23421bf038cKenny Root 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 971c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mGrants.clear(); 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 977c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mMasterKeys.clear(); 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root 980919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker /** 981919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker * Depending on the hardware keymaster version is this may return a 982919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker * keymaster0_device_t* cast to a keymaster1_device_t*. All methods from 983919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker * keymaster0 are safe to call, calls to keymaster1_device_t methods should 984919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker * be guarded by a check on the device's version. 985919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker */ 986919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker keymaster1_device_t *getDevice() const { 987655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 988655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 989655b958eb2180c7c06889f83f606d23421bf038cKenny Root 990919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker keymaster1_device_t *getFallbackDevice() const { 991fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return mFallbackDevice; 992fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 993fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 994919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker keymaster1_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 } 117717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (keyBlob.getType() == ::TYPE_KEYMASTER_10) { 117817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster1_device_t* dev = getDeviceForBlob(keyBlob); 117917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (dev->delete_key) { 118017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_blob_t blob; 118117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker blob.key_material = keyBlob.getValue(); 118217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker blob.key_material_size = keyBlob.getLength(); 118317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker dev->delete_key(dev, &blob); 118417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 118517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 11864b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (rc != ::NO_ERROR) { 11874b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return rc; 11884b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11894b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11904b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 11914b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11924b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11934b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ResponseCode saw(const android::String8& prefix, android::Vector<android::String16> *matches, 11944b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee uid_t uid) { 11954b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11964b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee UserState* userState = getUserState(uid); 11974b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t n = prefix.length(); 11984b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11994b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee DIR* dir = opendir(userState->getUserDirName()); 12004b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!dir) { 12014b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("can't open directory for user: %s", strerror(errno)); 12024b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 12034b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12044b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12054b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee struct dirent* file; 12064b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee while ((file = readdir(dir)) != NULL) { 12074b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // We only care about files. 12084b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_type != DT_REG) { 12094b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12104b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12114b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12124b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // Skip anything that starts with a "." 12134b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_name[0] == '.') { 12144b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12154b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12164b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12174b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!strncmp(prefix.string(), file->d_name, n)) { 12184b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee const char* p = &file->d_name[n]; 12194b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t plen = strlen(p); 12204b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12214b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t extra = decode_key_length(p, plen); 12224b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee char *match = (char*) malloc(extra + 1); 12234b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (match != NULL) { 12244b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee decode_key(match, p, plen); 12254b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee matches->push(android::String16(match, extra)); 12264b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee free(match); 12274b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } else { 12284b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("could not allocate match of size %zd", extra); 12294b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12304b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12314b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12324b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee closedir(dir); 12334b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 12344b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12354b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 123607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1237655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1238655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1239655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 124007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1241a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1242655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 124370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 124470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 124570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1247655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1248655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1249655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1250655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1251655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1252655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1253655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1254655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 125570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 125670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 125770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 125870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1259a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1260a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 126170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 126270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1263f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1264f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1265822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1268822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1269822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1270822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1271822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1272822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1273822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 127417208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 127507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1276822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 1277a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root /* 1278a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * Maybe the device doesn't support this type of key. Try to use the 1279a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * software fallback keymaster implementation. This is a little bit 1280a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * lazier than checking the PKCS#8 key type, but the software 1281a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * implementation will do that anyway. 1282a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root */ 12837c1eb75a6898452867ca28a4d7fad2d91edca615Chad Brubaker rc = mFallbackDevice->import_keypair(mFallbackDevice, key, keyLen, &data, &dataLength); 1284a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root isFallback = true; 128517208e0de5a42722901d803118745cca25fd10c1Kenny Root 128617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 128717208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 128817208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 128917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1295f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 129617208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1297f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1298655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1299822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 13011b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 13021b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 13031b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 13041b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 13051b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 13061b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 13071b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 13081b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 13091b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 13101b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 13111b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 13121b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 13131b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 13148ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 13158ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1316655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1317655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 131886b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 1319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1320655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1321655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1322655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1323655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1325655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1326655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1327655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 132886b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 1329655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1330655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1331655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1332655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1333655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 133470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 133686b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1337655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 133886b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1339655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1340655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1341655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 134286b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = android::String8::format("%s/%s", getUserState(uid)->getUserDirName(), 134386b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1344655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1345655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1348655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1349655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1355655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1359655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1360655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1366655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1368655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1370655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1372655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1374655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1385655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1387655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1392655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 13981b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 140007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1401919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker keymaster1_device_t* mDevice; 1402919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker keymaster1_device_t* mFallbackDevice; 1403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 140770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1409655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 141170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1415655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1417655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 141870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 142070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 142170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 142270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 142370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 142470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 142570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1426822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1427822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1428822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1429822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1430655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1431655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1432822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1433822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1434822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1435822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1436822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1437822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1438822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1439822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1440822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1441655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1442822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1443822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1444822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1445822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1446822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1447f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1448f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1449f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1450f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1451f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1452f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1453f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1454f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1455f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1459cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1460822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1461822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1463822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1464cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1465cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1474655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1478822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1483822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1486822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1490822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1493822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 149570c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 149670c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1497822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1499822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1500822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1501822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1502f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1503f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1504822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1505822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1506822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1507822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1508655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1509822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 151070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1511655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1512655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1513655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1514655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1515655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1516655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1517655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1518655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1519655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1520655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1521655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 152270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 152370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1524655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1525655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1526655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1527655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1528655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1529655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1530655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1531655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1532655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1533655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1534655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1535655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 153670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1537655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1538655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 153970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 154070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1541655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1542655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1543655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1544655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1545655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1546655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1547655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1548655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1549655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1550655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1551655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1552655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1553655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1554655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1555655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1556655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1557655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1558655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1559655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1560655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1562655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1563655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1564655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1565655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1566655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1568655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1569655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1570655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1571655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1572655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1574655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1575655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1576655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1578655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1579655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1581655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1582655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1583655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1584655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1585655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1586655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1587655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1588655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1589655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1590655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1591655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1592655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1593655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1594655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1595655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1596655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1597655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1598655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1599655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1600655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1601655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1602655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1603655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1604655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1605655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1606655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1607655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1608655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1609655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 161070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1611655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 161270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1613655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1614655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 161570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 16161b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 16171b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 162007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 162207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 162407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1631d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1632eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1633eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_TEST, spid)) { 1634d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 163507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1638655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 164107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1642d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1643eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1644eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 1645d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 164607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 164707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 165007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 165166dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 1652655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1653494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1655655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 165607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 165707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 165807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 165907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 166107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 166207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 166407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 166507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1668f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1669f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1670eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1671d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1672eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1673d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 167407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 167507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 167607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1677f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1678f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1679f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1680f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1681f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1682f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1683494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1684494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1685494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1686b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1687b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1688b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 168907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1690655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1693ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1694ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 1695fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(filename.string(), &keyBlob, targetUid); 1696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1698494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1699d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1700eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1701eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 1702d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 170507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1706494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1707494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1708494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1709b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1710b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1711b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1713655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 171417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return mKeyStore->del(filename.string(), ::TYPE_ANY, targetUid); 1715298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1716298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1717494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1718d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1719eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1720eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_EXIST, spid)) { 1721d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 172207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 172307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1725494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1726494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1727494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1728b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1729b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1730b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 173107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1732655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 173307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1734655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 173507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1738298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1739298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1740494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1741d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1742eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1743eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SAW, spid)) { 1744d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 174507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 174607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1748494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1749494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1750494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1751b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1752b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1753b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 175407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1755655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 175607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17574b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mKeyStore->saw(filename, matches, targetUid) != ::NO_ERROR) { 17584b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1761298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1762298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 176307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1764d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1765eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1766eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_RESET, spid)) { 1767d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 17714b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1773a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 177407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 177507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 177607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 177907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 178007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 178107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1782d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1783eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1784eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_PASSWORD, spid)) { 1785d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 178607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 178707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 178907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1791655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 179207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 179307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1794655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 179507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 179707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1798655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 179907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 180107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1802655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 180307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 180607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 180807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1809d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1810eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1811eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_LOCK, spid)) { 1812d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 181307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 181407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1816655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 18179d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 181807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 181907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 182007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 182170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1822655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 182307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 182470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 182607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1827d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1828eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1829eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_UNLOCK, spid)) { 1830d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 183107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 183207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 183307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1834655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 18359d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 183607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 183707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 183807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 183907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 184007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 184107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 184270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 184370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 184407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1845d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1846eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1847eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_ZERO, spid)) { 1848d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 184907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 185007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 185170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1852655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 185370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 185470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 185596427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 185696427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1857d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1858eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 1859eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 1860d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 186107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 186207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1864494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1865494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1866494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1867b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1868b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1869b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1870655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1871f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1872f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 187307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 187407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 187570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 187607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 187707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 187807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 187917208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 188070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1881919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 1882919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 188307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 188407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 188507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 188670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 188807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 188907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 189070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 189117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 189296427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 189396427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 189496427baf0094d50047049d329b0779c3c910402cKenny Root 189596427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 189696427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 189796427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 189896427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 189996427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 190096427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 190196427baf0094d50047049d329b0779c3c910402cKenny Root } 190296427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 190396427baf0094d50047049d329b0779c3c910402cKenny Root 190496427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 190596427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 190696427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 190796427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 190896427baf0094d50047049d329b0779c3c910402cKenny Root 190996427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 191096427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 191196427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 191296427baf0094d50047049d329b0779c3c910402cKenny Root 191396427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 191496427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 191596427baf0094d50047049d329b0779c3c910402cKenny Root 191696427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 191796427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 191896427baf0094d50047049d329b0779c3c910402cKenny Root } else { 191996427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 192096427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 192196427baf0094d50047049d329b0779c3c910402cKenny Root } 192296427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 192396427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 192496427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 192596427baf0094d50047049d329b0779c3c910402cKenny Root } 192696427baf0094d50047049d329b0779c3c910402cKenny Root 19271d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_DSA)) { 192817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 192917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 193017208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 1931fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = fallback->generate_keypair(fallback, TYPE_DSA, &dsa_params, &data, 1932fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker &dataLength); 193317208e0de5a42722901d803118745cca25fd10c1Kenny Root } 193417208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 193596427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 193696427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 193796427baf0094d50047049d329b0779c3c910402cKenny Root 193896427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 193996427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 194096427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 194196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 194296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 194396427baf0094d50047049d329b0779c3c910402cKenny Root } 194496427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 194596427baf0094d50047049d329b0779c3c910402cKenny Root 19461d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_EC)) { 194717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 194817208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 194917208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 1950fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = fallback->generate_keypair(fallback, TYPE_EC, &ec_params, &data, &dataLength); 195117208e0de5a42722901d803118745cca25fd10c1Kenny Root } 195296427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 195396427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 195496427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 195596427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 195696427baf0094d50047049d329b0779c3c910402cKenny Root 195796427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 195896427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 195996427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 196096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 196196427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 196296427baf0094d50047049d329b0779c3c910402cKenny Root } 196396427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 196496427baf0094d50047049d329b0779c3c910402cKenny Root 196596427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 19666489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin ALOGI("invalid number of arguments: %zu", args->size()); 196796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 196896427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 196996427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 197096427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 197196427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 197296427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 197396427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 197496427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 197596427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 197696427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 197796427baf0094d50047049d329b0779c3c910402cKenny Root } 197896427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 197996427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 198096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 198196427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 198296427baf0094d50047049d329b0779c3c910402cKenny Root } 198396427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 198496427baf0094d50047049d329b0779c3c910402cKenny Root } 198596427baf0094d50047049d329b0779c3c910402cKenny Root } 198696427baf0094d50047049d329b0779c3c910402cKenny Root 198796427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 198896427baf0094d50047049d329b0779c3c910402cKenny Root } else { 198996427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 199096427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 199196427baf0094d50047049d329b0779c3c910402cKenny Root } 199270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 199407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 199507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 199670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1997655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1998655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 199970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 200107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 200207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2003ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 200417208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 200517208e0de5a42722901d803118745cca25fd10c1Kenny Root 2006655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 200770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 200870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2009f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 2010f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 2011d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2012eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2013eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_INSERT, spid)) { 2014d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 201607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2018494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2019494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2020494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2021b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2022b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2023b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 2024fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root State state = mKeyStore->getState(targetUid); 2025f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 202607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 202707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 202807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 202970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 203160898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 203270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2033fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->importKey(data, length, filename.string(), targetUid, flags); 203470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 203570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 203707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 2038d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2039eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2040eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_SIGN, spid)) { 2041d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 204207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 204307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20449a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 204607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 204770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2048d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 204907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 205070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2051655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2052d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 205307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 205407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 205507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 205670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2057919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 205807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 205907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 207007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 2071fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 2072fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker length, out, outLength); 207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 207407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 207807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 207970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 208070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 208207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 2083d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2084eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2085eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_VERIFY, spid)) { 2086d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2090655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20919d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 209207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 209607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 209707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 209970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2100655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2101494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 210407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2106919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 210707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 210807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 210907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 211107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 211607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 211707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 211870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2119fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 2120fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker dataLength, signature, signatureLength); 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 212407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 212507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 212670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 212770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 212807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 212907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 213007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 213107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 213207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 213307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 213507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 213607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 213807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 213907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 2140d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2141eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2142eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2143d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 214507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 214670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 214707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 214807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 214970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2150d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 215170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2152655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 215307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 215607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2158919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 215907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 216007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 216107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 216270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 216307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 216407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 216507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 216607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2167344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 216817208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 2169fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 2170fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker pubkeyLength); 217107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 217207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 217307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2174344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 217507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2176344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2177344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2178494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2179d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2180eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2181eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DELETE, spid)) { 2182d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 218307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 218407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2185344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2186494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2187494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2188494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2189b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2190b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2191b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 219207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2193fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 21944b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return mKeyStore->del(filename.string(), ::TYPE_KEY_PAIR, targetUid); 2195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 219607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 219707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2198d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2199eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2200eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2201d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 220207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 220307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 220407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2205655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22069d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 220707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 220907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 221007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 221107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2212655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 221307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2214655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 221507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 221607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 221707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2218655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 221907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 222107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 222207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2223d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2224eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2225eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GRANT, spid)) { 2226d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 222707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 222807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 222907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2230655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22319d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 223207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 223307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 223407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 223507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 223607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2237655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 223807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2239655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 224007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 224107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 224207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2243655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 224507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 224607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2247d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2248eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2249eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_GET, spid)) { 2250d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 225136a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 225207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 225307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 225407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2255655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 225607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2257655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2258655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 225936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2260a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 226107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2262655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 226307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2264655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 226536a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 226607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 226707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 226807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 226907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 227007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 227107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2272655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 227336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 227407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 227507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 227636a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2277a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 227807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2279d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2280d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 22810225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2282eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2283eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DUPLICATE, spid)) { 2284d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 22850225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 22860225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22870225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2288655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 22890225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2290d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 22910225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 22920225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22930225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2294d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2295d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2296d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2297d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 22980225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 22990225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23000225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2301d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2302d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2303d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 23040225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2305d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2306d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2307d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2308d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2309d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2310d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 23110225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2312d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2313d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2314d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2315d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 23160225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23170225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2318d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2319655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2320d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2321d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2322fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid)); 23230225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2324655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2325655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 23260225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 23270225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23280225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2329d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2330655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2331fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root srcUid); 2332d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2333d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 23340225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2335d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2336fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, destUid); 23370225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 23380225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 23391b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 23401b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 23418ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 23428ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2343fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int32_t clear_uid(int64_t targetUid64) { 2344fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root uid_t targetUid = static_cast<uid_t>(targetUid64); 2345a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2346eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2347eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_CLEAR_UID, spid)) { 2348a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2349a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2350a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2351a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2352fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root if (targetUid64 == -1) { 2353fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root targetUid = callingUid; 2354007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root } else if (!is_self_or_system(callingUid, targetUid)) { 2355007cb236ada4b3d70815f03dd07116a5e187f4ddKenny Root ALOGW("permission denied for %d: clear_uid %d", callingUid, targetUid); 2356fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root return ::PERMISSION_DENIED; 2357fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root } 2358fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root 2359919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 2360a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2361655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2362a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2363a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2364a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23654b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 prefix = String8::format("%u_", targetUid); 23664b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee Vector<String16> aliases; 23674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mKeyStore->saw(prefix, &aliases, targetUid) != ::NO_ERROR) { 2368a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2369a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2370a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23714b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee for (uint32_t i = 0; i < aliases.size(); i++) { 23724b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 name8(aliases[i]); 23734b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 23744b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee mKeyStore->del(filename.string(), ::TYPE_ANY, targetUid); 2375a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 23764b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 2377a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2378a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23794b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee int32_t reset_uid(int32_t targetUid) { 23804e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 23814e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 23824b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 23834e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_RESET_UID, spid)) { 23844b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid); 23854e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 23864e865753346fc6a075966972a7a98051818859dbRobin Lee } 23874b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!is_self_or_system(callingUid, targetUid)) { 23884b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid); 23894e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 23904e865753346fc6a075966972a7a98051818859dbRobin Lee } 23914e865753346fc6a075966972a7a98051818859dbRobin Lee 23924b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return mKeyStore->reset(targetUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 23934e865753346fc6a075966972a7a98051818859dbRobin Lee } 23944e865753346fc6a075966972a7a98051818859dbRobin Lee 23954e865753346fc6a075966972a7a98051818859dbRobin Lee int32_t sync_uid(int32_t sourceUid, int32_t targetUid) { 23964e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 23974e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 23984e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_SYNC_UID, spid)) { 23994e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid); 24004e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24014e865753346fc6a075966972a7a98051818859dbRobin Lee } 24024e865753346fc6a075966972a7a98051818859dbRobin Lee if (callingUid != AID_SYSTEM) { 24034e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid); 24044e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24054e865753346fc6a075966972a7a98051818859dbRobin Lee } 24064e865753346fc6a075966972a7a98051818859dbRobin Lee if (sourceUid == targetUid) { 24074e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 24084e865753346fc6a075966972a7a98051818859dbRobin Lee } 24094e865753346fc6a075966972a7a98051818859dbRobin Lee 24104e865753346fc6a075966972a7a98051818859dbRobin Lee // Initialise user keystore with existing master key held in-memory 24114e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->copyMasterKey(sourceUid, targetUid); 24124e865753346fc6a075966972a7a98051818859dbRobin Lee } 24134e865753346fc6a075966972a7a98051818859dbRobin Lee 24144e865753346fc6a075966972a7a98051818859dbRobin Lee int32_t password_uid(const String16& pw, int32_t targetUid) { 24154e865753346fc6a075966972a7a98051818859dbRobin Lee uid_t callingUid = IPCThreadState::self()->getCallingUid(); 24164e865753346fc6a075966972a7a98051818859dbRobin Lee pid_t spid = IPCThreadState::self()->getCallingPid(); 24174e865753346fc6a075966972a7a98051818859dbRobin Lee if (!has_permission(callingUid, P_PASSWORD_UID, spid)) { 24184e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid); 24194e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24204e865753346fc6a075966972a7a98051818859dbRobin Lee } 24214e865753346fc6a075966972a7a98051818859dbRobin Lee if (callingUid != AID_SYSTEM) { 24224e865753346fc6a075966972a7a98051818859dbRobin Lee ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid); 24234e865753346fc6a075966972a7a98051818859dbRobin Lee return ::PERMISSION_DENIED; 24244e865753346fc6a075966972a7a98051818859dbRobin Lee } 24254e865753346fc6a075966972a7a98051818859dbRobin Lee 24264e865753346fc6a075966972a7a98051818859dbRobin Lee const String8 password8(pw); 24274e865753346fc6a075966972a7a98051818859dbRobin Lee 24284e865753346fc6a075966972a7a98051818859dbRobin Lee switch (mKeyStore->getState(targetUid)) { 24294e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_UNINITIALIZED: { 24304e865753346fc6a075966972a7a98051818859dbRobin Lee // generate master key, encrypt with password, write to file, initialize mMasterKey*. 24314e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->initializeUser(password8, targetUid); 24324e865753346fc6a075966972a7a98051818859dbRobin Lee } 24334e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_NO_ERROR: { 24344e865753346fc6a075966972a7a98051818859dbRobin Lee // rewrite master key with new password. 24354e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->writeMasterKey(password8, targetUid); 24364e865753346fc6a075966972a7a98051818859dbRobin Lee } 24374e865753346fc6a075966972a7a98051818859dbRobin Lee case ::STATE_LOCKED: { 24384e865753346fc6a075966972a7a98051818859dbRobin Lee // read master key, decrypt with password, initialize mMasterKey*. 24394e865753346fc6a075966972a7a98051818859dbRobin Lee return mKeyStore->readMasterKey(password8, targetUid); 24404e865753346fc6a075966972a7a98051818859dbRobin Lee } 24414e865753346fc6a075966972a7a98051818859dbRobin Lee } 24424e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 24434e865753346fc6a075966972a7a98051818859dbRobin Lee } 24444e865753346fc6a075966972a7a98051818859dbRobin Lee 24459c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t addRngEntropy(const uint8_t* data, size_t dataLength) { 24469c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 24479c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 24489c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t devResult = KM_ERROR_UNIMPLEMENTED; 24499c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t fallbackResult = KM_ERROR_UNIMPLEMENTED; 24509c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 24519c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker device->add_rng_entropy != NULL) { 24529c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker devResult = device->add_rng_entropy(device, data, dataLength); 24539c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 24549c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (fallback->add_rng_entropy) { 24559c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker fallbackResult = fallback->add_rng_entropy(fallback, data, dataLength); 24569c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 24579c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (devResult) { 24589c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return devResult; 24599c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 24609c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (fallbackResult) { 24619c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return fallbackResult; 24629c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 24639c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return ::NO_ERROR; 24649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 24659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 246617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker int32_t generateKey(const String16& name, const KeymasterArguments& params, 246717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker int uid, int flags, KeyCharacteristics* outCharacteristics) { 246817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 246917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker pid_t callingPid = IPCThreadState::self()->getCallingPid(); 247017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (!has_permission(callingUid, P_INSERT, callingPid)) { 247117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker ALOGW("permission denied for %d: generateKey", callingUid); 247217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return ::PERMISSION_DENIED; 247317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 247417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 247517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker State state = mKeyStore->getState(callingUid); 247617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 247717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker ALOGW("calling generate in state: %d", state); 247817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return state; 247917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 248017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 248117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (uid == -1) { 248217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker uid = callingUid; 248317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } else if (!is_granted_to(callingUid, uid)) { 248417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return ::PERMISSION_DENIED; 248517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 248617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 248717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker uint8_t* data; 248817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker size_t dataLength; 248917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker int rc = KM_ERROR_UNIMPLEMENTED; 249017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker bool isFallback = false; 249117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_blob_t blob; 249217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_characteristics_t *out = NULL; 249317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 249417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 249517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 249617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (device == NULL) { 249717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return ::SYSTEM_ERROR; 249817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 249917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker // TODO: Seed from Linux RNG either before this or periodically 250017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 250117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker device->generate_key != NULL) { 250217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker rc = device->generate_key(device, params.params.data(), params.params.size(), &blob, 250317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker &out); 250417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 250517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker // If the HW device didn't support generate_key or generate_key failed 250617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker // fall back to the software implementation. 250717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (rc && fallback->generate_key != NULL) { 250817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker isFallback = true; 250917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker rc = fallback->generate_key(fallback, params.params.data(), params.params.size(), 251017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker &blob, 251117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker &out); 251217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 251317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 251417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (out) { 251517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (outCharacteristics) { 251617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker outCharacteristics->characteristics = *out; 251717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } else { 251817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_free_characteristics(out); 251917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 252017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker free(out); 252117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 252217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 252317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (rc) { 252417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return rc; 252517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 252617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 252717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker String8 name8(name); 252817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid)); 252917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 253017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10); 253117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keyBlob.setFallback(isFallback); 253217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 253317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 253417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker free(const_cast<uint8_t*>(blob.key_material)); 253517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 253617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, uid); 25379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25399899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker int32_t getKeyCharacteristics(const String16& /*name*/, 25409899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker const keymaster_blob_t& /*clientId*/, 25419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker const keymaster_blob_t& /*appData*/, 25429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker KeyCharacteristics* /*outCharacteristics*/) { 25439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker return KM_ERROR_UNIMPLEMENTED; 25449899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25459899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25469899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker int32_t importKey(const String16& /*name*/, const KeymasterArguments& /*params*/, 25479899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker keymaster_key_format_t /*format*/, const uint8_t* /*keyData*/, 25489899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker size_t /*keyLength*/, int /*uid*/, int /*flags*/, 25499899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker KeyCharacteristics* /*outCharacteristics*/) { 25509899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker return KM_ERROR_UNIMPLEMENTED; 25519899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25529899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25539899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker void exportKey(const String16& /*name*/, keymaster_key_format_t /*format*/, 25549899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker const keymaster_blob_t& /*clientId*/, 25559899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker const keymaster_blob_t& /*appData*/, ExportResult* result) { 25569899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker result->resultCode = KM_ERROR_UNIMPLEMENTED; 25579899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25589899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25599899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker void begin(const sp<IBinder>& /*appToken*/, const String16& /*name*/, 25609899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker keymaster_purpose_t /*purpose*/, bool /*pruneable*/, 25619899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker const KeymasterArguments& /*params*/, KeymasterArguments* /*outParams*/, 25629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker OperationResult* result) { 25639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker result->resultCode = KM_ERROR_UNIMPLEMENTED; 25649899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25659899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25669899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker void update(const sp<IBinder>& /*token*/, const KeymasterArguments& /*params*/, 25679899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker uint8_t* /*data*/, size_t /*dataLength*/, OperationResult* result) { 25689899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker result->resultCode = KM_ERROR_UNIMPLEMENTED; 25699899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25709899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25719899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker void finish(const sp<IBinder>& /*token*/, const KeymasterArguments& /*args*/, 25729899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker uint8_t* /*signature*/, size_t /*signatureLength*/, OperationResult* result) { 25739899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker result->resultCode = KM_ERROR_UNIMPLEMENTED; 25749899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25759899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25769899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker int32_t abort(const sp<IBinder>& /*token*/) { 25779899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker return KM_ERROR_UNIMPLEMENTED; 25789899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25799899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 258007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 25819d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 25829d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 25839d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 25849d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 25859d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 25869d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 25879d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 25889d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 25899d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 259107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2592919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker bool isKeyTypeSupported(const keymaster1_device_t* device, keymaster_keypair_t keyType) { 25931d448c074a86ef5d05a22fdf1358718976628a86Kenny Root const int32_t device_api = device->common.module->module_api_version; 25941d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) { 25951d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 25961d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 25971d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 25981d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 25991d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 26001d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 26011d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 26021d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 26031d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) { 26041d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 26051d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 26061d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 26071d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 26081d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_DSA; 26091d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 26101d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_EC; 26111d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 26121d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 26131d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 26141d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else { 26151d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return keyType == TYPE_RSA; 26161d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 26171d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 26181d448c074a86ef5d05a22fdf1358718976628a86Kenny Root 261907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 262007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 262107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 262207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 263870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2639a5bbf2fb2a4853ecf6ae77ffee3efeb7a862498aShawn Willden keymaster0_device_t* dev; 264070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 264170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 264270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 264370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 264470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2645919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker keymaster1_device_t* fallback; 2646fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker if (fallback_keymaster_device_initialize(&fallback)) { 2647fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker ALOGE("software keymaster could not be initialized; exiting"); 2648fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 1; 2649fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 2650fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 2651eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ks_is_selinux_enabled = is_selinux_enabled(); 2652eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (ks_is_selinux_enabled) { 2653eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn union selinux_callback cb; 2654eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn cb.func_log = selinux_log_callback; 2655eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 2656eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getcon(&tctx) != 0) { 2657eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n"); 2658eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return -1; 2659eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2660eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 2661eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGI("SELinux: Keystore SELinux is disabled.\n"); 2662eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 2663eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 2664919cb2a5a9dabd61cb02eff7a589f9f1f0f793eeChad Brubaker KeyStore keyStore(&entropy, reinterpret_cast<keymaster1_device_t*>(dev), fallback); 2665655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 266607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 266707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 266807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 266907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 267007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 267107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 267370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 267407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 267507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 267607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 267707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 267807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 267970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 268007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2683