keystore.cpp revision cfeae072c96d84f286ddbf0aff8055c12c7c4f15
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, 140a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root P_CLEAR_UID = 1 << 15, 14107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 14207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 14307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 14407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 14507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 14607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 14707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 14807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 14907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 15007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 15107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 15507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 15607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 15707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 15807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic bool has_permission(uid_t uid, perm_t perm) { 16607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 16707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 16907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.perms & perm; 17007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 17107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 17207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return DEFAULT_PERMS & perm; 17407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 17507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 176494689083467ec372a58f094f041c8f102f39393Kenny Root/** 177494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 178494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 179494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 180494689083467ec372a58f094f041c8f102f39393Kenny Root */ 18107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 18207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 18307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 18407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 18507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 18607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 18907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 19007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 19107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 192494689083467ec372a58f094f041c8f102f39393Kenny Root/** 193494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 194494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 195494689083467ec372a58f094f041c8f102f39393Kenny Root */ 196494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 197494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 198494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 199494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 200494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 201494689083467ec372a58f094f041c8f102f39393Kenny Root } 202494689083467ec372a58f094f041c8f102f39393Kenny Root } 203494689083467ec372a58f094f041c8f102f39393Kenny Root 204494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 205494689083467ec372a58f094f041c8f102f39393Kenny Root} 206494689083467ec372a58f094f041c8f102f39393Kenny Root 207a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 208a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 209a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 210a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 211a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 212a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 21407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 21507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 21607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 217a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 218a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (*in >= '0' && *in <= '~') { 219a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = *in; 220a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 221a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 222a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 223a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 224a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 225a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 226a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 22770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 22870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 22970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 23007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) { 23170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 23270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 23370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 23407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return n + encode_key(out, keyName); 235a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 236a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 23707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 23807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 23907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 24007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 24107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 24207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 24307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 24407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 24507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 24607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 24707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 24807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 24907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 25007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 25107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 25207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 25307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 25407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 25507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 25607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 25707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 25807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 25907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 26007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 26107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 26207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 26307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 26407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 26507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 26607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 267a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 26807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 269a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 270a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 271a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 272a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 273a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 274a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 275a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 276a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 277150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 2785281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 279150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 280a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 282a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 283a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 284a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 285a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 286a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 287a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 288a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 289a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 290150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 291150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 292150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 293150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 294a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 295a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 296a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 297a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 298a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 299a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 300a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 301a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 302a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 303a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 304a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 305150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 306a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 307a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 308a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 309a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 310a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 312150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 313150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3205187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 332822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 333822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * the second is the blob's type, and the third byte is reserved. Fields other 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 335a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 336a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 337822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 338822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 339822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 340822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 341822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 342822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 343822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 344822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 345822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 346822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 347822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 348822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 349822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 350822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 352822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 353822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 354822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t reserved; 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 357822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 358a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 359822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 364822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 365d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 366822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 367822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 368822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 369822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 370822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 37107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 1; 372822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 37507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 37607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 377a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 378a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 382822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 38307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 384822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 385a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 386a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 387a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 388a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 389a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 390a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 391a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 392a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3935187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 394a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 395a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3975187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 398a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 399a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4015187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4025187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4035187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4045187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4055187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 409822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 410822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 411822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 412822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 413822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 414822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 415822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 416822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 417822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 418822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 419822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 420822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 421822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 422822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 423822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 424822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode encryptBlob(const char* filename, AES_KEY *aes_key, Entropy* entropy) { 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 427150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read random data for: %s", filename); 428a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 429a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 430a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 431a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 440a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 448a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 449a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root aes_key, vector, AES_ENCRYPT); 450a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 451822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.reserved = 0; 452a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 456150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 457150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 458150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 459150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 460a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 461a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 462a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 463a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 464a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 465a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 466a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 467150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 468a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 469a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 470a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 471150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 472150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 473150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 474150ca934edb745de3666a6492b039900df228ff0Kenny Root } 475150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 476a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 477a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 478a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) { 479150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 480150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 481a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 482a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 483a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 484a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 485a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 486a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 487a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 488a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 489a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 490a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 491a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 492a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 493a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 494a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 495a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 496a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (encryptedLength < 0 || encryptedLength % AES_BLOCK_SIZE != 0) { 497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 498a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.vector, AES_DECRYPT); 501a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 502a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 503a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root MD5(mBlob.digested, digestedLength, computedDigest); 504a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 505a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 506a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 507a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 508a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 509a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 510a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 51707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 52470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef struct { 52570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root uint32_t uid; 526a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom const uint8_t* filename; 52770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 52870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode plist; 52970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} grant_t; 53070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 531a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass KeyStore { 532a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 53370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 5345187818895c4c5f650a611c40531b1dff7764c18Kenny Root : mEntropy(entropy) 53570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root , mDevice(device) 5365187818895c4c5f650a611c40531b1dff7764c18Kenny Root , mRetry(MAX_RETRY) 5375187818895c4c5f650a611c40531b1dff7764c18Kenny Root { 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (access(MASTER_KEY_FILE, R_OK) == 0) { 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 541a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 542a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 54370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 54470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_init(&mGrants); 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5475187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5515187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 552a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 55570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* getDevice() const { 55670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return mDevice; 55770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 55870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 55907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode initialize(const android::String8& pw) { 560a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateMasterKey()) { 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 563a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = writeMasterKey(pw); 564a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 565a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 566a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 56807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 57107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode writeMasterKey(const android::String8& pw) { 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 576822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 577a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy); 578a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 579a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 58007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode readMasterKey(const android::String8& pw) { 581150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(MASTER_KEY_FILE, O_RDONLY)); 582150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 587a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 590a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 591a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 592a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 593a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 594a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 595a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 596a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 597a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 598a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 599a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 600a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 601a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 603a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 604a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 605a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey); 606a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root response = writeMasterKey(pw); 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 618a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 625a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 626a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 628a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 629a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 632a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 633a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 634a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 635a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 636a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 637a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool reset() { 638a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 639a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 640a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 641a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 642a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 643a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 648a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(file->d_name); 649a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 650a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 651a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 652a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 653a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6545187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool isEmpty() const { 655a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root DIR* dir = opendir("."); 656a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 657a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 658a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 659a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 660a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 661a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 662a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (isKeyFile(file->d_name)) { 663a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 665a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 666a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 667a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 668a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 671a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void lock() { 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root clearMasterKeys(); 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 675a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 676822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) { 677822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption); 678822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 679822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 680822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 681822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 682822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 68307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 684cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 685cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 686cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 687cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 688cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root if (upgrade(filename, keyBlob, version, type)) { 689cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root if ((rc = this->put(filename, keyBlob)) != NO_ERROR 690cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root || (rc = keyBlob->readBlob(filename, &mMasterKeyDecryption)) != NO_ERROR) { 691cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 692cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 693cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 694822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 695822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 696d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 697822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 698822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 699822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 700822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 701822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 703a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 704a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ResponseCode put(const char* filename, Blob* keyBlob) { 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy); 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 707a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 70807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 70907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 71070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant == NULL) { 71170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = new grant_t; 71207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 713a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 71470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_add_tail(&mGrants, &grant->plist); 71570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 71670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 71770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 71807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 71907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant_t *grant = getGrant(filename, granteeUid); 72070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant != NULL) { 72170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_remove(&grant->plist); 72270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root delete grant; 72370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return true; 72470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 72670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 72770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 72870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 729a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 730a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 73170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 73270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 73307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename) { 734822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 735822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 736822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 737822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 738822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 739822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 740822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 741822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 742822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 74307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 744822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 745822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Error while importing keypair: %d", rc); 746822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 747822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 748822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 749822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 750822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 751822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 752822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return put(filename, &keyBlob); 753822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 754822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 7558ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root bool isHardwareBacked() const { 7568ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) != 0; 7578ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 7588ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const char* MASTER_KEY_FILE; 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const int MAX_RETRY = 4; 765a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static const size_t SALT_SIZE = 16; 766a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 767a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy* mEntropy; 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 76970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* mDevice; 77070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 771a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root State mState; 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int8_t mRetry; 773a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 774a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t mSalt[SALT_SIZE]; 776a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyEncryption; 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY mMasterKeyDecryption; 779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 78070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode mGrants; 78170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 782a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setState(State state) { 783a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mState = state; 784a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 785a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mRetry = MAX_RETRY; 786a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 787a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateSalt() { 790a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mEntropy->generate_random_data(mSalt, sizeof(mSalt)); 791a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 792a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 793a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool generateMasterKey() { 794a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 795a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 796a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 797a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!generateSalt()) { 798a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 799a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 800a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 801a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 802a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 803a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void setupMasterKeys() { 804a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_NO_ERROR); 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root void clearMasterKeys() { 810a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 811a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mSalt, 0, sizeof(mSalt)); 812a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 813a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 814a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 815a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 81607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 81707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* salt) { 818a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t saltSize; 819a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt != NULL) { 820a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = SALT_SIZE; 821a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 822a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 823a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) "keystore"; 824a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // sizeof = 9, not strlen = 8 825a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root saltSize = sizeof("keystore"); 826a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 82707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 82807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 82907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root saltSize, 8192, keySize, key); 830a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 831a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 832a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root static bool isKeyFile(const char* filename) { 833a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return ((strcmp(filename, MASTER_KEY_FILE) != 0) 834a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, ".") != 0) 835a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root && (strcmp(filename, "..") != 0)); 836a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 83770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 838a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant_t* getGrant(const char* filename, uid_t uid) const { 83970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root struct listnode *node; 84070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant_t *grant; 84170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 84270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root list_for_each(node, &mGrants) { 84370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root grant = node_to_item(node, grant_t, plist); 84470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 845a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom && !strcmp(reinterpret_cast<const char*>(grant->filename), 846a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom filename)) { 84770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 84870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 84970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 85070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 85170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 85270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 85370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 854822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 855822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 856822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 857822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 858cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root bool upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) { 859822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 860822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 861822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 862822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 863822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 864822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 865822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 866822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 867822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 868822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root importBlobAsKey(blob, filename); 869822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 870822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 871822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 872822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 873822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 874822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 875822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 876822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 877cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 878822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 879822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 880822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 881822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 882cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 883cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 884822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 885822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 886822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 887822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 888822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 889822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 890822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 891822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 892822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename) { 893822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 894822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 895822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 896822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 897822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 898822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 899822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 900822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 901822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 902822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 903822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 904822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 905822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 906822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 907822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 908822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 909822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 910822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 911822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 912822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 91370c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 91470c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 915822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 916822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 917822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 918822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 919822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 92070c9889c5ca912e7c492580e1999f18ab65b267bKenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename); 921822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 922822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 923822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 924822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 925822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return get(filename, blob, TYPE_KEY_PAIR); 926822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 927a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 928a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 929a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootconst char* KeyStore::MASTER_KEY_FILE = ".masterkey"; 930a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 93107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, 93207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const android::String8& keyName, const uid_t uid, const BlobType type) { 93370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root char filename[NAME_MAX]; 93470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 93570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root encode_key_for_uid(filename, uid, keyName); 936822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ResponseCode responseCode = keyStore->get(filename, keyBlob, type); 93770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 93870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 93970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 94070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 941494689083467ec372a58f094f041c8f102f39393Kenny Root // If this is one of the legacy UID->UID mappings, use it. 942494689083467ec372a58f094f041c8f102f39393Kenny Root uid_t euid = get_keystore_euid(uid); 943494689083467ec372a58f094f041c8f102f39393Kenny Root if (euid != uid) { 944494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, euid, keyName); 945822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root responseCode = keyStore->get(filename, keyBlob, type); 94670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (responseCode == NO_ERROR) { 94770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 94870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 94970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 95070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 95170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // They might be using a granted key. 952a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom encode_key(filename, keyName); 953a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom if (!keyStore->hasGrant(filename, uid)) { 95470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return responseCode; 95570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 95670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 95770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root // It is a granted key. Try to load it. 958822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return keyStore->get(filename, keyBlob, type); 95970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 96070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 96107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 96207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 96307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 96407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 96507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 96607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 96707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 968a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 96907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 97007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 97107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 972a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 97307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 974d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 975d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 976d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 97707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 97807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 979a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 98007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->getState(); 981a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 982a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 98307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 984d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 985d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 986d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 98707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 98807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 989a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 9909d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 9919d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 99207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get in state: %d", state); 99307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 99407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 995a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 99607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 99707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 99807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 999494689083467ec372a58f094f041c8f102f39393Kenny Root 1000494689083467ec372a58f094f041c8f102f39393Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 1001494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 100207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1003150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("Could not read %s", filename); 100407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 100507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 100607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 100707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 100807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 100907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 101007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 101107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 101207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 101307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1014a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1015a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1016494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid) { 1017d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1018d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1019d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 102007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 102107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 102207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1023494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1024494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1025494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1026b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1027b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1028b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 10299d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 10309d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 103107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling insert in state: %d", state); 103207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 1033a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 103407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 103507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 103607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 103707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1038494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 103907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 104007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 104107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 1042a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1043a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1044494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1045d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1046d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1047d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 104807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 104907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 105007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1051494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1052494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1053494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1054b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1055b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1056b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 105707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 105807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 105907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1060494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 1061298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 106207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 106307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC); 106407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 106507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 106607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 106707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1068298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1069298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1070494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1071d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1072d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1073d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 107407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 107507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 107607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1077494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1078494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1079494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1080b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1081b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1082b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 108307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 108407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 108507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1086494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 108707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 108807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 108907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 109007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 109107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1092298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1093298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1094494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1095d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1096d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1097d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 109807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 109907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 110007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1101494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1102494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1103494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1104b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1105b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1106b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 110707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root DIR* dir = opendir("."); 110807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 110907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 111007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 111107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 111207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 111307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 111407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1115494689083467ec372a58f094f041c8f102f39393Kenny Root int n = encode_key_for_uid(filename, targetUid, prefix8); 111607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 111707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 111807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 111907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!strncmp(filename, file->d_name, n)) { 112007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 112107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 112207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 112307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 112407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 112507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 112607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 112707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 112807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 112907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 113007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 113107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 113207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 113307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 113407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 113507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 113607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1137298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1138298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 113907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1140d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1141d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1142d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 114307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 114407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1145a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 114607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR; 1147a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 114807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 114907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 115007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 115107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1152a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 115307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 115407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 115507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 115607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1157a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 115807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 115907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 116007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 116107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 116307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 116407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1165a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1166a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 116707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 116807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 116907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 117007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 117107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 117207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 117307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 117407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1175d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1176d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1177d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 117807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 117907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1180a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 118107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1182a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 118307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root switch (mKeyStore->getState()) { 118407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 118507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 118607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->initialize(password8); 118707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 118807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 118907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 119007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->writeMasterKey(password8); 119107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 119307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 119407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->readMasterKey(password8); 119507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 119707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 119807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1199a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 120007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1201d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1202d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1203d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 120407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 120507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 120607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 12079d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12089d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 120907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 121007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 121107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 121270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 121307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mKeyStore->lock(); 121407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 121570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1216a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 121707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1218d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1219d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1220d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 122107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 122207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 122307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 12249d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12259d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 122607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 122707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 122807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 122907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 123007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 123107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 123270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 123407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1235d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1236d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1237d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 123807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 123907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 124070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 124107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR; 124270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 124370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1244494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t generate(const String16& name, int targetUid) { 1245d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1246d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1247d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 124807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 124907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 125070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1251494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1252494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1253494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1254b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1255b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1256b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 12579d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 12589d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 125907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling generate in state: %d", state); 126007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 126107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 126270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 126407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 126570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 126607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 126707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 126807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 126970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 127107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 127207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 127307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 127470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 127607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 127707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 127870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 127907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_keygen_params_t rsa_params; 128007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.modulus_size = 2048; 128107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rsa_params.public_exponent = 0x10001; 128270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 128307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 128407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 128507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 128607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 128770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1288494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 128970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 129007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 129107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 129207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 129307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->put(filename, &keyBlob); 129470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 129570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1296494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid) { 1297d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1298d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1299d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 130007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 130107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 130270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1303494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1304494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1305494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1306b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1307b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1308b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 13099d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 13109d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 131107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 131207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 131307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 131470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 131507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 131607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 131770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1318494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 131970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 132007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->importKey(data, length, filename); 132170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 132270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 132307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 132407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1325d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1326d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1327d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 132807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 132907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 13309a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 13319d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 13329d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 133307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling sign in state: %d", state); 133407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 13359a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root } 133670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 133707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 133807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 133970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1340d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 134107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 134270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1343d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 1344d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 134507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 134607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 134707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 134870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 134907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 135007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 135107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 135207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 135307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 135470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 135507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 135607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 135707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 135807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 135970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 136007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 136107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 136207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 136307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 136407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 136507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, length, out, outLength); 136607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 136707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 136807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 136907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 137070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 137107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 137270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 137370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 137407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 137507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1376d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1377d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1378d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 137907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 138007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13829d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 13839d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 138407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 138507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 138607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 138770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 138807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 138907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 139007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 139170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1392494689083467ec372a58f094f041c8f102f39393Kenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 1393494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 139407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 139507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 139607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 139770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 139807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 139907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 140007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 140107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 140270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 140307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 140407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 140507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 140607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 140707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 140807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 140907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 141070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 141107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), 141207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root data, dataLength, signature, signatureLength); 141307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 141407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 141507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 141607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 141707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 141870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 141970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 142007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 142107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 142207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 142307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 142407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 142507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 142607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 142807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 142907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 143007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 143107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 1432d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1433d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1434d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 143507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 143770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 14389d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 14399d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 144007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling get_pubkey in state: %d", state); 144107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 144207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 144370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 144407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 144507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 144670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1447d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 144870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1449d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid, 145007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 145107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 145207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 145307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 145470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 145507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 145607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 145707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 145807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 145970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 146007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 146107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 146207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1464344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 146507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 146607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root pubkeyLength); 146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 146807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 146907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1470344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 147107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1472344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 1473344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1474494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 1475d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1476d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1477d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 147807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 147907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1480344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1481494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1482494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1483494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1484b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1485b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1486b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 148707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 148807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 1489344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 1490494689083467ec372a58f094f041c8f102f39393Kenny Root encode_key_for_uid(filename, targetUid, name8); 1491344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 149207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 149307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR); 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 149507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 149607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1497a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 149807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 1499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 150007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 150107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 150207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 150307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 150407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 150507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair != NULL) { 150607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 150707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 150807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 150907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 151007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1511a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 151207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 151307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 151607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 151807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 151907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 1520d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1521d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1522d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 152407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15269d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 15279d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 152807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 152907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 153007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 153107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 153207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 153307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 153407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1535d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 153607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 153707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 153807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mKeyStore->addGrant(filename, granteeUid); 154207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1543a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 1546d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1547d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 1548d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 154907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 155007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15529d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root State state = mKeyStore->getState(); 15539d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 155407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 155507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 155607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 155807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 155907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 156007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1561d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 156207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 156407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 1568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 156907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 1571d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1572d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1573d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 157436a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 157507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 157607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 157807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char filename[NAME_MAX]; 157907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1580d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root encode_key_for_uid(filename, callingUid, name8); 158107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (access(filename, R_OK) == -1) { 158336a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not access %s for getmtime", filename); 158436a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 1585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1587150ca934edb745de3666a6492b039900df228ff0Kenny Root int fd = TEMP_FAILURE_RETRY(open(filename, O_NOFOLLOW, O_RDONLY)); 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 158936a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not open %s for getmtime", filename); 159036a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 159507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 159607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 159736a9e231e03734cd2143383d26388455c1764e17Kenny Root ALOGW("could not stat %s for getmtime", filename); 159836a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 160136a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 1602a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 160307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1604d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 1605d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 16060225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1607d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!has_permission(callingUid, P_DUPLICATE)) { 1608d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 16090225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 16100225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16110225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 16120225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root State state = mKeyStore->getState(); 16130225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 1614d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 16150225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 16160225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16170225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1618d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 1619d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 1620d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 1621d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 16220225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 16230225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16240225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1625d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 1626d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 1627d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 16280225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1629d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 1630d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 1631d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 1632d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 1633d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 1634d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 16350225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1636d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 1637d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 1638d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 1639d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 16400225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16410225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1642d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 1643d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root char source[NAME_MAX]; 1644d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 1645d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root encode_key_for_uid(source, srcUid, source8); 1646d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 1647d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 16480225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root char target[NAME_MAX]; 16490225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1650d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root encode_key_for_uid(target, destUid, target8); 16510225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1652d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (access(target, W_OK) != -1 || errno != ENOENT) { 1653d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("destination already exists: %s", target); 16540225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 16550225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16560225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 1657d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 1658d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ResponseCode responseCode = mKeyStore->get(source, &keyBlob, TYPE_ANY); 1659d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 1660d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 16610225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 1662d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 1663d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return mKeyStore->put(target, &keyBlob); 16640225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 16650225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 16668ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root int32_t is_hardware_backed() { 16678ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root return mKeyStore->isHardwareBacked() ? 1 : 0; 16688ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 16698ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1670a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root int32_t clear_uid(int64_t targetUid) { 1671a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1672a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!has_permission(callingUid, P_CLEAR_UID)) { 1673a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 1674a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 1675a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1676a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1677a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root State state = mKeyStore->getState(); 1678a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!isKeystoreUnlocked(state)) { 1679a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGD("calling clear_uid in state: %d", state); 1680a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return state; 1681a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1682a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1683a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 1684a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 1685a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 1686a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1687a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1688a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root DIR* dir = opendir("."); 1689a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 1690a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 1691a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1692a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1693a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root char filename[NAME_MAX]; 1694a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root int n = snprintf(filename, NAME_MAX, "%u_", static_cast<uid_t>(targetUid)); 1695a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root char *end = &filename[n]; 1696a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1697a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 1698a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1699a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 1700a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 1701a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (strncmp(filename, file->d_name, n)) { 1702a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 1703a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1704a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1705a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root String8 file8(&file->d_name[n]); 1706a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root encode_key(end, file8); 1707a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1708a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 1709a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (mKeyStore->get(filename, &keyBlob, ::TYPE_ANY) != ::NO_ERROR) { 1710a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("couldn't open %s", filename); 1711a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 1712a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1713a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1714a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 1715a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 1716a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair != NULL) { 1717a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 1718a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 1719a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("device couldn't remove %s", filename); 1720a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1721a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1722a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1723a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1724a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (unlink(filename) && errno != ENOENT) { 1725a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 1726a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("couldn't unlink %s", filename); 1727a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1728a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1729a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 1730a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 1731a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 1732a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 1733a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 173407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 17359d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 17369d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 17379d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 17389d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 17399d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 17409d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 17419d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 17429d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 17439d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 1744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 174507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 174607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 174707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 174807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 174907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 1750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 1752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 1753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 1754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 1757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 1758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 1762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 1763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 176570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 176670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 176770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 176870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 176970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 177070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 177170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 177270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 177307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 177407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 177507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 177607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 177707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 177807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 1779a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 178070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 178107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 178207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 178307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 178407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 178507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 178670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 178707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 1788a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 1789a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 1790