keystore.cpp revision 17208e0de5a42722901d803118745cca25fd10c1
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> 27655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <errno.h> 28a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <fcntl.h> 29a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <limits.h> 30822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <assert.h> 31a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/types.h> 32a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/socket.h> 33a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/stat.h> 34a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <sys/time.h> 35a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <arpa/inet.h> 36a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 37a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/aes.h> 38822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/bio.h> 39a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/evp.h> 40a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <openssl/md5.h> 41822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <openssl/pem.h> 42a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h> 4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 4517208e0de5a42722901d803118745cca25fd10c1Kenny Root#include <keymaster/softkeymaster.h> 4617208e0de5a42722901d803118745cca25fd10c1Kenny Root 47655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/String8.h> 48822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root#include <utils/UniquePtr.h> 49655b958eb2180c7c06889f83f606d23421bf038cKenny Root#include <utils/Vector.h> 5070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 5107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/IKeystoreService.h> 5207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IPCThreadState.h> 5307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <binder/IServiceManager.h> 5407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 55a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/log.h> 56a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <cutils/sockets.h> 57a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#include <private/android_filesystem_config.h> 58a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 5907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h> 60a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6196427baf0094d50047049d329b0779c3c910402cKenny Root#include "defaults.h" 6296427baf0094d50047049d329b0779c3c910402cKenny Root 63a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* KeyStore is a secured storage for key-value pairs. In this implementation, 64a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * each file stores one key-value pair. Keys are encoded in file names, and 65a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * values are encrypted with checksums. The encryption key is protected by a 66a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * user-defined password. To keep things simple, buffers are always larger than 67a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the maximum space we needed, so boundary checks on buffers are omitted. */ 68a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 69a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define KEY_SIZE ((NAME_MAX - 15) / 2) 70a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define VALUE_SIZE 32768 71a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root#define PASSWORD_SIZE VALUE_SIZE 72a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 73822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 7496427baf0094d50047049d329b0779c3c910402cKenny Rootstruct BIGNUM_Delete { 7596427baf0094d50047049d329b0779c3c910402cKenny Root void operator()(BIGNUM* p) const { 7696427baf0094d50047049d329b0779c3c910402cKenny Root BN_free(p); 7796427baf0094d50047049d329b0779c3c910402cKenny Root } 7896427baf0094d50047049d329b0779c3c910402cKenny Root}; 7996427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM; 8096427baf0094d50047049d329b0779c3c910402cKenny Root 81822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct BIO_Delete { 82822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(BIO* p) const { 83822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BIO_free(p); 84822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 85822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 86822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<BIO, BIO_Delete> Unique_BIO; 87822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 88822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct EVP_PKEY_Delete { 89822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(EVP_PKEY* p) const { 90822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root EVP_PKEY_free(p); 91822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 92822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 93822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY; 94822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 95822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete { 96822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void operator()(PKCS8_PRIV_KEY_INFO* p) const { 97822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root PKCS8_PRIV_KEY_INFO_free(p); 98822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 99822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root}; 100822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO; 101822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 102822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 10370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int keymaster_device_initialize(keymaster_device_t** dev) { 10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int rc; 10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root const hw_module_t* mod; 10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod); 10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not find any keystore module"); 11070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 11170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 11370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root rc = keymaster_open(mod, dev); 11470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (rc) { 11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("could not open keymaster device in %s (%s)", 11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc)); 11770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root goto out; 11870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 0; 12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootout: 12370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *dev = NULL; 12470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return rc; 12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 12670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void keymaster_device_release(keymaster_device_t* dev) { 12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_close(dev); 12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 13107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/*************** 13207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * PERMISSIONS * 13307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ***************/ 13407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 13507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* Here are the permissions, actions, users, and the main function. */ 13607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Roottypedef enum { 137d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_TEST = 1 << 0, 138d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GET = 1 << 1, 139d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_INSERT = 1 << 2, 140d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DELETE = 1 << 3, 141d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_EXIST = 1 << 4, 142d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SAW = 1 << 5, 143d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_RESET = 1 << 6, 144d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_PASSWORD = 1 << 7, 145d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_LOCK = 1 << 8, 146d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_UNLOCK = 1 << 9, 147d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_ZERO = 1 << 10, 148d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_SIGN = 1 << 11, 149d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_VERIFY = 1 << 12, 150d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_GRANT = 1 << 13, 151d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root P_DUPLICATE = 1 << 14, 152a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root P_CLEAR_UID = 1 << 15, 15307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} perm_t; 15407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 15507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_euid { 15607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 15707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t euid; 15807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_euids[] = { 15907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, AID_SYSTEM}, 16007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, AID_SYSTEM}, 16107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, AID_SYSTEM}, 16207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 16307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 16407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic struct user_perm { 16507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uid_t uid; 16607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root perm_t perms; 16707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} user_perms[] = { 16807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) }, 16907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_VPN, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 17007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_WIFI, static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) }, 17107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root {AID_ROOT, static_cast<perm_t>(P_GET) }, 17207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 17307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 17407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN 17507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root | P_VERIFY); 17607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 177655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 178655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the app ID (in the Android multi-user sense) for the current 179655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 180655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 181655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_app_id(uid_t uid) { 182655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid % AID_USER; 183655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 184655b958eb2180c7c06889f83f606d23421bf038cKenny Root 185655b958eb2180c7c06889f83f606d23421bf038cKenny Root/** 186655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns the user ID (in the Android multi-user sense) for the current 187655b958eb2180c7c06889f83f606d23421bf038cKenny Root * UNIX UID. 188655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 189655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic uid_t get_user_id(uid_t uid) { 190655b958eb2180c7c06889f83f606d23421bf038cKenny Root return uid / AID_USER; 191655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 192655b958eb2180c7c06889f83f606d23421bf038cKenny Root 193655b958eb2180c7c06889f83f606d23421bf038cKenny Root 19407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic bool has_permission(uid_t uid, perm_t perm) { 195655b958eb2180c7c06889f83f606d23421bf038cKenny Root // All system users are equivalent for multi-user support. 196655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_app_id(uid) == AID_SYSTEM) { 197655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid = AID_SYSTEM; 198655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 199655b958eb2180c7c06889f83f606d23421bf038cKenny Root 20007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) { 20107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_perm user = user_perms[i]; 20207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 20307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.perms & perm; 20407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 20607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 20707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return DEFAULT_PERMS & perm; 20807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 20907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210494689083467ec372a58f094f041c8f102f39393Kenny Root/** 211494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns the UID that the callingUid should act as. This is here for 212494689083467ec372a58f094f041c8f102f39393Kenny Root * legacy support of the WiFi and VPN systems and should be removed 213494689083467ec372a58f094f041c8f102f39393Kenny Root * when WiFi can operate in its own namespace. 214494689083467ec372a58f094f041c8f102f39393Kenny Root */ 21507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic uid_t get_keystore_euid(uid_t uid) { 21607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 21707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct user_euid user = user_euids[i]; 21807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (user.uid == uid) { 21907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return user.euid; 22007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 22107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 22207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 22307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return uid; 22407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 22507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 226494689083467ec372a58f094f041c8f102f39393Kenny Root/** 227494689083467ec372a58f094f041c8f102f39393Kenny Root * Returns true if the callingUid is allowed to interact in the targetUid's 228494689083467ec372a58f094f041c8f102f39393Kenny Root * namespace. 229494689083467ec372a58f094f041c8f102f39393Kenny Root */ 230494689083467ec372a58f094f041c8f102f39393Kenny Rootstatic bool is_granted_to(uid_t callingUid, uid_t targetUid) { 231494689083467ec372a58f094f041c8f102f39393Kenny Root for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) { 232494689083467ec372a58f094f041c8f102f39393Kenny Root struct user_euid user = user_euids[i]; 233494689083467ec372a58f094f041c8f102f39393Kenny Root if (user.euid == callingUid && user.uid == targetUid) { 234494689083467ec372a58f094f041c8f102f39393Kenny Root return true; 235494689083467ec372a58f094f041c8f102f39393Kenny Root } 236494689083467ec372a58f094f041c8f102f39393Kenny Root } 237494689083467ec372a58f094f041c8f102f39393Kenny Root 238494689083467ec372a58f094f041c8f102f39393Kenny Root return false; 239494689083467ec372a58f094f041c8f102f39393Kenny Root} 240494689083467ec372a58f094f041c8f102f39393Kenny Root 241a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the encoding of keys. This is necessary in order to allow arbitrary 242a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * characters in keys. Characters in [0-~] are not encoded. Others are encoded 243a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * into two bytes. The first byte is one of [+-.] which represents the first 244a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * two bits of the character. The second byte encodes the rest of the bits into 245a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * [0-o]. Therefore in the worst case the length of a key gets doubled. Note 246a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * that Base64 cannot be used here due to the need of prefix match on keys. */ 247a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 248655b958eb2180c7c06889f83f606d23421bf038cKenny Rootstatic size_t encode_key_length(const android::String8& keyName) { 249655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 250655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t length = keyName.length(); 251655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (int i = length; i > 0; --i, ++in) { 252655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 253655b958eb2180c7c06889f83f606d23421bf038cKenny Root ++length; 254655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 255655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 256655b958eb2180c7c06889f83f606d23421bf038cKenny Root return length; 257655b958eb2180c7c06889f83f606d23421bf038cKenny Root} 258655b958eb2180c7c06889f83f606d23421bf038cKenny Root 25907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key(char* out, const android::String8& keyName) { 26007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string()); 26107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t length = keyName.length(); 262a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root for (int i = length; i > 0; --i, ++in, ++out) { 263655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (*in < '0' || *in > '~') { 264a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '+' + (*in >> 6); 265a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *++out = '0' + (*in & 0x3F); 266a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ++length; 267655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 268655b958eb2180c7c06889f83f606d23421bf038cKenny Root *out = *in; 269a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 270a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 271a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 27270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return length; 27370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root} 27470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 27507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) { 27670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root int n = snprintf(out, NAME_MAX, "%u_", uid); 27770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root out += n; 27870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 27907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return n + encode_key(out, keyName); 280a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 281a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 28207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root/* 28307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Converts from the "escaped" format on disk to actual name. 28407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * This will be smaller than the input string. 28507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 28607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Characters that should combine with the next at the end will be truncated. 28707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 28807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic size_t decode_key_length(const char* in, size_t length) { 28907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t outLength = 0; 29007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 29107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 29207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* This combines with the next character. */ 29307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 29407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root continue; 29507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 29707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root outLength++; 29807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 29907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return outLength; 30007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root} 30107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 30207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootstatic void decode_key(char* out, const char* in, size_t length) { 30307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root for (const char* end = in + length; in < end; in++) { 30407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (*in < '0' || *in > '~') { 30507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* Truncate combining characters at the end. */ 30607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (in + 1 >= end) { 30707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root break; 30807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 30907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 31007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out = (*in++ - '+') << 6; 31107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ |= (*in - '0') & 0x3F; 312a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 31307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *out++ = *in; 314a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 315a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 316a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root *out = '\0'; 317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t readFully(int fd, uint8_t* data, size_t size) { 320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 322150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(read(fd, data, remaining)); 3235281edbc9445065479e92a6c86da462f3943c2caKenny Root if (n <= 0) { 324150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 332a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstatic size_t writeFully(int fd, uint8_t* data, size_t size) { 333a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t remaining = size; 334a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while (remaining > 0) { 335150ca934edb745de3666a6492b039900df228ff0Kenny Root ssize_t n = TEMP_FAILURE_RETRY(write(fd, data, remaining)); 336150ca934edb745de3666a6492b039900df228ff0Kenny Root if (n < 0) { 337150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("write failed: %s", strerror(errno)); 338150ca934edb745de3666a6492b039900df228ff0Kenny Root return size - remaining; 339a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 340a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root data += n; 341a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root remaining -= n; 342a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 343a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return size; 344a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 345a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 346a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Entropy { 347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 348a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy() : mRandom(-1) {} 349a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ~Entropy() { 350150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom >= 0) { 351a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root close(mRandom); 352a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 353a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 354a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 355a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool open() { 356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* randomDevice = "/dev/urandom"; 357150ca934edb745de3666a6492b039900df228ff0Kenny Root mRandom = TEMP_FAILURE_RETRY(::open(randomDevice, O_RDONLY)); 358150ca934edb745de3666a6492b039900df228ff0Kenny Root if (mRandom < 0) { 359a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("open: %s: %s", randomDevice, strerror(errno)); 360a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 361a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 362a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 363a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 364a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 3655187818895c4c5f650a611c40531b1dff7764c18Kenny Root bool generate_random_data(uint8_t* data, size_t size) const { 366a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (readFully(mRandom, data, size) == size); 367a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 368a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 369a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 370a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int mRandom; 371a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 372a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 373a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root/* Here is the file format. There are two parts in blob.value, the secret and 374a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * the description. The secret is stored in ciphertext, and its original size 375a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * can be found in blob.length. The description is stored after the secret in 376a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * plaintext, and its size is specified in blob.info. The total size of the two 377822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * parts must be no more than VALUE_SIZE bytes. The first field is the version, 378f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root * the second is the blob's type, and the third byte is flags. Fields other 379a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * than blob.info, blob.length, and blob.value are modified by encryptBlob() 380a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root * and decryptBlob(). Thus they should not be accessed from outside. */ 381a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 382822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root/* ** Note to future implementors of encryption: ** 383822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Currently this is the construction: 384822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || Enc(MD5(data) || data) 385822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 386822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * This should be the construction used for encrypting if re-implementing: 387822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 388822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Derive independent keys for encryption and MAC: 389822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kenc = AES_encrypt(masterKey, "Encrypt") 390822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Kmac = AES_encrypt(masterKey, "MAC") 391822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * 392822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Store this: 393822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) || 394822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * HMAC(Kmac, metadata || Enc(data)) 395822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 396a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootstruct __attribute__((packed)) blob { 397822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version; 398822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t type; 399f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t flags; 400a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t info; 401a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t vector[AES_BLOCK_SIZE]; 402822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t encrypted[0]; // Marks offset to encrypted data. 403a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t digest[MD5_DIGEST_LENGTH]; 404822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t digested[0]; // Marks offset to digested data. 405a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root int32_t length; // in network byte order when encrypted 406a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE]; 407a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 408a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 409822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Roottypedef enum { 410d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root TYPE_ANY = 0, // meta type that matches anything 411822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_GENERIC = 1, 412822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_MASTER_KEY = 2, 413822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root TYPE_KEY_PAIR = 3, 414822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root} BlobType; 415822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 416f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Rootstatic const uint8_t CURRENT_BLOB_VERSION = 2; 417822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 418a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootclass Blob { 419a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootpublic: 42007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength, 42107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root BlobType type) { 422a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = valueLength; 423a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value, value, valueLength); 424a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 425a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.info = infoLength; 426a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mBlob.value + valueLength, info, infoLength); 427822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 42807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root mBlob.version = CURRENT_BLOB_VERSION; 429822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 430f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 431f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags = KEYSTORE_FLAG_NONE; 432a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 434a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob(blob b) { 435a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob = b; 436a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 438a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob() {} 439a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4405187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getValue() const { 441a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.value; 442a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 443a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4445187818895c4c5f650a611c40531b1dff7764c18Kenny Root int32_t getLength() const { 445a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.length; 446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 4485187818895c4c5f650a611c40531b1dff7764c18Kenny Root const uint8_t* getInfo() const { 4495187818895c4c5f650a611c40531b1dff7764c18Kenny Root return mBlob.value + mBlob.length; 4505187818895c4c5f650a611c40531b1dff7764c18Kenny Root } 4515187818895c4c5f650a611c40531b1dff7764c18Kenny Root 4525187818895c4c5f650a611c40531b1dff7764c18Kenny Root uint8_t getInfoLength() const { 453a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mBlob.info; 454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 455a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 456822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t getVersion() const { 457822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return mBlob.version; 458822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 459822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 460f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root bool isEncrypted() const { 461f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (mBlob.version < 2) { 462f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return true; 463f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 464f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 465f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED; 466f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 467f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 468f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root void setEncrypted(bool encrypted) { 469f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encrypted) { 470f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED; 471f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 472f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED; 473f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 474f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 475f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 47617208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback() const { 47717208e0de5a42722901d803118745cca25fd10c1Kenny Root return mBlob.flags & KEYSTORE_FLAG_FALLBACK; 47817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 47917208e0de5a42722901d803118745cca25fd10c1Kenny Root 48017208e0de5a42722901d803118745cca25fd10c1Kenny Root void setFallback(bool fallback) { 48117208e0de5a42722901d803118745cca25fd10c1Kenny Root if (fallback) { 48217208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags |= KEYSTORE_FLAG_FALLBACK; 48317208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 48417208e0de5a42722901d803118745cca25fd10c1Kenny Root mBlob.flags &= ~KEYSTORE_FLAG_FALLBACK; 48517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 48617208e0de5a42722901d803118745cca25fd10c1Kenny Root } 48717208e0de5a42722901d803118745cca25fd10c1Kenny Root 488822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setVersion(uint8_t version) { 489822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.version = version; 490822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 491822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 492822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root BlobType getType() const { 493822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return BlobType(mBlob.type); 494822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 495822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 496822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root void setType(BlobType type) { 497822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root mBlob.type = uint8_t(type); 498822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 499822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 500f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode writeBlob(const char* filename, AES_KEY *aes_key, State state, Entropy* entropy) { 501f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("writing blob %s", filename); 502f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 503f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (state != STATE_NO_ERROR) { 504f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("couldn't insert encrypted blob while not unlocked"); 505f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 506f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 507f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 508f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) { 509f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("Could not read random data for: %s", filename); 510f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return SYSTEM_ERROR; 511f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 512a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 513a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 514a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // data includes the value and the value's length 515a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t dataLength = mBlob.length + sizeof(mBlob.length); 516a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // pad data to the AES_BLOCK_SIZE 517a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) 518a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root / AES_BLOCK_SIZE * AES_BLOCK_SIZE); 519a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // encrypted data includes the digest value 520a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH; 521a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info after space for padding 522a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info); 523a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // zero padding area 524a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength); 525a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 526a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = htonl(mBlob.length); 527a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 528f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 529f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, mBlob.digest); 530f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 531f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t vector[AES_BLOCK_SIZE]; 532f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root memcpy(vector, mBlob.vector, AES_BLOCK_SIZE); 533f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, 534f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root aes_key, vector, AES_ENCRYPT); 535f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 536a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 537a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 538a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = encryptedLength + headerLength + mBlob.info; 539a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 540a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root const char* tmpFileName = ".tmp"; 541150ca934edb745de3666a6492b039900df228ff0Kenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 542150ca934edb745de3666a6492b039900df228ff0Kenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 543150ca934edb745de3666a6492b039900df228ff0Kenny Root if (out < 0) { 544150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno)); 545a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 546a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 547a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t writtenBytes = writeFully(out, (uint8_t*) &mBlob, fileLength); 548a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(out) != 0) { 549a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 550a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 551a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (writtenBytes != fileLength) { 552150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength); 553a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root unlink(tmpFileName); 554a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 555a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 556150ca934edb745de3666a6492b039900df228ff0Kenny Root if (rename(tmpFileName, filename) == -1) { 557150ca934edb745de3666a6492b039900df228ff0Kenny Root ALOGW("could not rename blob to %s: %s", filename, strerror(errno)); 558150ca934edb745de3666a6492b039900df228ff0Kenny Root return SYSTEM_ERROR; 559150ca934edb745de3666a6492b039900df228ff0Kenny Root } 560150ca934edb745de3666a6492b039900df228ff0Kenny Root return NO_ERROR; 561a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 562a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 563f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode readBlob(const char* filename, AES_KEY *aes_key, State state) { 564f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("reading blob %s", filename); 565150ca934edb745de3666a6492b039900df228ff0Kenny Root int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY)); 566150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 567a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR; 568a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 569a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // fileLength may be less than sizeof(mBlob) since the in 570a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // memory version has extra padding to tolerate rounding up to 571a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES_BLOCK_SIZE 572a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t fileLength = readFully(in, (uint8_t*) &mBlob, sizeof(mBlob)); 573a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 574a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 575a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 576f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 577f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted() && (state != STATE_NO_ERROR)) { 578f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return LOCKED; 579f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 580f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 581a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t headerLength = (mBlob.encrypted - (uint8_t*) &mBlob); 582a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (fileLength < headerLength) { 583a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 584a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 585a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 586a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t encryptedLength = fileLength - (headerLength + mBlob.info); 587f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength < 0) { 588a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 589a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 590f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 591f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ssize_t digestedLength; 592f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (isEncrypted()) { 593f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (encryptedLength % AES_BLOCK_SIZE != 0) { 594f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 595f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 596f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 597f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, 598f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mBlob.vector, AES_DECRYPT); 599f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength - MD5_DIGEST_LENGTH; 600f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root uint8_t computedDigest[MD5_DIGEST_LENGTH]; 601f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root MD5(mBlob.digested, digestedLength, computedDigest); 602f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) { 603f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return VALUE_CORRUPTED; 604f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 605f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } else { 606f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root digestedLength = encryptedLength; 607a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 608a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 609a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ssize_t maxValueLength = digestedLength - sizeof(mBlob.length); 610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root mBlob.length = ntohl(mBlob.length); 611a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.length < 0 || mBlob.length > maxValueLength) { 612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return VALUE_CORRUPTED; 613a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 614a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mBlob.info != 0) { 615a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // move info from after padding to after data 616a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info); 617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 61807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 619a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 620a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 621a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootprivate: 622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct blob mBlob; 623a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root}; 624a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 625655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass UserState { 626655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 627655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) { 628655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mUserDir, "user_%u", mUserId); 629655b958eb2180c7c06889f83f606d23421bf038cKenny Root asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir); 630655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 63170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 632655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~UserState() { 633655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mUserDir); 634655b958eb2180c7c06889f83f606d23421bf038cKenny Root free(mMasterKeyFile); 635655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 63670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 637655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool initialize() { 638655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) { 639655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("Could not create directory '%s'", mUserDir); 640655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 641655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 642655b958eb2180c7c06889f83f606d23421bf038cKenny Root 643655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(mMasterKeyFile, R_OK) == 0) { 644a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_LOCKED); 645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 646a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setState(STATE_UNINITIALIZED); 647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 64870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 649655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 650655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 651655b958eb2180c7c06889f83f606d23421bf038cKenny Root 652655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t getUserId() const { 653655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserId; 654655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 655655b958eb2180c7c06889f83f606d23421bf038cKenny Root 656655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getUserDirName() const { 657655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mUserDir; 658655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 659655b958eb2180c7c06889f83f606d23421bf038cKenny Root 660655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* getMasterKeyFileName() const { 661655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mMasterKeyFile; 662655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 663655b958eb2180c7c06889f83f606d23421bf038cKenny Root 664655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setState(State state) { 665655b958eb2180c7c06889f83f606d23421bf038cKenny Root mState = state; 666655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) { 667655b958eb2180c7c06889f83f606d23421bf038cKenny Root mRetry = MAX_RETRY; 668655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 669a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 670a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6715187818895c4c5f650a611c40531b1dff7764c18Kenny Root State getState() const { 672a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mState; 673a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 674a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 6755187818895c4c5f650a611c40531b1dff7764c18Kenny Root int8_t getRetry() const { 676a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return mRetry; 677a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 678a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 679655b958eb2180c7c06889f83f606d23421bf038cKenny Root void zeroizeMasterKeysInMemory() { 680655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mMasterKey, 0, sizeof(mMasterKey)); 681655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(mSalt, 0, sizeof(mSalt)); 682655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption)); 683655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption)); 68470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 68570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 686655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize(const android::String8& pw, Entropy* entropy) { 687655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateMasterKey(entropy)) { 688a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 689a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 690655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode response = writeMasterKey(pw, entropy); 691a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response != NO_ERROR) { 692a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 693a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 694a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 69507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 696a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 697a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 698655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) { 699a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 700a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt); 701a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 702a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 703822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY); 704f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy); 705a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 706a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 707655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) { 708655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY)); 709150ca934edb745de3666a6492b039900df228ff0Kenny Root if (in < 0) { 710a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 711a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 712a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 713a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // we read the raw blob to just to get the salt to generate 714a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // the AES key, then we create the Blob to use with decryptBlob 715a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root blob rawBlob; 716a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root size_t length = readFully(in, (uint8_t*) &rawBlob, sizeof(rawBlob)); 717a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (close(in) != 0) { 718a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 719a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 720a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // find salt at EOF if present, otherwise we have an old file 721a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t* salt; 722a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (length > SALT_SIZE && rawBlob.info == SALT_SIZE) { 723a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = (uint8_t*) &rawBlob + length - SALT_SIZE; 724a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } else { 725a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root salt = NULL; 726a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 727a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root uint8_t passwordKey[MASTER_KEY_SIZE_BYTES]; 728a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt); 729a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_KEY passwordAesKey; 730a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey); 731a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Blob masterKeyBlob(rawBlob); 732f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, 733f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root STATE_NO_ERROR); 734a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == SYSTEM_ERROR) { 735f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return response; 736a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 737a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) { 738a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root // if salt was missing, generate one and write a new master key file with the salt. 739a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (salt == NULL) { 740655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 741a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return SYSTEM_ERROR; 742a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 743655b958eb2180c7c06889f83f606d23421bf038cKenny Root response = writeMasterKey(pw, entropy); 744a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 745a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (response == NO_ERROR) { 746a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES); 747a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root setupMasterKeys(); 748a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 749a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return response; 750a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 751a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (mRetry <= 0) { 752a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root reset(); 753a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return UNINITIALIZED; 754a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 755a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root --mRetry; 756a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root switch (mRetry) { 757a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 0: return WRONG_PASSWORD_0; 758a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 1: return WRONG_PASSWORD_1; 759a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 2: return WRONG_PASSWORD_2; 760a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root case 3: return WRONG_PASSWORD_3; 761a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root default: return WRONG_PASSWORD_3; 762a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 763a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 764a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 765655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getEncryptionKey() { 766655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyEncryption; 767655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 768a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 769655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY* getDecryptionKey() { 770655b958eb2180c7c06889f83f606d23421bf038cKenny Root return &mMasterKeyDecryption; 771655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 772a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 773655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset() { 774655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(getUserDirName()); 775a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 776655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory: %s", strerror(errno)); 777a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return false; 778a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 779655b958eb2180c7c06889f83f606d23421bf038cKenny Root 780655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 781a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 782655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 783655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 784655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 785655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 786655b958eb2180c7c06889f83f606d23421bf038cKenny Root 787655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 788655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 789655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 790655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 791655b958eb2180c7c06889f83f606d23421bf038cKenny Root 792655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's UID. 793655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 794655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 795655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 796655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 797655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 798655b958eb2180c7c06889f83f606d23421bf038cKenny Root 799655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip if this is not our user. 800655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (get_user_id(thisUid) != mUserId) { 801655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 802655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 803655b958eb2180c7c06889f83f606d23421bf038cKenny Root 804655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 805a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 806a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 807a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 808a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 809a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 810655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 811655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BYTES = 16; 812655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; 813655b958eb2180c7c06889f83f606d23421bf038cKenny Root 814655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const int MAX_RETRY = 4; 815655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const size_t SALT_SIZE = 16; 816655b958eb2180c7c06889f83f606d23421bf038cKenny Root 817655b958eb2180c7c06889f83f606d23421bf038cKenny Root void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw, 818655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t* salt) { 819655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t saltSize; 820655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (salt != NULL) { 821655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = SALT_SIZE; 822655b958eb2180c7c06889f83f606d23421bf038cKenny Root } else { 823655b958eb2180c7c06889f83f606d23421bf038cKenny Root // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found 824655b958eb2180c7c06889f83f606d23421bf038cKenny Root salt = (uint8_t*) "keystore"; 825655b958eb2180c7c06889f83f606d23421bf038cKenny Root // sizeof = 9, not strlen = 8 826655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize = sizeof("keystore"); 827655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 828655b958eb2180c7c06889f83f606d23421bf038cKenny Root 829655b958eb2180c7c06889f83f606d23421bf038cKenny Root PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, 830655b958eb2180c7c06889f83f606d23421bf038cKenny Root saltSize, 8192, keySize, key); 831655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 832655b958eb2180c7c06889f83f606d23421bf038cKenny Root 833655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateSalt(Entropy* entropy) { 834655b958eb2180c7c06889f83f606d23421bf038cKenny Root return entropy->generate_random_data(mSalt, sizeof(mSalt)); 835655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 836655b958eb2180c7c06889f83f606d23421bf038cKenny Root 837655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool generateMasterKey(Entropy* entropy) { 838655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) { 839655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 840655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 841655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!generateSalt(entropy)) { 842655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 843655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 844655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 845655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 846655b958eb2180c7c06889f83f606d23421bf038cKenny Root 847655b958eb2180c7c06889f83f606d23421bf038cKenny Root void setupMasterKeys() { 848655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption); 849655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption); 850655b958eb2180c7c06889f83f606d23421bf038cKenny Root setState(STATE_NO_ERROR); 851655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 852655b958eb2180c7c06889f83f606d23421bf038cKenny Root 853655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t mUserId; 854655b958eb2180c7c06889f83f606d23421bf038cKenny Root 855655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mUserDir; 856655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* mMasterKeyFile; 857655b958eb2180c7c06889f83f606d23421bf038cKenny Root 858655b958eb2180c7c06889f83f606d23421bf038cKenny Root State mState; 859655b958eb2180c7c06889f83f606d23421bf038cKenny Root int8_t mRetry; 860655b958eb2180c7c06889f83f606d23421bf038cKenny Root 861655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES]; 862655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint8_t mSalt[SALT_SIZE]; 863655b958eb2180c7c06889f83f606d23421bf038cKenny Root 864655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyEncryption; 865655b958eb2180c7c06889f83f606d23421bf038cKenny Root AES_KEY mMasterKeyDecryption; 866655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 867655b958eb2180c7c06889f83f606d23421bf038cKenny Root 868655b958eb2180c7c06889f83f606d23421bf038cKenny Roottypedef struct { 869655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t uid; 870655b958eb2180c7c06889f83f606d23421bf038cKenny Root const uint8_t* filename; 871655b958eb2180c7c06889f83f606d23421bf038cKenny Root} grant_t; 872655b958eb2180c7c06889f83f606d23421bf038cKenny Root 873655b958eb2180c7c06889f83f606d23421bf038cKenny Rootclass KeyStore { 874655b958eb2180c7c06889f83f606d23421bf038cKenny Rootpublic: 875655b958eb2180c7c06889f83f606d23421bf038cKenny Root KeyStore(Entropy* entropy, keymaster_device_t* device) 876655b958eb2180c7c06889f83f606d23421bf038cKenny Root : mEntropy(entropy) 877655b958eb2180c7c06889f83f606d23421bf038cKenny Root , mDevice(device) 878655b958eb2180c7c06889f83f606d23421bf038cKenny Root { 879655b958eb2180c7c06889f83f606d23421bf038cKenny Root memset(&mMetaData, '\0', sizeof(mMetaData)); 880655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 881655b958eb2180c7c06889f83f606d23421bf038cKenny Root 882655b958eb2180c7c06889f83f606d23421bf038cKenny Root ~KeyStore() { 883655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 884655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 885655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 886655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 887655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 888655b958eb2180c7c06889f83f606d23421bf038cKenny Root 889655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 890655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 891655b958eb2180c7c06889f83f606d23421bf038cKenny Root delete *it; 892655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.erase(it); 893655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 894655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 895655b958eb2180c7c06889f83f606d23421bf038cKenny Root 896655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* getDevice() const { 897655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mDevice; 898655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 899655b958eb2180c7c06889f83f606d23421bf038cKenny Root 900655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initialize() { 901655b958eb2180c7c06889f83f606d23421bf038cKenny Root readMetaData(); 902655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeKeystore()) { 903655b958eb2180c7c06889f83f606d23421bf038cKenny Root writeMetaData(); 904655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 905655b958eb2180c7c06889f83f606d23421bf038cKenny Root 906655b958eb2180c7c06889f83f606d23421bf038cKenny Root return ::NO_ERROR; 907655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 908655b958eb2180c7c06889f83f606d23421bf038cKenny Root 909655b958eb2180c7c06889f83f606d23421bf038cKenny Root State getState(uid_t uid) { 910655b958eb2180c7c06889f83f606d23421bf038cKenny Root return getUserState(uid)->getState(); 911655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 912655b958eb2180c7c06889f83f606d23421bf038cKenny Root 913655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode initializeUser(const android::String8& pw, uid_t uid) { 914655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 915655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->initialize(pw, mEntropy); 916655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 917655b958eb2180c7c06889f83f606d23421bf038cKenny Root 918655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) { 919655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 920655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 921655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->writeMasterKey(pw, mEntropy); 922655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 923655b958eb2180c7c06889f83f606d23421bf038cKenny Root 924655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode readMasterKey(const android::String8& pw, uid_t uid) { 925655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t user_id = get_user_id(uid); 926655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(user_id); 927655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->readMasterKey(pw, mEntropy); 928655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 929655b958eb2180c7c06889f83f606d23421bf038cKenny Root 930655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyName(const android::String8& keyName) { 931a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 932655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 933655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8(encoded); 934655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 935655b958eb2180c7c06889f83f606d23421bf038cKenny Root 936655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) { 937a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 938655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 939655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%u_%s", uid, encoded); 940655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 941655b958eb2180c7c06889f83f606d23421bf038cKenny Root 942655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) { 943a77e809ecff5190790906fb7a3c527259c735071Douglas Leung char encoded[encode_key_length(keyName) + 1]; // add 1 for null char 944655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(encoded, keyName); 945655b958eb2180c7c06889f83f606d23421bf038cKenny Root return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid, 946655b958eb2180c7c06889f83f606d23421bf038cKenny Root encoded); 947655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 948655b958eb2180c7c06889f83f606d23421bf038cKenny Root 949655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool reset(uid_t uid) { 950655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 951655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 952655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_UNINITIALIZED); 953655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState->reset(); 954655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 955655b958eb2180c7c06889f83f606d23421bf038cKenny Root 956655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool isEmpty(uid_t uid) const { 957655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* userState = getUserState(uid); 958655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (userState == NULL) { 959655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 960655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 961655b958eb2180c7c06889f83f606d23421bf038cKenny Root 962655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 963a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root struct dirent* file; 964a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!dir) { 965a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return true; 966a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 967a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root bool result = true; 968655b958eb2180c7c06889f83f606d23421bf038cKenny Root 969655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 970655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(filename, sizeof(filename), "%u_", uid); 971655b958eb2180c7c06889f83f606d23421bf038cKenny Root 972a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root while ((file = readdir(dir)) != NULL) { 973655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 974655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 975655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 976655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 977655b958eb2180c7c06889f83f606d23421bf038cKenny Root 978655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 979655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 980655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 981655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 982655b958eb2180c7c06889f83f606d23421bf038cKenny Root 983655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(file->d_name, filename, n)) { 984a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root result = false; 985a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root break; 986a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 987a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 988a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root closedir(dir); 989a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return result; 990a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 991a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 992655b958eb2180c7c06889f83f606d23421bf038cKenny Root void lock(uid_t uid) { 993655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 994655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->zeroizeMasterKeysInMemory(); 995655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->setState(STATE_LOCKED); 996a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 997a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 998655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) { 999655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1000f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1001f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState()); 1002822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1003822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1004822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1005822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1006822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root const uint8_t version = keyBlob->getVersion(); 100707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (version < CURRENT_BLOB_VERSION) { 1008cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root /* If we upgrade the key, we need to write it to disk again. Then 1009cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it must be read it again since the blob is encrypted each time 1010cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root * it's written. 1011cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1012655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (upgradeBlob(filename, keyBlob, version, type, uid)) { 1013655b958eb2180c7c06889f83f606d23421bf038cKenny Root if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR 1014f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root || (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(), 1015f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root userState->getState())) != NO_ERROR) { 1016cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return rc; 1017cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1018cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root } 1019822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1020822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 102117208e0de5a42722901d803118745cca25fd10c1Kenny Root /* 102217208e0de5a42722901d803118745cca25fd10c1Kenny Root * This will upgrade software-backed keys to hardware-backed keys when 102317208e0de5a42722901d803118745cca25fd10c1Kenny Root * the HAL for the device supports the newer key types. 102417208e0de5a42722901d803118745cca25fd10c1Kenny Root */ 102517208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc == NO_ERROR && type == TYPE_KEY_PAIR 102617208e0de5a42722901d803118745cca25fd10c1Kenny Root && mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 102717208e0de5a42722901d803118745cca25fd10c1Kenny Root && keyBlob->isFallback()) { 102817208e0de5a42722901d803118745cca25fd10c1Kenny Root ResponseCode imported = importKey(keyBlob->getValue(), keyBlob->getLength(), filename, 102917208e0de5a42722901d803118745cca25fd10c1Kenny Root uid, keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 103017208e0de5a42722901d803118745cca25fd10c1Kenny Root 103117208e0de5a42722901d803118745cca25fd10c1Kenny Root // The HAL allowed the import, reget the key to have the "fresh" 103217208e0de5a42722901d803118745cca25fd10c1Kenny Root // version. 103317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (imported == NO_ERROR) { 103417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = get(filename, keyBlob, TYPE_KEY_PAIR, uid); 103517208e0de5a42722901d803118745cca25fd10c1Kenny Root } 103617208e0de5a42722901d803118745cca25fd10c1Kenny Root } 103717208e0de5a42722901d803118745cca25fd10c1Kenny Root 1038d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (type != TYPE_ANY && keyBlob->getType() != type) { 1039822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type); 1040822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return KEY_NOT_FOUND; 1041822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1042822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1043822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1044a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1045a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1046655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) { 1047655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1048f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(), 1049f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root mEntropy); 1050a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1051a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 105207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void addGrant(const char* filename, uid_t granteeUid) { 1053655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* existing = getGrant(filename, granteeUid); 1054655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (existing == NULL) { 1055655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = new grant_t; 105607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root grant->uid = granteeUid; 1057a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename)); 1058655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.add(grant); 105970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 106070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 106170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 106207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root bool removeGrant(const char* filename, uid_t granteeUid) { 1063655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::iterator it(mGrants.begin()); 1064655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1065655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 1066655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (grant->uid == granteeUid 1067655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 1068655b958eb2180c7c06889f83f606d23421bf038cKenny Root mGrants.erase(it); 1069655b958eb2180c7c06889f83f606d23421bf038cKenny Root return true; 1070655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 107170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return false; 107370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1075a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom bool hasGrant(const char* filename, const uid_t uid) const { 1076a8c703d9fdd98e3caefb6e74cd03c2878cecd0a1Brian Carlstrom return getGrant(filename, uid) != NULL; 107770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 107870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1079f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid, 1080f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1081822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t* data; 1082822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root size_t dataLength; 1083822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int rc; 1084822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1085822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (mDevice->import_keypair == NULL) { 1086822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Keymaster doesn't support import!"); 1087822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1088822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1089822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 109017208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 109107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength); 1092822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc) { 109317208e0de5a42722901d803118745cca25fd10c1Kenny Root // If this is an old device HAL, try to fall back to an old version 109417208e0de5a42722901d803118745cca25fd10c1Kenny Root if (mDevice->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_2) { 109517208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength); 109617208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 109717208e0de5a42722901d803118745cca25fd10c1Kenny Root } 109817208e0de5a42722901d803118745cca25fd10c1Kenny Root 109917208e0de5a42722901d803118745cca25fd10c1Kenny Root if (rc) { 110017208e0de5a42722901d803118745cca25fd10c1Kenny Root ALOGE("Error while importing keypair: %d", rc); 110117208e0de5a42722901d803118745cca25fd10c1Kenny Root return SYSTEM_ERROR; 110217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 1103822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1104822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1105822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 1106822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root free(data); 1107822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1108f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED); 110917208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 1110f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1111655b958eb2180c7c06889f83f606d23421bf038cKenny Root return put(filename, &keyBlob, uid); 1112822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1113822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 11148ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root bool isHardwareBacked() const { 1115483407eaca108d3717bb49770915d6d95d5d0e0cKenny Root return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0; 11168ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 11178ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 1118655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid, 1119655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type) { 1120655b958eb2180c7c06889f83f606d23421bf038cKenny Root char filename[NAME_MAX]; 1121655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key_for_uid(filename, uid, keyName); 1122a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1123655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(uid); 1124655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::String8 filepath8; 1125a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1126655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1127655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (filepath8.string() == NULL) { 1128655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't create filepath for key %s", filename); 1129655b958eb2180c7c06889f83f606d23421bf038cKenny Root return SYSTEM_ERROR; 1130655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1131a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1132655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid); 1133655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1134655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1135655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1136a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1137655b958eb2180c7c06889f83f606d23421bf038cKenny Root // If this is one of the legacy UID->UID mappings, use it. 1138655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t euid = get_keystore_euid(uid); 1139655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (euid != uid) { 1140655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key_for_uid(filename, euid, keyName); 1141655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1142655b958eb2180c7c06889f83f606d23421bf038cKenny Root responseCode = get(filepath8.string(), keyBlob, type, uid); 1143655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (responseCode == NO_ERROR) { 1144655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1145655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1146655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 114770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1148655b958eb2180c7c06889f83f606d23421bf038cKenny Root // They might be using a granted key. 1149655b958eb2180c7c06889f83f606d23421bf038cKenny Root encode_key(filename, keyName); 1150655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1151655b958eb2180c7c06889f83f606d23421bf038cKenny Root strtoul(filename, &end, 10); 1152655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1153655b958eb2180c7c06889f83f606d23421bf038cKenny Root return KEY_NOT_FOUND; 1154655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1155655b958eb2180c7c06889f83f606d23421bf038cKenny Root filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename); 1156655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!hasGrant(filepath8.string(), uid)) { 1157655b958eb2180c7c06889f83f606d23421bf038cKenny Root return responseCode; 1158a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1159a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1160655b958eb2180c7c06889f83f606d23421bf038cKenny Root // It is a granted key. Try to load it. 1161655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filepath8.string(), keyBlob, type, uid); 1162a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1163a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1164655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1165655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns any existing UserState or creates it if it doesn't exist. 1166655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1167655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* getUserState(uid_t uid) { 1168655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1169655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1170655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); 1171655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1172655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1173655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1174655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1175655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1176a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1177655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1178655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = new UserState(userId); 1179655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!userState->initialize()) { 1180655b958eb2180c7c06889f83f606d23421bf038cKenny Root /* There's not much we can do if initialization fails. Trying to 1181655b958eb2180c7c06889f83f606d23421bf038cKenny Root * unlock the keystore for that user will fail as well, so any 1182655b958eb2180c7c06889f83f606d23421bf038cKenny Root * subsequent request for this user will just return SYSTEM_ERROR. 1183655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1184655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("User initialization failed for %u; subsuquent operations will fail", userId); 1185a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1186655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMasterKeys.add(userState); 1187655b958eb2180c7c06889f83f606d23421bf038cKenny Root return userState; 1188a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1189a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1190655b958eb2180c7c06889f83f606d23421bf038cKenny Root /** 1191655b958eb2180c7c06889f83f606d23421bf038cKenny Root * Returns NULL if the UserState doesn't already exist. 1192655b958eb2180c7c06889f83f606d23421bf038cKenny Root */ 1193655b958eb2180c7c06889f83f606d23421bf038cKenny Root const UserState* getUserState(uid_t uid) const { 1194655b958eb2180c7c06889f83f606d23421bf038cKenny Root uid_t userId = get_user_id(uid); 1195655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1196655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin()); 1197655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mMasterKeys.end(); it++) { 1198655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* state = *it; 1199655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (state->getUserId() == userId) { 1200655b958eb2180c7c06889f83f606d23421bf038cKenny Root return state; 1201655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1202655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1203a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1204655b958eb2180c7c06889f83f606d23421bf038cKenny Root return NULL; 1205a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1206a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1207655b958eb2180c7c06889f83f606d23421bf038cKenny Rootprivate: 1208655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sOldMasterKey; 1209655b958eb2180c7c06889f83f606d23421bf038cKenny Root static const char* sMetaDataFile; 1210655b958eb2180c7c06889f83f606d23421bf038cKenny Root Entropy* mEntropy; 121107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1212655b958eb2180c7c06889f83f606d23421bf038cKenny Root keymaster_device_t* mDevice; 1213a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1214655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<UserState*> mMasterKeys; 1215655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1216655b958eb2180c7c06889f83f606d23421bf038cKenny Root android::Vector<grant_t*> mGrants; 121770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1218655b958eb2180c7c06889f83f606d23421bf038cKenny Root typedef struct { 1219655b958eb2180c7c06889f83f606d23421bf038cKenny Root uint32_t version; 1220655b958eb2180c7c06889f83f606d23421bf038cKenny Root } keystore_metadata_t; 122170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1222655b958eb2180c7c06889f83f606d23421bf038cKenny Root keystore_metadata_t mMetaData; 1223655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1224655b958eb2180c7c06889f83f606d23421bf038cKenny Root const grant_t* getGrant(const char* filename, uid_t uid) const { 1225655b958eb2180c7c06889f83f606d23421bf038cKenny Root for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); 1226655b958eb2180c7c06889f83f606d23421bf038cKenny Root it != mGrants.end(); it++) { 1227655b958eb2180c7c06889f83f606d23421bf038cKenny Root grant_t* grant = *it; 122870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (grant->uid == uid 1229655b958eb2180c7c06889f83f606d23421bf038cKenny Root && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) { 123070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return grant; 123170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return NULL; 123470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 123570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1236822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1237822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Upgrade code. This will upgrade the key from the current version 1238822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * to whatever is newest. 1239822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1240655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion, 1241655b958eb2180c7c06889f83f606d23421bf038cKenny Root const BlobType type, uid_t uid) { 1242822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root bool updated = false; 1243822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root uint8_t version = oldVersion; 1244822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1245822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* From V0 -> V1: All old types were unknown */ 1246822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (version == 0) { 1247822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("upgrading to version 1 and setting type %d", type); 1248822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1249822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setType(type); 1250822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (type == TYPE_KEY_PAIR) { 1251655b958eb2180c7c06889f83f606d23421bf038cKenny Root importBlobAsKey(blob, filename, uid); 1252822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1253822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root version = 1; 1254822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root updated = true; 1255822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1256822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1257f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root /* From V1 -> V2: All old keys were encrypted */ 1258f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if (version == 1) { 1259f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGV("upgrading to version 2"); 1260f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1261f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->setEncrypted(true); 1262f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root version = 2; 1263f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root updated = true; 1264f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1265f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1266822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /* 1267822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * If we've updated, set the key blob to the right version 1268822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * and write it. 1269cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root */ 1270822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (updated) { 1271822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGV("updated and writing file %s", filename); 1272822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root blob->setVersion(version); 1273822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1274cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root 1275cfeae072c96d84f286ddbf0aff8055c12c7c4f15Kenny Root return updated; 1276822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1277822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1278822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root /** 1279822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Takes a blob that is an PEM-encoded RSA key as a byte array and 1280822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * converts it to a DER-encoded PKCS#8 for import into a keymaster. 1281822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * Then it overwrites the original blob with the new blob 1282822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root * format that is returned from the keymaster. 1283822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root */ 1284655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) { 1285822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root // We won't even write to the blob directly with this BIO, so const_cast is okay. 1286822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength())); 1287822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (b.get() == NULL) { 1288822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Problem instantiating BIO"); 1289822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1290822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1291822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1292822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL)); 1293822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (pkey.get() == NULL) { 1294822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't read old PEM file"); 1295822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1296822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1297822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1298822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get())); 1299822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL); 1300822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (len < 0) { 1301822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't measure PKCS#8 length"); 1302822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1303822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1304822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 130570c9889c5ca912e7c492580e1999f18ab65b267bKenny Root UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]); 130670c9889c5ca912e7c492580e1999f18ab65b267bKenny Root uint8_t* tmp = pkcs8key.get(); 1307822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) { 1308822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root ALOGE("Couldn't convert to PKCS#8"); 1309822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return SYSTEM_ERROR; 1310822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1311822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1312f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid, 1313f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE); 1314822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root if (rc != NO_ERROR) { 1315822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root return rc; 1316822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 1317822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root 1318655b958eb2180c7c06889f83f606d23421bf038cKenny Root return get(filename, blob, TYPE_KEY_PAIR, uid); 1319822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root } 132070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1321655b958eb2180c7c06889f83f606d23421bf038cKenny Root void readMetaData() { 1322655b958eb2180c7c06889f83f606d23421bf038cKenny Root int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY)); 1323655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (in < 0) { 1324655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1325655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1326655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1327655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1328655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, 1329655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 1330655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1331655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(in); 133270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 133370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1334655b958eb2180c7c06889f83f606d23421bf038cKenny Root void writeMetaData() { 1335655b958eb2180c7c06889f83f606d23421bf038cKenny Root const char* tmpFileName = ".metadata.tmp"; 1336655b958eb2180c7c06889f83f606d23421bf038cKenny Root int out = TEMP_FAILURE_RETRY(open(tmpFileName, 1337655b958eb2180c7c06889f83f606d23421bf038cKenny Root O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)); 1338655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (out < 0) { 1339655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't write metadata file: %s", strerror(errno)); 1340655b958eb2180c7c06889f83f606d23421bf038cKenny Root return; 1341655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1342655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData)); 1343655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (fileLength != sizeof(mMetaData)) { 1344655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength, 1345655b958eb2180c7c06889f83f606d23421bf038cKenny Root sizeof(mMetaData)); 134670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1347655b958eb2180c7c06889f83f606d23421bf038cKenny Root close(out); 1348655b958eb2180c7c06889f83f606d23421bf038cKenny Root rename(tmpFileName, sMetaDataFile); 134970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 135070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1351655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgradeKeystore() { 1352655b958eb2180c7c06889f83f606d23421bf038cKenny Root bool upgraded = false; 1353655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1354655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mMetaData.version == 0) { 1355655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = getUserState(0); 1356655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1357655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize first so the directory is made. 1358655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1359655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1360655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Migrate the old .masterkey file to user 0. 1361655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(sOldMasterKey, R_OK) == 0) { 1362655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) { 1363655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't migrate old masterkey: %s", strerror(errno)); 1364655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1365655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1366655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1367655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1368655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Initialize again in case we had a key. 1369655b958eb2180c7c06889f83f606d23421bf038cKenny Root userState->initialize(); 1370655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1371655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Try to migrate existing keys. 1372655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir("."); 1373655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!dir) { 1374655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Give up now; maybe we can upgrade later. 1375655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGE("couldn't open keystore's directory; something is wrong"); 1376655b958eb2180c7c06889f83f606d23421bf038cKenny Root return false; 1377655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1378655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1379655b958eb2180c7c06889f83f606d23421bf038cKenny Root struct dirent* file; 1380655b958eb2180c7c06889f83f606d23421bf038cKenny Root while ((file = readdir(dir)) != NULL) { 1381655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1382655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1383655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1384655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1385655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1386655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1387655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1388655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1389655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1390655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1391655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Find the current file's user. 1392655b958eb2180c7c06889f83f606d23421bf038cKenny Root char* end; 1393655b958eb2180c7c06889f83f606d23421bf038cKenny Root unsigned long thisUid = strtoul(file->d_name, &end, 10); 1394655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (end[0] != '_' || end[1] == 0) { 1395655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1396655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1397655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* otherUser = getUserState(thisUid); 1398655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherUser->getUserId() != 0) { 1399655b958eb2180c7c06889f83f606d23421bf038cKenny Root unlinkat(dirfd(dir), file->d_name, 0); 1400655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1401655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1402655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Rename the file into user directory. 1403655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* otherdir = opendir(otherUser->getUserDirName()); 1404655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (otherdir == NULL) { 1405655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open user directory for rename"); 1406655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1407655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1408655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) { 1409655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno)); 1410655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1411655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(otherdir); 1412655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1413655b958eb2180c7c06889f83f606d23421bf038cKenny Root closedir(dir); 1414655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1415655b958eb2180c7c06889f83f606d23421bf038cKenny Root mMetaData.version = 1; 1416655b958eb2180c7c06889f83f606d23421bf038cKenny Root upgraded = true; 1417655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1418655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1419655b958eb2180c7c06889f83f606d23421bf038cKenny Root return upgraded; 142070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1421655b958eb2180c7c06889f83f606d23421bf038cKenny Root}; 142270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1423655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sOldMasterKey = ".masterkey"; 1424655b958eb2180c7c06889f83f606d23421bf038cKenny Rootconst char* KeyStore::sMetaDataFile = ".metadata"; 142570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 142607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootnamespace android { 142707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootclass KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient { 142807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootpublic: 142907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root KeyStoreProxy(KeyStore* keyStore) 143007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root : mKeyStore(keyStore) 143107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root { 143207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1433a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 143407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root void binderDied(const wp<IBinder>&) { 143507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("binder death detected"); 143607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1437a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 143807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t test() { 1439d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1440d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_TEST)) { 1441d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: test", callingUid); 144207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 144307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1444a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1445655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->getState(callingUid); 1446a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1447a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 144807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { 1449d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1450d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 1451d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get", callingUid); 145207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 145307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1454a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 145507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 145607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1457494689083467ec372a58f094f041c8f102f39393Kenny Root 1458655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1459494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_GENERIC); 146007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 1461655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("Could not read %s", name8.string()); 146207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = NULL; 146307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = 0; 146407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 146507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 146607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 146707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *item = (uint8_t*) malloc(keyBlob.getLength()); 146807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root memcpy(*item, keyBlob.getValue(), keyBlob.getLength()); 146907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root *itemLength = keyBlob.getLength(); 147007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 147107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1472a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1473a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1474f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid, 1475f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1476d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1477d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1478d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: insert", callingUid); 147907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 148007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 148107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1482f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root State state = mKeyStore->getState(callingUid); 1483f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1484f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGD("calling get in state: %d", state); 1485f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return state; 1486f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root } 1487f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root 1488494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1489494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1490494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1491b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1492b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1493b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 149407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1495655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 149607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 149707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC); 1498655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 1499a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1500a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1501494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del(const String16& name, int targetUid) { 1502d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1503d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 1504d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del", callingUid); 150507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 150607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 150707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1508494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1509494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1510494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1511b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1512b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1513b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 151407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1515655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 1516298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 151707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 1518655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC, 1519655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 152007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 152107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 152207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 152307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 1524298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1525298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1526494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t exist(const String16& name, int targetUid) { 1527d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1528d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_EXIST)) { 1529d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: exist", callingUid); 153007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 153107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 153207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1533494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1534494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1535494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1536b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1537b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1538b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 153907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 1540655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 154107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1542655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 154307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 154407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 154507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1546298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1547298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 1548494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) { 1549d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1550d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SAW)) { 1551d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 155207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 155307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 155407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1555494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1556494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1557494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1558b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1559b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1560b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1561655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(targetUid); 1562655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 156307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (!dir) { 1564655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open directory for user: %s", strerror(errno)); 156507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 156607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 156707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 156807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 prefix8(prefix); 1569655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid)); 1570655b958eb2180c7c06889f83f606d23421bf038cKenny Root size_t n = filename.length(); 157107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 157207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct dirent* file; 157307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root while ((file = readdir(dir)) != NULL) { 1574655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 1575655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 1576655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1577655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1578655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1579655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 1580655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 1581655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 1582655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 1583655b958eb2180c7c06889f83f606d23421bf038cKenny Root 1584655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (!strncmp(filename.string(), file->d_name, n)) { 158507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const char* p = &file->d_name[n]; 158607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t plen = strlen(p); 158707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 158807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t extra = decode_key_length(p, plen); 158907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root char *match = (char*) malloc(extra + 1); 159007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (match != NULL) { 159107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root decode_key(match, p, plen); 159207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root matches->push(String16(match, extra)); 159307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(match); 159407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 159507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("could not allocate match of size %zd", extra); 159607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 159907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root closedir(dir); 160007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 160107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 1602298e7b1b0f9116e2054d594d7538379d86585035Kenny Root } 1603298e7b1b0f9116e2054d594d7538379d86585035Kenny Root 160407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t reset() { 1605d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1606d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_RESET)) { 1607d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: reset", callingUid); 160807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 160907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1610a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1611655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR; 1612a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 161307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 161407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 161507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("No keymaster device!"); 161607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1617a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 161807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 161907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all == NULL) { 162007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGV("keymaster device doesn't implement delete_all"); 162107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1622a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 162307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 162407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_all(device)) { 162507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Problem calling keymaster's delete_all"); 162607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 1627a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 162807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 162907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 1630a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 1631a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 163207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 163307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Here is the history. To improve the security, the parameters to generate the 163407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * master key has been changed. To make a seamless transition, we update the 163507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * file using the same password when the user unlock it for the first time. If 163607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * any thing goes wrong during the transition, the new file will not overwrite 163707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * the old one. This avoids permanent damages of the existing data. 163807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 163907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t password(const String16& password) { 1640d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1641d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_PASSWORD)) { 1642d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: password", callingUid); 164307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 164407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1645a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 164607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(password); 1647a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 1648655b958eb2180c7c06889f83f606d23421bf038cKenny Root switch (mKeyStore->getState(callingUid)) { 164907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_UNINITIALIZED: { 165007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // generate master key, encrypt with password, write to file, initialize mMasterKey*. 1651655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->initializeUser(password8, callingUid); 165207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_NO_ERROR: { 165407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // rewrite master key with new password. 1655655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->writeMasterKey(password8, callingUid); 165607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 165707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root case ::STATE_LOCKED: { 165807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // read master key, decrypt with password, initialize mMasterKey*. 1659655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->readMasterKey(password8, callingUid); 166007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 166207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 166307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 1664a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 166507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t lock() { 1666d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1667d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_LOCK)) { 1668d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: lock", callingUid); 166907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 167007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 167107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1672655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16739d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_NO_ERROR) { 167407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling lock in state: %d", state); 167507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 167607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 167770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1678655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->lock(callingUid); 167907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 168070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 1681a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 168207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t unlock(const String16& pw) { 1683d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1684d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_UNLOCK)) { 1685d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: unlock", callingUid); 168607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 168707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 168807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 1689655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 16909d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (state != ::STATE_LOCKED) { 169107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling unlock when not locked"); 169207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 169307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 169407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 169507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const String8 password8(pw); 169607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return password(pw); 169770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 169870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 169907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t zero() { 1700d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1701d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_ZERO)) { 1702d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: zero", callingUid); 170307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 170407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 170570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1706655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR; 170770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 170870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 170996427baf0094d50047049d329b0779c3c910402cKenny Root int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize, 171096427baf0094d50047049d329b0779c3c910402cKenny Root int32_t flags, Vector<sp<KeystoreArg> >* args) { 1711d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1712d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1713d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: generate", callingUid); 171407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 171507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 171670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1717494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1718494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1719494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1720b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1721b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1722b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1723655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1724f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 1725f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root ALOGW("calling generate in state: %d", state); 172607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 172707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 172870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 172907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root uint8_t* data; 173007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t dataLength; 173107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 173217208e0de5a42722901d803118745cca25fd10c1Kenny Root bool isFallback = false; 173370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 173507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 173607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 173707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 173870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 173907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->generate_keypair == NULL) { 174007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 174107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 174270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 174317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyType == EVP_PKEY_DSA) { 174496427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_dsa_keygen_params_t dsa_params; 174596427baf0094d50047049d329b0779c3c910402cKenny Root memset(&dsa_params, '\0', sizeof(dsa_params)); 174696427baf0094d50047049d329b0779c3c910402cKenny Root 174796427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 174896427baf0094d50047049d329b0779c3c910402cKenny Root keySize = DSA_DEFAULT_KEY_SIZE; 174996427baf0094d50047049d329b0779c3c910402cKenny Root } else if ((keySize % 64) != 0 || keySize < DSA_MIN_KEY_SIZE 175096427baf0094d50047049d329b0779c3c910402cKenny Root || keySize > DSA_MAX_KEY_SIZE) { 175196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 175296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 175396427baf0094d50047049d329b0779c3c910402cKenny Root } 175496427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.key_size = keySize; 175596427baf0094d50047049d329b0779c3c910402cKenny Root 175696427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() == 3) { 175796427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> gArg = args->itemAt(0); 175896427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pArg = args->itemAt(1); 175996427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> qArg = args->itemAt(2); 176096427baf0094d50047049d329b0779c3c910402cKenny Root 176196427baf0094d50047049d329b0779c3c910402cKenny Root if (gArg != NULL && pArg != NULL && qArg != NULL) { 176296427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator = reinterpret_cast<const uint8_t*>(gArg->data()); 176396427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.generator_len = gArg->size(); 176496427baf0094d50047049d329b0779c3c910402cKenny Root 176596427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p = reinterpret_cast<const uint8_t*>(pArg->data()); 176696427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_p_len = pArg->size(); 176796427baf0094d50047049d329b0779c3c910402cKenny Root 176896427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q = reinterpret_cast<const uint8_t*>(qArg->data()); 176996427baf0094d50047049d329b0779c3c910402cKenny Root dsa_params.prime_q_len = qArg->size(); 177096427baf0094d50047049d329b0779c3c910402cKenny Root } else { 177196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("not all DSA parameters were read"); 177296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 177396427baf0094d50047049d329b0779c3c910402cKenny Root } 177496427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() != 0) { 177596427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("DSA args must be 3"); 177696427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 177796427baf0094d50047049d329b0779c3c910402cKenny Root } 177896427baf0094d50047049d329b0779c3c910402cKenny Root 177917208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) { 178017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 178117208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 178217208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 178317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength); 178417208e0de5a42722901d803118745cca25fd10c1Kenny Root } 178517208e0de5a42722901d803118745cca25fd10c1Kenny Root } else if (keyType == EVP_PKEY_EC) { 178696427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_ec_keygen_params_t ec_params; 178796427baf0094d50047049d329b0779c3c910402cKenny Root memset(&ec_params, '\0', sizeof(ec_params)); 178896427baf0094d50047049d329b0779c3c910402cKenny Root 178996427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 179096427baf0094d50047049d329b0779c3c910402cKenny Root keySize = EC_DEFAULT_KEY_SIZE; 179196427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) { 179296427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 179396427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 179496427baf0094d50047049d329b0779c3c910402cKenny Root } 179596427baf0094d50047049d329b0779c3c910402cKenny Root ec_params.field_size = keySize; 179696427baf0094d50047049d329b0779c3c910402cKenny Root 179717208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) { 179817208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 179917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 180017208e0de5a42722901d803118745cca25fd10c1Kenny Root isFallback = true; 180117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength); 180217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 180396427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keyType == EVP_PKEY_RSA) { 180496427baf0094d50047049d329b0779c3c910402cKenny Root keymaster_rsa_keygen_params_t rsa_params; 180596427baf0094d50047049d329b0779c3c910402cKenny Root memset(&rsa_params, '\0', sizeof(rsa_params)); 180696427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = RSA_DEFAULT_EXPONENT; 180796427baf0094d50047049d329b0779c3c910402cKenny Root 180896427baf0094d50047049d329b0779c3c910402cKenny Root if (keySize == -1) { 180996427baf0094d50047049d329b0779c3c910402cKenny Root keySize = RSA_DEFAULT_KEY_SIZE; 181096427baf0094d50047049d329b0779c3c910402cKenny Root } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) { 181196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid key size %d", keySize); 181296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 181396427baf0094d50047049d329b0779c3c910402cKenny Root } 181496427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.modulus_size = keySize; 181596427baf0094d50047049d329b0779c3c910402cKenny Root 181696427baf0094d50047049d329b0779c3c910402cKenny Root if (args->size() > 1) { 181796427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("invalid number of arguments: %d", args->size()); 181896427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 181996427baf0094d50047049d329b0779c3c910402cKenny Root } else if (args->size() == 1) { 182096427baf0094d50047049d329b0779c3c910402cKenny Root sp<KeystoreArg> pubExpBlob = args->itemAt(0); 182196427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBlob != NULL) { 182296427baf0094d50047049d329b0779c3c910402cKenny Root Unique_BIGNUM pubExpBn( 182396427baf0094d50047049d329b0779c3c910402cKenny Root BN_bin2bn(reinterpret_cast<const unsigned char*>(pubExpBlob->data()), 182496427baf0094d50047049d329b0779c3c910402cKenny Root pubExpBlob->size(), NULL)); 182596427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExpBn.get() == NULL) { 182696427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("Could not convert public exponent to BN"); 182796427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 182896427baf0094d50047049d329b0779c3c910402cKenny Root } 182996427baf0094d50047049d329b0779c3c910402cKenny Root unsigned long pubExp = BN_get_word(pubExpBn.get()); 183096427baf0094d50047049d329b0779c3c910402cKenny Root if (pubExp == 0xFFFFFFFFL) { 183196427baf0094d50047049d329b0779c3c910402cKenny Root ALOGI("cannot represent public exponent as a long value"); 183296427baf0094d50047049d329b0779c3c910402cKenny Root return ::SYSTEM_ERROR; 183396427baf0094d50047049d329b0779c3c910402cKenny Root } 183496427baf0094d50047049d329b0779c3c910402cKenny Root rsa_params.public_exponent = pubExp; 183596427baf0094d50047049d329b0779c3c910402cKenny Root } 183696427baf0094d50047049d329b0779c3c910402cKenny Root } 183796427baf0094d50047049d329b0779c3c910402cKenny Root 183896427baf0094d50047049d329b0779c3c910402cKenny Root rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength); 183996427baf0094d50047049d329b0779c3c910402cKenny Root } else { 184096427baf0094d50047049d329b0779c3c910402cKenny Root ALOGW("Unsupported key type %d", keyType); 184196427baf0094d50047049d329b0779c3c910402cKenny Root rc = -1; 184296427baf0094d50047049d329b0779c3c910402cKenny Root } 184370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 184407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 184507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 184607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 184770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1848655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 name8(name); 1849655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 185070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 185107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR); 185207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root free(data); 185307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 185417208e0de5a42722901d803118745cca25fd10c1Kenny Root keyBlob.setFallback(isFallback); 185517208e0de5a42722901d803118745cca25fd10c1Kenny Root 1856655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(filename.string(), &keyBlob, callingUid); 185770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 185870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1859f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid, 1860f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root int32_t flags) { 1861d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1862d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_INSERT)) { 1863d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: import", callingUid); 186407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 186507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 186670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1867494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 1868494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 1869494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 1870b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 1871b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 1872b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 1873655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 1874f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) { 187507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling import in state: %d", state); 187607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 187707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 187870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 187907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 188060898896c3f3b2245d10076cac64346c956dbaa5Kenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid)); 188170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1882f9119d6414f43ef669d64e9e53feb043eda49cf3Kenny Root return mKeyStore->importKey(data, length, filename.string(), callingUid, flags); 188370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 188470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 188507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, 188607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root size_t* outLength) { 1887d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1888d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_SIGN)) { 1889d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: saw", callingUid); 189007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 189107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 18929a53d3eaf42104ddf02feeccec3cf7f5c1a34baeKenny Root 189307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 189407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 189570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1896d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("sign %s from uid %d", name8.string(), callingUid); 189707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 189870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1899655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1900d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ::TYPE_KEY_PAIR); 190107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 190207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 190307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 190470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 190507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 190607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 190707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("no keymaster device; cannot sign"); 190807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 190907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 191107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->sign_data == NULL) { 191207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device doesn't implement signing"); 191307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 191407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 191570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 191607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 191707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 191807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 191907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 192017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 192117208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 192217208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 192317208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 192417208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->sign_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 192517208e0de5a42722901d803118745cca25fd10c1Kenny Root length, out, outLength); 192617208e0de5a42722901d803118745cca25fd10c1Kenny Root } 192707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 192807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGW("device couldn't sign data"); 192907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 193007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 193170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 193207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 193370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 193470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 193507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, 193607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const uint8_t* signature, size_t signatureLength) { 1937d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1938d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_VERIFY)) { 1939d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: verify", callingUid); 194007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 194107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1943655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 19449d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 194507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling verify in state: %d", state); 194607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 194707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 194870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 194907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 195007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 195107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int rc; 195270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 1953655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 1954494689083467ec372a58f094f041c8f102f39393Kenny Root TYPE_KEY_PAIR); 195507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 195607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 195707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 195870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 195907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 196007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 196107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 196207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 196407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->verify_data == NULL) { 196507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 196607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 196707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 196807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_rsa_sign_params_t params; 196907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.digest_type = DIGEST_NONE; 197007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root params.padding_type = PADDING_NONE; 197170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 197217208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 197317208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 197417208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 197517208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 197617208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->verify_data(device, ¶ms, keyBlob.getValue(), keyBlob.getLength(), data, 197717208e0de5a42722901d803118745cca25fd10c1Kenny Root dataLength, signature, signatureLength); 197817208e0de5a42722901d803118745cca25fd10c1Kenny Root } 197907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 198007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 198107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 198207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 198307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 198470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 198570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 198607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 198707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * TODO: The abstraction between things stored in hardware and regular blobs 198807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * of data stored on the filesystem should be moved down to keystore itself. 198907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Unfortunately the Java code that calls this has naming conventions that it 199007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * knows about. Ideally keystore shouldn't be used to store random blobs of 199107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * data. 199207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * 199307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Until that happens, it's necessary to have a separate "get_pubkey" and 199407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * "del_key" since the Java code doesn't really communicate what it's 199507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * intentions are. 199607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 199707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { 1998d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 1999d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 2000d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: get_pubkey", callingUid); 200107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 200207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 200370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 200407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 200507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 200670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2007d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid); 200870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 2009655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, 201007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root TYPE_KEY_PAIR); 201107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 201207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 201307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 201507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 201607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 201707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 201807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 201970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 202007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->get_keypair_public == NULL) { 202107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("device has no get_keypair_public implementation!"); 202207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 202307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2024344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 202517208e0de5a42722901d803118745cca25fd10c1Kenny Root int rc; 202617208e0de5a42722901d803118745cca25fd10c1Kenny Root if (keyBlob.isFallback()) { 202717208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 202817208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 202917208e0de5a42722901d803118745cca25fd10c1Kenny Root } else { 203017208e0de5a42722901d803118745cca25fd10c1Kenny Root rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey, 203117208e0de5a42722901d803118745cca25fd10c1Kenny Root pubkeyLength); 203217208e0de5a42722901d803118745cca25fd10c1Kenny Root } 203307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc) { 203407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::SYSTEM_ERROR; 203507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2036344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 203707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2038344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root } 2039344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2040494689083467ec372a58f094f041c8f102f39393Kenny Root int32_t del_key(const String16& name, int targetUid) { 2041d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2042d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_DELETE)) { 2043d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: del_key", callingUid); 204407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 204507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2046344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 2047494689083467ec372a58f094f041c8f102f39393Kenny Root if (targetUid == -1) { 2048494689083467ec372a58f094f041c8f102f39393Kenny Root targetUid = callingUid; 2049494689083467ec372a58f094f041c8f102f39393Kenny Root } else if (!is_granted_to(callingUid, targetUid)) { 2050b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root return ::PERMISSION_DENIED; 2051b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root } 2052b88c3eb96625513df4cc998d739d17266ebaf89fKenny Root 205307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2054655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 2055344e0bc23ca46b9acec97ac8bcd87949bde0ccabKenny Root 205607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root Blob keyBlob; 2057655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR, 2058655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 205907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (responseCode != ::NO_ERROR) { 206007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return responseCode; 206107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2062a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 206307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ResponseCode rc = ::NO_ERROR; 2064a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 206507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 206607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device == NULL) { 206707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 206807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } else { 206907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root // A device doesn't have to implement delete_keypair. 207017208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 207107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 207207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root rc = ::SYSTEM_ERROR; 207307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 207507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2076a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 207707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (rc != ::NO_ERROR) { 207807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return rc; 207907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 2080a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 208107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR; 2082a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 208307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 208407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t grant(const String16& name, int32_t granteeUid) { 2085d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2086d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 2087d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: grant", callingUid); 208807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 208907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2091655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 20929d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 209307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling grant in state: %d", state); 209407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 209507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 209607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 209707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2098655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 209907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2100655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 210107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 210207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 210307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2104655b958eb2180c7c06889f83f606d23421bf038cKenny Root mKeyStore->addGrant(filename.string(), granteeUid); 210507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::NO_ERROR; 2106a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 210707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 210807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int32_t ungrant(const String16& name, int32_t granteeUid) { 2109d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2110d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GRANT)) { 2111d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: ungrant", callingUid); 211207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return ::PERMISSION_DENIED; 211307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 211407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2115655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21169d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root if (!isKeystoreUnlocked(state)) { 211707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGD("calling ungrant in state: %d", state); 211807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return state; 211907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 212007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 212107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2122655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 212307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2124655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 212507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND; 212607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 212707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2128655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND; 2129a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 213007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 213107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int64_t getmtime(const String16& name) { 2132d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2133d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root if (!has_permission(callingUid, P_GET)) { 2134d38a0b07a3104fcb1e747a0fa06641dee8fc058fKenny Root ALOGW("permission denied for %d: getmtime", callingUid); 213536a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 213607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 213707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 213807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root String8 name8(name); 2139655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid)); 214007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2141655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(filename.string(), R_OK) == -1) { 2142655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not access %s for getmtime", filename.string()); 214336a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 2144a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 214507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2146655b958eb2180c7c06889f83f606d23421bf038cKenny Root int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY)); 214707438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (fd < 0) { 2148655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not open %s for getmtime", filename.string()); 214936a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 215007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 215207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root struct stat s; 215307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root int ret = fstat(fd, &s); 215407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root close(fd); 215507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret == -1) { 2156655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("could not stat %s for getmtime", filename.string()); 215736a9e231e03734cd2143383d26388455c1764e17Kenny Root return -1L; 215807438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root } 215907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 216036a9e231e03734cd2143383d26388455c1764e17Kenny Root return static_cast<int64_t>(s.st_mtime); 2161a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 216207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 2163d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, 2164d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root int32_t destUid) { 21650225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2166d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!has_permission(callingUid, P_DUPLICATE)) { 2167d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGW("permission denied for %d: duplicate", callingUid); 21680225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return -1L; 21690225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21700225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2171655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 21720225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root if (!isKeystoreUnlocked(state)) { 2173d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("calling duplicate in state: %d", state); 21740225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return state; 21750225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21760225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2177d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) { 2178d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root srcUid = callingUid; 2179d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } else if (!is_granted_to(callingUid, srcUid)) { 2180d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid); 21810225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::PERMISSION_DENIED; 21820225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 21830225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2184d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (destUid == -1) { 2185d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root destUid = callingUid; 2186d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21870225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2188d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (srcUid != destUid) { 2189d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (static_cast<uid_t>(srcUid) != callingUid) { 2190d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("can only duplicate from caller to other or to same uid: " 2191d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root "calling=%d, srcUid=%d, destUid=%d", callingUid, srcUid, destUid); 2192d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2193d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21940225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2195d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (!is_granted_to(callingUid, destUid)) { 2196d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid); 2197d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return ::PERMISSION_DENIED; 2198d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root } 21990225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22000225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2201d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 source8(srcKey); 2202655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid)); 2203d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2204d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root String8 target8(destKey); 2205655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, srcUid)); 22060225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2207655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) { 2208655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGD("destination already exists: %s", targetFile.string()); 22090225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root return ::SYSTEM_ERROR; 22100225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22110225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 2212d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root Blob keyBlob; 2213655b958eb2180c7c06889f83f606d23421bf038cKenny Root ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, 2214655b958eb2180c7c06889f83f606d23421bf038cKenny Root callingUid); 2215d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root if (responseCode != ::NO_ERROR) { 2216d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root return responseCode; 22170225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 2218d53bc92f1cc4eb669ec015480cebe5ae7aaaf7cfKenny Root 2219655b958eb2180c7c06889f83f606d23421bf038cKenny Root return mKeyStore->put(targetFile.string(), &keyBlob, callingUid); 22200225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root } 22210225407783ee339164a0cd8ca5ef04c99d27c59aKenny Root 22228ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root int32_t is_hardware_backed() { 22238ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root return mKeyStore->isHardwareBacked() ? 1 : 0; 22248ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root } 22258ddf35a6e1fd80a7d0685041d2bfc77078277c9dKenny Root 2226a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root int32_t clear_uid(int64_t targetUid) { 2227a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root uid_t callingUid = IPCThreadState::self()->getCallingUid(); 2228a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!has_permission(callingUid, P_CLEAR_UID)) { 2229a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGW("permission denied for %d: clear_uid", callingUid); 2230a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::PERMISSION_DENIED; 2231a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2232a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2233655b958eb2180c7c06889f83f606d23421bf038cKenny Root State state = mKeyStore->getState(callingUid); 2234a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!isKeystoreUnlocked(state)) { 2235a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ALOGD("calling clear_uid in state: %d", state); 2236a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return state; 2237a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2238a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2239a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root const keymaster_device_t* device = mKeyStore->getDevice(); 2240a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device == NULL) { 2241655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't get keymaster device"); 2242a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2243a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2244a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2245655b958eb2180c7c06889f83f606d23421bf038cKenny Root UserState* userState = mKeyStore->getUserState(callingUid); 2246655b958eb2180c7c06889f83f606d23421bf038cKenny Root DIR* dir = opendir(userState->getUserDirName()); 2247a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (!dir) { 2248655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("can't open user directory: %s", strerror(errno)); 2249a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return ::SYSTEM_ERROR; 2250a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2251a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2252655b958eb2180c7c06889f83f606d23421bf038cKenny Root char prefix[NAME_MAX]; 2253655b958eb2180c7c06889f83f606d23421bf038cKenny Root int n = snprintf(prefix, NAME_MAX, "%u_", static_cast<uid_t>(targetUid)); 2254a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2255a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root ResponseCode rc = ::NO_ERROR; 2256a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2257a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root struct dirent* file; 2258a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root while ((file = readdir(dir)) != NULL) { 2259655b958eb2180c7c06889f83f606d23421bf038cKenny Root // We only care about files. 2260655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_type != DT_REG) { 2261a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2262a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2263a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2264655b958eb2180c7c06889f83f606d23421bf038cKenny Root // Skip anything that starts with a "." 2265655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (file->d_name[0] == '.') { 2266655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2267655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2268655b958eb2180c7c06889f83f606d23421bf038cKenny Root 2269655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (strncmp(prefix, file->d_name, n)) { 2270655b958eb2180c7c06889f83f606d23421bf038cKenny Root continue; 2271655b958eb2180c7c06889f83f606d23421bf038cKenny Root } 2272a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2273655b958eb2180c7c06889f83f606d23421bf038cKenny Root String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name)); 2274a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root Blob keyBlob; 2275655b958eb2180c7c06889f83f606d23421bf038cKenny Root if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, callingUid) 2276655b958eb2180c7c06889f83f606d23421bf038cKenny Root != ::NO_ERROR) { 2277655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't open %s", filename.string()); 2278a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root continue; 2279a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2280a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2281a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (keyBlob.getType() == ::TYPE_KEY_PAIR) { 2282a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root // A device doesn't have to implement delete_keypair. 228317208e0de5a42722901d803118745cca25fd10c1Kenny Root if (device->delete_keypair != NULL && !keyBlob.isFallback()) { 2284a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) { 2285a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2286655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("device couldn't remove %s", filename.string()); 2287a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2288a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2289a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2290a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 22915f53124250025d3113c9c598a2f101330144b10cKenny Root if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) { 2292a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root rc = ::SYSTEM_ERROR; 2293655b958eb2180c7c06889f83f606d23421bf038cKenny Root ALOGW("couldn't unlink %s", filename.string()); 2294a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2295a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2296a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root closedir(dir); 2297a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 2298a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root return rc; 2299a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root } 2300a9bb549868035e05450a9b918f8d7de9deca5343Kenny Root 230107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Rootprivate: 23029d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root inline bool isKeystoreUnlocked(State state) { 23039d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root switch (state) { 23049d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_NO_ERROR: 23059d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return true; 23069d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_UNINITIALIZED: 23079d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root case ::STATE_LOCKED: 23089d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 23099d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root } 23109d45d1caba5135e6b8bd6d05d449e8dcf52b6802Kenny Root return false; 2311a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 231207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 231307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ::KeyStore* mKeyStore; 231407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; 231507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root 231607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root}; // namespace android 2317a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2318a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Rootint main(int argc, char* argv[]) { 2319a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (argc < 2) { 2320a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("A directory must be specified!"); 2321a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2322a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2323a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (chdir(argv[1]) == -1) { 2324a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root ALOGE("chdir: %s: %s", argv[1], strerror(errno)); 2325a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2326a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 2327a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root 2328a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root Entropy entropy; 2329a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root if (!entropy.open()) { 2330a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2331a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 233270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 233370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root keymaster_device_t* dev; 233470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root if (keymaster_device_initialize(&dev)) { 233570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root ALOGE("keystore keymaster could not be initialized; exiting"); 233670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root return 1; 233770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root } 233870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 233970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root KeyStore keyStore(&entropy, dev); 2340655b958eb2180c7c06889f83f606d23421bf038cKenny Root keyStore.initialize(); 234107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::IServiceManager> sm = android::defaultServiceManager(); 234207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore); 234307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy); 234407438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root if (ret != android::OK) { 234507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root ALOGE("Couldn't register binder service!"); 234607438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root return -1; 2347a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root } 234870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 234907438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root /* 235007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * We're the only thread in existence, so we're just going to process 235107438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root * Binder transaction as a single-threaded program. 235207438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root */ 235307438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root android::IPCThreadState::self()->joinThreadPool(); 235470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root 235507438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root keymaster_device_release(dev); 2356a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root return 1; 2357a91203b08350b2fc7efda5b1eab39e7541476b3aKenny Root} 2358