1a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* 2a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Copyright (C) 2009 The Android Open Source Project 3a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 4a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * you may not use this file except in compliance with the License. 6a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * You may obtain a copy of the License at 7a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 8a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 10a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Unless required by applicable law or agreed to in writing, software 11a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * See the License for the specific language governing permissions and 14a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * limitations under the License. 15a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root */ 16a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root//#define LOG_NDEBUG 0 1807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#define LOG_TAG "keystore" 1907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h> 21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h> 22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h> 23aaf9802da6cea710e0777abb852724e1825cad63Elliott Hughes#include <strings.h> 24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h> 25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h> 26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h> 27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h> 28655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <errno.h> 29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 31822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 37a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 39822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 40a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 42822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 43a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4480843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden#include <hardware/keymaster0.h> 4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker#include <keymaster/soft_keymaster_device.h> 470400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden#include <keymaster/soft_keymaster_logger.h> 480400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden#include <keymaster/softkeymaster.h> 4917208e0de5a42722901d803118745cca25fd10c1Kenny Root 5026cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h> 51655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h> 52655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h> 5370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 5507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 63a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 64eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn#include <selinux/android.h> 65eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 663a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker#include <sstream> 673a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 68d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker#include "auth_token_table.h" 6996427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h" 709221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden#include "keystore_keymaster_enforcement.h" 7140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker#include "operation.h" 7296427baf0094d50047049d329b0779c3c910402cKenny Root 73a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 74a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 75a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 76a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 77a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 78a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 79a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 80a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 81a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 82a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 8496427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete { 8596427baf0094d50047049d329b0779c3c910402cKenny Root void operator()(BIGNUM* p) const { 8696427baf0094d50047049d329b0779c3c910402cKenny Root BN_free(p); 8796427baf0094d50047049d329b0779c3c910402cKenny Root } 8896427baf0094d50047049d329b0779c3c910402cKenny Root}; 8996427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM; 9096427baf0094d50047049d329b0779c3c910402cKenny Root 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 106822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 107822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 108822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 109822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 110822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 111822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 112bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubakerstatic int keymaster_device_initialize(keymaster1_device_t** dev) { 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 116bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker keymaster::SoftKeymasterDevice* softkeymaster = NULL; 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 123bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker rc = mod->methods->open(mod, KEYSTORE_KEYMASTER, reinterpret_cast<struct hw_device_t**>(dev)); 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker // Wrap older hardware modules with a softkeymaster adapter. 131bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker if ((*dev)->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0) { 132bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker return 0; 133bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker } 134bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker softkeymaster = 135bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker new keymaster::SoftKeymasterDevice(reinterpret_cast<keymaster0_device_t*>(*dev)); 136bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker *dev = softkeymaster->keymaster_device(); 13770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 13870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1440400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden// softkeymaster_logger appears not to be used in keystore, but it installs itself as the 1450400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden// logger used by SoftKeymasterDevice. 1460400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willdenstatic keymaster::SoftKeymasterLogger softkeymaster_logger; 1470400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden 14867d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubakerstatic int fallback_keymaster_device_initialize(keymaster1_device_t** dev) { 14967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster::SoftKeymasterDevice* softkeymaster = 15067d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker new keymaster::SoftKeymasterDevice(); 1519fd05a9a6299e9688c8fcf755516ea254868d187Shawn Willden *dev = softkeymaster->keymaster_device(); 1529fd05a9a6299e9688c8fcf755516ea254868d187Shawn Willden // softkeymaster will be freed by *dev->close_device; don't delete here. 153fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 0; 154fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker} 155fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 156bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubakerstatic void keymaster_device_release(keymaster1_device_t* dev) { 157bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker dev->common.close(&dev->common); 15870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 15970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 166e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_GET_STATE = 1 << 0, 1674e865753346fc6a075966972a7a98051818859dbRobin Lee P_GET = 1 << 1, 1684e865753346fc6a075966972a7a98051818859dbRobin Lee P_INSERT = 1 << 2, 1694e865753346fc6a075966972a7a98051818859dbRobin Lee P_DELETE = 1 << 3, 1704e865753346fc6a075966972a7a98051818859dbRobin Lee P_EXIST = 1 << 4, 171e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_LIST = 1 << 5, 1724e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET = 1 << 6, 1734e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD = 1 << 7, 1744e865753346fc6a075966972a7a98051818859dbRobin Lee P_LOCK = 1 << 8, 1754e865753346fc6a075966972a7a98051818859dbRobin Lee P_UNLOCK = 1 << 9, 176e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_IS_EMPTY = 1 << 10, 1774e865753346fc6a075966972a7a98051818859dbRobin Lee P_SIGN = 1 << 11, 1784e865753346fc6a075966972a7a98051818859dbRobin Lee P_VERIFY = 1 << 12, 1794e865753346fc6a075966972a7a98051818859dbRobin Lee P_GRANT = 1 << 13, 1804e865753346fc6a075966972a7a98051818859dbRobin Lee P_DUPLICATE = 1 << 14, 1814e865753346fc6a075966972a7a98051818859dbRobin Lee P_CLEAR_UID = 1 << 15, 182e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_ADD_AUTH = 1 << 16, 183e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_USER_CHANGED = 1 << 17, 18407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 18507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 18607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 18707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 18807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 18907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 19007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 19107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 19207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 19307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 19407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 195eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */ 196eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = { 197e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker "get_state", 198eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "get", 199eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "insert", 200eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "delete", 201eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "exist", 202e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker "list", 203eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "reset", 204eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "password", 205eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "lock", 206eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "unlock", 207e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker "is_empty", 208eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "sign", 209eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "verify", 210eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "grant", 211eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "duplicate", 2124e865753346fc6a075966972a7a98051818859dbRobin Lee "clear_uid", 213d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker "add_auth", 214c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker "user_changed", 215eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}; 216eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 21707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 21807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 21907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 22007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 22107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 22207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 22307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 22407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 22507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 22607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 227e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubakerstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_GET_STATE | P_GET | P_INSERT | P_DELETE 228e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker | P_EXIST | P_LIST | P_SIGN | P_VERIFY); 22907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 230eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx; 231eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled; 232eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 233eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) { 234eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn unsigned int index = ffs(perm); 235eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) { 236eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return perm_labels[index - 1]; 237eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 238eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("Keystore: Failed to retrieve permission label.\n"); 239eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn abort(); 240eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 241eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 242eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 243655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 244655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 245655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 246655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 247655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 248655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 249655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 250655b958eb2180c7c06889f83f606d23421bf038cKenny Root 251655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 252655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 253655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 254655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 255655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 256655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 257655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 258655b958eb2180c7c06889f83f606d23421bf038cKenny Root 259a25b2a397fff48dea7bce16af2065e6f5f043956Chih-Hung Hsiehstatic bool keystore_selinux_check_access(uid_t /*uid*/, perm_t perm, pid_t spid) { 260eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!ks_is_selinux_enabled) { 261eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return true; 262eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 263eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 264eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn char *sctx = NULL; 265eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *selinux_class = "keystore_key"; 266eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *str_perm = get_perm_label(perm); 267eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 268eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!str_perm) { 269eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 270eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 271eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 272eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getpidcon(spid, &sctx) != 0) { 273eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Failed to get source pid context.\n"); 274eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 275eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 27666dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 277eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm, 278eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn NULL) == 0; 279eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn freecon(sctx); 280eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return allowed; 281eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 282eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 283eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) { 284655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 285655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 286655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 287655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 288655b958eb2180c7c06889f83f606d23421bf038cKenny Root 28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 29007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 292eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (user.perms & perm) && 293eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 29407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 297eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (DEFAULT_PERMS & perm) && 298eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 29907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 30007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 301494689083467ec372a58f094f041c8f102f39393Kenny Root/** 302494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 303494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 304494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 305494689083467ec372a58f094f041c8f102f39393Kenny Root */ 30607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 30707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 30807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 30907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 31007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 31107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 31207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 31307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 31407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 31507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 31607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 317494689083467ec372a58f094f041c8f102f39393Kenny Root/** 318494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 319494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 320494689083467ec372a58f094f041c8f102f39393Kenny Root */ 321494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 3229489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (callingUid == targetUid) { 3239489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return true; 3249489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 325494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 326494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 327494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 328494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 329494689083467ec372a58f094f041c8f102f39393Kenny Root } 330494689083467ec372a58f094f041c8f102f39393Kenny Root } 331494689083467ec372a58f094f041c8f102f39393Kenny Root 332494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 333494689083467ec372a58f094f041c8f102f39393Kenny Root} 334494689083467ec372a58f094f041c8f102f39393Kenny Root 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 342655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 343655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 344655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 345655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 346655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 347655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 348655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 349655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 350655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 351655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 352655b958eb2180c7c06889f83f606d23421bf038cKenny Root 35307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 35407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 35507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 357655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 361655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 362655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 365a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 36670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 36770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 36870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 37707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 37907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 38007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 38107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 38207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 38307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 38407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 38507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 38607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 38707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 38807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 38907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 39007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 39107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 39207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 39307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 39407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 39507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 39607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 39707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 39807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 40007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 409150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 4105281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 411150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 422150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 423150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 424150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 425150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 437150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 444150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 445150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4525187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 465f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 472822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 478822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 486f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 496822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 497d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 499822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 500822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 50117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker TYPE_KEYMASTER_10 = 4, 502822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 503822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 504f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 505822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 508803f37f5d1bf75cb6e0d007f7d473645efd19a1dChad Brubaker Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength, 50907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 5101773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin memset(&mBlob, 0, sizeof(mBlob)); 51154b1e9ad01c8042a449a9237833a335d6be04e83Chad Brubaker if (valueLength > VALUE_SIZE) { 51254b1e9ad01c8042a449a9237833a335d6be04e83Chad Brubaker valueLength = VALUE_SIZE; 513803f37f5d1bf75cb6e0d007f7d473645efd19a1dChad Brubaker ALOGW("Provided blob length too large"); 514803f37f5d1bf75cb6e0d007f7d473645efd19a1dChad Brubaker } 51554b1e9ad01c8042a449a9237833a335d6be04e83Chad Brubaker if (infoLength + valueLength > VALUE_SIZE) { 51654b1e9ad01c8042a449a9237833a335d6be04e83Chad Brubaker infoLength = VALUE_SIZE - valueLength; 517803f37f5d1bf75cb6e0d007f7d473645efd19a1dChad Brubaker ALOGW("Provided info length too large"); 518803f37f5d1bf75cb6e0d007f7d473645efd19a1dChad Brubaker } 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 524822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 52507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 526822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 527f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 528ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 529ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 530ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 531ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 532ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5391773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin Blob() { 5401773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin memset(&mBlob, 0, sizeof(mBlob)); 5411773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin } 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5435187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5475187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5515187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 5525187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 5535187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 5545187818895c4c5f650a611c40531b1dff7764c18Kenny Root 5555187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 556a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 559822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 560822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 561822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 562822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 563f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 564f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 565f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 566f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 567f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 568f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 569f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 570f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 571f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 572f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 573f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 574f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 575f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 576f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 577f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 578f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 57917208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 58017208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 58117208e0de5a42722901d803118745cca25fd10c1Kenny Root } 58217208e0de5a42722901d803118745cca25fd10c1Kenny Root 58317208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 58417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 58517208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 58617208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 58717208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 58817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 58917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 59017208e0de5a42722901d803118745cca25fd10c1Kenny Root 591822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 592822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 593822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 594822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 595822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 596822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 597822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 598822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 599822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 600822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 601822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 602822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 603f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 604f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 605f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 606f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 607f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 608f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 609f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 610f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 611f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 612f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 613f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 614f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 631f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 632f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 633f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 634f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 635f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 636f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 637f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 638f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 644150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 645150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 646150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 647150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 655150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 659150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 660150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 661150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 662150ca934edb745de3666a6492b039900df228ff0Kenny Root } 663150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 666f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 667f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 668150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 669150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 679f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 680a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker if (fileLength == 0) { 681a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker return VALUE_CORRUPTED; 682a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker } 683a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker 684f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 685f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 686f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 687f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 694f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 697f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 698f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 699f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 700f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 701f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 702f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 703f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 704f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 705f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 706f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 707f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 708f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 709f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 710f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 711f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 712f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 713f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 72507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 732655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 733655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 734655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 735655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 736655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 737655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 73870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 739655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 741655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 742655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 74370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 744655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 745655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 746655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 748655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 749655b958eb2180c7c06889f83f606d23421bf038cKenny Root 750655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 75570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 756655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 757655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 758655b958eb2180c7c06889f83f606d23421bf038cKenny Root 759655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 760655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 761655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 762655b958eb2180c7c06889f83f606d23421bf038cKenny Root 763655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 765655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root 767655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 768655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 769655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 770655b958eb2180c7c06889f83f606d23421bf038cKenny Root 771655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 772655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 774655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 775655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7785187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7825187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 786655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 787655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 788655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 789655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 790655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 79170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 79270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 79396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker bool deleteMasterKey() { 79496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker setState(STATE_UNINITIALIZED); 79596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker zeroizeMasterKeysInMemory(); 79696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return unlink(mMasterKeyFile) == 0 || errno == ENOENT; 79796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 79896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker 799655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 800655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 803655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 80807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 8114e865753346fc6a075966972a7a98051818859dbRobin Lee ResponseCode copyMasterKey(UserState* src) { 8124e865753346fc6a075966972a7a98051818859dbRobin Lee if (mState != STATE_UNINITIALIZED) { 8134e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 8144e865753346fc6a075966972a7a98051818859dbRobin Lee } 8154e865753346fc6a075966972a7a98051818859dbRobin Lee if (src->getState() != STATE_NO_ERROR) { 8164e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 8174e865753346fc6a075966972a7a98051818859dbRobin Lee } 8184e865753346fc6a075966972a7a98051818859dbRobin Lee memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES); 8194e865753346fc6a075966972a7a98051818859dbRobin Lee setupMasterKeys(); 8204e865753346fc6a075966972a7a98051818859dbRobin Lee return ::NO_ERROR; 8214e865753346fc6a075966972a7a98051818859dbRobin Lee } 8224e865753346fc6a075966972a7a98051818859dbRobin Lee 823655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 828822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 829f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 832655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 834150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 835a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 840a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 841a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 842a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 845a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 851a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 857f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 858f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 860f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 865655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 867a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 869a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 871a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 872a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 873a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 874a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 875a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 876a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 877a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 878a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 879a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 880a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 881a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 882a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 883a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 884a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 885a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 886a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 887a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 888a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 889a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 893a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 897a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 900a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 90196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // If the directory doesn't exist then nothing to do. 90296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (errno == ENOENT) { 90396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return true; 90496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 906a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 907a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 910a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 91196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // skip . and .. 91296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (!strcmp(".", file->d_name) || !strcmp("..", file->d_name)) { 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 917a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 918a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 919a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 920a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 921a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 922655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 957655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 963655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 964655b958eb2180c7c06889f83f606d23421bf038cKenny Root 965655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root 967655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 977655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root 980655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 983655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 984655b958eb2180c7c06889f83f606d23421bf038cKenny Root 985655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 986655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 98767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker KeyStore(Entropy* entropy, keymaster1_device_t* device, keymaster1_device_t* fallback) 988655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 989655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 990fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker , mFallbackDevice(fallback) 991655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 992655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 993655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 994655b958eb2180c7c06889f83f606d23421bf038cKenny Root 995655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 996655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 997655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 998655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 999655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1000c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mGrants.clear(); 1001655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1002655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1003655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1004655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1006c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mMasterKeys.clear(); 1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1008655b958eb2180c7c06889f83f606d23421bf038cKenny Root 100967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker /** 101067d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * Depending on the hardware keymaster version is this may return a 101167d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * keymaster0_device_t* cast to a keymaster1_device_t*. All methods from 101267d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * keymaster0 are safe to call, calls to keymaster1_device_t methods should 101367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * be guarded by a check on the device's version. 101467d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker */ 101567d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t *getDevice() const { 1016655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 1017655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1018655b958eb2180c7c06889f83f606d23421bf038cKenny Root 101967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t *getFallbackDevice() const { 1020fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return mFallbackDevice; 1021fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 1022fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 102367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t *getDeviceForBlob(const Blob& blob) const { 1024fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return blob.isFallback() ? mFallbackDevice: mDevice; 1025fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 1026fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 1027655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 1028655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 1029655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 1031655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1032655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1033655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 1034655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1035655b958eb2180c7c06889f83f606d23421bf038cKenny Root 103672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State getState(uid_t userId) { 103772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return getUserState(userId)->getState(); 1038655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1039655b958eb2180c7c06889f83f606d23421bf038cKenny Root 104072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode initializeUser(const android::String8& pw, uid_t userId) { 104172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1042655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root 104572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser) { 104672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState *userState = getUserState(dstUser); 104772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState *initState = getUserState(srcUser); 10484e865753346fc6a075966972a7a98051818859dbRobin Lee return userState->copyMasterKey(initState); 10494e865753346fc6a075966972a7a98051818859dbRobin Lee } 10504e865753346fc6a075966972a7a98051818859dbRobin Lee 105172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode writeMasterKey(const android::String8& pw, uid_t userId) { 105272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1053655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 1054655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root 105672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode readMasterKey(const android::String8& pw, uid_t userId) { 105772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1058655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 1059655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1060655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1061655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 1062a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1063655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1064655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 1065655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1066655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1067655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 1068a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1069655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1070655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 1071655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1072655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1073655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 1074a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1075655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 107672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid, 1077655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 1078655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1079655b958eb2180c7c06889f83f606d23421bf038cKenny Root 108096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker /* 108196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * Delete entries owned by userId. If keepUnencryptedEntries is true 108296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * then only encrypted entries will be removed, otherwise all entries will 108396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * be removed. 108496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker */ 108596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker void resetUser(uid_t userId, bool keepUnenryptedEntries) { 10864b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::String8 prefix(""); 10874b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::Vector<android::String16> aliases; 108872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1089e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (list(prefix, &aliases, userId) != ::NO_ERROR) { 109096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return; 10914b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 10924b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee for (uint32_t i = 0; i < aliases.size(); i++) { 10934b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::String8 filename(aliases[i]); 10944b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee filename = android::String8::format("%s/%s", userState->getUserDirName(), 109596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker getKeyName(filename).string()); 109696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker bool shouldDelete = true; 109796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (keepUnenryptedEntries) { 109896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker Blob blob; 109972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode rc = get(filename, &blob, ::TYPE_ANY, userId); 110096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker 110196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker /* get can fail if the blob is encrypted and the state is 110296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * not unlocked, only skip deleting blobs that were loaded and 110396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * who are not encrypted. If there are blobs we fail to read for 110496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * other reasons err on the safe side and delete them since we 110596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * can't tell if they're encrypted. 110696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker */ 110796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker shouldDelete = !(rc == ::NO_ERROR && !blob.isEncrypted()); 110896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 110996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (shouldDelete) { 111072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker del(filename, ::TYPE_ANY, userId); 111196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 111296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 111396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (!userState->deleteMasterKey()) { 111496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGE("Failed to delete user %d's master key", userId); 111596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 111696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (!keepUnenryptedEntries) { 111796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if(!userState->reset()) { 111896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGE("Failed to remove user %d's directory", userId); 111996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 11204b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 1121655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root 112372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker bool isEmpty(uid_t userId) const { 112472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker const UserState* userState = getUserState(userId); 112596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (userState == NULL) { 1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1128655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1129655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 1130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 1131a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 1132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1133655b958eb2180c7c06889f83f606d23421bf038cKenny Root 113431e27468b6d822adbd2aec9219a68c206aa6957cKenny Root bool result = true; 113531e27468b6d822adbd2aec9219a68c206aa6957cKenny Root struct dirent* file; 1136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 1137655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1138655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1139655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1140655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1141655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1142655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1143655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1144655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1145655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1146655b958eb2180c7c06889f83f606d23421bf038cKenny Root 114731e27468b6d822adbd2aec9219a68c206aa6957cKenny Root result = false; 114831e27468b6d822adbd2aec9219a68c206aa6957cKenny Root break; 1149a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1150a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 1151a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 1152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 115472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker void lock(uid_t userId) { 115572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1156655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1157655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 1158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 116072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) { 116172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1162f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1163f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 1164822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1165822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1166822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1167822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1168822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 116907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1170cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1171cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1172cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1173cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 117472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker if (upgradeBlob(filename, keyBlob, version, type, userId)) { 117572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker if ((rc = this->put(filename, keyBlob, userId)) != NO_ERROR 1176f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1177f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1178cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1179cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1180cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1181822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1182822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 118317208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 118417208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 118517208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 118617208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 118717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 118817208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 118917208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 119017208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 119172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker userId, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 119217208e0de5a42722901d803118745cca25fd10c1Kenny Root 119317208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 119417208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 119517208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 119672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId); 119717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 119817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 119917208e0de5a42722901d803118745cca25fd10c1Kenny Root 12003a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker // Keymaster 0.3 keys are valid keymaster 1.0 keys, so silently upgrade. 12013a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (keyBlob->getType() == TYPE_KEY_PAIR) { 12023cc40125e8b495e7f0784dad53bb9acdb5b9a8ebChad Brubaker keyBlob->setType(TYPE_KEYMASTER_10); 12033a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker rc = this->put(filename, keyBlob, userId); 12043cc40125e8b495e7f0784dad53bb9acdb5b9a8ebChad Brubaker } 12053cc40125e8b495e7f0784dad53bb9acdb5b9a8ebChad Brubaker 1206d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1207822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1208822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1209822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1210822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1211822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 121472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode put(const char* filename, Blob* keyBlob, uid_t userId) { 121572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1216f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1217f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 122072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode del(const char *filename, const BlobType type, uid_t userId) { 12214b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee Blob keyBlob; 122272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode rc = get(filename, &keyBlob, type, userId); 1223a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker if (rc == ::VALUE_CORRUPTED) { 1224a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker // The file is corrupt, the best we can do is rm it. 1225a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1226a9a17eeca2f5d9d3101a7e0bb136360697b6e2f0Chad Brubaker } 12274b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (rc != ::NO_ERROR) { 12284b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return rc; 12294b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12304b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12314b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 12324b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // A device doesn't have to implement delete_keypair. 12334b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mDevice->delete_keypair != NULL && !keyBlob.isFallback()) { 12344b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mDevice->delete_keypair(mDevice, keyBlob.getValue(), keyBlob.getLength())) { 12354b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee rc = ::SYSTEM_ERROR; 12364b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12374b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12384b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 123917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (keyBlob.getType() == ::TYPE_KEYMASTER_10) { 124017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster1_device_t* dev = getDeviceForBlob(keyBlob); 124117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (dev->delete_key) { 124217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_blob_t blob; 124317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker blob.key_material = keyBlob.getValue(); 124417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker blob.key_material_size = keyBlob.getLength(); 124517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker dev->delete_key(dev, &blob); 124617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 124717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 12484b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (rc != ::NO_ERROR) { 12494b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return rc; 12504b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12514b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12524b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 12534b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12544b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 1255e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker ResponseCode list(const android::String8& prefix, android::Vector<android::String16> *matches, 125672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker uid_t userId) { 12574b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 125872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 12594b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t n = prefix.length(); 12604b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12614b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee DIR* dir = opendir(userState->getUserDirName()); 12624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!dir) { 12634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("can't open directory for user: %s", strerror(errno)); 12644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 12654b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12664b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12674b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee struct dirent* file; 12684b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee while ((file = readdir(dir)) != NULL) { 12694b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // We only care about files. 12704b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_type != DT_REG) { 12714b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12724b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12734b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12744b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // Skip anything that starts with a "." 12754b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_name[0] == '.') { 12764b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12774b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12784b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12794b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!strncmp(prefix.string(), file->d_name, n)) { 12804b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee const char* p = &file->d_name[n]; 12814b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t plen = strlen(p); 12824b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12834b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t extra = decode_key_length(p, plen); 12844b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee char *match = (char*) malloc(extra + 1); 12854b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (match != NULL) { 12864b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee decode_key(match, p, plen); 12874b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee matches->push(android::String16(match, extra)); 12884b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee free(match); 12894b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } else { 12904b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("could not allocate match of size %zd", extra); 12914b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12924b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12934b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12944b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee closedir(dir); 12954b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 12964b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12974b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 129807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1299655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1300655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1301655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 130207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1303a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1304655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 130570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 130670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 130770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1309655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1310655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1311655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1312655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1313655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1314655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1315655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1316655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 131770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 131870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 131970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 132070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1321a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1322a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 132370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 132470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 132572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t userId, 1326f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1327822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1328822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1329822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1330822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1331822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1332822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1333822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1334822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 133617208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 133707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 1339a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root /* 1340a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * Maybe the device doesn't support this type of key. Try to use the 1341a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * software fallback keymaster implementation. This is a little bit 1342a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * lazier than checking the PKCS#8 key type, but the software 1343a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * implementation will do that anyway. 1344a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root */ 13457c1eb75a6898452867ca28a4d7fad2d91edca615Chad Brubaker rc = mFallbackDevice->import_keypair(mFallbackDevice, key, keyLen, &data, &dataLength); 1346a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root isFallback = true; 134717208e0de5a42722901d803118745cca25fd10c1Kenny Root 134817208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 134917208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 135017208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 135117208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1352822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1353822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1354822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1355822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1356822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1357f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 135817208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1359f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 136072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return put(filename, &keyBlob, userId); 1361822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1362822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 13631b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 13641b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 13651b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 13661b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 13671b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 13681b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 13691b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 13701b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 13711b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 13721b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 13731b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 13741b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 13751b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 13768ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 13778ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 138086b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 138172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker uid_t userId = get_user_id(uid); 1382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 138372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode responseCode = get(filepath8.string(), keyBlob, type, userId); 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1385655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 139186b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 139272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker responseCode = get(filepath8.string(), keyBlob, type, userId); 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 139770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 139986b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 140186b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 140572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker filepath8 = android::String8::format("%s/%s", getUserState(userId)->getUserDirName(), 140686b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 141272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return get(filepath8.string(), keyBlob, type, userId); 1413a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1415655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1417655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 141872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* getUserState(uid_t userId) { 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1420655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1421655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1422655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1423655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1424655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1426655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1427655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1428655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1429655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1430655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1431655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1432655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1433655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1435655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1436655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1439655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 144072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker * Returns any existing UserState or creates it if it doesn't exist. 1441655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 144272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* getUserStateByUid(uid_t uid) { 1443655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 144472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return getUserState(userId); 144572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker } 1446655b958eb2180c7c06889f83f606d23421bf038cKenny Root 144772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker /** 144872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker * Returns NULL if the UserState doesn't already exist. 144972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker */ 145072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker const UserState* getUserState(uid_t userId) const { 1451655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1452655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1453655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1454655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1455655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1456655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1457655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1459655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 146272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker /** 146372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker * Returns NULL if the UserState doesn't already exist. 146472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker */ 146572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker const UserState* getUserStateByUid(uid_t uid) const { 146672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker uid_t userId = get_user_id(uid); 146772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return getUserState(userId); 146872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker } 146972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker 1470655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1471655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1472655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 14731b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1474655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 147507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 147667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t* mDevice; 147767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t* mFallbackDevice; 1478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1479655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1480655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1481655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 148270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1483655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1484655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1485655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 148670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1487655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1488655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1489655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1490655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1491655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1492655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 149370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1494655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 149570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 149670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 149770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 149870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 149970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 150070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1501822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1502822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1503822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1504822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1505655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1506655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1507822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1508822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1509822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1510822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1511822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1512822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1513822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1514822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1515822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1516655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1517822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1518822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1519822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1520822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1521822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1522f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1523f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1524f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1525f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1526f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1527f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1528f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1529f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1530f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1531822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1532822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1533822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1534cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1535822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1536822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1537822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1538822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1539cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1540cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1541822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1542822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1543822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1544822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1545822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1546822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1547822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1548822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1549655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1550822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1551822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1552822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1553822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1554822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1555822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1556822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1557822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1558822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1559822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1560822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1561822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1562822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1563822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1564822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1565822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1566822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1567822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1568822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1569822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 157070c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 157170c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1572822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1573822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1574822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1575822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1576822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 157772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode rc = importKey(pkcs8key.get(), len, filename, get_user_id(uid), 1578f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1579822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1580822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1581822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1582822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1583655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1584822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 158570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1586655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1587655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1588655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1589655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1590655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1591655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1592655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1593655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1594655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1595655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1596655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 159770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 159870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1599655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1600655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1601655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1602655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1603655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1604655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1605655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1606655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1607655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1608655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1609655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1610655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 161170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1612655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1613655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 161470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 161570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1616655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1617655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1618655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1619655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 162072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserStateByUid(0); 1621655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1622655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1623655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1624655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1625655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1626655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1627655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1628655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1629655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1630655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1631655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1632655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1633655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1634655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1635655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1636655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1637655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1638655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1639655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1640655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1641655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1642655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1643655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1644655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1645655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1646655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1647655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1649655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1650655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1652655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1653655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1654655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1655655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1656655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1657655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1658655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1659655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1660655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1661655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 166272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* otherUser = getUserStateByUid(thisUid); 1663655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1664655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1665655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1666655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1667655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1668655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1669655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1670655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1671655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1672655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1673655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1674655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1675655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1676655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1677655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1678655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1679655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1680655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1681655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1682655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1683655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1684655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 168570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1686655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 168770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1688655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1689655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 169070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 16911b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 16921b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 169740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker : mKeyStore(keyStore), 169840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker mOperationMap(this) 169907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 170007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 170240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void binderDied(const wp<IBinder>& who) { 170340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker auto operations = mOperationMap.getOperationsForToken(who.unsafe_get()); 170440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker for (auto token: operations) { 170540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker abort(token); 170640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 170707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1709e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker int32_t getState(int32_t userId) { 1710e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (!checkBinderPermission(P_GET_STATE)) { 171107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1714e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker return mKeyStore->getState(userId); 1715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 171707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 17189489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_GET)) { 171907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 172007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 17229489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 172307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 172407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 172566dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 1726655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1727494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 172807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 172907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 173007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 173107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 173207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 173407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 173507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 173707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 173807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1740a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1741f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1742f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 17439489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 17449489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, 17459489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 17469489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 17479489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 1748b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1749b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 175007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1751655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 175207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 175307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1754ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1755ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 175672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid)); 1757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1759494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 17609489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 17619489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_DELETE, targetUid)) { 1762b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1763b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 176407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1765655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 176672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid)); 1767298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1768298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1769494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 17709489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 17719489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_EXIST, targetUid)) { 1772b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1773b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1774b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 177507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1776655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1778655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 177907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 178007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 178107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1782298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1783298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1784e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker int32_t list(const String16& prefix, int targetUid, Vector<String16>* matches) { 17859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 1786e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (!checkBinderPermission(P_LIST, targetUid)) { 1787b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1788b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 178907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1790655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 179107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1792e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ::NO_ERROR) { 17934b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 179407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 179507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1796298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1797298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 179807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 17999489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_RESET)) { 180007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 180107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 18039489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 180496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker mKeyStore->resetUser(get_user_id(callingUid), false); 180596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return ::NO_ERROR; 1806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 180896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker int32_t onUserPasswordChanged(int32_t userId, const String16& password) { 18099489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_PASSWORD)) { 181007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 181107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 181307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 181496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // Flush the auth token table to prevent stale tokens from sticking 181596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // around. 181696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker mAuthTokenTable.Clear(); 181796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker 181896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (password.size() == 0) { 181996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId); 182072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->resetUser(userId, true); 182196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return ::NO_ERROR; 182296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } else { 182372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker switch (mKeyStore->getState(userId)) { 182496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker case ::STATE_UNINITIALIZED: { 182596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // generate master key, encrypt with password, write to file, 182696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // initialize mMasterKey*. 182772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->initializeUser(password8, userId); 182896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 182996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker case ::STATE_NO_ERROR: { 183096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // rewrite master key with new password. 183172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->writeMasterKey(password8, userId); 183296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 183396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker case ::STATE_LOCKED: { 183496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGE("Changing user %d's password while locked, clearing old encryption", 183596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker userId); 183672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->resetUser(userId, true); 183772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->initializeUser(password8, userId); 183896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 183907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 184096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return ::SYSTEM_ERROR; 184107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 184207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1844c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker int32_t onUserAdded(int32_t userId, int32_t parentId) { 1845c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (!checkBinderPermission(P_USER_CHANGED)) { 1846c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::PERMISSION_DENIED; 1847c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1848c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1849c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // Sanity check that the new user has an empty keystore. 1850c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (!mKeyStore->isEmpty(userId)) { 1851c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker ALOGW("New user %d's keystore not empty. Clearing old entries.", userId); 1852c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1853c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // Unconditionally clear the keystore, just to be safe. 1854c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker mKeyStore->resetUser(userId, false); 1855c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1856c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // If the user has a parent user then use the parent's 1857c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // masterkey/password, otherwise there's nothing to do. 1858c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (parentId != -1) { 1859c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return mKeyStore->copyMasterKey(parentId, userId); 1860c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } else { 1861c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::NO_ERROR; 1862c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1863c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1864c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1865c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker int32_t onUserRemoved(int32_t userId) { 1866c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (!checkBinderPermission(P_USER_CHANGED)) { 1867c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::PERMISSION_DENIED; 1868c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1869c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1870c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker mKeyStore->resetUser(userId, false); 1871c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::NO_ERROR; 1872c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1873c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1874e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker int32_t lock(int32_t userId) { 18759489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_LOCK)) { 187607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 187707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 187807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 187972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(userId); 18809d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 188107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 188207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 188307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 188470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->lock(userId); 188607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 188770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1888a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 188996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker int32_t unlock(int32_t userId, const String16& pw) { 18909489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_UNLOCK)) { 189107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 189207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 189307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 189472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(userId); 18959d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 189696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGI("calling unlock when not locked, ignoring."); 189707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 189807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 189907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 190007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 190196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // read master key, decrypt with password, initialize mMasterKey*. 190272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->readMasterKey(password8, userId); 190370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 190470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1905e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker bool isEmpty(int32_t userId) { 1906e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (!checkBinderPermission(P_IS_EMPTY)) { 1907e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker return false; 190807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1910e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker return mKeyStore->isEmpty(userId); 191170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 191270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 191396427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 191496427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 19159489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 19169489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, 19179489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 19189489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 19199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 192007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 192170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 19223a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker KeymasterArguments params; 19232de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden addLegacyKeyAuthorizations(params.params, keyType); 192470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 19253a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker switch (keyType) { 19263a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker case EVP_PKEY_EC: { 19273a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC)); 19283a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (keySize == -1) { 19293a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker keySize = EC_DEFAULT_KEY_SIZE; 19303a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 19313a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGI("invalid key size %d", keySize); 193296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 193396427baf0094d50047049d329b0779c3c910402cKenny Root } 19343a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.params.push_back(keymaster_param_int(KM_TAG_KEY_SIZE, keySize)); 19353a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker break; 193696427baf0094d50047049d329b0779c3c910402cKenny Root } 19373a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker case EVP_PKEY_RSA: { 19383a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA)); 19393a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (keySize == -1) { 19403a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker keySize = RSA_DEFAULT_KEY_SIZE; 19413a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 19423a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGI("invalid key size %d", keySize); 19433a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 19443a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 19453a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.params.push_back(keymaster_param_int(KM_TAG_KEY_SIZE, keySize)); 19463a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker unsigned long exponent = RSA_DEFAULT_EXPONENT; 19473a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (args->size() > 1) { 19483a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGI("invalid number of arguments: %zu", args->size()); 19493a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 19503a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } else if (args->size() == 1) { 19513a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker sp<KeystoreArg> expArg = args->itemAt(0); 19523a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (expArg != NULL) { 19533a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker Unique_BIGNUM pubExpBn( 19543a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker BN_bin2bn(reinterpret_cast<const unsigned char*>(expArg->data()), 19553a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker expArg->size(), NULL)); 19563a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (pubExpBn.get() == NULL) { 19573a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGI("Could not convert public exponent to BN"); 19583a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 19593a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 19603a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker exponent = BN_get_word(pubExpBn.get()); 19613a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (exponent == 0xFFFFFFFFL) { 19623a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("cannot represent public exponent as a long value"); 19633a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 19643a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 19653a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } else { 19663a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("public exponent not read"); 196796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 196896427baf0094d50047049d329b0779c3c910402cKenny Root } 196996427baf0094d50047049d329b0779c3c910402cKenny Root } 19703a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.params.push_back(keymaster_param_long(KM_TAG_RSA_PUBLIC_EXPONENT, 19713a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker exponent)); 19723a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker break; 19733a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 19743a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker default: { 19753a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("Unsupported key type %d", keyType); 19763a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 197796427baf0094d50047049d329b0779c3c910402cKenny Root } 197896427baf0094d50047049d329b0779c3c910402cKenny Root } 197970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 19803a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker int32_t rc = generateKey(name, params, NULL, 0, targetUid, flags, 19813a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker /*outCharacteristics*/ NULL); 19823a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (rc != ::NO_ERROR) { 19833a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("generate failed: %d", rc); 198407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 19853a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return translateResultToLegacyResult(rc); 198670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 198770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1988f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1989f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 19903a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker const uint8_t* ptr = data; 19919a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 19923a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, length)); 19933a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (!pkcs8.get()) { 199407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 199507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 19963a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get())); 19973a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (!pkey.get()) { 199807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 199907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20003a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker int type = EVP_PKEY_type(pkey->type); 20012de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden KeymasterArguments params; 20022de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden addLegacyKeyAuthorizations(params.params, type); 20033a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker switch (type) { 20043a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker case EVP_PKEY_RSA: 20053a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA)); 20063a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker break; 20073a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker case EVP_PKEY_EC: 20083a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, 20093a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker KM_ALGORITHM_EC)); 20103a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker break; 20113a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker default: 20123a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("Unsupported key type %d", type); 20133a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 20143a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 20153a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker int32_t rc = importKey(name, params, KM_KEY_FORMAT_PKCS8, data, length, targetUid, flags, 20163a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker /*outCharacteristics*/ NULL); 20173a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (rc != ::NO_ERROR) { 20183a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("importKey failed: %d", rc); 201907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20203a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return translateResultToLegacyResult(rc); 20213a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 202270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 20233a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 20243a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker size_t* outLength) { 20253a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (!checkBinderPermission(P_SIGN)) { 20263a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::PERMISSION_DENIED; 20273a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 20283a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return doLegacySignVerify(name, data, length, out, outLength, NULL, 0, KM_PURPOSE_SIGN); 202970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 203070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 203207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 20339489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_VERIFY)) { 203407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 203507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20363a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return doLegacySignVerify(name, data, dataLength, NULL, NULL, signature, signatureLength, 20373a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker KM_PURPOSE_VERIFY); 203870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 203970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 204007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 204107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 204207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 204307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 204607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 204707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 204807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 204907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 205007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 205107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 20523a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ExportResult result; 20533a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker exportKey(name, KM_KEY_FORMAT_X509, NULL, NULL, &result); 20543a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (result.resultCode != ::NO_ERROR) { 20553a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("export failed: %d", result.resultCode); 20563a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return translateResultToLegacyResult(result.resultCode); 205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2058344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 20593a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker *pubkey = result.exportData.release(); 20603a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker *pubkeyLength = result.dataLength; 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2062344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2063344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2065d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 20669489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT); 20679489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 20689489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2072655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2074655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2078655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2080a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 208207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2083d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 20849489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT); 20859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 20869489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 208907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2090655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 209107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2092655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2096655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2097a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2100d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 21019489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_GET)) { 2102d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 210336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 210407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2107655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 210807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2109655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2110655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 211136a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2112a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2114655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2116655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 211736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 211807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2124655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 212536a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 212607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 212836a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 213007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2131d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2132d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 21330225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2134eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2135eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DUPLICATE, spid)) { 2136d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 21370225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 21380225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21390225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 214072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(get_user_id(callingUid)); 21410225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2142d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 21430225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 21440225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21450225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2146d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2147d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2148d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2149d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 21500225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 21510225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21520225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2153d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2154d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2155d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21560225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2157d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2158d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2159d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2160d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2161d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2162d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21630225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2164d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2165d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2166d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2167d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21680225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21690225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2170d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2171655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2172d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2173d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2174fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid)); 21750225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2176655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2177655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 21780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 21790225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21800225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2181d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2182655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 218372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker get_user_id(srcUid)); 2184d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2185d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 21860225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2187d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 218872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(targetFile.string(), &keyBlob, get_user_id(destUid)); 21890225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21900225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 21911b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 21921b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 21938ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 21948ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2195fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int32_t clear_uid(int64_t targetUid64) { 21969489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t targetUid = getEffectiveUid(targetUid64); 2197b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) { 2198a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2199a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2200a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 22014b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 prefix = String8::format("%u_", targetUid); 22024b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee Vector<String16> aliases; 2203e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (mKeyStore->list(prefix, &aliases, get_user_id(targetUid)) != ::NO_ERROR) { 2204a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2205a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2206a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 22074b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee for (uint32_t i = 0; i < aliases.size(); i++) { 22084b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 name8(aliases[i]); 22094b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 221072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid)); 2211a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 22124b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 2213a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2214a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 22159c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t addRngEntropy(const uint8_t* data, size_t dataLength) { 22169c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 22179c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 22189c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t devResult = KM_ERROR_UNIMPLEMENTED; 22199c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t fallbackResult = KM_ERROR_UNIMPLEMENTED; 22209c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 22219c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker device->add_rng_entropy != NULL) { 22229c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker devResult = device->add_rng_entropy(device, data, dataLength); 22239c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 22249c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (fallback->add_rng_entropy) { 22259c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker fallbackResult = fallback->add_rng_entropy(fallback, data, dataLength); 22269c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 22279c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (devResult) { 22289c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return devResult; 22299c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 22309c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (fallbackResult) { 22319c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return fallbackResult; 22329c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 22339c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return ::NO_ERROR; 22349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 22359899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 223617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker int32_t generateKey(const String16& name, const KeymasterArguments& params, 2237154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker const uint8_t* entropy, size_t entropyLength, int uid, int flags, 2238154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker KeyCharacteristics* outCharacteristics) { 22399489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid = getEffectiveUid(uid); 22409489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid, 22419489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 22429489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (rc != ::NO_ERROR) { 22439489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return rc; 224417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 224517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 22469489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 224717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker bool isFallback = false; 224817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_blob_t blob; 224917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_characteristics_t *out = NULL; 225017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 225117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 225217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 225357e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 225457e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker const keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()}; 225517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (device == NULL) { 225617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return ::SYSTEM_ERROR; 225717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 2258154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker // TODO: Seed from Linux RNG before this. 225917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 226017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker device->generate_key != NULL) { 2261154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (!entropy) { 2262154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_OK; 2263154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else if (device->add_rng_entropy) { 2264154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = device->add_rng_entropy(device, entropy, entropyLength); 2265154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else { 2266154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 2267154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2268154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (rc == KM_ERROR_OK) { 226957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker rc = device->generate_key(device, &inParams, &blob, &out); 2270154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 227117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 227217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker // If the HW device didn't support generate_key or generate_key failed 227317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker // fall back to the software implementation. 227417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (rc && fallback->generate_key != NULL) { 227517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker isFallback = true; 2276154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (!entropy) { 2277154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_OK; 2278154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else if (fallback->add_rng_entropy) { 2279154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = fallback->add_rng_entropy(fallback, entropy, entropyLength); 2280154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else { 2281154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 2282154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2283154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (rc == KM_ERROR_OK) { 228457e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker rc = fallback->generate_key(fallback, &inParams, &blob, &out); 2285154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 228617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 228717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 228817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (out) { 228917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (outCharacteristics) { 229017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker outCharacteristics->characteristics = *out; 229117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } else { 229217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_free_characteristics(out); 229317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 229417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker free(out); 229517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 229617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 229717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (rc) { 229817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return rc; 229917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 230017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 230117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker String8 name8(name); 230217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid)); 230317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 230417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10); 230517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keyBlob.setFallback(isFallback); 230617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 230717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 230817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker free(const_cast<uint8_t*>(blob.key_material)); 230917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 231072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid)); 23119899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 23129899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 2313f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker int32_t getKeyCharacteristics(const String16& name, 2314d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* clientId, 2315d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* appData, 2316f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker KeyCharacteristics* outCharacteristics) { 2317f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (!outCharacteristics) { 2318f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return KM_ERROR_UNEXPECTED_NULL_POINTER; 2319f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2320f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker 2321f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2322f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker 2323f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker Blob keyBlob; 2324f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker String8 name8(name); 2325f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker int rc; 2326f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker 2327f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2328f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker TYPE_KEYMASTER_10); 2329f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (responseCode != ::NO_ERROR) { 2330f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return responseCode; 2331f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2332f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker keymaster_key_blob_t key; 2333f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker key.key_material_size = keyBlob.getLength(); 2334f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker key.key_material = keyBlob.getValue(); 2335f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob); 2336f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker keymaster_key_characteristics_t *out = NULL; 2337f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (!dev->get_key_characteristics) { 2338f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker ALOGW("device does not implement get_key_characteristics"); 2339f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return KM_ERROR_UNIMPLEMENTED; 2340f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2341d663442b590b59250062335cc057478001b8e439Chad Brubaker rc = dev->get_key_characteristics(dev, &key, clientId, appData, &out); 2342f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (out) { 2343f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker outCharacteristics->characteristics = *out; 2344f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker free(out); 2345f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2346f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return rc ? rc : ::NO_ERROR; 23479899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 23489899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 23494c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker int32_t importKey(const String16& name, const KeymasterArguments& params, 23504c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_key_format_t format, const uint8_t *keyData, 23514c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker size_t keyLength, int uid, int flags, 23524c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker KeyCharacteristics* outCharacteristics) { 23539489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid = getEffectiveUid(uid); 23549489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid, 23559489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 23569489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (rc != ::NO_ERROR) { 23579489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return rc; 23584c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 23594c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 23609489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 23614c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker bool isFallback = false; 23624c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_key_blob_t blob; 23634c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_key_characteristics_t *out = NULL; 23644c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 23654c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 23664c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 236757e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 236857e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker const keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()}; 236957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker const keymaster_blob_t input = {keyData, keyLength}; 23704c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (device == NULL) { 23714c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker return ::SYSTEM_ERROR; 23724c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 23734c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 23744c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker device->import_key != NULL) { 237557e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker rc = device->import_key(device, &inParams, format,&input, &blob, &out); 23764c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 23774c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (rc && fallback->import_key != NULL) { 23784c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker isFallback = true; 237957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker rc = fallback->import_key(fallback, &inParams, format, &input, &blob, &out); 23804c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 23814c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (out) { 23824c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (outCharacteristics) { 23834c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker outCharacteristics->characteristics = *out; 23844c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } else { 23854c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_free_characteristics(out); 23864c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 23874c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker free(out); 23884c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 23894c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (rc) { 23904c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker return rc; 23914c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 23924c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 23934c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker String8 name8(name); 23944c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid)); 23954c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 23964c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10); 23974c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keyBlob.setFallback(isFallback); 23984c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 23994c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 24004c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker free((void*) blob.key_material); 24014c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 240272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid)); 24039899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 24049899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 240507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker void exportKey(const String16& name, keymaster_key_format_t format, 2406d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* clientId, 2407d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* appData, ExportResult* result) { 240807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker 240907b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 241007b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker 241107b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker Blob keyBlob; 241207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker String8 name8(name); 241307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker int rc; 241407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker 241507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 241607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker TYPE_KEYMASTER_10); 241707b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker if (responseCode != ::NO_ERROR) { 241807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker result->resultCode = responseCode; 241907b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker return; 242007b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker } 242107b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker keymaster_key_blob_t key; 242207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker key.key_material_size = keyBlob.getLength(); 242307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker key.key_material = keyBlob.getValue(); 242407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob); 242507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker if (!dev->export_key) { 242607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker result->resultCode = KM_ERROR_UNIMPLEMENTED; 242707b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker return; 242807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker } 242957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_blob_t output = {NULL, 0}; 243057e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker rc = dev->export_key(dev, format, &key, clientId, appData, &output); 243157e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->exportData.reset(const_cast<uint8_t*>(output.data)); 243257e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->dataLength = output.data_length; 243307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker result->resultCode = rc ? rc : ::NO_ERROR; 24349899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 24359899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 2436ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker 243740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void begin(const sp<IBinder>& appToken, const String16& name, keymaster_purpose_t purpose, 2438154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker bool pruneable, const KeymasterArguments& params, const uint8_t* entropy, 243957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker size_t entropyLength, OperationResult* result) { 244040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 244140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) { 244240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid); 244340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = ::PERMISSION_DENIED; 244440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 244540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 24460cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!checkAllowedOperationParams(params.params)) { 24470cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = KM_ERROR_INVALID_ARGUMENT; 24480cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return; 24490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 245040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker Blob keyBlob; 245140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker String8 name8(name); 245240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 245340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker TYPE_KEYMASTER_10); 245440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (responseCode != ::NO_ERROR) { 245540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = responseCode; 245640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 245740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 245840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_key_blob_t key; 245940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker key.key_material_size = keyBlob.getLength(); 246040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker key.key_material = keyBlob.getValue(); 246140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 246240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob); 2463154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker keymaster_error_t err = KM_ERROR_UNIMPLEMENTED; 246406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 2465ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker Unique_keymaster_key_characteristics characteristics; 2466ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker characteristics.reset(new keymaster_key_characteristics_t); 2467ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker err = getOperationCharacteristics(key, dev, opParams, characteristics.get()); 2468ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker if (err) { 2469ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker result->resultCode = err; 2470ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker return; 2471ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker } 24720cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* authToken = NULL; 2473b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden int32_t authResult = getAuthToken(characteristics.get(), 0, purpose, &authToken, 247406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker /*failOnTokenMissing*/ false); 24750cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // If per-operation auth is needed we need to begin the operation and 24760cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // the client will need to authorize that operation before calling 24770cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // update. Any other auth issues stop here. 24780cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authResult != ::NO_ERROR && authResult != ::OP_AUTH_NEEDED) { 24790cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = authResult; 248006801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker return; 248106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } 24820cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker addAuthToParams(&opParams, authToken); 2483154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker // Add entropy to the device first. 2484154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (entropy) { 2485154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (dev->add_rng_entropy) { 2486154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker err = dev->add_rng_entropy(dev, entropy, entropyLength); 2487154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else { 2488154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker err = KM_ERROR_UNIMPLEMENTED; 2489154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2490154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (err) { 2491154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker result->resultCode = err; 2492154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker return; 2493154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2494154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 249557e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()}; 249640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker 24979221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden // Create a keyid for this key. 24989221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::km_id_t keyid; 24999221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (!enforcement_policy.CreateKeyId(key, &keyid)) { 25009221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden ALOGE("Failed to create a key ID for authorization checking."); 25019221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden result->resultCode = KM_ERROR_UNKNOWN_ERROR; 25029221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden return; 25039221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden } 25049221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden 25059221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden // Check that all key authorization policy requirements are met. 25069221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::AuthorizationSet key_auths(characteristics->hw_enforced); 25079221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden key_auths.push_back(characteristics->sw_enforced); 25089221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::AuthorizationSet operation_params(inParams); 25099221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden err = enforcement_policy.AuthorizeOperation(purpose, keyid, key_auths, operation_params, 25109221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden 0 /* op_handle */, 25119221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden true /* is_begin_operation */); 25129221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (err) { 25139221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden result->resultCode = err; 25149221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden return; 25159221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden } 25169221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden 25174e88f9be2b3bb3dcea43f338532882681ee77352Alex Klyubin keymaster_key_param_set_t outParams = {NULL, 0}; 25184e88f9be2b3bb3dcea43f338532882681ee77352Alex Klyubin err = dev->begin(dev, purpose, &key, &inParams, &outParams, &handle); 25194e88f9be2b3bb3dcea43f338532882681ee77352Alex Klyubin 252040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker // If there are too many operations abort the oldest operation that was 252140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker // started as pruneable and try again. 252240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker while (err == KM_ERROR_TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) { 252340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation(); 252440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker ALOGD("Ran out of operation handles, trying to prune %p", oldest.get()); 2525700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin 2526700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin // We mostly ignore errors from abort() below because all we care about is whether at 2527700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin // least one pruneable operation has been removed. 2528700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin size_t op_count_before = mOperationMap.getPruneableOperationCount(); 2529700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin int abort_error = abort(oldest); 2530700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin size_t op_count_after = mOperationMap.getPruneableOperationCount(); 2531700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin if (op_count_after >= op_count_before) { 2532700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin // Failed to create space for a new operation. Bail to avoid an infinite loop. 2533700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin ALOGE("Failed to remove pruneable operation %p, error: %d", 2534700c1a35c52798831b8a8d76a042c4650c6d793fAlex Klyubin oldest.get(), abort_error); 253540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker break; 253640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 253757e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker err = dev->begin(dev, purpose, &key, &inParams, &outParams, &handle); 253840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 253940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (err) { 254040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = err; 254140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 254240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 25439899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 25449221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden sp<IBinder> operationToken = mOperationMap.addOperation(handle, keyid, purpose, dev, 25459221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden appToken, characteristics.release(), 254606801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker pruneable); 25470cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authToken) { 25480cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker mOperationMap.setOperationAuthToken(operationToken, authToken); 25490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 25500cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // Return the authentication lookup result. If this is a per operation 25510cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the 25520cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // application should get an auth token using the handle before the 25530cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // first call to update, which will fail if keystore hasn't received the 25540cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // auth token. 25550cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = authResult; 255640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->token = operationToken; 2557c3a1856bbe2e39d5b3430f5f088b12fd710a159fChad Brubaker result->handle = handle; 255857e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker if (outParams.params) { 255957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->outParams.params.assign(outParams.params, outParams.params + outParams.length); 256057e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker free(outParams.params); 256157e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker } 25629899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25639899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 256440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void update(const sp<IBinder>& token, const KeymasterArguments& params, const uint8_t* data, 256540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker size_t dataLength, OperationResult* result) { 25660cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!checkAllowedOperationParams(params.params)) { 25670cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = KM_ERROR_INVALID_ARGUMENT; 25680cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return; 25690cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 257040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker const keymaster1_device_t* dev; 257140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 2572b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden keymaster_purpose_t purpose; 25739221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::km_id_t keyid; 25749221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden const keymaster_key_characteristics_t* characteristics; 25759221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) { 257640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE; 257740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 257840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 257906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 25800cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams); 25810cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authResult != ::NO_ERROR) { 258206801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker result->resultCode = authResult; 258306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker return; 258406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } 258557e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()}; 258657e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_blob_t input = {data, dataLength}; 258757e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker size_t consumed = 0; 258857e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_blob_t output = {NULL, 0}; 258957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_key_param_set_t outParams = {NULL, 0}; 259057e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker 25919221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden // Check that all key authorization policy requirements are met. 25929221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::AuthorizationSet key_auths(characteristics->hw_enforced); 25939221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden key_auths.push_back(characteristics->sw_enforced); 25949221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::AuthorizationSet operation_params(inParams); 25959221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden result->resultCode = 25969221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden enforcement_policy.AuthorizeOperation(purpose, keyid, key_auths, 25979221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden operation_params, handle, 25989221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden false /* is_begin_operation */); 25999221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (result->resultCode) { 26009221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden return; 26019221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden } 26029221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden 260357e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_error_t err = dev->update(dev, handle, &inParams, &input, &consumed, &outParams, 260457e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker &output); 260557e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->data.reset(const_cast<uint8_t*>(output.data)); 260657e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->dataLength = output.data_length; 260740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->inputConsumed = consumed; 260840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = err ? (int32_t) err : ::NO_ERROR; 260957e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker if (outParams.params) { 261057e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->outParams.params.assign(outParams.params, outParams.params + outParams.length); 261157e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker free(outParams.params); 261257e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker } 261340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 261440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker 261540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void finish(const sp<IBinder>& token, const KeymasterArguments& params, 26160d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker const uint8_t* signature, size_t signatureLength, 26170d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker const uint8_t* entropy, size_t entropyLength, OperationResult* result) { 26180cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!checkAllowedOperationParams(params.params)) { 26190cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = KM_ERROR_INVALID_ARGUMENT; 26200cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return; 26210cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 262240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker const keymaster1_device_t* dev; 262340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 2624b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden keymaster_purpose_t purpose; 26259221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::km_id_t keyid; 26269221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden const keymaster_key_characteristics_t* characteristics; 26279221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) { 262840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE; 262940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 263040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 263106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 26320cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams); 26330cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authResult != ::NO_ERROR) { 263406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker result->resultCode = authResult; 263506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker return; 263606801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } 26370d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker keymaster_error_t err; 26380d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker if (entropy) { 26390d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker if (dev->add_rng_entropy) { 26400d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker err = dev->add_rng_entropy(dev, entropy, entropyLength); 26410d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker } else { 26420d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker err = KM_ERROR_UNIMPLEMENTED; 26430d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker } 26440d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker if (err) { 26450d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker result->resultCode = err; 26460d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker return; 26470d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker } 26480d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker } 26490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 265057e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()}; 265157e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_blob_t input = {signature, signatureLength}; 265257e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_blob_t output = {NULL, 0}; 265357e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker keymaster_key_param_set_t outParams = {NULL, 0}; 26549221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden 26559221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden // Check that all key authorization policy requirements are met. 26569221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::AuthorizationSet key_auths(characteristics->hw_enforced); 26579221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden key_auths.push_back(characteristics->sw_enforced); 26589221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::AuthorizationSet operation_params(inParams); 26599221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden err = enforcement_policy.AuthorizeOperation(purpose, keyid, key_auths, operation_params, 26609221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden handle, false /* is_begin_operation */); 26619221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (err) { 26629221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden result->resultCode = err; 26639221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden return; 26649221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden } 26659221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden 26660d33e0babec356b1e69f1f15e8d9fe2ad878762cChad Brubaker err = dev->finish(dev, handle, &inParams, &input, &outParams, &output); 266740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker // Remove the operation regardless of the result 266840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker mOperationMap.removeOperation(token); 266906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker mAuthTokenTable.MarkCompleted(handle); 267057e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker 267157e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->data.reset(const_cast<uint8_t*>(output.data)); 267257e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->dataLength = output.data_length; 267340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = err ? (int32_t) err : ::NO_ERROR; 267457e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker if (outParams.params) { 267557e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker result->outParams.params.assign(outParams.params, outParams.params + outParams.length); 267657e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker free(outParams.params); 267757e106dc183744cdc05c62bea11bc285b3346846Chad Brubaker } 267840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 267940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker 268040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker int32_t abort(const sp<IBinder>& token) { 268140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker const keymaster1_device_t* dev; 268240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 2683b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden keymaster_purpose_t purpose; 26849221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::km_id_t keyid; 26859221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, NULL)) { 268640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return KM_ERROR_INVALID_OPERATION_HANDLE; 268740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 268840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker mOperationMap.removeOperation(token); 268906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker int32_t rc; 269040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (!dev->abort) { 269106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 269206801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } else { 269306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker rc = dev->abort(dev, handle); 269440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 269506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker mAuthTokenTable.MarkCompleted(handle); 269640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (rc) { 269740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return rc; 269840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 269940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return ::NO_ERROR; 27009899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 27019899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 27022ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker bool isOperationAuthorized(const sp<IBinder>& token) { 27032ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker const keymaster1_device_t* dev; 27042ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker keymaster_operation_handle_t handle; 2705ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker const keymaster_key_characteristics_t* characteristics; 2706b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden keymaster_purpose_t purpose; 27079221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::km_id_t keyid; 27089221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) { 27092ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker return false; 27102ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker } 27110cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* authToken = NULL; 27120cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker mOperationMap.getOperationAuthToken(token, &authToken); 271306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> ignored; 27140cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t authResult = addOperationAuthTokenIfNeeded(token, &ignored); 27150cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return authResult == ::NO_ERROR; 27162ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker } 27172ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker 2718d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker int32_t addAuthToken(const uint8_t* token, size_t length) { 27199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_ADD_AUTH)) { 27209489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker ALOGW("addAuthToken: permission denied for %d", 27219489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker IPCThreadState::self()->getCallingUid()); 2722d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker return ::PERMISSION_DENIED; 2723d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker } 2724d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker if (length != sizeof(hw_auth_token_t)) { 2725d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker return KM_ERROR_INVALID_ARGUMENT; 2726d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker } 2727d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker hw_auth_token_t* authToken = new hw_auth_token_t; 2728d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker memcpy(reinterpret_cast<void*>(authToken), token, sizeof(hw_auth_token_t)); 2729d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker // The table takes ownership of authToken. 2730d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker mAuthTokenTable.AddAuthenticationToken(authToken); 2731d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker return ::NO_ERROR; 27322ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker } 27332ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker 273407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 27359489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker static const int32_t UID_SELF = -1; 27369489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 27379489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 27389489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Get the effective target uid for a binder operation that takes an 27399489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * optional uid as the target. 27409489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 27419489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline uid_t getEffectiveUid(int32_t targetUid) { 27429489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (targetUid == UID_SELF) { 27439489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return IPCThreadState::self()->getCallingUid(); 27449489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27459489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return static_cast<uid_t>(targetUid); 27469489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27479489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 27489489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 27499489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Check if the caller of the current binder method has the required 27509489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * permission and if acting on other uids the grants to do so. 27519489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 27529489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline bool checkBinderPermission(perm_t permission, int32_t targetUid = UID_SELF) { 27539489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 27549489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker pid_t spid = IPCThreadState::self()->getCallingPid(); 27559489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!has_permission(callingUid, permission, spid)) { 27569489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid); 27579489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return false; 27589489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27599489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!is_granted_to(callingUid, getEffectiveUid(targetUid))) { 27609489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker ALOGW("uid %d not granted to act for %d", callingUid, targetUid); 27619489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return false; 27629489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27639489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return true; 27649489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27659489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 27669489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 27679489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Check if the caller of the current binder method has the required 2768b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker * permission and the target uid is the caller or the caller is system. 2769b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker */ 2770b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker inline bool checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid) { 2771b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2772b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker pid_t spid = IPCThreadState::self()->getCallingPid(); 2773b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker if (!has_permission(callingUid, permission, spid)) { 2774b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid); 2775b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker return false; 2776b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker } 2777b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker return getEffectiveUid(targetUid) == callingUid || callingUid == AID_SYSTEM; 2778b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker } 2779b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker 2780b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker /** 2781b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker * Check if the caller of the current binder method has the required 27829489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * permission or the target of the operation is the caller's uid. This is 27839489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * for operation where the permission is only for cross-uid activity and all 27849489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * uids are allowed to act on their own (ie: clearing all entries for a 27859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * given uid). 27869489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 27879489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline bool checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid) { 27889489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 27899489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (getEffectiveUid(targetUid) == callingUid) { 27909489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return true; 27919489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } else { 27929489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return checkBinderPermission(permission, targetUid); 27939489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27949489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27959489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 27969489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 27979489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Helper method to check that the caller has the required permission as 27989489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * well as the keystore is in the unlocked state if checkUnlocked is true. 27999489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * 28009489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and 28019489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * otherwise the state of keystore when not unlocked and checkUnlocked is 28029489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * true. 28039489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 28049489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline int32_t checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid = -1, 28059489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker bool checkUnlocked = true) { 28069489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(permission, targetUid)) { 28079489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return ::PERMISSION_DENIED; 28089489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 280972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(get_user_id(getEffectiveUid(targetUid))); 28109489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (checkUnlocked && !isKeystoreUnlocked(state)) { 28119489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return state; 28129489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 28139489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 28149489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return ::NO_ERROR; 28159489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 28169489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 28179489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 28189d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 28199d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 28209d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 28219d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 28229d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 28239d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 28249d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 28259d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 28269d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 282807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 282967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker bool isKeyTypeSupported(const keymaster1_device_t* device, keymaster_keypair_t keyType) { 28301d448c074a86ef5d05a22fdf1358718976628a86Kenny Root const int32_t device_api = device->common.module->module_api_version; 28311d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) { 28321d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 28331d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 28341d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 28351d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 28361d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 28371d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 28381d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 28391d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28401d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) { 28411d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 28421d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 28431d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 28441d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 28451d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_DSA; 28461d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 28471d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_EC; 28481d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 28491d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 28501d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28511d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else { 28521d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return keyType == TYPE_RSA; 28531d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28541d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28551d448c074a86ef5d05a22fdf1358718976628a86Kenny Root 28560cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker /** 28570cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Check that all keymaster_key_param_t's provided by the application are 28580cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * allowed. Any parameter that keystore adds itself should be disallowed here. 28590cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker */ 28600cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker bool checkAllowedOperationParams(const std::vector<keymaster_key_param_t>& params) { 28610cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (auto param: params) { 28620cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker switch (param.tag) { 28630cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case KM_TAG_AUTH_TOKEN: 28640cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return false; 28650cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker default: 28660cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker break; 28670cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28680cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28690cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return true; 28700cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28710cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 28720cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_error_t getOperationCharacteristics(const keymaster_key_blob_t& key, 28730cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const keymaster1_device_t* dev, 28740cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const std::vector<keymaster_key_param_t>& params, 28750cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_key_characteristics_t* out) { 28760cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker UniquePtr<keymaster_blob_t> appId; 28770cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker UniquePtr<keymaster_blob_t> appData; 28780cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (auto param : params) { 28790cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (param.tag == KM_TAG_APPLICATION_ID) { 28800cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appId.reset(new keymaster_blob_t); 28810cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appId->data = param.blob.data; 28820cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appId->data_length = param.blob.data_length; 28830cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } else if (param.tag == KM_TAG_APPLICATION_DATA) { 28840cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData.reset(new keymaster_blob_t); 28850cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData->data = param.blob.data; 28860cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData->data_length = param.blob.data_length; 28870cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28880cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28890cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_key_characteristics_t* result = NULL; 28900cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!dev->get_key_characteristics) { 28910cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_UNIMPLEMENTED; 28920cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28930cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_error_t error = dev->get_key_characteristics(dev, &key, appId.get(), 28940cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData.get(), &result); 28950cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (result) { 28960cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker *out = *result; 28970cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker free(result); 28980cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28990cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return error; 29000cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29010cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29020cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker /** 29030cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Get the auth token for this operation from the auth token table. 29040cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * 29050cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Returns ::NO_ERROR if the auth token was set or none was required. 29060cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * ::OP_AUTH_NEEDED if it is a per op authorization, no 29070cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * authorization token exists for that operation and 29080cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * failOnTokenMissing is false. 29090cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth 29100cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * token for the operation 29110cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker */ 29120cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t getAuthToken(const keymaster_key_characteristics_t* characteristics, 29130cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_operation_handle_t handle, 2914b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden keymaster_purpose_t purpose, 29150cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t** authToken, 29160cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker bool failOnTokenMissing = true) { 29170cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29180cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker std::vector<keymaster_key_param_t> allCharacteristics; 29190cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (size_t i = 0; i < characteristics->sw_enforced.length; i++) { 29200cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker allCharacteristics.push_back(characteristics->sw_enforced.params[i]); 29210cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29220cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (size_t i = 0; i < characteristics->hw_enforced.length; i++) { 29230cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker allCharacteristics.push_back(characteristics->hw_enforced.params[i]); 29240cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 2925b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden keymaster::AuthTokenTable::Error err = mAuthTokenTable.FindAuthorization( 2926b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden allCharacteristics.data(), allCharacteristics.size(), purpose, handle, authToken); 29270cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker switch (err) { 29280cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::OK: 29290cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_NOT_REQUIRED: 29300cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return ::NO_ERROR; 29310cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_TOKEN_NOT_FOUND: 29320cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_TOKEN_EXPIRED: 29330cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_TOKEN_WRONG_SID: 29340cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_KEY_USER_NOT_AUTHENTICATED; 29350cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::OP_HANDLE_REQUIRED: 29360cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return failOnTokenMissing ? (int32_t) KM_ERROR_KEY_USER_NOT_AUTHENTICATED : 29370cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker (int32_t) ::OP_AUTH_NEEDED; 29380cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker default: 29390cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker ALOGE("Unexpected FindAuthorization return value %d", err); 29400cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_INVALID_ARGUMENT; 29410cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29420cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29430cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29440cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker inline void addAuthToParams(std::vector<keymaster_key_param_t>* params, 29450cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* token) { 29460cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (token) { 29470cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker params->push_back(keymaster_param_blob(KM_TAG_AUTH_TOKEN, 29480cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker reinterpret_cast<const uint8_t*>(token), 29490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker sizeof(hw_auth_token_t))); 29500cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29510cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29520cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29530cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker /** 29540cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Add the auth token for the operation to the param list if the operation 29550cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * requires authorization. Uses the cached result in the OperationMap if available 29560cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * otherwise gets the token from the AuthTokenTable and caches the result. 29570cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * 29580cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Returns ::NO_ERROR if the auth token was added or not needed. 29590cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not 29600cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * authenticated. 29610cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid 29620cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * operation token. 29630cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker */ 29640cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t addOperationAuthTokenIfNeeded(sp<IBinder> token, 29650cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker std::vector<keymaster_key_param_t>* params) { 29660cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* authToken = NULL; 29677169a8470f6539036addf3c960b075af224e83e2Chad Brubaker mOperationMap.getOperationAuthToken(token, &authToken); 29687169a8470f6539036addf3c960b075af224e83e2Chad Brubaker if (!authToken) { 29690cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const keymaster1_device_t* dev; 29700cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_operation_handle_t handle; 29710cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const keymaster_key_characteristics_t* characteristics = NULL; 2972b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden keymaster_purpose_t purpose; 29739221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden keymaster::km_id_t keyid; 29749221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, 29759221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden &characteristics)) { 29760cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_INVALID_OPERATION_HANDLE; 29770cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 2978b2ffa420da26414379b31807eec76ec8c9f3b0a9Shawn Willden int32_t result = getAuthToken(characteristics, handle, purpose, &authToken); 29790cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (result != ::NO_ERROR) { 29800cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return result; 29810cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29820cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authToken) { 29830cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker mOperationMap.setOperationAuthToken(token, authToken); 29840cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29850cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29860cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker addAuthToParams(params, authToken); 29870cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return ::NO_ERROR; 29880cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29890cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29903a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker /** 29913a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker * Translate a result value to a legacy return value. All keystore errors are 29923a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker * preserved and keymaster errors become SYSTEM_ERRORs 29933a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker */ 29943a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker inline int32_t translateResultToLegacyResult(int32_t result) { 29953a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (result > 0) { 29963a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return result; 29973a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 29983a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 29993a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30003a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 30012de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden void addLegacyKeyAuthorizations(std::vector<keymaster_key_param_t>& params, int keyType) { 30023a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN)); 30033a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_VERIFY)); 30043a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_ENCRYPT)); 30053a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_DECRYPT)); 30063a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE)); 30072de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden if (keyType == EVP_PKEY_RSA) { 30082de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN)); 30092de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)); 30102de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PSS)); 30112de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_OAEP)); 30122de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden } 30133a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE)); 30142de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_MD5)); 30152de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA1)); 30162de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_224)); 30172de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_256)); 30182de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_384)); 30192de8b75821bd62c90dde78e2ca78bbddfaf7ab19Shawn Willden params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_512)); 30203a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_bool(KM_TAG_ALL_USERS)); 30213a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED)); 30223a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_date(KM_TAG_ORIGINATION_EXPIRE_DATETIME, LLONG_MAX)); 30233a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_date(KM_TAG_USAGE_EXPIRE_DATETIME, LLONG_MAX)); 30243a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_date(KM_TAG_ACTIVE_DATETIME, 0)); 30253a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker uint64_t now = keymaster::java_time(time(NULL)); 30263a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_date(KM_TAG_CREATION_DATETIME, now)); 30273a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30283a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 30293a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker keymaster_key_param_t* getKeyAlgorithm(keymaster_key_characteristics_t* characteristics) { 30303a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker for (size_t i = 0; i < characteristics->hw_enforced.length; i++) { 30313a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (characteristics->hw_enforced.params[i].tag == KM_TAG_ALGORITHM) { 30323a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return &characteristics->hw_enforced.params[i]; 30333a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30343a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30353a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker for (size_t i = 0; i < characteristics->sw_enforced.length; i++) { 30363a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (characteristics->sw_enforced.params[i].tag == KM_TAG_ALGORITHM) { 30373a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return &characteristics->sw_enforced.params[i]; 30383a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30393a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30403a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return NULL; 30413a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30423a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 30433a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker void addLegacyBeginParams(const String16& name, std::vector<keymaster_key_param_t>& params) { 30443a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker // All legacy keys are DIGEST_NONE/PAD_NONE. 30453a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE)); 30463a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE)); 30473a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 30483a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker // Look up the algorithm of the key. 30493a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker KeyCharacteristics characteristics; 30503a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker int32_t rc = getKeyCharacteristics(name, NULL, NULL, &characteristics); 30513a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (rc != ::NO_ERROR) { 30523a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGE("Failed to get key characteristics"); 30533a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return; 30543a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30553a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker keymaster_key_param_t* algorithm = getKeyAlgorithm(&characteristics.characteristics); 30563a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (!algorithm) { 30573a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGE("getKeyCharacteristics did not include KM_TAG_ALGORITHM"); 30583a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return; 30593a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30603a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker params.push_back(*algorithm); 30613a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30623a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 30633a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker int32_t doLegacySignVerify(const String16& name, const uint8_t* data, size_t length, 30643a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker uint8_t** out, size_t* outLength, const uint8_t* signature, 30653a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker size_t signatureLength, keymaster_purpose_t purpose) { 30663a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 30673a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker std::basic_stringstream<uint8_t> outBuffer; 30683a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker OperationResult result; 30693a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker KeymasterArguments inArgs; 30703a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker addLegacyBeginParams(name, inArgs.params); 30713a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker sp<IBinder> appToken(new BBinder); 30723a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker sp<IBinder> token; 30733a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 30743a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker begin(appToken, name, purpose, true, inArgs, NULL, 0, &result); 30753a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (result.resultCode != ResponseCode::NO_ERROR) { 3076df70517b8d85b30e6ac7001ec68348f07d5129cbChad Brubaker if (result.resultCode == ::KEY_NOT_FOUND) { 3077df70517b8d85b30e6ac7001ec68348f07d5129cbChad Brubaker ALOGW("Key not found"); 3078df70517b8d85b30e6ac7001ec68348f07d5129cbChad Brubaker } else { 3079df70517b8d85b30e6ac7001ec68348f07d5129cbChad Brubaker ALOGW("Error in begin: %d", result.resultCode); 3080df70517b8d85b30e6ac7001ec68348f07d5129cbChad Brubaker } 30813a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return translateResultToLegacyResult(result.resultCode); 30823a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30833a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker inArgs.params.clear(); 30843a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker token = result.token; 30853a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker size_t consumed = 0; 30863a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker size_t lastConsumed = 0; 30873a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker do { 30883a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker update(token, inArgs, data + consumed, length - consumed, &result); 30893a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (result.resultCode != ResponseCode::NO_ERROR) { 30903a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("Error in update: %d", result.resultCode); 30913a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return translateResultToLegacyResult(result.resultCode); 30923a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30933a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (out) { 30943a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker outBuffer.write(result.data.get(), result.dataLength); 30953a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 30963a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker lastConsumed = result.inputConsumed; 30973a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker consumed += lastConsumed; 30983a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } while (consumed < length && lastConsumed > 0); 30993a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 31003a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (consumed != length) { 31013a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, length); 31023a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::SYSTEM_ERROR; 31033a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 31043a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 31053a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker finish(token, inArgs, signature, signatureLength, NULL, 0, &result); 31063a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (result.resultCode != ResponseCode::NO_ERROR) { 31073a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker ALOGW("Error in finish: %d", result.resultCode); 31083a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return translateResultToLegacyResult(result.resultCode); 31093a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 31103a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (out) { 31113a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker outBuffer.write(result.data.get(), result.dataLength); 31123a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 31133a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 31143a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker if (out) { 31153a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker auto buf = outBuffer.str(); 31163a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker *out = new uint8_t[buf.size()]; 31173a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker memcpy(*out, buf.c_str(), buf.size()); 31183a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker *outLength = buf.size(); 31193a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 31203a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 31213a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker return ::NO_ERROR; 31223a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker } 31233a7d9e626fa6c0e116c07be912c319aad6e08614Chad Brubaker 312407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 312540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker OperationMap mOperationMap; 3126d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker keymaster::AuthTokenTable mAuthTokenTable; 31279221bff2f13451ef330135bb32ea96de2a8b09ccShawn Willden KeystoreKeymasterEnforcement enforcement_policy; 312807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 312907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 313007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 3131a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 3133a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 3134a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 3135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 3137a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 3138a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 3139a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3140a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 3141a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3142a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 3143a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 3144a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3145a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 314670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 3147bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker keymaster1_device_t* dev; 314870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 314970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 315070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 315170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 315270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 315367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t* fallback; 3154fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker if (fallback_keymaster_device_initialize(&fallback)) { 3155fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker ALOGE("software keymaster could not be initialized; exiting"); 3156fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 1; 3157fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 3158fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 3159eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ks_is_selinux_enabled = is_selinux_enabled(); 3160eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (ks_is_selinux_enabled) { 3161eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn union selinux_callback cb; 3162eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn cb.func_log = selinux_log_callback; 3163eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 3164eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getcon(&tctx) != 0) { 3165eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n"); 3166eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return -1; 3167eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 3168eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 3169eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGI("SELinux: Keystore SELinux is disabled.\n"); 3170eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 3171eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 3172bd07a239085228c25898bc6cdece8b1b8758df83Chad Brubaker KeyStore keyStore(&entropy, dev, fallback); 3173655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 317407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 317507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 317607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 317707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 317807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 317907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 3180a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 318170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 318207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 318307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 318407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 318507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 318607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 318770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 318807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 3189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 3191