keystore.cpp revision 5281edbc9445065479e92a6c86da462f3943c2ca
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 91a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct Value { 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Value(const uint8_t* orig, int origLen) { 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root assert(origLen <= VALUE_SIZE); 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root memcpy(value, orig, origLen); 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root length = origLen; 96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Value() { 99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 101a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int length; 102a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE]; 103a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 104a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootclass ValueString { 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootpublic: 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString(const Value* orig) { 108822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root assert(length <= VALUE_SIZE); 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root length = orig->length; 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value = new char[length + 1]; 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root memcpy(value, orig->value, length); 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value[length] = '\0'; 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ~ValueString() { 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete[] value; 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const char* c_str() const { 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return value; 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* release() { 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* ret = value; 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root value = NULL; 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return ret; 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootprivate: 13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* value; 13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root size_t length; 13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}; 13370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 13570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 13670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 13870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 14570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 14970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 15070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 15170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 15270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 15370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 15470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 15570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 15670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 15770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 15870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 15970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 16070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 16170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 16707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_TEST = 1 << 0, 16907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_GET = 1 << 1, 17007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_INSERT = 1 << 2, 17107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_DELETE = 1 << 3, 17207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_EXIST = 1 << 4, 17307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_SAW = 1 << 5, 17407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_RESET = 1 << 6, 17507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_PASSWORD = 1 << 7, 17607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_LOCK = 1 << 8, 17707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_UNLOCK = 1 << 9, 17807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_ZERO = 1 << 10, 17907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_SIGN = 1 << 11, 18007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_VERIFY = 1 << 12, 18107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root P_GRANT = 1 << 13, 18207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 18407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 18507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 18607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 18707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 18807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 18907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 19007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 19107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 19207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 19307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 19407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 19507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 19607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 19707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 19807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 19907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 20007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 20107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 20207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 20407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 20507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic bool has_permission(uid_t uid, perm_t perm) { 20707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 20807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 20907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 21007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.perms & perm; 21107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 21207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return DEFAULT_PERMS & perm; 21507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 21607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 21707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 21807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 21907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 22007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 22107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 22207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 22307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 22407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 22507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 22607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 22707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 228a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 229a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 230a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 231a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 232a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 233a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 23507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 23607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 23707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 238a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 239a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 240a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 246a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 24870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 24970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 25070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 25107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) { 25270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 25370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 25470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 25507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return n + encode_key(out, keyName); 256a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 257a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 25807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 25907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 26007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 26107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 26207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 26307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 26407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 26507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 26607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 26707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 26807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 26907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 27007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 27107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 27207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 27307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 27407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 27507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 27607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 27707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 27807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 27907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 28007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 28107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 28707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 290a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 291a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 292a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 293a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 294a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 298150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 2995281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 300150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 311150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 312150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 313150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 314150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 326150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 333150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 334150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 337a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 338a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3415187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 353822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 354822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 358822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 359822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 360822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 361822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 362822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 363822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 364822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 365822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 366822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 367822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 368822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 369822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 370822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 371822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 373822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 374822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 375822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t reserved; 376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 378822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 380822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 382a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 383a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 385822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 386822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 387822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 388822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 389822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 390822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 39107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 1; 392822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 39507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 39607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 402822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 40307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 404822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 409a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 410a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 411a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 412a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4135187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 414a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 415a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 416a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4175187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 420a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4215187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4225187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4235187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4245187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4255187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 429822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 430822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 431822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 432822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 433822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 434822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 435822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 436822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 437822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 438822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 439822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 440822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 441822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 442822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 443822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 444822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) { 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 447150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read random data for: %s", filename); 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 456a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 457a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 458a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root aes_key, vector, AES_ENCRYPT); 470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 471822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.reserved = 0; 472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 474a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 476150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 477150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 478150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 479150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 487150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 491150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 492150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 493150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 494150ca934edb745de3666a6492b039900df228ff0Kenny Root } 495150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) { 499150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 500150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) { 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.vector, AES_DECRYPT); 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, computedDigest); 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 529a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 533a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 534a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 535a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 53707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 54470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct { 54570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint32_t uid; 546a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom const uint8_t* filename; 54770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 54870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode plist; 54970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t; 55070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore { 552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 55370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 5545187818895c4c5f650a611c40531b1dff7764c18Kenny Root : mEntropy(entropy) 55570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root , mDevice(device) 5565187818895c4c5f650a611c40531b1dff7764c18Kenny Root , mRetry(MAX_RETRY) 5575187818895c4c5f650a611c40531b1dff7764c18Kenny Root { 558a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(MASTER_KEY_FILE, R_OK) == 0) { 559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 56370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 56470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_init(&mGrants); 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5675187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5715187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 57570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* getDevice() const { 57670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return mDevice; 57770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 57870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 57907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode initialize(const android::String8& pw) { 580a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateMasterKey()) { 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = writeMasterKey(pw); 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 58807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 59107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode writeMasterKey(const android::String8& pw) { 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 596822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy); 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 60007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode readMasterKey(const android::String8& pw) { 601150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(MASTER_KEY_FILE, O_RDONLY)); 602150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey); 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = writeMasterKey(pw); 636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool reset() { 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(file->d_name); 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6745187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool isEmpty() const { 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 682a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (isKeyFile(file->d_name)) { 683a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 684a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 685a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 686a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 687a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 690a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void lock() { 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 696822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) { 697822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption); 698822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 699822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 700822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 701822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 702822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 70307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 704822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root upgrade(filename, keyBlob, version, type); 705822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 706822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 707822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (keyBlob->getType() != type) { 708822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 709822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 710822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 711822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 712822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode put(const char* filename, Blob* keyBlob) { 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy); 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 71907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 72007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 72170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant == NULL) { 72270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = new grant_t; 72307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 724a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 72570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_add_tail(&mGrants, &grant->plist); 72670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 72907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 73007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 73170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant != NULL) { 73270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_remove(&grant->plist); 73370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete grant; 73470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return true; 73570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 73670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 73770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 73870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 73970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 740a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 741a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 74270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 74370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 74407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename) { 745822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 746822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 747822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 748822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 749822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 750822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 751822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 752822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 753822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 75407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 755822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 756822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 757822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 758822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 759822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 760822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 761822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 762822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 763822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return put(filename, &keyBlob); 764822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 765822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const char* MASTER_KEY_FILE; 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MAX_RETRY = 4; 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const size_t SALT_SIZE = 16; 773a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy* mEntropy; 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 77670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* mDevice; 77770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State mState; 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t mRetry; 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mSalt[SALT_SIZE]; 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyEncryption; 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyDecryption; 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 78770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode mGrants; 78870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setState(State state) { 790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mState = state; 791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 792a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRetry = MAX_RETRY; 793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateSalt() { 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mEntropy->generate_random_data(mSalt, sizeof(mSalt)); 798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateMasterKey() { 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setupMasterKeys() { 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_NO_ERROR); 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void clearMasterKeys() { 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mSalt, 0, sizeof(mSalt)); 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 82307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 82407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* salt) { 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t saltSize; 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt != NULL) { 827a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = SALT_SIZE; 828a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 829a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) "keystore"; 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // sizeof = 9, not strlen = 8 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = sizeof("keystore"); 833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 83407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 83507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 83607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root saltSize, 8192, keySize, key); 837a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 838a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 839a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static bool isKeyFile(const char* filename) { 840a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return ((strcmp(filename, MASTER_KEY_FILE) != 0) 841a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, ".") != 0) 842a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, "..") != 0)); 843a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 84470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 845a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant_t* getGrant(const char* filename, uid_t uid) const { 84670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode *node; 84770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant; 84870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 84970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_for_each(node, &mGrants) { 85070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = node_to_item(node, grant_t, plist); 85170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 852a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom && !strcmp(reinterpret_cast<const char*>(grant->filename), 853a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom filename)) { 85470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 85570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 85670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 85770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 85870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 85970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 86070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 86170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root bool convertToUid(const Value* uidValue, uid_t* uid) const { 86270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ValueString uidString(uidValue); 86370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char* end = NULL; 86470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *uid = strtol(uidString.c_str(), &end, 10); 86570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return *end == '\0'; 86670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 867822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 868822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 869822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 870822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 871822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 872822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) { 873822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 874822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 875822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 876822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 877822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 878822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 879822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 880822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 881822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 882822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root importBlobAsKey(blob, filename); 883822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 884822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 885822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 886822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 887822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 888822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 889822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 890822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 891822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * */ 892822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 893822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 894822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 895822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root this->put(filename, blob); 896822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 897822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 898822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 899822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 900822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 901822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 902822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 903822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 904822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 905822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename) { 906822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 907822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 908822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 909822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 910822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 911822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 912822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 913822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 914822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 915822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 916822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 917822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 918822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 919822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 920822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 921822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 922822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 923822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 924822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 925822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 926822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Value pkcs8key; 927822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root pkcs8key.length = len; 928822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* tmp = pkcs8key.value; 929822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 930822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 931822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 932822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 933822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 93407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = importKey(pkcs8key.value, pkcs8key.length, filename); 935822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 936822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 937822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 938822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 939822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return get(filename, blob, TYPE_KEY_PAIR); 940822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 941a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 942a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 943a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey"; 944a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 94507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, 94607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const android::String8& keyName, const uid_t uid, const BlobType type) { 94770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 94870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 94970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 950822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, keyBlob, type); 95170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 95270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 95370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 95470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 95570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // If this is the Wifi or VPN user, they actually want system 95670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // UID keys. 95770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (uid == AID_WIFI || uid == AID_VPN) { 95870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, AID_SYSTEM, keyName); 959822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root responseCode = keyStore->get(filename, keyBlob, type); 96070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 96170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 96270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 96370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 96470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 96570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // They might be using a granted key. 966a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom encode_key(filename, keyName); 967a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom if (!keyStore->hasGrant(filename, uid)) { 96870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 96970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 97070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 97170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // It is a granted key. Try to load it. 972822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->get(filename, keyBlob, type); 97370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 97470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 97507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 97607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 97707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 97807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 97907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 98007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 98107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 982a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 98307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 98407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 98507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 986a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 98707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 98807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 98907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_TEST)) { 99007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: test", uid); 99107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 99207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 993a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 99407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->getState(); 995a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 996a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 99707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 99807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 99907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_GET)) { 100007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: get", uid); 100107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 100207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 100307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 1004a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 100507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 100607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 100707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get in state: %d", state); 100807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 100907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1010a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 101107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 101207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 1013a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 101407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 101507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 101607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 101707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC); 101807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1019150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read %s", filename); 102007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 102107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 102207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 102307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 102407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 102507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 102607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 102707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 102807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 102907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1030a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1031a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 103207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength) { 103307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 103407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_INSERT)) { 103507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: insert", uid); 103607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 103707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 103807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 103907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 104007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 104107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 104207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling insert in state: %d", state); 104307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 1044a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 104507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 104607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 104707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 104807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 104907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 105007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 105107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 105207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 1053a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1054a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 105507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t del(const String16& name) { 105607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 105707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_DELETE)) { 105807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: del", uid); 105907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 106007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 106107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 106207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 106307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 106407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 106507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 106607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 1067298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 106807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 106907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC); 107007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 107107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 107207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 107307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1074298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1075298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 107607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t exist(const String16& name) { 107707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 107807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_EXIST)) { 107907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: exist", uid); 108007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 108107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 108207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 108307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 108407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 108507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 108607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 108707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 108807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 108907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 109007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 109107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 109207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1093298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1094298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 109507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t saw(const String16& prefix, Vector<String16>* matches) { 109607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 109707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_SAW)) { 109807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: saw", uid); 109907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 110007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 110107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 110207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 110307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root DIR* dir = opendir("."); 110407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 110507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 110607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 110707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 110807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 110907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 111007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 111107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int n = encode_key_for_uid(filename, uid, prefix8); 111207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 111307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 111407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 111507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!strncmp(filename, file->d_name, n)) { 111607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 111707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 111807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 111907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 112007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 112107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 112207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 112307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 112407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 112507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 112607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 112707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 112807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 112907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 113007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 113107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 113207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1133298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1134298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 113507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 113607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 113707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_RESET)) { 113807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: reset", uid); 113907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 114007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1141a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 114207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR; 1143a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 114407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 114507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 114607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 114707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1148a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 114907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 115007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 115107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 115207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1153a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 115407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 115507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 115607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 115707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 115907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 116007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 116307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 116407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 116507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 116607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 116707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 116807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 116907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 117007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 117107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 117207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_PASSWORD)) { 117307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: password", uid); 117407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 117507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 117707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1178a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 117907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root switch (mKeyStore->getState()) { 118007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 118107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 118207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->initialize(password8); 118307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 118407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 118507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 118607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->writeMasterKey(password8); 118707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 118807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 118907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 119007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->readMasterKey(password8); 119107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 119407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1195a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 119607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 119707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 119807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_LOCK)) { 119907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: lock", uid); 120007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 120107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 120207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 120307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 120407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 120507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 120607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 120707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 120870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 120907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mKeyStore->lock(); 121007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 121170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 121307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 121407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 121507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_UNLOCK)) { 121607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: unlock", uid); 121707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 121807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 121907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 122007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 122107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_LOCKED) { 122207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 122307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 122407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 122507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 122607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 122707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 122870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 122970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 123007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 123107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 123207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_ZERO)) { 123307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: zero", uid); 123407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 123507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 123670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 123707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR; 123870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t generate(const String16& name) { 124107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 124207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_INSERT)) { 124307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: generate", uid); 124407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 124507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 124607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 124770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 124907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 125007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling generate in state: %d", state); 125107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 125207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 125370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 125407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 125507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 125670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 125707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 125807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 125907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 126070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 126207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 126307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 126407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 126570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 126707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 126807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 126970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_keygen_params_t rsa_params; 127107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.modulus_size = 2048; 127207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.public_exponent = 0x10001; 127370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 127507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 127607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 127707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 127870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 128070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 128107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 128207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 128307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 128407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 128570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 128707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length) { 128807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 128907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_INSERT)) { 129007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: import", uid); 129107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 129207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 129307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 129470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 129507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 129607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 129707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 129807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 129907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 130070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 130207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 130370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 130570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->importKey(data, length, filename); 130770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 130870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 131007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 131107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 131207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_SIGN)) { 131307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: saw", uid); 131407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 131507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 131607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 13179a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 131807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 131907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 132007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling sign in state: %d", state); 132107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 13229a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } 132370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 132407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 132507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 132670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 132707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("sign %s from uid %d", name8.string(), uid); 132807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 132970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 133007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, uid, ::TYPE_KEY_PAIR); 133107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 133207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 133307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 133470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 133507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 133607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 133707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 133807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 133907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 134070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 134107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 134207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 134307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 134407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 134570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 134607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 134707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 134807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 134907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 135007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 135107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, length, out, outLength); 135207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 135307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 135407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 135507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 135670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 135707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 135870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 135970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 136007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 136107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 136207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 136307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_VERIFY)) { 136407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: verify", uid); 136507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 136607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 136707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 136870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 136907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 137007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 137107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 137207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 137307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 137470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 137507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 137607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 137707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 137870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 137907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, uid, TYPE_KEY_PAIR); 138007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 138107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 138207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 138407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 138507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 138607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 138707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 138907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 139007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 139107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 139207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 139307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 139407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 139507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 139670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 139707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 139807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, dataLength, signature, signatureLength); 139907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 140007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 140107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 140207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 140307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 140470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 140570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 140607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 140707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 140807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 140907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 141007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 141107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 141207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 141307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 141407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 141507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 141607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 141707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 141807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 141907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_GET)) { 142007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: get_pubkey", uid); 142107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 142207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 142307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 142470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 142507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 142607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get_pubkey in state: %d", state); 142807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 142907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 143070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 143107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 143207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 143370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 143407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), uid); 143570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, uid, 143707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 143807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 143907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 144007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 144170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 144207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 144307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 144407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 144507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 144670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 144707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 144807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 144907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 145007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1451344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 145207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 145307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root pubkeyLength); 145407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 145507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 145607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1457344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 145807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1459344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1460344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 146107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t del_key(const String16& name) { 146207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_DELETE)) { 146407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: del_key", uid); 146507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 146607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 1468344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 146907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 147007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 1471344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 147207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 1473344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 147407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 147507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR); 147607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 147707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 147807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1479a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 148007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 1481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 148207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 148307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 148407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 148507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 148607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 148707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair != NULL) { 148807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 148907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 149007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 149607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 150007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 150107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 150207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 150307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_GRANT)) { 150407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: grant", uid); 150507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 150707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 150807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 150907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 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 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, 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) { 152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 153007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_GRANT)) { 153107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: ungrant", uid); 153207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 153507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 153607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root State state = checkState(); 153707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (state != STATE_NO_ERROR) { 153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 154607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 154807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 1552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 155307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 155507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid = IPCThreadState::self()->getCallingUid(); 155607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!has_permission(uid, P_GET)) { 155707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("permission denied for %d: getmtime", uid); 155807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 155907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid = get_keystore_euid(uid); 156107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root encode_key_for_uid(filename, uid, name8); 156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 156807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 1569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 157007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1571150ca934edb745de3666a6492b039900df228ff0Kenny Root int fd = TEMP_FAILURE_RETRY(open(filename, O_NOFOLLOW, O_RDONLY)); 157207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 157307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 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) { 158007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 158107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return s.st_mtime; 1584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root inline State checkState() { 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->getState(); 1589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 159207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 1595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 1597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 1598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 1599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 1602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 1603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 1607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 1608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 161070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 161170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 161270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 161370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 161470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 161570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 161670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 161770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 162007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 162207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 1624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 162570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 162707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 163007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 163170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 1633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1635