keystore.cpp revision d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cf
1a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* 2a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Copyright (C) 2009 The Android Open Source Project 3a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 4a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Licensed under the Apache License, Version 2.0 (the "License"); 5a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * you may not use this file except in compliance with the License. 6a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * You may obtain a copy of the License at 7a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 8a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * http://www.apache.org/licenses/LICENSE-2.0 9a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * 10a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * Unless required by applicable law or agreed to in writing, software 11a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * distributed under the License is distributed on an "AS IS" BASIS, 12a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * See the License for the specific language governing permissions and 14a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * limitations under the License. 15a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root */ 16a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root//#define LOG_NDEBUG 0 1807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#define LOG_TAG "keystore" 1907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdio.h> 21a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <stdint.h> 22a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <string.h> 23a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <unistd.h> 24a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <signal.h> 25a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <errno.h> 26a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <dirent.h> 27a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 29822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 30a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 37822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 38a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 39a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 40822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 41a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h> 4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 44822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <utils/UniquePtr.h> 45822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 4670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/list.h> 4770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 4907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 52a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 53a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 54a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 59a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 61a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 62a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 63a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 64a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 65a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 66a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 68822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 69822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 70822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 71822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 72822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 73822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 74822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 75822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 76822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 77822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 78822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 79822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 80822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 81822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 82822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 9170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 9270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 9370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 9470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 9570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 9670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 9770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 9870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 9970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 10370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 12007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 12107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 12207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 12307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 12407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 125d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_TEST = 1 << 0, 126d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GET = 1 << 1, 127d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_INSERT = 1 << 2, 128d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DELETE = 1 << 3, 129d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_EXIST = 1 << 4, 130d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SAW = 1 << 5, 131d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_RESET = 1 << 6, 132d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_PASSWORD = 1 << 7, 133d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_LOCK = 1 << 8, 134d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_UNLOCK = 1 << 9, 135d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_ZERO = 1 << 10, 136d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SIGN = 1 << 11, 137d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_VERIFY = 1 << 12, 138d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GRANT = 1 << 13, 139d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DUPLICATE = 1 << 14, 14007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 14107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 14207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 14307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 14407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 14507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 14607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 14707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 14807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 14907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 15007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 15207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 15507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 15607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 15707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 15807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic bool has_permission(uid_t uid, perm_t perm) { 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 16607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 16707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.perms & perm; 16907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 17007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 17107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return DEFAULT_PERMS & perm; 17307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 17407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 175494689083467ec372a58f094f041c8f102f39393Kenny Root/** 176494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 177494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 178494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 179494689083467ec372a58f094f041c8f102f39393Kenny Root */ 18007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 18107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 18207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 18407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 18507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 18807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 18907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 19007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 191494689083467ec372a58f094f041c8f102f39393Kenny Root/** 192494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 193494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 194494689083467ec372a58f094f041c8f102f39393Kenny Root */ 195494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 196494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 197494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 198494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 199494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 200494689083467ec372a58f094f041c8f102f39393Kenny Root } 201494689083467ec372a58f094f041c8f102f39393Kenny Root } 202494689083467ec372a58f094f041c8f102f39393Kenny Root 203494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 204494689083467ec372a58f094f041c8f102f39393Kenny Root} 205494689083467ec372a58f094f041c8f102f39393Kenny Root 206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 21307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 21507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 22670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 22770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 22870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 22907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) { 23070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 23170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 23270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 23307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return n + encode_key(out, keyName); 234a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 23607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 23707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 23807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 23907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 24007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 24107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 24207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 24307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 24407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 24507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 24607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 24707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 24807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 24907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 25007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 25107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 25207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 25307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 25407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 25507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 25607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 25707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 25807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 25907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 26007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 26107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 26207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 26307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 26407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 26507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 266a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 26707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 268a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 269a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 270a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 271a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 272a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 273a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 274a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 275a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 276150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 2775281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 278150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 279a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 280a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 283a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 285a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 289150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 290150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 291150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 292150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 293a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 294a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 300a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 304150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 305a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 311150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 312150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 313a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3195187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 331822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 332822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 336822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 349822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 350a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 351822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 352822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 353822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t reserved; 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 356822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 358822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 363822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 364d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 365822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 366822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 367822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 368822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 369822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 37007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 1; 371822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 37407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 381822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 38207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 383822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 384a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3925187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 393a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3965187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 397a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4005187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4015187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4025187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4035187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4045187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 408822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 409822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 410822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 411822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 412822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 413822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 414822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 415822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 416822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 417822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 418822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 419822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 420822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 421822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 422822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 423822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) { 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 426150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read random data for: %s", filename); 427a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root aes_key, vector, AES_ENCRYPT); 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 450822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.reserved = 0; 451a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 455150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 456150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 457150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 458150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 459a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 466150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 467a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 470150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 471150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 472150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 473150ca934edb745de3666a6492b039900df228ff0Kenny Root } 474150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 475a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) { 478150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 479150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 480a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) { 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.vector, AES_DECRYPT); 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, computedDigest); 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 51607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 52370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct { 52470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint32_t uid; 525a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom const uint8_t* filename; 52670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 52770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode plist; 52870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t; 52970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 530a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore { 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 53270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 5335187818895c4c5f650a611c40531b1dff7764c18Kenny Root : mEntropy(entropy) 53470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root , mDevice(device) 5355187818895c4c5f650a611c40531b1dff7764c18Kenny Root , mRetry(MAX_RETRY) 5365187818895c4c5f650a611c40531b1dff7764c18Kenny Root { 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(MASTER_KEY_FILE, R_OK) == 0) { 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 54270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 54370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_init(&mGrants); 544a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5465187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5505187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 55470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* getDevice() const { 55570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return mDevice; 55670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 55770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 55807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode initialize(const android::String8& pw) { 559a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateMasterKey()) { 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = writeMasterKey(pw); 563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 56707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 57007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode writeMasterKey(const android::String8& pw) { 571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 575822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 576a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy); 577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 57907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode readMasterKey(const android::String8& pw) { 580150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(MASTER_KEY_FILE, O_RDONLY)); 581150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey); 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = writeMasterKey(pw); 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool reset() { 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(file->d_name); 648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6535187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool isEmpty() const { 654a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (isKeyFile(file->d_name)) { 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void lock() { 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 675822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) { 676822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption); 677822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 678822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 679822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 680822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 681822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 68207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 683822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root upgrade(filename, keyBlob, version, type); 684822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 685822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 686d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 687822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 688822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 689822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 690822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 691822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode put(const char* filename, Blob* keyBlob) { 695a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy); 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 69807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 69907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 70070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant == NULL) { 70170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = new grant_t; 70207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 703a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 70470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_add_tail(&mGrants, &grant->plist); 70570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 70670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 70770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 70807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 70907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 71070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant != NULL) { 71170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_remove(&grant->plist); 71270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete grant; 71370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return true; 71470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 71570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 71670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 71770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 71870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 719a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 720a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 72170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 72307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename) { 724822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 725822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 726822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 727822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 728822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 729822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 730822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 731822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 732822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 73307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 734822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 735822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 736822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 737822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 738822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 739822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 740822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 741822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 742822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return put(filename, &keyBlob); 743822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 744822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const char* MASTER_KEY_FILE; 747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MAX_RETRY = 4; 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const size_t SALT_SIZE = 16; 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy* mEntropy; 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 75570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* mDevice; 75670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State mState; 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t mRetry; 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mSalt[SALT_SIZE]; 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyEncryption; 764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyDecryption; 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 76670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode mGrants; 76770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setState(State state) { 769a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mState = state; 770a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRetry = MAX_RETRY; 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 773a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateSalt() { 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mEntropy->generate_random_data(mSalt, sizeof(mSalt)); 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateMasterKey() { 780a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setupMasterKeys() { 790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 792a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_NO_ERROR); 793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void clearMasterKeys() { 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mSalt, 0, sizeof(mSalt)); 798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 80207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 80307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* salt) { 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t saltSize; 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt != NULL) { 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = SALT_SIZE; 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) "keystore"; 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // sizeof = 9, not strlen = 8 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = sizeof("keystore"); 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 81307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 81407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 81507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root saltSize, 8192, keySize, key); 816a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 817a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static bool isKeyFile(const char* filename) { 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return ((strcmp(filename, MASTER_KEY_FILE) != 0) 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, ".") != 0) 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, "..") != 0)); 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 82370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 824a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant_t* getGrant(const char* filename, uid_t uid) const { 82570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode *node; 82670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant; 82770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 82870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_for_each(node, &mGrants) { 82970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = node_to_item(node, grant_t, plist); 83070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 831a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom && !strcmp(reinterpret_cast<const char*>(grant->filename), 832a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom filename)) { 83370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 83470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 83570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 83670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 83770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 83870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 83970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 840822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 841822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 842822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 843822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 844822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) { 845822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 846822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 847822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 848822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 849822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 850822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 851822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 852822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 853822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 854822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root importBlobAsKey(blob, filename); 855822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 856822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 857822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 858822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 859822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 860822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 861822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 862822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 863822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * */ 864822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 865822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 866822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 867822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root this->put(filename, blob); 868822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 869822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 870822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 871822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 872822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 873822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 874822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 875822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 876822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 877822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename) { 878822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 879822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 880822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 881822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 882822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 883822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 884822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 885822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 886822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 887822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 888822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 889822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 890822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 891822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 892822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 893822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 894822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 895822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 896822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 897822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 89870c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 89970c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 900822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 901822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 902822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 903822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 904822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 90570c9889c5ca912e7c492580e1999f18ab65b267bKenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename); 906822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 907822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 908822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 909822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 910822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return get(filename, blob, TYPE_KEY_PAIR); 911822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 912a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 913a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 914a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey"; 915a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 91607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, 91707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const android::String8& keyName, const uid_t uid, const BlobType type) { 91870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 91970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 92070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 921822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, keyBlob, type); 92270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 92370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 92470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 92570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 926494689083467ec372a58f094f041c8f102f39393Kenny Root // If this is one of the legacy UID->UID mappings, use it. 927494689083467ec372a58f094f041c8f102f39393Kenny Root uid_t euid = get_keystore_euid(uid); 928494689083467ec372a58f094f041c8f102f39393Kenny Root if (euid != uid) { 929494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, euid, keyName); 930822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root responseCode = keyStore->get(filename, keyBlob, type); 93170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 93270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 93370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 93470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 93570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 93670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // They might be using a granted key. 937a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom encode_key(filename, keyName); 938a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom if (!keyStore->hasGrant(filename, uid)) { 93970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 94070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 94170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 94270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // It is a granted key. Try to load it. 943822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->get(filename, keyBlob, type); 94470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 94570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 94607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 94707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 94807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 94907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 95007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 95107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 95207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 953a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 95407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 95507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 95607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 957a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 95807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 959d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 960d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 961d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 96207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 96307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 964a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 96507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->getState(); 966a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 967a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 96807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 969d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 970d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 971d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 97207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 97307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 974a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9759d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 9769d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 97707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get in state: %d", state); 97807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 97907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 980a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 98107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 98207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 98307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 984494689083467ec372a58f094f041c8f102f39393Kenny Root 985494689083467ec372a58f094f041c8f102f39393Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 986494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 98707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 988150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read %s", filename); 98907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 99007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 99107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 99207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 99307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 99407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 99507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 99607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 99707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 99807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 999a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1000a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1001494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid) { 1002d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1003d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1004d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 100507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 100607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 100707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1008494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1009494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1010494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1011b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1012b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1013b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 10149d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 10159d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 101607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling insert in state: %d", state); 101707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 1018a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 101907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 102007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 102107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 102207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1023494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 102407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 102507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 102607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 1027a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1028a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1029494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1030d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1031d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1032d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 103307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 103407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 103507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1036494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1037494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1038494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1039b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1040b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1041b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 104207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 104307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 104407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1045494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 1046298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 104707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 104807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC); 104907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 105007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 105107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 105207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1053298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1054298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1055494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1056d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1057d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1058d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 105907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 106007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 106107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1062494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1063494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1064494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1065b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1066b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1067b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 106807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 106907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 107007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1071494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 107207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 107307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 107407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 107507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 107607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1077298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1078298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1079494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1080d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1081d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1082d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 108307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 108407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 108507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1086494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1087494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1088494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1089b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1090b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1091b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 109207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root DIR* dir = opendir("."); 109307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 109407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 109507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 109607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 109707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 109807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 109907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1100494689083467ec372a58f094f041c8f102f39393Kenny Root int n = encode_key_for_uid(filename, targetUid, prefix8); 110107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 110207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 110307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 110407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!strncmp(filename, file->d_name, n)) { 110507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 110607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 110707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 110807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 110907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 111007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 111107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 111207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 111307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 111407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 111507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 111607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 111707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 111807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 111907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 112007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 112107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1122298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1123298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 112407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1125d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1126d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1127d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 112807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 112907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1130a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 113107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR; 1132a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 113307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 113407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 113507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 113607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1137a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 113807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 113907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 114007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 114107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1142a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 114307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 114407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 114507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 114607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1147a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 114807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 114907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1150a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1151a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 115207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 115307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 115407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 115507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 115607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 115707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 115807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 115907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1160d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1161d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1162d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 116307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 116407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 116607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1167a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 116807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root switch (mKeyStore->getState()) { 116907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 117007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 117107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->initialize(password8); 117207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 117307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 117407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 117507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->writeMasterKey(password8); 117607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 117707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 117807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 117907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->readMasterKey(password8); 118007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 118107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 118207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 118307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1184a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 118507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1186d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1187d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1188d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 118907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 119007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 11929d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 11939d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 119407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 119507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 119607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 119807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mKeyStore->lock(); 119907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 120070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1201a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 120207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1203d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1204d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1205d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 120607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 120707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 120807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 12099d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12109d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 121107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 121207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 121307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 121407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 121507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 121607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 121770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 121870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 121907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1220d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1221d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1222d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 122307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 122407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 122570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 122607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR; 122770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 122870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1229494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t generate(const String16& name, int targetUid) { 1230d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1231d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1232d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 123307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 123407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 123570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1236494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1237494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1238494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1239b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1240b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1241b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 12429d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12439d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 124407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling generate in state: %d", state); 124507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 124607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 124770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 124907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 125070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 125107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 125207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 125307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 125470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 125507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 125607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 125707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 125807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 125970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 126107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 126207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 126370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_keygen_params_t rsa_params; 126507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.modulus_size = 2048; 126607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.public_exponent = 0x10001; 126770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 126907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 127007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 127107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 127270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1273494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 127470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 127607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 127707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 127807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 127970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 128070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1281494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid) { 1282d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1283d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1284d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 128507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 128607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 128770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1288494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1289494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1290494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1291b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1292b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1293b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 12949d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12959d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 129607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 129707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 129807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 129970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 130107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 130270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1303494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 130470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->importKey(data, length, filename); 130670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 130770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 130807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 130907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1310d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1311d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1312d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 131307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 131407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 13159a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 13169d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 13179d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 131807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling sign in state: %d", state); 131907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 13209a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } 132170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 132207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 132307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 132470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1325d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 132607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 132770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1328d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 1329d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 133007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 133107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 133207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 133370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 133407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 133507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 133607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 133707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 133807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 133970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 134007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 134107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 134207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 134307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 134470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 134507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 134607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 134707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 134807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 134907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 135007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, length, out, outLength); 135107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 135207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 135307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 135407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 135570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 135607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 135770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 135870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 135907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 136007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1361d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1362d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1363d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 136407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 136507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 136670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13679d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 13689d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 136907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 137007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 137107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 137270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 137307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 137407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 137507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 137670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1377494689083467ec372a58f094f041c8f102f39393Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 1378494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 137907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 138007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 138107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 138307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 138407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 138507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 138607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 138807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 138907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 139007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 139107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 139207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 139307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 139407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 139570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 139607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 139707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, dataLength, signature, signatureLength); 139807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 139907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 140007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 140107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 140207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 140370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 140470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 140507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 140607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 140707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 140807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 140907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 141007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 141107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 141207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 141307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 141407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 141507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 141607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 1417d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1418d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1419d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 142007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 142107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 142270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14239d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 14249d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 142507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get_pubkey in state: %d", state); 142607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 142870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 142907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 143007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 143170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1432d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 143370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1434d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 143507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 143707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 143807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 143970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 144007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 144107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 144207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 144307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 144470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 144507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 144607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 144707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 144807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1449344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 145007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 145107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root pubkeyLength); 145207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 145307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 145407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1455344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 145607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1457344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1458344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1459494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 1460d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1461d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1462d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 146407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1465344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1466494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1467494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1468494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1469b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1470b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1471b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 147207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 147307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 1474344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1475494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 1476344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 147707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 147807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR); 147907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 148007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 148107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 148307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 1484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 148507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 148607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 148707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 148807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 148907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 149007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair != NULL) { 149107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 149207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 149307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 149807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 149907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 150107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 150307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 150407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 1505d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1506d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1507d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 150807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15119d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 15129d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 151507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 151607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 151907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1520d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 152107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 152407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 152607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mKeyStore->addGrant(filename, granteeUid); 152707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1528a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 153007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 1531d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1532d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1533d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 153607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15379d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 15389d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1546d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 154707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 155007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 1553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 155407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 1556d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1557d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1558d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 155936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1565d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 156836a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not access %s for getmtime", filename); 156936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 1570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 157107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1572150ca934edb745de3666a6492b039900df228ff0Kenny Root int fd = TEMP_FAILURE_RETRY(open(filename, O_NOFOLLOW, O_RDONLY)); 157307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 157436a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not open %s for getmtime", filename); 157536a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 157707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 157907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 158007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 158107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 158236a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not stat %s for getmtime", filename); 158336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 158407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158636a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 1587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1589d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 1590d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 15910225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1592d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!has_permission(callingUid, P_DUPLICATE)) { 1593d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 15940225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 15950225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 15960225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 15970225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root State state = mKeyStore->getState(); 15980225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 1599d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 16000225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 16010225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16020225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1603d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 1604d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 1605d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 1606d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 16070225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 16080225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16090225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1610d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 1611d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 1612d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 16130225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1614d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 1615d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 1616d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 1617d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 1618d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 1619d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 16200225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1621d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 1622d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 1623d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 1624d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 16250225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16260225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1627d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 1628d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root char source[NAME_MAX]; 1629d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 1630d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root encode_key_for_uid(source, srcUid, source8); 1631d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 1632d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 16330225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root char target[NAME_MAX]; 16340225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1635d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root encode_key_for_uid(target, destUid, target8); 16360225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1637d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (access(target, W_OK) != -1 || errno != ENOENT) { 1638d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("destination already exists: %s", target); 16390225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 16400225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16410225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1642d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 1643d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ResponseCode responseCode = mKeyStore->get(source, &keyBlob, TYPE_ANY); 1644d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 1645d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 16460225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 1647d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 1648d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return mKeyStore->put(target, &keyBlob); 16490225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16500225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 165107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 16529d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 16539d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 16549d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 16559d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 16569d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 16579d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 16589d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 16599d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 16609d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 1661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 166207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 166407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 166507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 166607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 1667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 1669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 1670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 1671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 1674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 1675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 1679a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 1680a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 168270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 168370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 168470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 168570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 168670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 168770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 168870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 168970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 169007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 169207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 1696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 169770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 169807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 169907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 170007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 170107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 170207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 170370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 1705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1707