keystore.cpp revision 494689083467ec372a58f094f041c8f102f39393
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> 23a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h> 24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h> 25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h> 26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h> 27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 29822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 37822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 39a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 40822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h> 4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 44822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <utils/UniquePtr.h> 45822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 4670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/list.h> 4770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 4907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 52a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 63a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 64a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 65a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 66a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 68822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 69822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 70822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 71822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 72822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 73822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 74822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 75822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 77822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 78822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 79822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 81822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 82822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 9170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 9270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 9370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 9470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 9570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 9670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 9770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 9870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 9970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 10370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 12007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 12107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 12207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 12307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 12407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 12507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_TEST = 1 << 0, 12607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_GET = 1 << 1, 12707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_INSERT = 1 << 2, 12807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_DELETE = 1 << 3, 12907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_EXIST = 1 << 4, 13007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_SAW = 1 << 5, 13107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_RESET = 1 << 6, 13207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_PASSWORD = 1 << 7, 13307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_LOCK = 1 << 8, 13407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_UNLOCK = 1 << 9, 13507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_ZERO = 1 << 10, 13607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_SIGN = 1 << 11, 13707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_VERIFY = 1 << 12, 13807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_GRANT = 1 << 13, 13907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 14007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 14107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 14207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 14307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 14407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 14507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 14607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 14707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 14807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 14907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 15107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 15207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 15507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 15607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 15707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 15807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic bool has_permission(uid_t uid, perm_t perm) { 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 16607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 16707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.perms & perm; 16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 16907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 17007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return DEFAULT_PERMS & perm; 17207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 17307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 174494689083467ec372a58f094f041c8f102f39393Kenny Root/** 175494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 176494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 177494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 178494689083467ec372a58f094f041c8f102f39393Kenny Root */ 17907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 18007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 18107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 18207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 18407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 18707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 18807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 18907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 190494689083467ec372a58f094f041c8f102f39393Kenny Root/** 191494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 192494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 193494689083467ec372a58f094f041c8f102f39393Kenny Root */ 194494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 195494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 196494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 197494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 198494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 199494689083467ec372a58f094f041c8f102f39393Kenny Root } 200494689083467ec372a58f094f041c8f102f39393Kenny Root } 201494689083467ec372a58f094f041c8f102f39393Kenny Root 202494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 203494689083467ec372a58f094f041c8f102f39393Kenny Root} 204494689083467ec372a58f094f041c8f102f39393Kenny Root 205a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 21207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 215a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 22570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 22670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 22770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 22807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) { 22970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 23070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 23170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 23207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return n + encode_key(out, keyName); 233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 23507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 23607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 23707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 23807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 23907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 24007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 24107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 24207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 24307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 24407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 24507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 24607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 24707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 24807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 24907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 25007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 25107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 25207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 25307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 25407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 25507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 25607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 25707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 25807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 25907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 26007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 26107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 26207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 26307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 26407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 265a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 26607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 267a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 268a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 269a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 270a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 271a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 272a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 273a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 274a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 275150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 2765281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 277150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 278a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 279a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 280a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 283a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 285a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 288150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 289150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 290150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 291150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 292a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 293a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 294a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 300a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 303150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 310150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 311150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3185187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 330822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 331822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 335822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 336822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 350822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 351822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 352822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t reserved; 353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 355822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 357822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 362822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 363822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 364822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 365822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 366822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 367822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 36807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 1; 369822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 37207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 37307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 379822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 38007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 381822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3905187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3945187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3985187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 3995187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4005187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4015187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4025187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 404a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 406822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 407822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 408822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 409822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 410822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 411822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 412822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 413822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 414822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 415822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 416822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 417822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 418822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 419822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 420822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 421822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) { 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 424150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read random data for: %s", filename); 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root aes_key, vector, AES_ENCRYPT); 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 448822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.reserved = 0; 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 453150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 454150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 455150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 456150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 464150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 468150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 469150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 470150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 471150ca934edb745de3666a6492b039900df228ff0Kenny Root } 472150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) { 476150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 477150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) { 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.vector, AES_DECRYPT); 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, computedDigest); 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 51407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 52170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct { 52270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint32_t uid; 523a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom const uint8_t* filename; 52470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 52570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode plist; 52670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t; 52770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore { 529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 53070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 5315187818895c4c5f650a611c40531b1dff7764c18Kenny Root : mEntropy(entropy) 53270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root , mDevice(device) 5335187818895c4c5f650a611c40531b1dff7764c18Kenny Root , mRetry(MAX_RETRY) 5345187818895c4c5f650a611c40531b1dff7764c18Kenny Root { 535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(MASTER_KEY_FILE, R_OK) == 0) { 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 54070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 54170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_init(&mGrants); 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5445187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5485187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 55270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* getDevice() const { 55370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return mDevice; 55470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 55570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 55607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode initialize(const android::String8& pw) { 557a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateMasterKey()) { 558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = writeMasterKey(pw); 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 56507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 56807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode writeMasterKey(const android::String8& pw) { 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 573822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy); 575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 57707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode readMasterKey(const android::String8& pw) { 578150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(MASTER_KEY_FILE, O_RDONLY)); 579150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey); 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = writeMasterKey(pw); 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool reset() { 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(file->d_name); 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6515187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool isEmpty() const { 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (isKeyFile(file->d_name)) { 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void lock() { 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 673822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) { 674822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption); 675822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 676822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 677822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 678822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 679822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 68007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 681822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root upgrade(filename, keyBlob, version, type); 682822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 683822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 684822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (keyBlob->getType() != type) { 685822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 686822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 687822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 688822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 689822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode put(const char* filename, Blob* keyBlob) { 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy); 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 69607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 69707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 69870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant == NULL) { 69970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = new grant_t; 70007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 701a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 70270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_add_tail(&mGrants, &grant->plist); 70370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 70470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 70570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 70607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 70707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 70870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant != NULL) { 70970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_remove(&grant->plist); 71070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete grant; 71170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return true; 71270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 71370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 71470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 71570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 71670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 717a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 718a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 71970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 72107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename) { 722822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 723822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 724822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 725822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 726822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 727822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 728822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 729822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 730822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 73107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 732822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 733822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 734822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 735822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 736822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 737822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 738822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 739822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 740822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return put(filename, &keyBlob); 741822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 742822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 743a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const char* MASTER_KEY_FILE; 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MAX_RETRY = 4; 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const size_t SALT_SIZE = 16; 750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy* mEntropy; 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 75370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* mDevice; 75470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State mState; 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t mRetry; 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mSalt[SALT_SIZE]; 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyEncryption; 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyDecryption; 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 76470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode mGrants; 76570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setState(State state) { 767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mState = state; 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRetry = MAX_RETRY; 770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 773a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateSalt() { 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mEntropy->generate_random_data(mSalt, sizeof(mSalt)); 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateMasterKey() { 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setupMasterKeys() { 788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_NO_ERROR); 791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 792a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void clearMasterKeys() { 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mSalt, 0, sizeof(mSalt)); 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 80007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 80107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* salt) { 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t saltSize; 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt != NULL) { 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = SALT_SIZE; 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) "keystore"; 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // sizeof = 9, not strlen = 8 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = sizeof("keystore"); 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 81107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 81207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 81307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root saltSize, 8192, keySize, key); 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static bool isKeyFile(const char* filename) { 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return ((strcmp(filename, MASTER_KEY_FILE) != 0) 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, ".") != 0) 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, "..") != 0)); 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 82170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 822a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant_t* getGrant(const char* filename, uid_t uid) const { 82370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode *node; 82470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant; 82570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 82670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_for_each(node, &mGrants) { 82770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = node_to_item(node, grant_t, plist); 82870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 829a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom && !strcmp(reinterpret_cast<const char*>(grant->filename), 830a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom filename)) { 83170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 83270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 83370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 83470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 83570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 83670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 83770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 838822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 839822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 840822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 841822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 842822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) { 843822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 844822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 845822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 846822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 847822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 848822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 849822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 850822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 851822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 852822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root importBlobAsKey(blob, filename); 853822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 854822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 855822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 856822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 857822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 858822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 859822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 860822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 861822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * */ 862822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 863822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 864822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 865822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root this->put(filename, blob); 866822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 867822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 868822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 869822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 870822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 871822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 872822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 873822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 874822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 875822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename) { 876822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 877822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 878822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 879822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 880822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 881822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 882822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 883822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 884822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 885822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 886822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 887822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 888822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 889822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 890822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 891822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 892822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 893822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 894822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 895822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 89670c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 89770c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 898822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 899822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 900822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 901822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 902822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 90370c9889c5ca912e7c492580e1999f18ab65b267bKenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename); 904822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 905822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 906822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 907822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 908822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return get(filename, blob, TYPE_KEY_PAIR); 909822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 910a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 911a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 912a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey"; 913a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 91407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, 91507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const android::String8& keyName, const uid_t uid, const BlobType type) { 91670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 91770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 91870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 919822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, keyBlob, type); 92070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 92170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 92270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 92370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 924494689083467ec372a58f094f041c8f102f39393Kenny Root // If this is one of the legacy UID->UID mappings, use it. 925494689083467ec372a58f094f041c8f102f39393Kenny Root uid_t euid = get_keystore_euid(uid); 926494689083467ec372a58f094f041c8f102f39393Kenny Root if (euid != uid) { 927494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, euid, keyName); 928822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root responseCode = keyStore->get(filename, keyBlob, type); 92970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 93070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 93170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 93270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 93370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 93470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // They might be using a granted key. 935a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom encode_key(filename, keyName); 936a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom if (!keyStore->hasGrant(filename, uid)) { 93770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 93870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 93970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 94070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // It is a granted key. Try to load it. 941822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->get(filename, keyBlob, type); 94270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 94370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 94407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 94507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 94607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 94707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 94807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 94907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 95007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 951a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 95207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 95307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 95407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 955a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 95607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 957d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 958d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 959d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 96007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 96107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 962a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 96307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->getState(); 964a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 965a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 96607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 967d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 968d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 969d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 97007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 97107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 972a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9739d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 9749d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 97507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get in state: %d", state); 97607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 97707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 978a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 97907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 98007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 98107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 982494689083467ec372a58f094f041c8f102f39393Kenny Root 983494689083467ec372a58f094f041c8f102f39393Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 984494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 98507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 986150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read %s", filename); 98707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 98807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 98907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 99007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 99107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 99207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 99307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 99407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 99507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 99607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 997a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 998a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 999494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid) { 1000d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1001d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1002d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 100307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 100407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 100507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1006494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1007494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1008494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1009b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1010b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1011b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 10129d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 10139d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 101407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling insert in state: %d", state); 101507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 1016a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 101707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 101807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 101907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 102007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1021494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 102207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 102307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 102407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 1025a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1026a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1027494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1028d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1029d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1030d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 103107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 103207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 103307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1034494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1035494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1036494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1037b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1038b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1039b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 104007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 104107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 104207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1043494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 1044298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 104507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 104607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC); 104707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 104807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 104907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 105007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1051298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1052298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1053494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1054d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1055d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1056d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 105707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 105807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 105907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1060494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1061494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1062494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1063b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1064b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1065b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 106607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 106707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 106807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1069494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 107007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 107107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 107207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 107307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 107407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1075298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1076298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1077494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1078d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1079d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1080d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 108107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 108207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 108307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1084494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1085494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1086494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1087b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1088b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1089b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 109007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root DIR* dir = opendir("."); 109107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 109207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 109307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 109407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 109507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 109607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 109707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1098494689083467ec372a58f094f041c8f102f39393Kenny Root int n = encode_key_for_uid(filename, targetUid, prefix8); 109907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 110007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 110107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 110207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!strncmp(filename, file->d_name, n)) { 110307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 110407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 110507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 110607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 110707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 110807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 110907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 111007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 111107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 111207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 111307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 111407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 111507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 111607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 111707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 111807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 111907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1120298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1121298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 112207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1123d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1124d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1125d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 112607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 112707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1128a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 112907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR; 1130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 113107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 113207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 113307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 113407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1135a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 113607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 113707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 113807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 113907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1140a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 114107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 114207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 114307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 114407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1145a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 114607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 114707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1148a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1149a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 115007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 115107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 115207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 115307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 115407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 115507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 115607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 115707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1158d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1159d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1160d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 116107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 116207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 116407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 116607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root switch (mKeyStore->getState()) { 116707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 116807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 116907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->initialize(password8); 117007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 117107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 117207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 117307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->writeMasterKey(password8); 117407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 117507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 117607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 117707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->readMasterKey(password8); 117807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 117907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 118007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 118107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1182a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 118307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1184d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1185d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1186d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 118707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 118807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 118907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 11909d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 11919d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 119207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 119307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 119407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 119607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mKeyStore->lock(); 119707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 119870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 120007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1201d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1202d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1203d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 120407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 120507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 120607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 12079d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12089d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 120907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 121007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 121107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 121207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 121307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 121407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 121570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 121670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 121707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1218d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1219d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1220d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 122107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 122207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 122370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 122407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR; 122570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 122670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1227494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t generate(const String16& name, int targetUid) { 1228d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1229d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1230d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 123107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 123207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 123370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1234494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1235494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1236494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1237b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1238b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1239b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 12409d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12419d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 124207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling generate in state: %d", state); 124307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 124407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 124570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 124707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 124870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 125007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 125107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 125270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 125307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 125407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 125507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 125607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 125770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 125807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 125907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 126007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 126170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_keygen_params_t rsa_params; 126307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.modulus_size = 2048; 126407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.public_exponent = 0x10001; 126570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 126707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 126807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 126907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 127070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1271494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 127270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 127407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 127507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 127607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 127770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 127870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1279494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid) { 1280d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1281d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1282d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 128307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 128407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 128570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1286494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1287494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1288494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1289b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1290b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1291b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 12929d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12939d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 129407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 129507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 129607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 129770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 129807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 129907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 130070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1301494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 130270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->importKey(data, length, filename); 130470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 130570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 130707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1308d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1309d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1310d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 131107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 131207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 13139a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 13149d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 13159d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 131607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling sign in state: %d", state); 131707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 13189a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } 131970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 132007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 132107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 132270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1323d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 132407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 132570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1326d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 1327d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 132807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 132907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 133007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 133170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 133207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 133307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 133407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 133507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 133607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 133770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 133807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 133907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 134007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 134107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 134270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 134307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 134407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 134507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 134607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 134707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 134807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, length, out, outLength); 134907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 135007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 135107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 135207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 135370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 135407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 135570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 135670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 135707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 135807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1359d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1360d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1361d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 136207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 136307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 136470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13659d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 13669d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 136707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 136807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 136907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 137070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 137107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 137207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 137307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 137470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1375494689083467ec372a58f094f041c8f102f39393Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 1376494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 137707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 137807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 137907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 138107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 138207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 138307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 138407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 138607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 138707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 138807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 139007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 139107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 139207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 139370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 139407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 139507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, dataLength, signature, signatureLength); 139607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 139707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 139807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 139907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 140007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 140170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 140270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 140307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 140407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 140507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 140607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 140707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 140807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 140907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 141007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 141107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 141207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 141307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 141407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 1415d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1416d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1417d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 141807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 141907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 142070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14219d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 14229d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 142307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get_pubkey in state: %d", state); 142407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 142507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 142670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 142807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 142970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1430d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 143170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1432d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 143307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 143407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 143507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 143770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 143807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 143907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 144007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 144107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 144270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 144307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 144407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 144507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 144607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1447344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 144807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 144907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root pubkeyLength); 145007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 145107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 145207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1453344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 145407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1455344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1456344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1457494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 1458d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1459d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1460d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 146107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 146207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1463344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1464494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1465494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1466494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1467b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1468b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1469b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 147007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 147107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 1472344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1473494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 1474344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 147507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 147607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR); 147707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 147807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 147907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 148107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 1482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 148307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 148407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 148507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 148607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 148707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 148807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair != NULL) { 148907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 149007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 149607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 149707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 150107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 150207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 1503d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1504d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1505d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 150607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 150807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15099d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 15109d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 151107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 151207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 151507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 151607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1518d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 151907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 152107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 152207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mKeyStore->addGrant(filename, granteeUid); 152507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 152707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 1529d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1530d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1531d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 153207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15359d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 15369d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 153707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1544d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 154807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 1551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 155207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 1554d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1555d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1556d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 155736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 155807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 156107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 156207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1563d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 156636a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not access %s for getmtime", filename); 156736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 1568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1570150ca934edb745de3666a6492b039900df228ff0Kenny Root int fd = TEMP_FAILURE_RETRY(open(filename, O_NOFOLLOW, O_RDONLY)); 157107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 157236a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not open %s for getmtime", filename); 157336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 157407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 157507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 157707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 157807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 157907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 158036a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not stat %s for getmtime", filename); 158136a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158436a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 1585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 15889d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 15899d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 15909d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 15919d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 15929d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 15939d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 15949d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 15959d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 15969d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 1597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 159807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 160107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 160207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 1603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 1605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 1606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 1607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 1610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 1611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 1615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 1616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 161870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 161970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 162070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 162170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 162270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 162370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 162470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 162570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 163107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 1632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 163370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 163407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 163507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 163807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 163970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 164007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 1641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1643