keystore.cpp revision e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8
1a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* 2a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Copyright (C) 2009 The Android Open Source Project 3a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 4a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * you may not use this file except in compliance with the License. 6a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * You may obtain a copy of the License at 7a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 8a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 10a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Unless required by applicable law or agreed to in writing, software 11a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * See the License for the specific language governing permissions and 14a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * limitations under the License. 15a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root */ 16a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root//#define LOG_NDEBUG 0 1807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#define LOG_TAG "keystore" 1907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h> 21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h> 22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h> 23aaf9802da6cea710e0777abb852724e1825cad63Elliott Hughes#include <strings.h> 24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h> 25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h> 26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h> 27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h> 28655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <errno.h> 29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 31822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 37a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 39822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 40a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 42822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 43a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4480843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden#include <hardware/keymaster0.h> 4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker#include <keymaster/soft_keymaster_device.h> 470400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden#include <keymaster/soft_keymaster_logger.h> 480400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden#include <keymaster/softkeymaster.h> 4917208e0de5a42722901d803118745cca25fd10c1Kenny Root 5026cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h> 51655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h> 52655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h> 5370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 5507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 63a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 64eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn#include <selinux/android.h> 65eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 66d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker#include "auth_token_table.h" 6796427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h" 6840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker#include "operation.h" 6996427baf0094d50047049d329b0779c3c910402cKenny Root 70a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 71a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 72a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 73a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 74a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 75a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 76a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 77a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 78a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 79a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 8196427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete { 8296427baf0094d50047049d329b0779c3c910402cKenny Root void operator()(BIGNUM* p) const { 8396427baf0094d50047049d329b0779c3c910402cKenny Root BN_free(p); 8496427baf0094d50047049d329b0779c3c910402cKenny Root } 8596427baf0094d50047049d329b0779c3c910402cKenny Root}; 8696427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM; 8796427baf0094d50047049d329b0779c3c910402cKenny Root 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 106822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 107822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 108822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 10980843db63ed6b61c953a1243801117a15c9e8c38Shawn Willdenstatic int keymaster_device_initialize(keymaster0_device_t** dev) { 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11980843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden rc = keymaster0_open(mod, dev); 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1330400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden// softkeymaster_logger appears not to be used in keystore, but it installs itself as the 1340400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden// logger used by SoftKeymasterDevice. 1350400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willdenstatic keymaster::SoftKeymasterLogger softkeymaster_logger; 1360400675b20e36b976ec13b63e290e6d5d19bf654Shawn Willden 13767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubakerstatic int fallback_keymaster_device_initialize(keymaster1_device_t** dev) { 13867d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster::SoftKeymasterDevice* softkeymaster = 13967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker new keymaster::SoftKeymasterDevice(); 1409fd05a9a6299e9688c8fcf755516ea254868d187Shawn Willden *dev = softkeymaster->keymaster_device(); 1419fd05a9a6299e9688c8fcf755516ea254868d187Shawn Willden // softkeymaster will be freed by *dev->close_device; don't delete here. 142fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 0; 143fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker} 144fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 14580843db63ed6b61c953a1243801117a15c9e8c38Shawn Willdenstatic void keymaster_device_release(keymaster0_device_t* dev) { 14680843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden keymaster0_close(dev); 14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 15007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 15107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 15207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 155e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_GET_STATE = 1 << 0, 1564e865753346fc6a075966972a7a98051818859dbRobin Lee P_GET = 1 << 1, 1574e865753346fc6a075966972a7a98051818859dbRobin Lee P_INSERT = 1 << 2, 1584e865753346fc6a075966972a7a98051818859dbRobin Lee P_DELETE = 1 << 3, 1594e865753346fc6a075966972a7a98051818859dbRobin Lee P_EXIST = 1 << 4, 160e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_LIST = 1 << 5, 1614e865753346fc6a075966972a7a98051818859dbRobin Lee P_RESET = 1 << 6, 1624e865753346fc6a075966972a7a98051818859dbRobin Lee P_PASSWORD = 1 << 7, 1634e865753346fc6a075966972a7a98051818859dbRobin Lee P_LOCK = 1 << 8, 1644e865753346fc6a075966972a7a98051818859dbRobin Lee P_UNLOCK = 1 << 9, 165e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_IS_EMPTY = 1 << 10, 1664e865753346fc6a075966972a7a98051818859dbRobin Lee P_SIGN = 1 << 11, 1674e865753346fc6a075966972a7a98051818859dbRobin Lee P_VERIFY = 1 << 12, 1684e865753346fc6a075966972a7a98051818859dbRobin Lee P_GRANT = 1 << 13, 1694e865753346fc6a075966972a7a98051818859dbRobin Lee P_DUPLICATE = 1 << 14, 1704e865753346fc6a075966972a7a98051818859dbRobin Lee P_CLEAR_UID = 1 << 15, 171e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_ADD_AUTH = 1 << 16, 172e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker P_USER_CHANGED = 1 << 17, 17307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 17407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 17607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 17707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 17807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 17907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 18007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 18107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 18207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 184eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn/* perm_labels associcated with keystore_key SELinux class verbs. */ 185eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnconst char *perm_labels[] = { 186e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker "get_state", 187eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "get", 188eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "insert", 189eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "delete", 190eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "exist", 191e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker "list", 192eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "reset", 193eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "password", 194eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "lock", 195eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "unlock", 196e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker "is_empty", 197eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "sign", 198eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "verify", 199eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "grant", 200eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn "duplicate", 2014e865753346fc6a075966972a7a98051818859dbRobin Lee "clear_uid", 202d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker "add_auth", 203c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker "user_changed", 204eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn}; 205eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 20607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 20707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 20807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 20907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 21007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 21107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 21207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 21507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 216e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubakerstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_GET_STATE | P_GET | P_INSERT | P_DELETE 217e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker | P_EXIST | P_LIST | P_SIGN | P_VERIFY); 21807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 219eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic char *tctx; 220eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic int ks_is_selinux_enabled; 221eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 222eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic const char *get_perm_label(perm_t perm) { 223eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn unsigned int index = ffs(perm); 224eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) { 225eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return perm_labels[index - 1]; 226eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 227eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("Keystore: Failed to retrieve permission label.\n"); 228eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn abort(); 229eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 230eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 231eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 232655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 233655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 234655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 235655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 236655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 237655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 238655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 239655b958eb2180c7c06889f83f606d23421bf038cKenny Root 240655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 241655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 242655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 243655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 244655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 245655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 246655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 247655b958eb2180c7c06889f83f606d23421bf038cKenny Root 248a25b2a397fff48dea7bce16af2065e6f5f043956Chih-Hung Hsiehstatic bool keystore_selinux_check_access(uid_t /*uid*/, perm_t perm, pid_t spid) { 249eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!ks_is_selinux_enabled) { 250eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return true; 251eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 252eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 253eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn char *sctx = NULL; 254eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *selinux_class = "keystore_key"; 255eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn const char *str_perm = get_perm_label(perm); 256eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 257eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!str_perm) { 258eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 259eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 260eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 261eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getpidcon(spid, &sctx) != 0) { 262eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Failed to get source pid context.\n"); 263eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return false; 264eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 26566dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 266eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm, 267eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn NULL) == 0; 268eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn freecon(sctx); 269eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return allowed; 270eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn} 271eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 272eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahnstatic bool has_permission(uid_t uid, perm_t perm, pid_t spid) { 273655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 274655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 275655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 276655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 277655b958eb2180c7c06889f83f606d23421bf038cKenny Root 27807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 27907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 28007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 281eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (user.perms & perm) && 282eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 286eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return (DEFAULT_PERMS & perm) && 287eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn keystore_selinux_check_access(uid, perm, spid); 28807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 290494689083467ec372a58f094f041c8f102f39393Kenny Root/** 291494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 292494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 293494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 294494689083467ec372a58f094f041c8f102f39393Kenny Root */ 29507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 29607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 29707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 29807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 29907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 30007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 30107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 30207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 30307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 30407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 30507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 306494689083467ec372a58f094f041c8f102f39393Kenny Root/** 307494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 308494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 309494689083467ec372a58f094f041c8f102f39393Kenny Root */ 310494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 3119489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (callingUid == targetUid) { 3129489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return true; 3139489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 314494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 315494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 316494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 317494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 318494689083467ec372a58f094f041c8f102f39393Kenny Root } 319494689083467ec372a58f094f041c8f102f39393Kenny Root } 320494689083467ec372a58f094f041c8f102f39393Kenny Root 321494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 322494689083467ec372a58f094f041c8f102f39393Kenny Root} 323494689083467ec372a58f094f041c8f102f39393Kenny Root 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 331655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 332655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 333655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 334655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 335655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 336655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 337655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 338655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 339655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 340655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 341655b958eb2180c7c06889f83f606d23421bf038cKenny Root 34207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 34307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 34407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 346655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 350655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 351655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 35570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 35670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 35770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 35807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 35907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 36007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 36107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 36207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 36307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 36407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 36507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 36607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 36707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 36907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 37707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 37807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 37907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 38007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 38107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 38207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 38307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 38407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 38507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 38607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 38707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 38907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 398150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 3995281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 400150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 402a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 411150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 412150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 413150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 414150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 417a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 421a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 426150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 433150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 434150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4415187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 453822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 454f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 460822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 461822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 462822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 463822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 464822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 465822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 466822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 467822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 473822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 475f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 478822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 486d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 49017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker TYPE_KEYMASTER_10 = 4, 491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 493f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 49707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 49807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 4991773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin memset(&mBlob, 0, sizeof(mBlob)); 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 505822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 50607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 507822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 508f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 509ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root if (type == TYPE_MASTER_KEY) { 510ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_ENCRYPTED; 511ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } else { 512ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 513ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root } 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5201773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin Blob() { 5211773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin memset(&mBlob, 0, sizeof(mBlob)); 5221773b442b16098c6d111d6371d4a986a0747992bAlex Klyubin } 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5245187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5285187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5325187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 5335187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 5345187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 5355187818895c4c5f650a611c40531b1dff7764c18Kenny Root 5365187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 540822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 541822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 542822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 543822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 544f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 545f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 546f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 547f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 548f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 549f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 550f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 551f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 552f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 553f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 554f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 555f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 556f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 557f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 558f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 559f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 56017208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 56117208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 56217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 56317208e0de5a42722901d803118745cca25fd10c1Kenny Root 56417208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 56517208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 56617208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 56717208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 56817208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 56917208e0de5a42722901d803118745cca25fd10c1Kenny Root } 57017208e0de5a42722901d803118745cca25fd10c1Kenny Root } 57117208e0de5a42722901d803118745cca25fd10c1Kenny Root 572822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 573822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 574822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 575822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 576822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 577822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 578822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 579822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 580822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 581822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 582822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 583822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 584f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 585f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 586f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 587f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 588f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 589f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 593f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 595f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 612f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 613f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 614f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 615f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 616f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 617f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 618f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 619f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 625150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 626150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 627150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 628150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 636150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 640150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 641150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 642150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 643150ca934edb745de3666a6492b039900df228ff0Kenny Root } 644150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 647f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 648f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 649150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 650150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 660f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 661f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 662f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 663f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 664f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 671f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 674f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 675f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 676f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 677f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 678f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 679f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 680f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 681f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 682f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 683f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 684f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 685f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 686f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 687f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 688f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 689f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 690f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 698a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 70207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 709655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 710655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 711655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 712655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 713655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 714655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 71570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 716655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 717655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 718655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 719655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 72070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 721655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 722655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 723655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 724655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 725655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 726655b958eb2180c7c06889f83f606d23421bf038cKenny Root 727655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 73270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 733655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 734655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 735655b958eb2180c7c06889f83f606d23421bf038cKenny Root 736655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 737655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 738655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 739655b958eb2180c7c06889f83f606d23421bf038cKenny Root 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 741655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 742655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 743655b958eb2180c7c06889f83f606d23421bf038cKenny Root 744655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 745655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 746655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 747655b958eb2180c7c06889f83f606d23421bf038cKenny Root 748655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 749655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 750655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 751655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 752655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7555187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7595187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 763655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 764655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 765655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 767655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 76870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 76970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 77096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker bool deleteMasterKey() { 77196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker setState(STATE_UNINITIALIZED); 77296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker zeroizeMasterKeysInMemory(); 77396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return unlink(mMasterKeyFile) == 0 || errno == ENOENT; 77496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 77596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker 776655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 777655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 780655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 78507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 7884e865753346fc6a075966972a7a98051818859dbRobin Lee ResponseCode copyMasterKey(UserState* src) { 7894e865753346fc6a075966972a7a98051818859dbRobin Lee if (mState != STATE_UNINITIALIZED) { 7904e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7914e865753346fc6a075966972a7a98051818859dbRobin Lee } 7924e865753346fc6a075966972a7a98051818859dbRobin Lee if (src->getState() != STATE_NO_ERROR) { 7934e865753346fc6a075966972a7a98051818859dbRobin Lee return ::SYSTEM_ERROR; 7944e865753346fc6a075966972a7a98051818859dbRobin Lee } 7954e865753346fc6a075966972a7a98051818859dbRobin Lee memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES); 7964e865753346fc6a075966972a7a98051818859dbRobin Lee setupMasterKeys(); 7974e865753346fc6a075966972a7a98051818859dbRobin Lee return ::NO_ERROR; 7984e865753346fc6a075966972a7a98051818859dbRobin Lee } 7994e865753346fc6a075966972a7a98051818859dbRobin Lee 800655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 805822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 806f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 809655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 810655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 811150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 834f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 835f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 837f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 840a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 841a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 844a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 845655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 846a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 848a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 849a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 850a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 851a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 852a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 853a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 854a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 855a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 857a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 858a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 859a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 860a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 861a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 862a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 863a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 864a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 865a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 866a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 868655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 870a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 873655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 874a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 877a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 87896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // If the directory doesn't exist then nothing to do. 87996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (errno == ENOENT) { 88096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return true; 88196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 883a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 884a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 887a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 88896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // skip . and .. 88996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (!strcmp(".", file->d_name) || !strcmp("..", file->d_name)) { 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 894a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 895a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 896a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 897a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 898a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 899655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 931655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 937655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 943655b958eb2180c7c06889f83f606d23421bf038cKenny Root 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root 957655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root 962655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 963655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 96467d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker KeyStore(Entropy* entropy, keymaster1_device_t* device, keymaster1_device_t* fallback) 965655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 966655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 967fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker , mFallbackDevice(fallback) 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root 972655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 977c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mGrants.clear(); 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 983c35d4eb3e66aa69ca17dd83b1bcdcc19276bf8e5haitao fang mMasterKeys.clear(); 984655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 985655b958eb2180c7c06889f83f606d23421bf038cKenny Root 98667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker /** 98767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * Depending on the hardware keymaster version is this may return a 98867d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * keymaster0_device_t* cast to a keymaster1_device_t*. All methods from 98967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * keymaster0 are safe to call, calls to keymaster1_device_t methods should 99067d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker * be guarded by a check on the device's version. 99167d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker */ 99267d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t *getDevice() const { 993655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 994655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 995655b958eb2180c7c06889f83f606d23421bf038cKenny Root 99667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t *getFallbackDevice() const { 997fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return mFallbackDevice; 998fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 999fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 100067d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t *getDeviceForBlob(const Blob& blob) const { 1001fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return blob.isFallback() ? mFallbackDevice: mDevice; 1002fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 1003fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 1004655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 1005655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 1006655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 1007655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 1008655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1009655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1010655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 1011655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root 101372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State getState(uid_t userId) { 101472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return getUserState(userId)->getState(); 1015655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1016655b958eb2180c7c06889f83f606d23421bf038cKenny Root 101772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode initializeUser(const android::String8& pw, uid_t userId) { 101872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1019655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 1020655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1021655b958eb2180c7c06889f83f606d23421bf038cKenny Root 102272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser) { 102372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState *userState = getUserState(dstUser); 102472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState *initState = getUserState(srcUser); 10254e865753346fc6a075966972a7a98051818859dbRobin Lee return userState->copyMasterKey(initState); 10264e865753346fc6a075966972a7a98051818859dbRobin Lee } 10274e865753346fc6a075966972a7a98051818859dbRobin Lee 102872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode writeMasterKey(const android::String8& pw, uid_t userId) { 102972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1030655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 1031655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1032655b958eb2180c7c06889f83f606d23421bf038cKenny Root 103372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode readMasterKey(const android::String8& pw, uid_t userId) { 103472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1035655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 1036655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1037655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1038655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 1039a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1040655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1041655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 1042655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1043655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1044655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 1045a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1046655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 1047655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 1048655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1049655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1050655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 1051a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 1052655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 105372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid, 1054655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1056655b958eb2180c7c06889f83f606d23421bf038cKenny Root 105796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker /* 105896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * Delete entries owned by userId. If keepUnencryptedEntries is true 105996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * then only encrypted entries will be removed, otherwise all entries will 106096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * be removed. 106196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker */ 106296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker void resetUser(uid_t userId, bool keepUnenryptedEntries) { 10634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::String8 prefix(""); 10644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::Vector<android::String16> aliases; 106572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1066e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (list(prefix, &aliases, userId) != ::NO_ERROR) { 106796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return; 10684b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 10694b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee for (uint32_t i = 0; i < aliases.size(); i++) { 10704b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee android::String8 filename(aliases[i]); 10714b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee filename = android::String8::format("%s/%s", userState->getUserDirName(), 107296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker getKeyName(filename).string()); 107396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker bool shouldDelete = true; 107496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (keepUnenryptedEntries) { 107596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker Blob blob; 107672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode rc = get(filename, &blob, ::TYPE_ANY, userId); 107796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker 107896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker /* get can fail if the blob is encrypted and the state is 107996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * not unlocked, only skip deleting blobs that were loaded and 108096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * who are not encrypted. If there are blobs we fail to read for 108196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * other reasons err on the safe side and delete them since we 108296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker * can't tell if they're encrypted. 108396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker */ 108496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker shouldDelete = !(rc == ::NO_ERROR && !blob.isEncrypted()); 108596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 108696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (shouldDelete) { 108772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker del(filename, ::TYPE_ANY, userId); 108896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 108996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 109096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (!userState->deleteMasterKey()) { 109196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGE("Failed to delete user %d's master key", userId); 109296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 109396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (!keepUnenryptedEntries) { 109496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if(!userState->reset()) { 109596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGE("Failed to remove user %d's directory", userId); 109696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 10974b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 1098655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1099655b958eb2180c7c06889f83f606d23421bf038cKenny Root 110072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker bool isEmpty(uid_t userId) const { 110172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker const UserState* userState = getUserState(userId); 110296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (userState == NULL) { 1103655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1104655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1105655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1106655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 1107a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 1108a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 1109a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1110655b958eb2180c7c06889f83f606d23421bf038cKenny Root 111131e27468b6d822adbd2aec9219a68c206aa6957cKenny Root bool result = true; 111231e27468b6d822adbd2aec9219a68c206aa6957cKenny Root struct dirent* file; 1113a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 1114655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1115655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1116655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1117655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1118655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1119655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1120655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1121655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1122655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root 112431e27468b6d822adbd2aec9219a68c206aa6957cKenny Root result = false; 112531e27468b6d822adbd2aec9219a68c206aa6957cKenny Root break; 1126a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1127a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 1128a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 1129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 113172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker void lock(uid_t userId) { 113272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1133655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 1134655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 1135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 113772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) { 113872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1139f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1140f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 1141822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1142822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1143822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1144822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1145822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 114607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1147cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1148cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1149cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1150cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 115172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker if (upgradeBlob(filename, keyBlob, version, type, userId)) { 115272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker if ((rc = this->put(filename, keyBlob, userId)) != NO_ERROR 1153f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1154f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1155cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1156cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1157cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1158822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1159822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 116017208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 116117208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 116217208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 116317208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 116417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 116517208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 116617208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 116717208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 116872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker userId, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 116917208e0de5a42722901d803118745cca25fd10c1Kenny Root 117017208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 117117208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 117217208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 117372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId); 117417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 117517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 117617208e0de5a42722901d803118745cca25fd10c1Kenny Root 1177d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1178822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1179822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1180822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1181822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1182822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1183a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1184a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 118572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode put(const char* filename, Blob* keyBlob, uid_t userId) { 118672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 1187f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1188f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1190a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 119172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode del(const char *filename, const BlobType type, uid_t userId) { 11924b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee Blob keyBlob; 119372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode rc = get(filename, &keyBlob, type, userId); 11944b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (rc != ::NO_ERROR) { 11954b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return rc; 11964b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 11974b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 11984b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 11994b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // A device doesn't have to implement delete_keypair. 12004b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mDevice->delete_keypair != NULL && !keyBlob.isFallback()) { 12014b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (mDevice->delete_keypair(mDevice, keyBlob.getValue(), keyBlob.getLength())) { 12024b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee rc = ::SYSTEM_ERROR; 12034b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12044b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12054b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 120617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (keyBlob.getType() == ::TYPE_KEYMASTER_10) { 120717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster1_device_t* dev = getDeviceForBlob(keyBlob); 120817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (dev->delete_key) { 120917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_blob_t blob; 121017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker blob.key_material = keyBlob.getValue(); 121117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker blob.key_material_size = keyBlob.getLength(); 121217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker dev->delete_key(dev, &blob); 121317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 121417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 12154b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (rc != ::NO_ERROR) { 12164b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return rc; 12174b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12184b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12194b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 12204b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12214b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 1222e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker ResponseCode list(const android::String8& prefix, android::Vector<android::String16> *matches, 122372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker uid_t userId) { 12244b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 122572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserState(userId); 12264b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t n = prefix.length(); 12274b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12284b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee DIR* dir = opendir(userState->getUserDirName()); 12294b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!dir) { 12304b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("can't open directory for user: %s", strerror(errno)); 12314b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 12324b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12334b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12344b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee struct dirent* file; 12354b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee while ((file = readdir(dir)) != NULL) { 12364b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // We only care about files. 12374b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_type != DT_REG) { 12384b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12394b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12404b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12414b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee // Skip anything that starts with a "." 12424b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (file->d_name[0] == '.') { 12434b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee continue; 12444b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12454b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12464b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (!strncmp(prefix.string(), file->d_name, n)) { 12474b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee const char* p = &file->d_name[n]; 12484b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t plen = strlen(p); 12494b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 12504b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee size_t extra = decode_key_length(p, plen); 12514b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee char *match = (char*) malloc(extra + 1); 12524b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee if (match != NULL) { 12534b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee decode_key(match, p, plen); 12544b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee matches->push(android::String16(match, extra)); 12554b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee free(match); 12564b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } else { 12574b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee ALOGW("could not allocate match of size %zd", extra); 12584b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12594b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12604b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12614b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee closedir(dir); 12624b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 12634b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee } 12644b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee 126507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1266655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1267655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1268655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 126907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1270a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1271655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 127270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 127370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 127470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1276655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1277655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1278655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1279655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1280655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1281655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1282655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1283655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 128470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 128670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1288a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1289a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 129070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 129170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 129272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t userId, 1293f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1298822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1299822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1301822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1302822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 130317208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 130407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1305822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 1306a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root /* 1307a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * Maybe the device doesn't support this type of key. Try to use the 1308a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * software fallback keymaster implementation. This is a little bit 1309a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * lazier than checking the PKCS#8 key type, but the software 1310a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root * implementation will do that anyway. 1311a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root */ 13127c1eb75a6898452867ca28a4d7fad2d91edca615Chad Brubaker rc = mFallbackDevice->import_keypair(mFallbackDevice, key, keyLen, &data, &dataLength); 1313a39da5a226975f8b75f93de255a21d526ae8d334Kenny Root isFallback = true; 131417208e0de5a42722901d803118745cca25fd10c1Kenny Root 131517208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 131617208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 131717208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 131817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1319822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1320822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1321822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1322822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1323822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1324f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 132517208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1326f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 132772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return put(filename, &keyBlob, userId); 1328822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1329822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 13301b0e3933900c7ea21189704d5db64e7346aee7afKenny Root bool isHardwareBacked(const android::String16& keyType) const { 13311b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (mDevice == NULL) { 13321b0e3933900c7ea21189704d5db64e7346aee7afKenny Root ALOGW("can't get keymaster device"); 13331b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return false; 13341b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 13351b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 13361b0e3933900c7ea21189704d5db64e7346aee7afKenny Root if (sRSAKeyType == keyType) { 13371b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 13381b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } else { 13391b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 13401b0e3933900c7ea21189704d5db64e7346aee7afKenny Root && (mDevice->common.module->module_api_version 13411b0e3933900c7ea21189704d5db64e7346aee7afKenny Root >= KEYMASTER_MODULE_API_VERSION_0_2); 13421b0e3933900c7ea21189704d5db64e7346aee7afKenny Root } 13438ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 13448ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1345655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1346655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 134786b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filepath8(getKeyNameForUidWithDir(keyName, uid)); 134872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker uid_t userId = get_user_id(uid); 1349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 135072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode responseCode = get(filepath8.string(), keyBlob, type, userId); 1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1355655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 135886b16e8c0d353af97f0411917789308dba417295Kenny Root filepath8 = getKeyNameForUidWithDir(keyName, euid); 135972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker responseCode = get(filepath8.string(), keyBlob, type, userId); 1360655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 136470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 136686b16e8c0d353af97f0411917789308dba417295Kenny Root android::String8 filename8 = getKeyName(keyName); 1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 136886b16e8c0d353af97f0411917789308dba417295Kenny Root strtoul(filename8.string(), &end, 10); 1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1370655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 137272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker filepath8 = android::String8::format("%s/%s", getUserState(userId)->getUserDirName(), 137386b16e8c0d353af97f0411917789308dba417295Kenny Root filename8.string()); 1374655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 137972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return get(filepath8.string(), keyBlob, type, userId); 1380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 138572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* getUserState(uid_t userId) { 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1387655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1391655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 140772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker * Returns any existing UserState or creates it if it doesn't exist. 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 140972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* getUserStateByUid(uid_t uid) { 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 141172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return getUserState(userId); 141272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker } 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root 141472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker /** 141572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker * Returns NULL if the UserState doesn't already exist. 141672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker */ 141772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker const UserState* getUserState(uid_t userId) const { 1418655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1420655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1421655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1422655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1423655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1424655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1426655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 142972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker /** 143072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker * Returns NULL if the UserState doesn't already exist. 143172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker */ 143272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker const UserState* getUserStateByUid(uid_t uid) const { 143372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker uid_t userId = get_user_id(uid); 143472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return getUserState(userId); 143572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker } 143672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker 1437655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1438655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1439655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 14401b0e3933900c7ea21189704d5db64e7346aee7afKenny Root static const android::String16 sRSAKeyType; 1441655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 144207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 144367d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t* mDevice; 144467d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t* mFallbackDevice; 1445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1446655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1447655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1448655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 144970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1450655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1451655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1452655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 145370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1454655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1455655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1456655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1457655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1458655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1459655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 146070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1461655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 146270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 146370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 146470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 146570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 146670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 146770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1468822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1469822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1470822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1472655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1473655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1474822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1475822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1476822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1477822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1478822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1479822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1480822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1481822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1482822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1483655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1484822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1485822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1486822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1487822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1489f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1490f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1491f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1492f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1493f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1494f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1495f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1496f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1497f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1499822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1500822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1501cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1502822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1503822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1504822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1505822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1506cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1507cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1508822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1509822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1510822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1511822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1512822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1513822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1514822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1515822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1516655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1517822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1518822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1519822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1520822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1521822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1522822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1523822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1524822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1525822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1526822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1527822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1528822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1529822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1530822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1531822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1532822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1533822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1534822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1535822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1536822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 153770c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 153870c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1539822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1540822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1541822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1542822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1543822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 154472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker ResponseCode rc = importKey(pkcs8key.get(), len, filename, get_user_id(uid), 1545f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1546822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1547822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1548822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1549822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1550655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1551822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 155270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1553655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1554655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1555655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1556655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1557655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1558655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1559655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1560655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1562655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1563655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 156470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 156570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1566655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1567655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1568655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1569655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1570655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1571655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1572655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1573655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1574655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1575655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1576655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 157870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1579655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 158170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 158270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1583655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1584655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1585655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1586655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 158772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* userState = getUserStateByUid(0); 1588655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1589655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1590655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1591655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1592655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1593655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1594655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1595655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1596655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1597655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1598655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1599655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1600655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1601655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1602655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1603655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1604655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1605655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1606655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1607655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1608655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1609655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1610655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1611655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1612655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1613655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1614655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1615655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1616655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1617655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1618655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1619655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1620655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1621655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1622655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1623655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1624655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1625655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1626655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1627655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1628655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 162972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker UserState* otherUser = getUserStateByUid(thisUid); 1630655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1631655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1632655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1633655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1634655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1635655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1636655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1637655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1638655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1639655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1640655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1641655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1642655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1643655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1644655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1645655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1646655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1647655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1649655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1650655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 165270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1653655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 165470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1655655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1656655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 165770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 16581b0e3933900c7ea21189704d5db64e7346aee7afKenny Rootconst android::String16 KeyStore::sRSAKeyType("RSA"); 16591b0e3933900c7ea21189704d5db64e7346aee7afKenny Root 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 166107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 166207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 166440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker : mKeyStore(keyStore), 166540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker mOperationMap(this) 166607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 166707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 166940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void binderDied(const wp<IBinder>& who) { 167040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker auto operations = mOperationMap.getOperationsForToken(who.unsafe_get()); 167140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker for (auto token: operations) { 167240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker abort(token); 167340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 167407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1676e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker int32_t getState(int32_t userId) { 1677e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (!checkBinderPermission(P_GET_STATE)) { 167807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1681e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker return mKeyStore->getState(userId); 1682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 168407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 16859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_GET)) { 168607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 168707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 16899489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 169266dbf67dd65b4808a15ef64f0ffde1275bdd58a9Nick Kralevich 1693655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1694494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1696655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 169707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 169807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 169907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 170007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 170507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 170607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1708a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1709f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1710f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 17119489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 17129489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, 17139489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 17149489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 17159489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 1716b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1717b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 171807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1719655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 172007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 172107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1722ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 1723ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root 172472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid)); 1725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1727494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 17289489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 17299489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_DELETE, targetUid)) { 1730b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1731b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 173207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1733655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 173472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid)); 1735298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1736298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1737494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 17389489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 17399489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_EXIST, targetUid)) { 1740b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1741b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1742b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 174307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1744655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 174507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1746655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 174707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 174807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1750298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1751298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1752e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker int32_t list(const String16& prefix, int targetUid, Vector<String16>* matches) { 17539489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 1754e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (!checkBinderPermission(P_LIST, targetUid)) { 1755b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1756b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 175707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1758655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 175907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1760e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ::NO_ERROR) { 17614b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::SYSTEM_ERROR; 176207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 176307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1764298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1765298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 176607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 17679489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_RESET)) { 176807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 176907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 17719489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 177296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker mKeyStore->resetUser(get_user_id(callingUid), false); 177396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return ::NO_ERROR; 1774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 177696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker int32_t onUserPasswordChanged(int32_t userId, const String16& password) { 17779489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_PASSWORD)) { 177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 177907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 178107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 178296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // Flush the auth token table to prevent stale tokens from sticking 178396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // around. 178496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker mAuthTokenTable.Clear(); 178596d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker 178696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker if (password.size() == 0) { 178796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId); 178872593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->resetUser(userId, true); 178996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return ::NO_ERROR; 179096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } else { 179172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker switch (mKeyStore->getState(userId)) { 179296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker case ::STATE_UNINITIALIZED: { 179396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // generate master key, encrypt with password, write to file, 179496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // initialize mMasterKey*. 179572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->initializeUser(password8, userId); 179696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 179796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker case ::STATE_NO_ERROR: { 179896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // rewrite master key with new password. 179972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->writeMasterKey(password8, userId); 180096d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 180196d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker case ::STATE_LOCKED: { 180296d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGE("Changing user %d's password while locked, clearing old encryption", 180396d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker userId); 180472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->resetUser(userId, true); 180572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->initializeUser(password8, userId); 180696d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker } 180707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 180896d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker return ::SYSTEM_ERROR; 180907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 181007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1812c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker int32_t onUserAdded(int32_t userId, int32_t parentId) { 1813c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (!checkBinderPermission(P_USER_CHANGED)) { 1814c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::PERMISSION_DENIED; 1815c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1816c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1817c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // Sanity check that the new user has an empty keystore. 1818c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (!mKeyStore->isEmpty(userId)) { 1819c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker ALOGW("New user %d's keystore not empty. Clearing old entries.", userId); 1820c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1821c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // Unconditionally clear the keystore, just to be safe. 1822c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker mKeyStore->resetUser(userId, false); 1823c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1824c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // If the user has a parent user then use the parent's 1825c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker // masterkey/password, otherwise there's nothing to do. 1826c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (parentId != -1) { 1827c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return mKeyStore->copyMasterKey(parentId, userId); 1828c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } else { 1829c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::NO_ERROR; 1830c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1831c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1832c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1833c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker int32_t onUserRemoved(int32_t userId) { 1834c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker if (!checkBinderPermission(P_USER_CHANGED)) { 1835c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::PERMISSION_DENIED; 1836c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1837c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1838c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker mKeyStore->resetUser(userId, false); 1839c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker return ::NO_ERROR; 1840c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker } 1841c0f031a867a6c3fa05732fcd72bd284d56073cf8Chad Brubaker 1842e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker int32_t lock(int32_t userId) { 18439489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_LOCK)) { 184407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 184507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 184607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 184772593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(userId); 18489d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 184907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 185007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 185107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 185270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 185372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->lock(userId); 185407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 185570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1856a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 185796d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker int32_t unlock(int32_t userId, const String16& pw) { 18589489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_UNLOCK)) { 185907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 186007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 186272593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(userId); 18639d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 186496d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker ALOGI("calling unlock when not locked, ignoring."); 186507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 186607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 186807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 186996d6d7868303ad87f1f408c40d3c44bcb39f561eChad Brubaker // read master key, decrypt with password, initialize mMasterKey*. 187072593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->readMasterKey(password8, userId); 187170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 187270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1873e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker bool isEmpty(int32_t userId) { 1874e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (!checkBinderPermission(P_IS_EMPTY)) { 1875e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker return false; 187607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 187770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1878e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker return mKeyStore->isEmpty(userId); 187970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 188070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188196427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 188296427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 18839489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 18849489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, 18859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 18869489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 18879489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 188807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 188907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 189007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 189107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 189217208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 189370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 189467d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 189567d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 189607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 189707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 189807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 189970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 190007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 190107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 190207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 190417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 190596427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 190696427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 190796427baf0094d50047049d329b0779c3c910402cKenny Root 190896427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 190996427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 191096427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 191196427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 191296427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 191396427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 191496427baf0094d50047049d329b0779c3c910402cKenny Root } 191596427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 191696427baf0094d50047049d329b0779c3c910402cKenny Root 191796427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 191896427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 191996427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 192096427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 192196427baf0094d50047049d329b0779c3c910402cKenny Root 192296427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 192396427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 192496427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 192596427baf0094d50047049d329b0779c3c910402cKenny Root 192696427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 192796427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 192896427baf0094d50047049d329b0779c3c910402cKenny Root 192996427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 193096427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 193196427baf0094d50047049d329b0779c3c910402cKenny Root } else { 193296427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 193396427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 193496427baf0094d50047049d329b0779c3c910402cKenny Root } 193596427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 193696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 193796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 193896427baf0094d50047049d329b0779c3c910402cKenny Root } 193996427baf0094d50047049d329b0779c3c910402cKenny Root 19401d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_DSA)) { 194117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 194217208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 194317208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 1944fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = fallback->generate_keypair(fallback, TYPE_DSA, &dsa_params, &data, 1945fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker &dataLength); 194617208e0de5a42722901d803118745cca25fd10c1Kenny Root } 194717208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 194896427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 194996427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 195096427baf0094d50047049d329b0779c3c910402cKenny Root 195196427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 195296427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 195396427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 195496427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 195596427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 195696427baf0094d50047049d329b0779c3c910402cKenny Root } 195796427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 195896427baf0094d50047049d329b0779c3c910402cKenny Root 19591d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (isKeyTypeSupported(device, TYPE_EC)) { 196017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 196117208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 196217208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 1963fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = fallback->generate_keypair(fallback, TYPE_EC, &ec_params, &data, &dataLength); 196417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 196596427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 196696427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 196796427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 196896427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 196996427baf0094d50047049d329b0779c3c910402cKenny Root 197096427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 197196427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 197296427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 197396427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 197496427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 197596427baf0094d50047049d329b0779c3c910402cKenny Root } 197696427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 197796427baf0094d50047049d329b0779c3c910402cKenny Root 197896427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 19796489e02e134e4779d35c4a340ff68ad445fde133Matteo Franchin ALOGI("invalid number of arguments: %zu", args->size()); 198096427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 198196427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 198296427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 198396427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 198496427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 198596427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 198696427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 198796427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 198896427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 198996427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 199096427baf0094d50047049d329b0779c3c910402cKenny Root } 199196427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 199296427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 199396427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 199496427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 199596427baf0094d50047049d329b0779c3c910402cKenny Root } 199696427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 199796427baf0094d50047049d329b0779c3c910402cKenny Root } 199896427baf0094d50047049d329b0779c3c910402cKenny Root } 199996427baf0094d50047049d329b0779c3c910402cKenny Root 200096427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 200196427baf0094d50047049d329b0779c3c910402cKenny Root } else { 200296427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 200396427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 200496427baf0094d50047049d329b0779c3c910402cKenny Root } 200570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 200707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 200807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2010655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 20119489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 201270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 201407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2016ee8068b9e7bfb2770635062fc9c2035be2142bd8Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 201717208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 201817208e0de5a42722901d803118745cca25fd10c1Kenny Root 201972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid)); 202070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 202170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2022f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 2023f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 20249489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker targetUid = getEffectiveUid(targetUid); 20259489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, 20269489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 20279489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 20289489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 202907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 203007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 203160898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 203270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->importKey(data, length, filename.string(), get_user_id(targetUid), 203472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker flags); 203570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 203670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 203707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 203807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 20399489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_SIGN)) { 204007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 204107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20429a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 20439489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 204670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2047d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 204870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2049655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2050d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 205107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 205207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 205307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 205470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 205567d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 205607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 205707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 205807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 205907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 206207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 206407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 206570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 206807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 20699489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 2070fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker length, out, outLength); 207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 207407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 207607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 207770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 207870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 208007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 20819489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_VERIFY)) { 208207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 208307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 208470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 20859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 208607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 208707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 208970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2090655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2091494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 209207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 209667d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 209707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 209807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 210107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 210607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 210707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 210870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2109fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 2110fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker dataLength, signature, signatureLength); 211107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 211507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 211770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 211807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 211907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 212207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 212407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 212507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 212607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 212807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 212907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 2130d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 21319489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_GET)) { 2132d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 213307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 213407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 213570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 213607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 213870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2139d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 214070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2141655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 214207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 214307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 214407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 214507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 214670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 214767d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob); 214807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 214907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 215307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2156344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 215717208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 2158fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 2159fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker pubkeyLength); 216007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 216107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2163344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 216407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2165344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2166344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 216707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2168d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 21699489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT); 21709489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 21719489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 217207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 217307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 217407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2175655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 217607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2177655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 217807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 217907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 218007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2181655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 218207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2183a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 218407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 218507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2186d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 21879489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT); 21889489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (result != ::NO_ERROR) { 21899489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return result; 219007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 219207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2193655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 219407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2195655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 219607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 219707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 219807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2199655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2200a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 220107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 220207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2203d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 22049489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_GET)) { 2205d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 220636a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 220707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 220807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 220907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2210655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 221107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2212655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2213655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 221436a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 221607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2217655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 221807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2219655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 222036a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 222107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 222207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 222307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 222407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 222507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 222607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2227655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 222836a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 222907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 223007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 223136a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 223307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2234d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2235d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 22360225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2237eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn pid_t spid = IPCThreadState::self()->getCallingPid(); 2238eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (!has_permission(callingUid, P_DUPLICATE, spid)) { 2239d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 22400225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 22410225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22420225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 224372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(get_user_id(callingUid)); 22440225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2245d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 22460225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 22470225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22480225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2249d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2250d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2251d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2252d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 22530225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 22540225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22550225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2256d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2257d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2258d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22590225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2260d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2261d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2262d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2263d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2264d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2265d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22660225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2267d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2268d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2269d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2270d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 22710225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2273d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2274655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2275d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2276d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2277fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid)); 22780225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2279655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2280655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 22810225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 22820225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22830225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2284d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2285655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 228672593ee807e89239d98ae08d32c733ecc08203baChad Brubaker get_user_id(srcUid)); 2287d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2288d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 22890225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2290d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 229172593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(targetFile.string(), &keyBlob, get_user_id(destUid)); 22920225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22930225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 22941b0e3933900c7ea21189704d5db64e7346aee7afKenny Root int32_t is_hardware_backed(const String16& keyType) { 22951b0e3933900c7ea21189704d5db64e7346aee7afKenny Root return mKeyStore->isHardwareBacked(keyType) ? 1 : 0; 22968ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 22978ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2298fa27d5bbc366e4ecb45aee5ae08565ab3ad3dcbcKenny Root int32_t clear_uid(int64_t targetUid64) { 22999489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t targetUid = getEffectiveUid(targetUid64); 2300b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) { 2301a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2302a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2303a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23044b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 prefix = String8::format("%u_", targetUid); 23054b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee Vector<String16> aliases; 2306e6c3bfa8d39c7addbfbac0b2df63b0067bb664d8Chad Brubaker if (mKeyStore->list(prefix, &aliases, get_user_id(targetUid)) != ::NO_ERROR) { 2307a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2308a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2309a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23104b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee for (uint32_t i = 0; i < aliases.size(); i++) { 23114b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 name8(aliases[i]); 23124b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 231372593ee807e89239d98ae08d32c733ecc08203baChad Brubaker mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid)); 2314a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 23154b84fdc21457e16b08dc2738f4744c9ca7f7cc46Robin Lee return ::NO_ERROR; 2316a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2317a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 23189c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t addRngEntropy(const uint8_t* data, size_t dataLength) { 23199c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 23209c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 23219c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t devResult = KM_ERROR_UNIMPLEMENTED; 23229c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker int32_t fallbackResult = KM_ERROR_UNIMPLEMENTED; 23239c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 23249c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker device->add_rng_entropy != NULL) { 23259c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker devResult = device->add_rng_entropy(device, data, dataLength); 23269c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 23279c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (fallback->add_rng_entropy) { 23289c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker fallbackResult = fallback->add_rng_entropy(fallback, data, dataLength); 23299c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 23309c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (devResult) { 23319c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return devResult; 23329c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 23339c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker if (fallbackResult) { 23349c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return fallbackResult; 23359c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker } 23369c8612c88dc03dc52d85e7a482453e04e7e3e2a2Chad Brubaker return ::NO_ERROR; 23379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 23389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 233917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker int32_t generateKey(const String16& name, const KeymasterArguments& params, 2340154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker const uint8_t* entropy, size_t entropyLength, int uid, int flags, 2341154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker KeyCharacteristics* outCharacteristics) { 23429489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid = getEffectiveUid(uid); 23439489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid, 23449489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 23459489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (rc != ::NO_ERROR) { 23469489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return rc; 234717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 234817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 23499489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 235017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker bool isFallback = false; 235117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_blob_t blob; 235217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_key_characteristics_t *out = NULL; 235317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 235417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 235517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 235617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (device == NULL) { 235717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return ::SYSTEM_ERROR; 235817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 2359154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker // TODO: Seed from Linux RNG before this. 236017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 236117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker device->generate_key != NULL) { 2362154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (!entropy) { 2363154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_OK; 2364154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else if (device->add_rng_entropy) { 2365154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = device->add_rng_entropy(device, entropy, entropyLength); 2366154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else { 2367154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 2368154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2369154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (rc == KM_ERROR_OK) { 2370154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = device->generate_key(device, params.params.data(), params.params.size(), 2371154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker &blob, &out); 2372154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 237317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 237417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker // If the HW device didn't support generate_key or generate_key failed 237517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker // fall back to the software implementation. 237617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (rc && fallback->generate_key != NULL) { 237717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker isFallback = true; 2378154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (!entropy) { 2379154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_OK; 2380154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else if (fallback->add_rng_entropy) { 2381154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = fallback->add_rng_entropy(fallback, entropy, entropyLength); 2382154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else { 2383154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 2384154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2385154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (rc == KM_ERROR_OK) { 2386154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker rc = fallback->generate_key(fallback, params.params.data(), params.params.size(), 2387154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker &blob, 2388154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker &out); 2389154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 239017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 239117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 239217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (out) { 239317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (outCharacteristics) { 239417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker outCharacteristics->characteristics = *out; 239517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } else { 239617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keymaster_free_characteristics(out); 239717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 239817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker free(out); 239917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 240017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 240117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker if (rc) { 240217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker return rc; 240317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker } 240417d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 240517d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker String8 name8(name); 240617d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid)); 240717d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 240817d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10); 240917d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keyBlob.setFallback(isFallback); 241017d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 241117d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 241217d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker free(const_cast<uint8_t*>(blob.key_material)); 241317d68b9520e66226f1c7b2e1b3bd183ac80ca58bChad Brubaker 241472593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid)); 24159899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 24169899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 2417f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker int32_t getKeyCharacteristics(const String16& name, 2418d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* clientId, 2419d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* appData, 2420f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker KeyCharacteristics* outCharacteristics) { 2421f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (!outCharacteristics) { 2422f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return KM_ERROR_UNEXPECTED_NULL_POINTER; 2423f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2424f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker 2425f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2426f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker 2427f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker Blob keyBlob; 2428f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker String8 name8(name); 2429f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker int rc; 2430f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker 2431f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 2432f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker TYPE_KEYMASTER_10); 2433f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (responseCode != ::NO_ERROR) { 2434f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return responseCode; 2435f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2436f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker keymaster_key_blob_t key; 2437f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker key.key_material_size = keyBlob.getLength(); 2438f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker key.key_material = keyBlob.getValue(); 2439f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob); 2440f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker keymaster_key_characteristics_t *out = NULL; 2441f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (!dev->get_key_characteristics) { 2442f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker ALOGW("device does not implement get_key_characteristics"); 2443f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return KM_ERROR_UNIMPLEMENTED; 2444f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2445d663442b590b59250062335cc057478001b8e439Chad Brubaker rc = dev->get_key_characteristics(dev, &key, clientId, appData, &out); 2446f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker if (out) { 2447f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker outCharacteristics->characteristics = *out; 2448f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker free(out); 2449f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker } 2450f3f071fc5020fa5255f49e898a7c4a1cbf824a99Chad Brubaker return rc ? rc : ::NO_ERROR; 24519899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 24529899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 24534c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker int32_t importKey(const String16& name, const KeymasterArguments& params, 24544c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_key_format_t format, const uint8_t *keyData, 24554c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker size_t keyLength, int uid, int flags, 24564c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker KeyCharacteristics* outCharacteristics) { 24579489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid = getEffectiveUid(uid); 24589489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid, 24599489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker flags & KEYSTORE_FLAG_ENCRYPTED); 24609489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (rc != ::NO_ERROR) { 24619489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return rc; 24624c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 24634c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 24649489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 24654c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker bool isFallback = false; 24664c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_key_blob_t blob; 24674c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_key_characteristics_t *out = NULL; 24684c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 24694c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker const keymaster1_device_t* device = mKeyStore->getDevice(); 24704c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice(); 24714c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (device == NULL) { 24724c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker return ::SYSTEM_ERROR; 24734c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 24744c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 && 24754c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker device->import_key != NULL) { 24764c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker rc = device->import_key(device, params.params.data(), params.params.size(), 24774c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker format, keyData, keyLength, &blob, &out); 24784c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 24794c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (rc && fallback->import_key != NULL) { 24804c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker isFallback = true; 24814c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker rc = fallback->import_key(fallback, params.params.data(), params.params.size(), 24824c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker format, keyData, keyLength, &blob, &out); 24834c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 24844c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (out) { 24854c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (outCharacteristics) { 24864c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker outCharacteristics->characteristics = *out; 24874c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } else { 24884c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keymaster_free_characteristics(out); 24894c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 24904c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker free(out); 24914c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 24924c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker if (rc) { 24934c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker return rc; 24944c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker } 24954c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 24964c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker String8 name8(name); 24974c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid)); 24984c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 24994c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10); 25004c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keyBlob.setFallback(isFallback); 25014c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 25024c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 25034c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker free((void*) blob.key_material); 25044c353cb98e52e2ea8f051b517fec064f1d3fa99fChad Brubaker 250572593ee807e89239d98ae08d32c733ecc08203baChad Brubaker return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid)); 25069899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25079899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 250807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker void exportKey(const String16& name, keymaster_key_format_t format, 2509d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* clientId, 2510d663442b590b59250062335cc057478001b8e439Chad Brubaker const keymaster_blob_t* appData, ExportResult* result) { 251107b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker 251207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 251307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker 251407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker Blob keyBlob; 251507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker String8 name8(name); 251607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker int rc; 251707b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker 251807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 251907b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker TYPE_KEYMASTER_10); 252007b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker if (responseCode != ::NO_ERROR) { 252107b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker result->resultCode = responseCode; 252207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker return; 252307b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker } 252407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker keymaster_key_blob_t key; 252507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker key.key_material_size = keyBlob.getLength(); 252607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker key.key_material = keyBlob.getValue(); 252707b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob); 252807b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker if (!dev->export_key) { 252907b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker result->resultCode = KM_ERROR_UNIMPLEMENTED; 253007b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker return; 253107b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker } 253207b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker uint8_t* ptr = NULL; 2533d663442b590b59250062335cc057478001b8e439Chad Brubaker rc = dev->export_key(dev, format, &key, clientId, appData, 253407b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker &ptr, &result->dataLength); 253507b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker result->exportData.reset(ptr); 253607b0cda3b14d16205ce3040d00bc18d15eda5fdcChad Brubaker result->resultCode = rc ? rc : ::NO_ERROR; 25379899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 25389899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 2539ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker 254040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void begin(const sp<IBinder>& appToken, const String16& name, keymaster_purpose_t purpose, 2541154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker bool pruneable, const KeymasterArguments& params, const uint8_t* entropy, 2542154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker size_t entropyLength, KeymasterArguments* outParams, OperationResult* result) { 254340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (!result || !outParams) { 254440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker ALOGE("Unexpected null arguments to begin()"); 254540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 254640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 254740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 254840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) { 254940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid); 255040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = ::PERMISSION_DENIED; 255140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 255240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 25530cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!checkAllowedOperationParams(params.params)) { 25540cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = KM_ERROR_INVALID_ARGUMENT; 25550cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return; 25560cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 255740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker Blob keyBlob; 255840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker String8 name8(name); 255940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 256040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker TYPE_KEYMASTER_10); 256140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (responseCode != ::NO_ERROR) { 256240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = responseCode; 256340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 256440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 256540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_key_blob_t key; 256640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker key.key_material_size = keyBlob.getLength(); 256740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker key.key_material = keyBlob.getValue(); 256840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_key_param_t* out; 256940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker size_t outSize; 257040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 257140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob); 2572154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker keymaster_error_t err = KM_ERROR_UNIMPLEMENTED; 257306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 2574ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker Unique_keymaster_key_characteristics characteristics; 2575ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker characteristics.reset(new keymaster_key_characteristics_t); 2576ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker err = getOperationCharacteristics(key, dev, opParams, characteristics.get()); 2577ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker if (err) { 2578ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker result->resultCode = err; 2579ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker return; 2580ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker } 25810cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* authToken = NULL; 25820cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t authResult = getAuthToken(characteristics.get(), 0, &authToken, 258306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker /*failOnTokenMissing*/ false); 25840cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // If per-operation auth is needed we need to begin the operation and 25850cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // the client will need to authorize that operation before calling 25860cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // update. Any other auth issues stop here. 25870cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authResult != ::NO_ERROR && authResult != ::OP_AUTH_NEEDED) { 25880cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = authResult; 258906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker return; 259006801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } 25910cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker addAuthToParams(&opParams, authToken); 2592154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker // Add entropy to the device first. 2593154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (entropy) { 2594154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (dev->add_rng_entropy) { 2595154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker err = dev->add_rng_entropy(dev, entropy, entropyLength); 2596154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } else { 2597154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker err = KM_ERROR_UNIMPLEMENTED; 2598154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2599154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker if (err) { 2600154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker result->resultCode = err; 2601154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker return; 2602154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 2603154d7699cc30ef5156d6497258c4dd350fcb1286Chad Brubaker } 260406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker err = dev->begin(dev, purpose, &key, opParams.data(), opParams.size(), &out, &outSize, 260506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker &handle); 260640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker 260740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker // If there are too many operations abort the oldest operation that was 260840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker // started as pruneable and try again. 260940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker while (err == KM_ERROR_TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) { 261040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation(); 261140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker ALOGD("Ran out of operation handles, trying to prune %p", oldest.get()); 261240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (abort(oldest) != ::NO_ERROR) { 261340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker break; 261440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 26150cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker err = dev->begin(dev, purpose, &key, opParams.data(), opParams.size(), &out, &outSize, 261640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker &handle); 261740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 261840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (err) { 261940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = err; 262040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 262140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 262240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (out) { 262340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker outParams->params.assign(out, out + outSize); 262440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker free(out); 262540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 26269899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 2627ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker sp<IBinder> operationToken = mOperationMap.addOperation(handle, dev, appToken, 2628ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker characteristics.release(), 262906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker pruneable); 26300cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authToken) { 26310cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker mOperationMap.setOperationAuthToken(operationToken, authToken); 26320cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 26330cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // Return the authentication lookup result. If this is a per operation 26340cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the 26350cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // application should get an auth token using the handle before the 26360cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // first call to update, which will fail if keystore hasn't received the 26370cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker // auth token. 26380cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = authResult; 263940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->token = operationToken; 2640c3a1856bbe2e39d5b3430f5f088b12fd710a159fChad Brubaker result->handle = handle; 26419899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 26429899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 264340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void update(const sp<IBinder>& token, const KeymasterArguments& params, const uint8_t* data, 264440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker size_t dataLength, OperationResult* result) { 26450cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!checkAllowedOperationParams(params.params)) { 26460cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = KM_ERROR_INVALID_ARGUMENT; 26470cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return; 26480cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 264940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker const keymaster1_device_t* dev; 265040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 26510cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!mOperationMap.getOperation(token, &handle, &dev, NULL)) { 265240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE; 265340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 265440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 265540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker uint8_t* output_buf = NULL; 265640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker size_t output_length = 0; 265740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker size_t consumed = 0; 265806801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 26590cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams); 26600cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authResult != ::NO_ERROR) { 266106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker result->resultCode = authResult; 266206801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker return; 266306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } 266406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker keymaster_error_t err = dev->update(dev, handle, opParams.data(), opParams.size(), data, 266506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker dataLength, &consumed, &output_buf, &output_length); 266640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->data.reset(output_buf); 266740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->dataLength = output_length; 266840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->inputConsumed = consumed; 266940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = err ? (int32_t) err : ::NO_ERROR; 267040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 267140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker 267240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker void finish(const sp<IBinder>& token, const KeymasterArguments& params, 267340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker const uint8_t* signature, size_t signatureLength, OperationResult* result) { 26740cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!checkAllowedOperationParams(params.params)) { 26750cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker result->resultCode = KM_ERROR_INVALID_ARGUMENT; 26760cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return; 26770cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 267840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker const keymaster1_device_t* dev; 267940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 26800cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!mOperationMap.getOperation(token, &handle, &dev, NULL)) { 268140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE; 268240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return; 268340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 268440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker uint8_t* output_buf = NULL; 268540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker size_t output_length = 0; 268606801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> opParams(params.params); 26870cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams); 26880cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authResult != ::NO_ERROR) { 268906801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker result->resultCode = authResult; 269006801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker return; 269106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } 26920cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 269306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker keymaster_error_t err = dev->finish(dev, handle, opParams.data(), opParams.size(), 269406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker signature, signatureLength, &output_buf, 269506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker &output_length); 269640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker // Remove the operation regardless of the result 269740a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker mOperationMap.removeOperation(token); 269806801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker mAuthTokenTable.MarkCompleted(handle); 269940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->data.reset(output_buf); 270040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->dataLength = output_length; 270140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker result->resultCode = err ? (int32_t) err : ::NO_ERROR; 270240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 270340a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker 270440a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker int32_t abort(const sp<IBinder>& token) { 270540a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker const keymaster1_device_t* dev; 270640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker keymaster_operation_handle_t handle; 270706801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker if (!mOperationMap.getOperation(token, &handle, &dev, NULL)) { 270840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return KM_ERROR_INVALID_OPERATION_HANDLE; 270940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 271040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker mOperationMap.removeOperation(token); 271106801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker int32_t rc; 271240a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (!dev->abort) { 271306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker rc = KM_ERROR_UNIMPLEMENTED; 271406801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker } else { 271506801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker rc = dev->abort(dev, handle); 271640a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 271706801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker mAuthTokenTable.MarkCompleted(handle); 271840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker if (rc) { 271940a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return rc; 272040a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker } 272140a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker return ::NO_ERROR; 27229899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker } 27239899d6b392e8223c3c00bfccadd43b18cdc96b4fChad Brubaker 27242ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker bool isOperationAuthorized(const sp<IBinder>& token) { 27252ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker const keymaster1_device_t* dev; 27262ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker keymaster_operation_handle_t handle; 2727ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker const keymaster_key_characteristics_t* characteristics; 2728ad6514ab7a57504aa3b04bcc383f60940b923710Chad Brubaker if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) { 27292ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker return false; 27302ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker } 27310cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* authToken = NULL; 27320cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker mOperationMap.getOperationAuthToken(token, &authToken); 273306801e0a7ccabbe8f22cff29b7edb7c7d02d7692Chad Brubaker std::vector<keymaster_key_param_t> ignored; 27340cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t authResult = addOperationAuthTokenIfNeeded(token, &ignored); 27350cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return authResult == ::NO_ERROR; 27362ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker } 27372ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker 2738d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker int32_t addAuthToken(const uint8_t* token, size_t length) { 27399489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(P_ADD_AUTH)) { 27409489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker ALOGW("addAuthToken: permission denied for %d", 27419489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker IPCThreadState::self()->getCallingUid()); 2742d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker return ::PERMISSION_DENIED; 2743d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker } 2744d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker if (length != sizeof(hw_auth_token_t)) { 2745d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker return KM_ERROR_INVALID_ARGUMENT; 2746d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker } 2747d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker hw_auth_token_t* authToken = new hw_auth_token_t; 2748d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker memcpy(reinterpret_cast<void*>(authToken), token, sizeof(hw_auth_token_t)); 2749d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker // The table takes ownership of authToken. 2750d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker mAuthTokenTable.AddAuthenticationToken(authToken); 2751d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker return ::NO_ERROR; 27522ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker } 27532ed2baa7de690b09430b40625e6b18d10757a2fdChad Brubaker 275407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 27559489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker static const int32_t UID_SELF = -1; 27569489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 27579489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 27589489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Get the effective target uid for a binder operation that takes an 27599489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * optional uid as the target. 27609489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 27619489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline uid_t getEffectiveUid(int32_t targetUid) { 27629489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (targetUid == UID_SELF) { 27639489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return IPCThreadState::self()->getCallingUid(); 27649489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27659489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return static_cast<uid_t>(targetUid); 27669489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27679489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 27689489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 27699489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Check if the caller of the current binder method has the required 27709489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * permission and if acting on other uids the grants to do so. 27719489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 27729489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline bool checkBinderPermission(perm_t permission, int32_t targetUid = UID_SELF) { 27739489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 27749489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker pid_t spid = IPCThreadState::self()->getCallingPid(); 27759489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!has_permission(callingUid, permission, spid)) { 27769489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid); 27779489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return false; 27789489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27799489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!is_granted_to(callingUid, getEffectiveUid(targetUid))) { 27809489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker ALOGW("uid %d not granted to act for %d", callingUid, targetUid); 27819489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return false; 27829489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27839489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return true; 27849489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 27859489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 27869489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 27879489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Check if the caller of the current binder method has the required 2788b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker * permission and the target uid is the caller or the caller is system. 2789b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker */ 2790b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker inline bool checkBinderPermissionSelfOrSystem(perm_t permission, int32_t targetUid) { 2791b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2792b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker pid_t spid = IPCThreadState::self()->getCallingPid(); 2793b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker if (!has_permission(callingUid, permission, spid)) { 2794b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid); 2795b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker return false; 2796b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker } 2797b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker return getEffectiveUid(targetUid) == callingUid || callingUid == AID_SYSTEM; 2798b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker } 2799b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker 2800b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker /** 2801b37a52337f001f8a43f7cbb64203dba78560ee6bChad Brubaker * Check if the caller of the current binder method has the required 28029489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * permission or the target of the operation is the caller's uid. This is 28039489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * for operation where the permission is only for cross-uid activity and all 28049489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * uids are allowed to act on their own (ie: clearing all entries for a 28059489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * given uid). 28069489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 28079489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline bool checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid) { 28089489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker uid_t callingUid = IPCThreadState::self()->getCallingUid(); 28099489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (getEffectiveUid(targetUid) == callingUid) { 28109489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return true; 28119489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } else { 28129489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return checkBinderPermission(permission, targetUid); 28139489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 28149489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 28159489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 28169489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker /** 28179489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Helper method to check that the caller has the required permission as 28189489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * well as the keystore is in the unlocked state if checkUnlocked is true. 28199489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * 28209489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and 28219489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * otherwise the state of keystore when not unlocked and checkUnlocked is 28229489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker * true. 28239489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker */ 28249489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker inline int32_t checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid = -1, 28259489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker bool checkUnlocked = true) { 28269489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (!checkBinderPermission(permission, targetUid)) { 28279489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return ::PERMISSION_DENIED; 28289489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 282972593ee807e89239d98ae08d32c733ecc08203baChad Brubaker State state = mKeyStore->getState(get_user_id(getEffectiveUid(targetUid))); 28309489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker if (checkUnlocked && !isKeystoreUnlocked(state)) { 28319489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return state; 28329489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 28339489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 28349489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker return ::NO_ERROR; 28359489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 28369489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker } 28379489b7905acfb27a99dd505364a715f4cf2ab5e6Chad Brubaker 28389d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 28399d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 28409d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 28419d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 28429d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 28439d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 28449d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 28459d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 28469d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2847a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 284807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 284967d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker bool isKeyTypeSupported(const keymaster1_device_t* device, keymaster_keypair_t keyType) { 28501d448c074a86ef5d05a22fdf1358718976628a86Kenny Root const int32_t device_api = device->common.module->module_api_version; 28511d448c074a86ef5d05a22fdf1358718976628a86Kenny Root if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) { 28521d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 28531d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 28541d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 28551d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 28561d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 28571d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 28581d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 28591d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28601d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) { 28611d448c074a86ef5d05a22fdf1358718976628a86Kenny Root switch (keyType) { 28621d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_RSA: 28631d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return true; 28641d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_DSA: 28651d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_DSA; 28661d448c074a86ef5d05a22fdf1358718976628a86Kenny Root case TYPE_EC: 28671d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return device->flags & KEYMASTER_SUPPORTS_EC; 28681d448c074a86ef5d05a22fdf1358718976628a86Kenny Root default: 28691d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return false; 28701d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28711d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } else { 28721d448c074a86ef5d05a22fdf1358718976628a86Kenny Root return keyType == TYPE_RSA; 28731d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28741d448c074a86ef5d05a22fdf1358718976628a86Kenny Root } 28751d448c074a86ef5d05a22fdf1358718976628a86Kenny Root 28760cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker /** 28770cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Check that all keymaster_key_param_t's provided by the application are 28780cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * allowed. Any parameter that keystore adds itself should be disallowed here. 28790cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker */ 28800cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker bool checkAllowedOperationParams(const std::vector<keymaster_key_param_t>& params) { 28810cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (auto param: params) { 28820cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker switch (param.tag) { 28830cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case KM_TAG_AUTH_TOKEN: 28840cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return false; 28850cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker default: 28860cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker break; 28870cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28880cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28890cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return true; 28900cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 28910cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 28920cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_error_t getOperationCharacteristics(const keymaster_key_blob_t& key, 28930cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const keymaster1_device_t* dev, 28940cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const std::vector<keymaster_key_param_t>& params, 28950cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_key_characteristics_t* out) { 28960cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker UniquePtr<keymaster_blob_t> appId; 28970cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker UniquePtr<keymaster_blob_t> appData; 28980cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (auto param : params) { 28990cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (param.tag == KM_TAG_APPLICATION_ID) { 29000cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appId.reset(new keymaster_blob_t); 29010cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appId->data = param.blob.data; 29020cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appId->data_length = param.blob.data_length; 29030cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } else if (param.tag == KM_TAG_APPLICATION_DATA) { 29040cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData.reset(new keymaster_blob_t); 29050cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData->data = param.blob.data; 29060cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData->data_length = param.blob.data_length; 29070cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29080cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29090cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_key_characteristics_t* result = NULL; 29100cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!dev->get_key_characteristics) { 29110cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_UNIMPLEMENTED; 29120cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29130cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_error_t error = dev->get_key_characteristics(dev, &key, appId.get(), 29140cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker appData.get(), &result); 29150cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (result) { 29160cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker *out = *result; 29170cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker free(result); 29180cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29190cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return error; 29200cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29210cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29220cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker /** 29230cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Get the auth token for this operation from the auth token table. 29240cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * 29250cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Returns ::NO_ERROR if the auth token was set or none was required. 29260cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * ::OP_AUTH_NEEDED if it is a per op authorization, no 29270cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * authorization token exists for that operation and 29280cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * failOnTokenMissing is false. 29290cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth 29300cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * token for the operation 29310cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker */ 29320cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t getAuthToken(const keymaster_key_characteristics_t* characteristics, 29330cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_operation_handle_t handle, 29340cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t** authToken, 29350cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker bool failOnTokenMissing = true) { 29360cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29370cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker std::vector<keymaster_key_param_t> allCharacteristics; 29380cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (size_t i = 0; i < characteristics->sw_enforced.length; i++) { 29390cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker allCharacteristics.push_back(characteristics->sw_enforced.params[i]); 29400cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29410cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker for (size_t i = 0; i < characteristics->hw_enforced.length; i++) { 29420cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker allCharacteristics.push_back(characteristics->hw_enforced.params[i]); 29430cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29440cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster::AuthTokenTable::Error err = 29450cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker mAuthTokenTable.FindAuthorization(allCharacteristics.data(), 29460cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker allCharacteristics.size(), handle, authToken); 29470cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker switch (err) { 29480cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::OK: 29490cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_NOT_REQUIRED: 29500cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return ::NO_ERROR; 29510cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_TOKEN_NOT_FOUND: 29520cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_TOKEN_EXPIRED: 29530cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::AUTH_TOKEN_WRONG_SID: 29540cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_KEY_USER_NOT_AUTHENTICATED; 29550cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker case keymaster::AuthTokenTable::OP_HANDLE_REQUIRED: 29560cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return failOnTokenMissing ? (int32_t) KM_ERROR_KEY_USER_NOT_AUTHENTICATED : 29570cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker (int32_t) ::OP_AUTH_NEEDED; 29580cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker default: 29590cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker ALOGE("Unexpected FindAuthorization return value %d", err); 29600cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_INVALID_ARGUMENT; 29610cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29620cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29630cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29640cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker inline void addAuthToParams(std::vector<keymaster_key_param_t>* params, 29650cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* token) { 29660cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (token) { 29670cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker params->push_back(keymaster_param_blob(KM_TAG_AUTH_TOKEN, 29680cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker reinterpret_cast<const uint8_t*>(token), 29690cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker sizeof(hw_auth_token_t))); 29700cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29710cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29720cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 29730cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker /** 29740cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Add the auth token for the operation to the param list if the operation 29750cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * requires authorization. Uses the cached result in the OperationMap if available 29760cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * otherwise gets the token from the AuthTokenTable and caches the result. 29770cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * 29780cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * Returns ::NO_ERROR if the auth token was added or not needed. 29790cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not 29800cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * authenticated. 29810cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid 29820cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker * operation token. 29830cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker */ 29840cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t addOperationAuthTokenIfNeeded(sp<IBinder> token, 29850cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker std::vector<keymaster_key_param_t>* params) { 29860cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const hw_auth_token_t* authToken = NULL; 29877169a8470f6539036addf3c960b075af224e83e2Chad Brubaker mOperationMap.getOperationAuthToken(token, &authToken); 29887169a8470f6539036addf3c960b075af224e83e2Chad Brubaker if (!authToken) { 29890cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const keymaster1_device_t* dev; 29900cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker keymaster_operation_handle_t handle; 29910cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker const keymaster_key_characteristics_t* characteristics = NULL; 29920cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) { 29930cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return KM_ERROR_INVALID_OPERATION_HANDLE; 29940cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29950cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker int32_t result = getAuthToken(characteristics, handle, &authToken); 29960cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (result != ::NO_ERROR) { 29970cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return result; 29980cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 29990cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker if (authToken) { 30000cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker mOperationMap.setOperationAuthToken(token, authToken); 30010cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 30020cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 30030cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker addAuthToParams(params, authToken); 30040cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker return ::NO_ERROR; 30050cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker } 30060cf34a249c008743cf2e2371743a89f86aa4b03cChad Brubaker 300707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 300840a1a9b306d4e3c85b24f80ff39841507cf42357Chad Brubaker OperationMap mOperationMap; 3009d80c7b487b2f7f0bf955d0efeaa3db6dcd160639Chad Brubaker keymaster::AuthTokenTable mAuthTokenTable; 301007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 301107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 301207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 3013a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3014a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 3015a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 3016a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 3017a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3018a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 3019a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 3020a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 3021a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3022a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 3023a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3024a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 3025a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 3026a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3027a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 302870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 302980843db63ed6b61c953a1243801117a15c9e8c38Shawn Willden keymaster0_device_t* dev; 303070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 303170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 303270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 303370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 303470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 303567d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker keymaster1_device_t* fallback; 3036fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker if (fallback_keymaster_device_initialize(&fallback)) { 3037fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker ALOGE("software keymaster could not be initialized; exiting"); 3038fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker return 1; 3039fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker } 3040fc18edcdfe2f7774e621030d51338f3216170b97Chad Brubaker 3041eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ks_is_selinux_enabled = is_selinux_enabled(); 3042eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (ks_is_selinux_enabled) { 3043eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn union selinux_callback cb; 3044eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn cb.func_log = selinux_log_callback; 3045eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn selinux_set_callback(SELINUX_CB_LOG, cb); 3046eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn if (getcon(&tctx) != 0) { 3047eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n"); 3048eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn return -1; 3049eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 3050eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } else { 3051eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn ALOGI("SELinux: Keystore SELinux is disabled.\n"); 3052eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn } 3053eaabae9bf8ff0873b0ece2a835f71ee6c6b49437Riley Spahn 305467d2a5029e8c25c5ee448e3bbd245cdcebe6abd3Chad Brubaker KeyStore keyStore(&entropy, reinterpret_cast<keymaster1_device_t*>(dev), fallback); 3055655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 305607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 305707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 305807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 305907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 306007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 306107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 3062a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 306370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 306407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 306507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 306607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 306707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 306807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 306970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 307007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 3071a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 3072a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 3073